From 5468b1186d119ff40f551196001183e5bb783ef0 Mon Sep 17 00:00:00 2001 From: Mrxtyyp <1126084777@qq.com> Date: Sun, 28 Apr 2024 15:30:35 +0800 Subject: [PATCH] feat: first commit --- .DS_Store | Bin 0 -> 8196 bytes .dockerignore | 3 + .env | 5 + .env.analyze | 23 + .env.development | 16 + .env.docker | 22 + .env.production | 25 + .eslintignore | 15 + .eslintrc.js | 15 + .gitignore | 110 + .npmrc | 7 + .prettierignore | 17 + .prettierrc.js | 20 + .stylelintrc.js | 4 + Dockerfile | 24 + README.md | 113 + deploy/default.conf | 18 + docker/Dockerfile | 8 + docker/Makefile | 25 + docs/README_ZH.md | 24 + docs/template/会员信息模板.xlsx | Bin 0 -> 18944 bytes docs/template/供应商模板.xlsx | Bin 0 -> 19456 bytes docs/template/客户信息模板.xlsx | Bin 0 -> 19456 bytes images/add-menu-zh.png | Bin 0 -> 92146 bytes images/home-page-zh.png | Bin 0 -> 121887 bytes images/login-page-en.png | Bin 0 -> 201474 bytes images/register-page-zh.png | Bin 0 -> 194526 bytes images/role-permission-zh.png | Bin 0 -> 98014 bytes images/user-manage-zh.png | Bin 0 -> 78390 bytes images/user-mgt.png | Bin 0 -> 117563 bytes images/wansenai-logo.png | Bin 0 -> 7551 bytes index.html | 153 + internal/.DS_Store | Bin 0 -> 6148 bytes internal/stylelint-config/.eslintignore | 4 + internal/stylelint-config/build.config.ts | 10 + internal/stylelint-config/package.json | 39 + internal/stylelint-config/src/index.ts | 91 + internal/stylelint-config/tsconfig.json | 5 + internal/ts-config/.eslintignore | 4 + internal/ts-config/base.json | 27 + internal/ts-config/node-server.json | 18 + internal/ts-config/node.json | 12 + internal/ts-config/package.json | 17 + internal/ts-config/vue-app.json | 11 + internal/vite-config/.eslintignore | 4 + internal/vite-config/build.config.ts | 10 + internal/vite-config/package.json | 50 + .../vite-config/src/config/application.ts | 115 + internal/vite-config/src/config/common.ts | 46 + internal/vite-config/src/config/package.ts | 42 + internal/vite-config/src/index.ts | 2 + internal/vite-config/src/plugins/appConfig.ts | 96 + internal/vite-config/src/plugins/compress.ts | 38 + internal/vite-config/src/plugins/html.ts | 13 + internal/vite-config/src/plugins/index.ts | 61 + internal/vite-config/src/plugins/mock.ts | 19 + internal/vite-config/src/plugins/svgSprite.ts | 17 + .../vite-config/src/plugins/visualizer.ts | 14 + internal/vite-config/src/utils/env.ts | 44 + internal/vite-config/src/utils/hash.ts | 8 + internal/vite-config/src/utils/modifyVars.ts | 47 + internal/vite-config/tsconfig.json | 5 + nginx.conf | 33 + package.json | 152 + packages/.DS_Store | Bin 0 -> 6148 bytes packages/hooks/.eslintrc.js | 4 + packages/hooks/build.config.ts | 10 + packages/hooks/package.json | 29 + packages/hooks/src/index.ts | 6 + packages/hooks/src/onMountedOrActivated.ts | 25 + packages/hooks/src/useAttrs.ts | 43 + packages/hooks/src/useRefs.ts | 24 + packages/hooks/src/useScrollTo.ts | 60 + packages/hooks/src/useWindowSizeFn.ts | 40 + packages/hooks/tsconfig.json | 5 + packages/types/.eslintrc.js | 4 + packages/types/build.config.ts | 10 + packages/types/package.json | 22 + packages/types/src/index.ts | 1 + packages/types/src/utils.ts | 58 + packages/types/tsconfig.json | 5 + pnpm-lock.yaml | 15390 ++++++++++++++++ pnpm-workspace.yaml | 4 + public/favicon.ico | Bin 0 -> 16025 bytes public/resource/.DS_Store | Bin 0 -> 6148 bytes public/resource/img/logo.png | Bin 0 -> 16025 bytes .../tinymce/icons/default/icons.min.js | 1 + public/resource/tinymce/langs/README.md | 3 + public/resource/tinymce/langs/en.js | 419 + public/resource/tinymce/langs/zh_CN.js | 389 + public/resource/tinymce/license.txt | 21 + .../resource/tinymce/models/dom/model.min.js | 4 + .../tinymce/plugins/advlist/plugin.min.js | 4 + .../tinymce/plugins/anchor/plugin.min.js | 4 + .../tinymce/plugins/autolink/plugin.min.js | 4 + .../tinymce/plugins/autoresize/plugin.min.js | 4 + .../tinymce/plugins/autosave/plugin.min.js | 4 + .../tinymce/plugins/charmap/plugin.min.js | 4 + .../tinymce/plugins/code/plugin.min.js | 4 + .../tinymce/plugins/codesample/plugin.min.js | 4 + .../plugins/directionality/plugin.min.js | 4 + .../plugins/emoticons/js/emojiimages.js | 1 + .../plugins/emoticons/js/emojiimages.min.js | 3 + .../tinymce/plugins/emoticons/js/emojis.js | 1 + .../plugins/emoticons/js/emojis.min.js | 2 + .../tinymce/plugins/emoticons/plugin.min.js | 4 + .../tinymce/plugins/fullscreen/plugin.min.js | 4 + .../tinymce/plugins/help/plugin.min.js | 4 + .../tinymce/plugins/image/plugin.min.js | 4 + .../tinymce/plugins/importcss/plugin.min.js | 4 + .../plugins/insertdatetime/plugin.min.js | 4 + .../tinymce/plugins/link/plugin.min.js | 4 + .../tinymce/plugins/lists/plugin.min.js | 4 + .../tinymce/plugins/media/plugin.min.js | 4 + .../tinymce/plugins/nonbreaking/plugin.min.js | 4 + .../tinymce/plugins/pagebreak/plugin.min.js | 4 + .../tinymce/plugins/preview/plugin.min.js | 4 + .../tinymce/plugins/quickbars/plugin.min.js | 4 + .../tinymce/plugins/save/plugin.min.js | 4 + .../plugins/searchreplace/plugin.min.js | 4 + .../tinymce/plugins/table/plugin.min.js | 4 + .../tinymce/plugins/template/plugin.min.js | 4 + .../plugins/visualblocks/plugin.min.js | 4 + .../tinymce/plugins/visualchars/plugin.min.js | 4 + .../tinymce/plugins/wordcount/plugin.min.js | 4 + .../skins/content/dark/content.min.css | 1 + .../skins/content/default/content.min.css | 1 + .../skins/content/document/content.min.css | 1 + .../content/tinymce-5-dark/content.min.css | 1 + .../skins/content/tinymce-5/content.min.css | 1 + .../skins/content/writer/content.min.css | 1 + .../ui/oxide-dark/content.inline.min.css | 1 + .../skins/ui/oxide-dark/content.min.css | 1 + .../tinymce/skins/ui/oxide-dark/skin.min.css | 1 + .../ui/oxide-dark/skin.shadowdom.min.css | 1 + .../skins/ui/oxide/content.inline.min.css | 1 + .../tinymce/skins/ui/oxide/content.min.css | 1 + .../tinymce/skins/ui/oxide/skin.min.css | 1 + .../skins/ui/oxide/skin.shadowdom.min.css | 1 + .../ui/tinymce-5-dark/content.inline.min.css | 1 + .../skins/ui/tinymce-5-dark/content.min.css | 1 + .../skins/ui/tinymce-5-dark/skin.min.css | 1 + .../ui/tinymce-5-dark/skin.shadowdom.min.css | 1 + .../skins/ui/tinymce-5/content.inline.min.css | 1 + .../skins/ui/tinymce-5/content.min.css | 1 + .../tinymce/skins/ui/tinymce-5/skin.min.css | 1 + .../skins/ui/tinymce-5/skin.shadowdom.min.css | 1 + .../tinymce/themes/silver/theme.min.js | 4 + public/resource/tinymce/tinymce.d.ts | 3185 ++++ public/resource/tinymce/tinymce.min.js | 4 + src/.DS_Store | Bin 0 -> 10244 bytes src/App.vue | 25 + src/api/.DS_Store | Bin 0 -> 8196 bytes src/api/basic/common.ts | 70 + src/api/basic/customer.ts | 82 + src/api/basic/incomeExpense.ts | 69 + src/api/basic/member.ts | 79 + src/api/basic/model/customerModel.ts | 49 + src/api/basic/model/incomeExpenseModel.ts | 24 + src/api/basic/model/memberModel.ts | 29 + src/api/basic/model/operatorModel.ts | 23 + src/api/basic/model/supplierModel.ts | 88 + src/api/basic/model/warehouseModel.ts | 33 + src/api/basic/operator.ts | 68 + src/api/basic/supplier.ts | 94 + src/api/basic/warehouse.ts | 86 + src/api/financial/account.ts | 68 + src/api/financial/advance.ts | 96 + src/api/financial/collection.ts | 99 + src/api/financial/expense.ts | 89 + src/api/financial/income.ts | 88 + src/api/financial/model/accountModel.ts | 29 + src/api/financial/model/advanceModel.ts | 65 + src/api/financial/model/collectionModel.ts | 86 + src/api/financial/model/expenseModel.ts | 58 + src/api/financial/model/incomeModel.ts | 58 + src/api/financial/model/paymentModel.ts | 87 + src/api/financial/model/transferModel.ts | 54 + src/api/financial/payment.ts | 101 + src/api/financial/transfer.ts | 89 + src/api/model/baseModel.ts | 25 + .../product/model/productAttributeModel.ts | 30 + src/api/product/model/productCategoryModel.ts | 24 + src/api/product/model/productModel.ts | 183 + src/api/product/model/productUnitModel.ts | 28 + src/api/product/product.ts | 125 + src/api/product/productAttribute.ts | 52 + src/api/product/productCategory.ts | 43 + src/api/product/productUnit.ts | 58 + src/api/purchase/model/orderModel.ts | 82 + src/api/purchase/model/refundModel.ts | 69 + src/api/purchase/model/storageModel.ts | 68 + src/api/purchase/order.ts | 97 + src/api/purchase/refund.ts | 97 + src/api/purchase/storage.ts | 97 + src/api/receipt/model/receiptModel.ts | 36 + src/api/receipt/receipt.ts | 26 + src/api/report/report.ts | 359 + src/api/report/reportModel.ts | 313 + src/api/retail/model/refundModel.ts | 49 + src/api/retail/model/shipmentsModel.ts | 82 + src/api/retail/refund.ts | 102 + src/api/retail/shipments.ts | 118 + src/api/sale/model/orderModel.ts | 83 + src/api/sale/model/refundModel.ts | 94 + src/api/sale/model/shipmentsModel.ts | 94 + src/api/sale/order.ts | 98 + src/api/sale/refund.ts | 98 + src/api/sale/shipments.ts | 98 + src/api/sys/captcha.ts | 23 + src/api/sys/config.ts | 20 + src/api/sys/dept.ts | 42 + src/api/sys/menu.ts | 37 + src/api/sys/model/captchaModel.ts | 12 + src/api/sys/model/configModel.ts | 20 + src/api/sys/model/dpetModel.ts | 29 + src/api/sys/model/menuModel.ts | 70 + src/api/sys/model/roleModel.ts | 35 + src/api/sys/model/uploadModel.ts | 5 + src/api/sys/model/userModel.ts | 119 + src/api/sys/role.ts | 73 + src/api/sys/upload.ts | 25 + src/api/sys/user.ts | 271 + src/api/warehouse/allotShipments.ts | 89 + src/api/warehouse/assemble.ts | 89 + src/api/warehouse/disassemble.ts | 89 + .../warehouse/model/allotShipmentsModel.ts | 60 + src/api/warehouse/model/assembleModel.ts | 60 + src/api/warehouse/model/disassembleModel.ts | 71 + src/api/warehouse/model/shipmentsModel.ts | 65 + src/api/warehouse/model/storageModel.ts | 64 + src/api/warehouse/shipments.ts | 89 + src/api/warehouse/storage.ts | 89 + src/assets/.DS_Store | Bin 0 -> 6148 bytes src/assets/icons/download-count.svg | 1 + src/assets/icons/dynamic-avatar-1.svg | 1 + src/assets/icons/dynamic-avatar-2.svg | 1 + src/assets/icons/dynamic-avatar-3.svg | 1 + src/assets/icons/dynamic-avatar-4.svg | 1 + src/assets/icons/dynamic-avatar-5.svg | 1 + src/assets/icons/dynamic-avatar-6.svg | 1 + src/assets/icons/moon.svg | 16 + src/assets/icons/sun.svg | 42 + src/assets/icons/test.svg | 21 + src/assets/icons/total-sales.svg | 1 + src/assets/icons/transaction.svg | 1 + src/assets/icons/visit-count.svg | 1 + src/assets/images/demo.png | Bin 0 -> 33342 bytes src/assets/images/header.jpg | Bin 0 -> 31553 bytes src/assets/images/login-page-bg-2.png | Bin 0 -> 253341 bytes src/assets/images/logo.png | Bin 0 -> 16025 bytes src/assets/svg/illustration.svg | 1 + src/assets/svg/login-bg-dark.svg | 19 + src/assets/svg/login-bg.svg | 17 + src/assets/svg/login-box-bg.svg | 1 + src/assets/svg/net-error.svg | 1 + src/assets/svg/no-data.svg | 1 + src/assets/svg/preview/p-rotate.svg | 1 + src/assets/svg/preview/resume.svg | 1 + src/assets/svg/preview/scale.svg | 1 + src/assets/svg/preview/unrotate.svg | 1 + src/assets/svg/preview/unscale.svg | 1 + src/components/.DS_Store | Bin 0 -> 14340 bytes src/components/Application/index.ts | 15 + .../Application/src/AppDarkModeToggle.vue | 89 + .../Application/src/AppLocalePicker.vue | 72 + src/components/Application/src/AppLogo.vue | 96 + .../Application/src/AppProvider.vue | 82 + .../Application/src/search/AppSearch.vue | 33 + .../src/search/AppSearchFooter.vue | 57 + .../src/search/AppSearchKeyItem.vue | 12 + .../Application/src/search/AppSearchModal.vue | 267 + .../Application/src/search/useMenuSearch.ts | 167 + .../Application/src/useAppContext.ts | 17 + src/components/Basic/index.ts | 8 + src/components/Basic/src/BasicArrow.vue | 80 + src/components/Basic/src/BasicHelp.vue | 114 + src/components/Basic/src/BasicTitle.vue | 76 + src/components/Button/index.ts | 9 + src/components/Button/src/BasicButton.vue | 39 + .../Button/src/PopConfirmButton.vue | 54 + src/components/Button/src/props.ts | 26 + src/components/ClickOutSide/index.ts | 4 + .../ClickOutSide/src/ClickOutSide.vue | 20 + src/components/Container/index.ts | 8 + .../Container/src/ScrollContainer.vue | 94 + .../src/collapse/CollapseContainer.vue | 118 + .../Container/src/collapse/CollapseHeader.vue | 44 + src/components/Container/src/typing.ts | 17 + src/components/ContextMenu/index.ts | 3 + .../ContextMenu/src/ContextMenu.vue | 209 + .../ContextMenu/src/createContextMenu.ts | 77 + src/components/ContextMenu/src/typing.ts | 36 + src/components/CountDown/index.ts | 6 + src/components/CountDown/src/CountButton.vue | 62 + .../CountDown/src/CountdownInput.vue | 54 + src/components/CountDown/src/useCountdown.ts | 51 + src/components/CountTo/index.ts | 4 + src/components/CountTo/src/CountTo.vue | 110 + src/components/Cropper/index.ts | 7 + src/components/Cropper/src/Cropper.vue | 188 + src/components/Cropper/src/CropperAvatar.vue | 166 + src/components/Cropper/src/CropperModal.vue | 295 + src/components/Cropper/src/typing.ts | 8 + src/components/Description/index.ts | 6 + .../Description/src/Description.vue | 195 + src/components/Description/src/typing.ts | 50 + .../Description/src/useDescription.ts | 28 + src/components/Drawer/index.ts | 6 + src/components/Drawer/src/BasicDrawer.vue | 256 + .../Drawer/src/components/DrawerFooter.vue | 83 + .../Drawer/src/components/DrawerHeader.vue | 75 + src/components/Drawer/src/props.ts | 45 + src/components/Drawer/src/typing.ts | 194 + src/components/Drawer/src/useDrawer.ts | 161 + src/components/Dropdown/index.ts | 5 + src/components/Dropdown/src/Dropdown.vue | 98 + src/components/Dropdown/src/typing.ts | 9 + src/components/Form/index.ts | 17 + src/components/Form/src/BasicForm.vue | 354 + src/components/Form/src/componentMap.ts | 88 + .../Form/src/components/ApiCascader.vue | 200 + .../Form/src/components/ApiMultipleSelect.vue | 155 + .../src/components/ApiMultipleTreeSelect.vue | 104 + .../Form/src/components/ApiRadioGroup.vue | 136 + .../Form/src/components/ApiSelect.vue | 153 + .../Form/src/components/ApiTransfer.vue | 137 + .../Form/src/components/ApiTree.vue | 92 + .../Form/src/components/ApiTreeSelect.vue | 101 + .../Form/src/components/FormAction.vue | 134 + .../Form/src/components/FormItem.vue | 414 + .../Form/src/components/RadioButtonGroup.vue | 63 + src/components/Form/src/helper.ts | 91 + src/components/Form/src/hooks/useAdvanced.ts | 171 + src/components/Form/src/hooks/useAutoFocus.ts | 40 + .../Form/src/hooks/useComponentRegister.ts | 11 + src/components/Form/src/hooks/useForm.ts | 122 + .../Form/src/hooks/useFormContext.ts | 17 + .../Form/src/hooks/useFormEvents.ts | 428 + .../Form/src/hooks/useFormValues.ts | 161 + .../Form/src/hooks/useLabelWidth.ts | 42 + src/components/Form/src/props.ts | 103 + src/components/Form/src/types/form.ts | 241 + src/components/Form/src/types/formItem.ts | 91 + src/components/Form/src/types/hooks.ts | 6 + src/components/Form/src/types/index.ts | 120 + src/components/Icon/Icon.vue | 121 + src/components/Icon/data/icons.data.ts | 793 + src/components/Icon/index.ts | 4 + src/components/Icon/src/IconPicker.vue | 200 + src/components/Icon/src/SvgIcon.vue | 65 + src/components/Loading/index.ts | 5 + src/components/Loading/src/Loading.vue | 78 + src/components/Loading/src/createLoading.ts | 63 + src/components/Loading/src/typing.ts | 10 + src/components/Loading/src/useLoading.ts | 49 + src/components/Menu/index.ts | 3 + src/components/Menu/src/BasicMenu.vue | 164 + .../Menu/src/components/BasicMenuItem.vue | 21 + .../Menu/src/components/BasicSubMenuItem.vue | 55 + .../Menu/src/components/MenuItemContent.vue | 34 + src/components/Menu/src/index.less | 74 + src/components/Menu/src/props.ts | 61 + src/components/Menu/src/types.ts | 25 + src/components/Menu/src/useOpenKeys.ts | 81 + src/components/Modal/index.ts | 8 + src/components/Modal/src/BasicModal.vue | 243 + src/components/Modal/src/components/Modal.tsx | 31 + .../Modal/src/components/ModalClose.vue | 106 + .../Modal/src/components/ModalFooter.vue | 41 + .../Modal/src/components/ModalHeader.vue | 21 + .../Modal/src/components/ModalWrapper.vue | 170 + src/components/Modal/src/hooks/useModal.ts | 163 + .../Modal/src/hooks/useModalContext.ts | 16 + .../Modal/src/hooks/useModalDrag.ts | 107 + .../Modal/src/hooks/useModalFullScreen.ts | 43 + src/components/Modal/src/index.less | 139 + src/components/Modal/src/props.ts | 83 + src/components/Modal/src/typing.ts | 209 + src/components/Page/index.ts | 7 + src/components/Page/src/PageFooter.vue | 47 + src/components/Page/src/PageWrapper.vue | 205 + src/components/Qrcode/index.ts | 5 + src/components/Qrcode/src/Qrcode.vue | 112 + src/components/Qrcode/src/drawCanvas.ts | 37 + src/components/Qrcode/src/drawLogo.ts | 89 + src/components/Qrcode/src/qrcodePlus.ts | 5 + src/components/Qrcode/src/toCanvas.ts | 11 + src/components/Qrcode/src/typing.ts | 38 + src/components/Scrollbar/index.ts | 8 + src/components/Scrollbar/src/Scrollbar.vue | 207 + src/components/Scrollbar/src/bar.ts | 110 + src/components/Scrollbar/src/types.d.ts | 18 + src/components/Scrollbar/src/util.ts | 51 + src/components/SimpleMenu/index.ts | 2 + src/components/SimpleMenu/src/SimpleMenu.vue | 161 + .../SimpleMenu/src/SimpleMenuTag.vue | 68 + .../SimpleMenu/src/SimpleSubMenu.vue | 116 + .../SimpleMenu/src/components/Menu.vue | 159 + .../src/components/MenuCollapseTransition.vue | 78 + .../SimpleMenu/src/components/MenuItem.vue | 107 + .../SimpleMenu/src/components/SubMenuItem.vue | 336 + .../SimpleMenu/src/components/menu.less | 309 + .../SimpleMenu/src/components/types.ts | 25 + .../SimpleMenu/src/components/useMenu.ts | 84 + .../src/components/useSimpleMenuContext.ts | 18 + src/components/SimpleMenu/src/index.less | 77 + src/components/SimpleMenu/src/types.ts | 0 src/components/SimpleMenu/src/useOpenKeys.ts | 48 + src/components/StrengthMeter/index.ts | 4 + .../StrengthMeter/src/StrengthMeter.vue | 142 + src/components/Table/index.ts | 11 + src/components/Table/src/BasicTable.vue | 467 + src/components/Table/src/componentMap.ts | 40 + .../src/components/EditTableHeaderIcon.vue | 17 + .../Table/src/components/HeaderCell.vue | 60 + .../Table/src/components/TableAction.vue | 202 + .../Table/src/components/TableFooter.vue | 94 + .../Table/src/components/TableHeader.vue | 81 + .../Table/src/components/TableImg.vue | 91 + .../Table/src/components/TableTitle.vue | 53 + .../src/components/editable/CellComponent.ts | 44 + .../src/components/editable/EditableCell.vue | 535 + .../Table/src/components/editable/helper.ts | 28 + .../Table/src/components/editable/index.ts | 68 + .../src/components/settings/ColumnSetting.vue | 515 + .../components/settings/FullScreenSetting.vue | 38 + .../src/components/settings/RedoSetting.vue | 33 + .../src/components/settings/SizeSetting.vue | 64 + .../Table/src/components/settings/index.vue | 76 + src/components/Table/src/const.ts | 38 + src/components/Table/src/hooks/useColumns.ts | 329 + .../Table/src/hooks/useCustomRow.ts | 101 + .../Table/src/hooks/useDataSource.ts | 409 + src/components/Table/src/hooks/useLoading.ts | 21 + .../Table/src/hooks/usePagination.tsx | 85 + .../Table/src/hooks/useRowSelection.ts | 123 + src/components/Table/src/hooks/useScrollTo.ts | 55 + src/components/Table/src/hooks/useTable.ts | 171 + .../Table/src/hooks/useTableContext.ts | 22 + .../Table/src/hooks/useTableExpand.ts | 65 + .../Table/src/hooks/useTableFooter.ts | 56 + .../Table/src/hooks/useTableForm.ts | 50 + .../Table/src/hooks/useTableHeader.ts | 54 + .../Table/src/hooks/useTableScroll.ts | 245 + .../Table/src/hooks/useTableStyle.ts | 20 + src/components/Table/src/props.ts | 151 + src/components/Table/src/types/column.ts | 198 + .../Table/src/types/componentType.ts | 14 + src/components/Table/src/types/pagination.ts | 115 + src/components/Table/src/types/table.ts | 485 + src/components/Table/src/types/tableAction.ts | 40 + src/components/Time/index.ts | 4 + src/components/Time/src/Time.vue | 108 + src/components/Tools/ImportFileModal.vue | 124 + src/components/Transition/index.ts | 27 + .../Transition/src/CollapseTransition.vue | 78 + .../Transition/src/CreateTransition.tsx | 73 + .../Transition/src/ExpandTransition.ts | 89 + src/components/Tree/index.ts | 6 + src/components/Tree/src/BasicTree.vue | 459 + src/components/Tree/src/TreeIcon.ts | 12 + .../Tree/src/components/TreeHeader.vue | 170 + src/components/Tree/src/hooks/useTree.ts | 211 + src/components/Tree/src/types/tree.ts | 195 + src/components/Tree/style/index.less | 52 + src/components/Tree/style/index.ts | 1 + src/components/Upload/index.ts | 4 + src/components/Upload/src/BasicUpload.vue | 124 + src/components/Upload/src/FileList.vue | 104 + src/components/Upload/src/ThumbUrl.vue | 29 + src/components/Upload/src/UploadModal.vue | 323 + .../Upload/src/UploadPreviewModal.vue | 99 + src/components/Upload/src/data.tsx | 153 + src/components/Upload/src/helper.ts | 27 + src/components/Upload/src/props.ts | 83 + src/components/Upload/src/typing.ts | 55 + src/components/Upload/src/useUpload.ts | 61 + src/components/VxeTable/index.ts | 12 + src/components/VxeTable/src/VxeBasicTable.tsx | 116 + src/components/VxeTable/src/componentMap.ts | 59 + src/components/VxeTable/src/componentType.ts | 22 + .../VxeTable/src/components/AApiSelect.tsx | 20 + .../src/components/AApiTreeSelect.tsx | 20 + .../VxeTable/src/components/AAutoComplete.tsx | 16 + .../VxeTable/src/components/AButton.tsx | 120 + .../VxeTable/src/components/AButtonGroup.tsx | 59 + .../VxeTable/src/components/ACascader.tsx | 42 + .../src/components/ACheckboxGroup.tsx | 5 + .../VxeTable/src/components/ADatePicker.tsx | 33 + .../VxeTable/src/components/AEmpty.tsx | 27 + .../VxeTable/src/components/AInput.tsx | 16 + .../VxeTable/src/components/AInputNumber.tsx | 16 + .../VxeTable/src/components/AInputSearch.tsx | 17 + .../VxeTable/src/components/AMonthPicker.tsx | 18 + .../VxeTable/src/components/ARadioGroup.tsx | 5 + .../VxeTable/src/components/ARangePicker.tsx | 30 + .../VxeTable/src/components/ARate.tsx | 15 + .../VxeTable/src/components/ASelect.tsx | 271 + .../VxeTable/src/components/ASwitch.tsx | 53 + .../VxeTable/src/components/ATimePicker.tsx | 18 + .../VxeTable/src/components/ATreeSelect.tsx | 35 + .../VxeTable/src/components/AWeekPicker.tsx | 18 + .../VxeTable/src/components/AYearPicker.tsx | 18 + .../VxeTable/src/components/common.tsx | 427 + .../VxeTable/src/components/index.tsx | 114 + src/components/VxeTable/src/const.ts | 4 + src/components/VxeTable/src/css/common.scss | 8 + .../VxeTable/src/css/component.scss | 123 + src/components/VxeTable/src/css/index.scss | 5 + .../VxeTable/src/css/scrollbar.scss | 29 + src/components/VxeTable/src/css/toolbar.scss | 26 + src/components/VxeTable/src/css/variable.scss | 54 + src/components/VxeTable/src/emits.ts | 17 + src/components/VxeTable/src/helper.ts | 19 + src/components/VxeTable/src/methods.ts | 160 + src/components/VxeTable/src/props.ts | 52 + src/components/VxeTable/src/setting.ts | 4 + src/components/VxeTable/src/types.ts | 7 + src/components/registerGlobComp.ts | 8 + src/design/.DS_Store | Bin 0 -> 6148 bytes src/design/ant/btn.less | 524 + src/design/ant/index.less | 63 + src/design/ant/input.less | 27 + src/design/ant/pagination.less | 96 + src/design/ant/table.less | 72 + src/design/color.less | 160 + src/design/config.less | 2 + src/design/dark.less | 110 + src/design/entry.css | 168 + src/design/index.less | 54 + src/design/public.less | 51 + src/design/theme.less | 28 + src/design/transition/base.less | 18 + src/design/transition/fade.less | 93 + src/design/transition/index.less | 10 + src/design/transition/scale.less | 21 + src/design/transition/scroll.less | 67 + src/design/transition/slide.less | 39 + src/design/transition/zoom.less | 27 + src/design/var/breakpoint.less | 33 + src/design/var/easing.less | 18 + src/design/var/index.less | 39 + src/directives/clickOutside.ts | 86 + src/directives/ellipsis.ts | 42 + src/directives/index.ts | 13 + src/directives/loading.ts | 39 + src/directives/permission.ts | 32 + src/directives/ripple/index.less | 21 + src/directives/ripple/index.ts | 192 + src/enums/appEnum.ts | 56 + src/enums/breakpointEnum.ts | 28 + src/enums/cacheEnum.ts | 33 + src/enums/exceptionEnum.ts | 27 + src/enums/httpEnum.ts | 31 + src/enums/menuEnum.ts | 50 + src/enums/pageEnum.ts | 11 + src/enums/sizeEnum.ts | 5 + src/hooks/.DS_Store | Bin 0 -> 6148 bytes src/hooks/component/useFormItem.ts | 60 + src/hooks/component/usePageContext.ts | 18 + src/hooks/core/useAttrs.ts | 41 + src/hooks/core/useContext.ts | 43 + src/hooks/event/useBreakpoint.ts | 93 + src/hooks/event/useEventListener.ts | 58 + src/hooks/event/useScroll.ts | 65 + src/hooks/setting/index.ts | 18 + src/hooks/setting/useDarkModeTheme.ts | 18 + src/hooks/setting/useHeaderSetting.ts | 105 + src/hooks/setting/useMenuSetting.ts | 168 + src/hooks/setting/useMultipleTabSetting.ts | 28 + src/hooks/setting/useRootSetting.ts | 95 + src/hooks/setting/useTransitionSetting.ts | 31 + src/hooks/web/useAppInject.ts | 10 + src/hooks/web/useContentHeight.ts | 189 + src/hooks/web/useContextMenu.ts | 13 + src/hooks/web/useCopyToClipboard.ts | 70 + src/hooks/web/useDesign.ts | 22 + src/hooks/web/useECharts.ts | 131 + src/hooks/web/useFullContent.ts | 28 + src/hooks/web/useI18n.ts | 55 + src/hooks/web/useLockPage.ts | 72 + src/hooks/web/useMessage.tsx | 121 + src/hooks/web/usePage.ts | 54 + src/hooks/web/usePagination.ts | 34 + src/hooks/web/usePermission.ts | 119 + src/hooks/web/useScript.ts | 46 + src/hooks/web/useSortable.ts | 21 + src/hooks/web/useTabs.ts | 103 + src/hooks/web/useTitle.ts | 34 + src/hooks/web/useWatermark.ts | 106 + src/layouts/.DS_Store | Bin 0 -> 6148 bytes src/layouts/default/content/index.vue | 53 + .../default/content/useContentContext.ts | 17 + .../default/content/useContentViewHeight.ts | 41 + src/layouts/default/feature/index.vue | 84 + src/layouts/default/footer/index.vue | 95 + src/layouts/default/header/MultipleHeader.vue | 126 + .../default/header/components/Breadcrumb.vue | 204 + .../default/header/components/ErrorAction.vue | 47 + .../default/header/components/FullScreen.vue | 45 + .../default/header/components/index.ts | 14 + .../header/components/lock/LockModal.vue | 127 + .../header/components/notify/NoticeList.vue | 190 + .../default/header/components/notify/data.ts | 193 + .../header/components/notify/index.vue | 93 + .../components/user-dropdown/DropMenuItem.vue | 32 + .../header/components/user-dropdown/index.vue | 191 + src/layouts/default/header/index.less | 196 + src/layouts/default/header/index.vue | 153 + src/layouts/default/index.vue | 92 + src/layouts/default/menu/index.vue | 197 + src/layouts/default/menu/useLayoutMenu.ts | 109 + src/layouts/default/setting/SettingDrawer.tsx | 427 + .../setting/components/InputNumberItem.vue | 56 + .../default/setting/components/SelectItem.vue | 75 + .../setting/components/SettingFooter.vue | 100 + .../default/setting/components/SwitchItem.vue | 66 + .../setting/components/ThemeColorPicker.vue | 88 + .../default/setting/components/TypePicker.vue | 179 + .../default/setting/components/index.ts | 8 + src/layouts/default/setting/enum.ts | 156 + src/layouts/default/setting/handler.ts | 172 + src/layouts/default/setting/index.vue | 26 + src/layouts/default/sider/DragBar.vue | 66 + src/layouts/default/sider/LayoutSider.vue | 157 + src/layouts/default/sider/MixSider.vue | 591 + src/layouts/default/sider/index.vue | 59 + src/layouts/default/sider/useLayoutSider.ts | 143 + .../default/tabs/components/FoldButton.vue | 42 + .../default/tabs/components/TabContent.vue | 76 + .../default/tabs/components/TabRedo.vue | 38 + src/layouts/default/tabs/index.less | 199 + src/layouts/default/tabs/index.vue | 144 + src/layouts/default/tabs/types.ts | 25 + src/layouts/default/tabs/useMultipleTabs.ts | 80 + src/layouts/default/tabs/useTabDropdown.ts | 140 + src/layouts/default/trigger/HeaderTrigger.vue | 17 + src/layouts/default/trigger/SiderTrigger.vue | 12 + src/layouts/default/trigger/index.vue | 15 + src/layouts/iframe/index.vue | 29 + src/layouts/iframe/useFrameKeepAlive.ts | 59 + src/layouts/page/index.vue | 70 + src/layouts/page/transition.ts | 33 + src/locales/helper.ts | 37 + src/locales/lang/en.ts | 12 + src/locales/lang/en/common.ts | 35 + src/locales/lang/en/component.ts | 130 + src/locales/lang/en/layout.ts | 116 + src/locales/lang/en/routes/basic.ts | 4 + src/locales/lang/en/routes/dashboard.ts | 6 + src/locales/lang/en/routes/demo.ts | 199 + src/locales/lang/en/sys.ts | 127 + .../lang/zh-CN/antdLocale/DatePicker.ts | 19 + src/locales/lang/zh-CN/common.ts | 37 + src/locales/lang/zh-CN/component.ts | 135 + src/locales/lang/zh-CN/layout.ts | 116 + src/locales/lang/zh-CN/routes/basic.ts | 4 + src/locales/lang/zh-CN/routes/dashboard.ts | 6 + src/locales/lang/zh-CN/routes/demo.ts | 190 + src/locales/lang/zh-CN/sys.ts | 121 + src/locales/lang/zh_CN.ts | 10 + src/locales/setupI18n.ts | 44 + src/locales/useLocale.ts | 69 + src/logics/.DS_Store | Bin 0 -> 6148 bytes src/logics/error-handle/index.ts | 184 + src/logics/initAppConfig.ts | 88 + src/logics/mitt/routeChange.ts | 31 + src/logics/theme/dark.ts | 20 + src/logics/theme/index.ts | 1 + src/logics/theme/updateBackground.ts | 198 + src/logics/theme/updateColorWeak.ts | 9 + src/logics/theme/updateGrayMode.ts | 9 + src/logics/theme/util.ts | 11 + src/main.ts | 64 + src/router/.DS_Store | Bin 0 -> 6148 bytes src/router/constant.ts | 24 + src/router/guard/index.ts | 147 + src/router/guard/paramMenuGuard.ts | 47 + src/router/guard/permissionGuard.ts | 119 + src/router/guard/stateGuard.ts | 24 + src/router/helper/menuHelper.ts | 106 + src/router/helper/routeHelper.ts | 178 + src/router/index.ts | 42 + src/router/menus/index.ts | 136 + src/router/routes/basic.ts | 78 + src/router/routes/index.ts | 42 + src/router/types.ts | 58 + src/settings/componentSetting.ts | 51 + src/settings/designSetting.ts | 48 + src/settings/encryptionSetting.ts | 13 + src/settings/localeSetting.ts | 29 + src/settings/projectSetting.ts | 183 + src/settings/siteSetting.ts | 8 + src/store/index.ts | 10 + src/store/modules/app.ts | 112 + src/store/modules/errorLog.ts | 77 + src/store/modules/locale.ts | 55 + src/store/modules/lock.ts | 59 + src/store/modules/multipleTab.ts | 361 + src/store/modules/permission.ts | 264 + src/store/modules/user.ts | 222 + src/utils/.DS_Store | Bin 0 -> 6148 bytes src/utils/auth/index.ts | 25 + src/utils/bem.ts | 52 + src/utils/cache/index.ts | 31 + src/utils/cache/memory.ts | 107 + src/utils/cache/persistent.ts | 132 + src/utils/cache/storageCache.ts | 111 + src/utils/cipher.ts | 54 + src/utils/color.ts | 151 + src/utils/dateUtil.ts | 28 + src/utils/domUtils.ts | 180 + src/utils/env.ts | 74 + src/utils/event/index.ts | 42 + src/utils/factory/createAsyncComponent.tsx | 56 + src/utils/file/base64Conver.ts | 41 + src/utils/file/download.ts | 45 + src/utils/helper/treeHelper.ts | 216 + src/utils/helper/tsxHelper.tsx | 37 + src/utils/http/axios/Axios.ts | 251 + src/utils/http/axios/axiosCancel.ts | 60 + src/utils/http/axios/axiosRetry.ts | 30 + src/utils/http/axios/axiosTransform.ts | 57 + src/utils/http/axios/checkStatus.ts | 80 + src/utils/http/axios/helper.ts | 48 + src/utils/http/axios/index.ts | 295 + src/utils/index.ts | 122 + src/utils/is.ts | 98 + src/utils/lib/echarts.ts | 57 + src/utils/log.ts | 9 + src/utils/mitt.ts | 122 + src/utils/propTypes.ts | 35 + src/utils/props.ts | 184 + src/utils/tree.ts | 83 + src/utils/types.ts | 42 + src/utils/uuid.ts | 28 + src/views/.DS_Store | Bin 0 -> 8196 bytes src/views/basic/account/BaseSetting.vue | 100 + src/views/basic/account/BindEmailModal.vue | 145 + src/views/basic/account/BindPhoneModal.vue | 146 + src/views/basic/account/MsgNotify.vue | 75 + .../basic/account/ResetPasswordModal.vue | 50 + src/views/basic/account/SecureSetting.vue | 93 + src/views/basic/account/data.ts | 133 + src/views/basic/account/index.vue | 59 + .../customer/components/CustomerModal.vue | 101 + src/views/basic/customer/customer.data.ts | 251 + src/views/basic/customer/index.vue | 194 + .../components/AddEditModal.vue | 76 + .../income-expense/incomeExpense.data.ts | 93 + src/views/basic/income-expense/index.vue | 153 + .../basic/member/components/MemberModal.vue | 78 + src/views/basic/member/index.vue | 193 + src/views/basic/member/member.data.ts | 170 + .../operator/components/OperatorModal.vue | 76 + src/views/basic/operator/index.vue | 147 + src/views/basic/operator/operator.data.ts | 118 + .../components/FinancialAccountModal.vue | 78 + .../components/MultipleAccountsModal.vue | 152 + .../financialAccount.data.ts | 147 + src/views/basic/settlement-account/index.vue | 153 + .../supplier/components/SupplierModal.vue | 102 + src/views/basic/supplier/index.vue | 196 + src/views/basic/supplier/supplier.data.ts | 261 + .../warehouse/components/WarehouseModal.vue | 80 + src/views/basic/warehouse/index.vue | 153 + src/views/basic/warehouse/warehouse.data.ts | 165 + .../analysis/components/GrowCard.vue | 50 + .../analysis/components/GrowCardFour.vue | 39 + .../analysis/components/GrowCardThree.vue | 39 + .../analysis/components/GrowCardTwo.vue | 39 + .../analysis/components/SalesProductPie.vue | 63 + .../analysis/components/SiteAnalysis.vue | 38 + .../analysis/components/VisitAnalysis.vue | 89 + .../analysis/components/VisitAnalysisBar.vue | 46 + .../analysis/components/VisitRadar.vue | 62 + .../analysis/components/VisitSource.vue | 63 + .../dashboard/analysis/components/props.ts | 16 + src/views/dashboard/analysis/data.ts | 141 + src/views/dashboard/analysis/index.vue | 81 + .../workbench/components/DynamicInfo.vue | 31 + .../workbench/components/ProjectCard.vue | 32 + .../workbench/components/QuickNav.vue | 15 + .../workbench/components/SaleRadar.vue | 94 + .../workbench/components/WorkbenchHeader.vue | 33 + .../dashboard/workbench/components/data.ts | 144 + src/views/dashboard/workbench/index.vue | 36 + .../financial/advance-charge/advance.data.ts | 183 + .../components/AdvanceChargeModal.vue | 584 + .../components/ViewAdvanceChargeModal.vue | 181 + src/views/financial/advance-charge/index.vue | 223 + .../collection/addEditCollection.data.ts | 148 + .../financial/collection/collection.data.ts | 266 + .../components/AddEditCollectionModal.vue | 617 + .../components/SaleArrearsModal.vue | 95 + .../components/ViewCollectionModal.vue | 193 + src/views/financial/collection/index.vue | 242 + .../financial/expense/addEditExpense.data.ts | 141 + .../components/AddEditExpenseModal.vue | 569 + .../expense/components/ViewExpenseModal.vue | 181 + src/views/financial/expense/expense.data.ts | 159 + src/views/financial/expense/index.vue | 241 + .../financial/income/addEditIncome.data.ts | 141 + .../income/components/AddEditIncomeModal.vue | 575 + .../income/components/ViewIncomeModal.vue | 181 + src/views/financial/income/income.data.ts | 159 + src/views/financial/income/index.vue | 240 + .../financial/payment/addEditPayment.data.ts | 148 + .../components/AddEditPaymentModal.vue | 614 + .../components/PurchaseArrearsModal.vue | 95 + .../payment/components/ViewPaymentModal.vue | 193 + src/views/financial/payment/index.vue | 240 + src/views/financial/payment/payment.data.ts | 266 + .../transfer/addEditTransfer.data.ts | 139 + .../components/AddEditTransferModal.vue | 530 + .../transfer/components/ViewTransferModal.vue | 177 + src/views/financial/transfer/index.vue | 240 + src/views/financial/transfer/transfer.data.ts | 141 + .../product/attributes/attributes.data.ts | 71 + .../attributes/components/AttributeModal.vue | 73 + src/views/product/attributes/index.vue | 110 + src/views/product/category/category.data.ts | 72 + .../category/components/CategoryModal.vue | 74 + src/views/product/category/index.vue | 134 + .../info/components/BatchEditModal.vue | 206 + .../info/components/BatchSetPriceModal.vue | 119 + .../info/components/BatchSetStockModal.vue | 108 + .../info/components/ProductInfoModal.vue | 1304 ++ .../info/components/SelectProductModal.vue | 63 + src/views/product/info/index.vue | 201 + src/views/product/info/info.data.ts | 382 + .../product/info/model/productInfoModel.ts | 99 + .../product/units/components/UnitModal.vue | 90 + src/views/product/units/index.vue | 110 + src/views/product/units/units.data.ts | 173 + src/views/purchase/model/addEditModel.ts | 467 + .../order/components/AddEditModal.vue | 998 + .../order/components/ViewOrderModal.vue | 197 + src/views/purchase/order/index.vue | 239 + .../purchase/order/purchaseOrder.data.ts | 213 + .../refund/components/AddEditModal.vue | 1189 ++ .../refund/components/ViewRefundModal.vue | 231 + src/views/purchase/refund/index.vue | 242 + .../purchase/refund/purchaseRefund.data.ts | 143 + .../storage/components/AddEditModal.vue | 1195 ++ .../storage/components/ViewStorageModal.vue | 223 + src/views/purchase/storage/index.vue | 244 + .../purchase/storage/purchaseStorage.data.ts | 145 + src/views/receipt/LinkReceiptModal.vue | 104 + src/views/receipt/ReceiptDetailModal.vue | 73 + src/views/receipt/receipt.data.ts | 162 + src/views/report/accountStatistics.vue | 147 + src/views/report/customerBill.vue | 174 + src/views/report/modal/AccountFlowModal.vue | 149 + .../report/modal/CustomerBillDetailModal.vue | 170 + src/views/report/modal/StockFlowModal.vue | 180 + .../report/modal/SupplierBillDetailModal.vue | 171 + src/views/report/productStock.vue | 160 + src/views/report/purchaseStatistics.vue | 143 + src/views/report/report.data.ts | 1452 ++ src/views/report/retailStatistics.vue | 144 + src/views/report/saleStatistics.vue | 143 + src/views/report/shipmentsDetail.vue | 176 + src/views/report/shipmentsSummary.vue | 132 + src/views/report/storageDetail.vue | 180 + src/views/report/storageSummary.vue | 133 + src/views/report/supplierBill.vue | 169 + .../retail/refund/components/AddEditModal.vue | 859 + .../refund/components/ViewRefundModal.vue | 215 + src/views/retail/refund/index.vue | 240 + src/views/retail/refund/refund.data.ts | 213 + .../shipments/components/AddEditModal.vue | 838 + .../components/ViewShipmentModal.vue | 211 + src/views/retail/shipments/index.vue | 243 + .../retail/shipments/model/addEditModel.ts | 230 + src/views/retail/shipments/shipments.data.ts | 224 + src/views/sales/model/addEditModel.ts | 473 + .../sales/order/components/AddEditModal.vue | 1022 + .../order/components/ViewSaleOrderModal.vue | 196 + src/views/sales/order/index.vue | 238 + src/views/sales/order/sales.data.ts | 213 + .../sales/refund/components/AddEditModal.vue | 1191 ++ .../refund/components/ViewSaleRefundModal.vue | 223 + src/views/sales/refund/index.vue | 238 + src/views/sales/refund/saleRefund.data.ts | 143 + .../shipments/components/AddEditModal.vue | 1205 ++ .../components/ViewSaleShipmentsModal.vue | 224 + src/views/sales/shipments/index.vue | 238 + .../sales/shipments/saleShipments.data.ts | 143 + src/views/sys/about/index.vue | 98 + src/views/sys/config/config.data.ts | 82 + src/views/sys/config/index.vue | 86 + .../sys/department/components/DeptModal.vue | 77 + src/views/sys/department/dept.data.ts | 116 + src/views/sys/department/index.vue | 108 + src/views/sys/error-log/DetailModal.vue | 27 + src/views/sys/error-log/data.tsx | 67 + src/views/sys/error-log/index.vue | 96 + src/views/sys/exception/Exception.vue | 148 + src/views/sys/exception/index.ts | 1 + src/views/sys/iframe/FrameBlank.vue | 6 + src/views/sys/iframe/index.vue | 90 + src/views/sys/lock/LockPage.vue | 236 + src/views/sys/lock/index.vue | 13 + src/views/sys/lock/useNow.ts | 60 + src/views/sys/login/ForgetPasswordForm.vue | 106 + src/views/sys/login/Login.vue | 221 + src/views/sys/login/LoginForm.vue | 200 + src/views/sys/login/LoginFormTitle.vue | 25 + src/views/sys/login/MobileForm.vue | 98 + src/views/sys/login/QrCodeForm.vue | 31 + src/views/sys/login/RegisterForm.vue | 148 + src/views/sys/login/SessionTimeoutLogin.vue | 54 + src/views/sys/login/useLogin.ts | 185 + src/views/sys/menu/MenuDrawer.vue | 95 + src/views/sys/menu/index.vue | 115 + src/views/sys/menu/menu.data.ts | 208 + src/views/sys/redirect/index.vue | 30 + src/views/sys/role/components/RoleDrawer.vue | 70 + .../role/components/RolePermissionModal.vue | 66 + src/views/sys/role/index.vue | 131 + src/views/sys/role/role.data.ts | 163 + src/views/sys/user/account.data.ts | 171 + .../sys/user/components/AccountDetail.vue | 61 + .../sys/user/components/AccountModal.vue | 89 + src/views/sys/user/components/DeptTree.vue | 43 + src/views/sys/user/index.vue | 158 + .../addEditAssembleOrDisassemble.data.ts | 194 + .../warehouse/addEditStorageShipments.data.ts | 196 + .../warehouse/allot/allotShipments.data.ts | 158 + .../components/AddEditAllotShipmentsModal.vue | 640 + .../components/ViewAllotShipmentsModal.vue | 159 + .../components/addEditAllotShipments.data.ts | 164 + src/views/warehouse/allot/index.vue | 241 + src/views/warehouse/assemble/assemble.data.ts | 173 + .../components/AddEditAssembleModal.vue | 728 + .../assemble/components/ViewAssembleModal.vue | 157 + src/views/warehouse/assemble/index.vue | 241 + .../components/AddEditDisassembleModal.vue | 731 + .../components/ViewDisassembleModal.vue | 157 + .../warehouse/disassemble/disassemble.data.ts | 173 + src/views/warehouse/disassemble/index.vue | 242 + .../components/AddEditOtherShipmentsModal.vue | 713 + .../components/ViewOtherShipmentsModal.vue | 173 + src/views/warehouse/shipments/index.vue | 240 + .../shipments/otherShipments.data.ts | 186 + .../components/AddEditOtherStorageModal.vue | 708 + .../components/ViewOtherStorageModal.vue | 173 + src/views/warehouse/storage/index.vue | 240 + .../warehouse/storage/otherStorage.data.ts | 186 + src/views/workflow/bpmn/index.vue | 206 + src/views/workflow/bpmn/zh.ts | 271 + test.txt | 1 - tsconfig.json | 29 + turbo.json | 18 + types/axios.d.ts | 56 + types/codemirror.d.ts | 1 + types/config.d.ts | 162 + types/global.d.ts | 91 + types/index.d.ts | 27 + types/module.d.ts | 18 + types/store.d.ts | 48 + types/tree.d.ts | 1 + types/utils.d.ts | 5 + types/vue-router.d.ts | 47 + types/vueuseCore.d.ts | 1 + vite.config.ts | 32 + wansenai-logo.png | Bin 0 -> 7551 bytes 969 files changed, 116813 insertions(+), 1 deletion(-) create mode 100644 .DS_Store create mode 100644 .dockerignore create mode 100644 .env create mode 100644 .env.analyze create mode 100644 .env.development create mode 100644 .env.docker create mode 100644 .env.production create mode 100644 .eslintignore create mode 100644 .eslintrc.js create mode 100644 .gitignore create mode 100644 .npmrc create mode 100644 .prettierignore create mode 100644 .prettierrc.js create mode 100644 .stylelintrc.js create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 deploy/default.conf create mode 100644 docker/Dockerfile create mode 100644 docker/Makefile create mode 100644 docs/README_ZH.md create mode 100644 docs/template/会员信息模板.xlsx create mode 100644 docs/template/供应商模板.xlsx create mode 100644 docs/template/客户信息模板.xlsx create mode 100644 images/add-menu-zh.png create mode 100644 images/home-page-zh.png create mode 100644 images/login-page-en.png create mode 100644 images/register-page-zh.png create mode 100644 images/role-permission-zh.png create mode 100644 images/user-manage-zh.png create mode 100644 images/user-mgt.png create mode 100644 images/wansenai-logo.png create mode 100644 index.html create mode 100644 internal/.DS_Store create mode 100644 internal/stylelint-config/.eslintignore create mode 100644 internal/stylelint-config/build.config.ts create mode 100644 internal/stylelint-config/package.json create mode 100644 internal/stylelint-config/src/index.ts create mode 100644 internal/stylelint-config/tsconfig.json create mode 100644 internal/ts-config/.eslintignore create mode 100644 internal/ts-config/base.json create mode 100644 internal/ts-config/node-server.json create mode 100644 internal/ts-config/node.json create mode 100644 internal/ts-config/package.json create mode 100644 internal/ts-config/vue-app.json create mode 100644 internal/vite-config/.eslintignore create mode 100644 internal/vite-config/build.config.ts create mode 100644 internal/vite-config/package.json create mode 100644 internal/vite-config/src/config/application.ts create mode 100644 internal/vite-config/src/config/common.ts create mode 100644 internal/vite-config/src/config/package.ts create mode 100644 internal/vite-config/src/index.ts create mode 100644 internal/vite-config/src/plugins/appConfig.ts create mode 100644 internal/vite-config/src/plugins/compress.ts create mode 100644 internal/vite-config/src/plugins/html.ts create mode 100644 internal/vite-config/src/plugins/index.ts create mode 100644 internal/vite-config/src/plugins/mock.ts create mode 100644 internal/vite-config/src/plugins/svgSprite.ts create mode 100644 internal/vite-config/src/plugins/visualizer.ts create mode 100644 internal/vite-config/src/utils/env.ts create mode 100644 internal/vite-config/src/utils/hash.ts create mode 100644 internal/vite-config/src/utils/modifyVars.ts create mode 100644 internal/vite-config/tsconfig.json create mode 100644 nginx.conf create mode 100644 package.json create mode 100644 packages/.DS_Store create mode 100644 packages/hooks/.eslintrc.js create mode 100644 packages/hooks/build.config.ts create mode 100644 packages/hooks/package.json create mode 100644 packages/hooks/src/index.ts create mode 100644 packages/hooks/src/onMountedOrActivated.ts create mode 100644 packages/hooks/src/useAttrs.ts create mode 100644 packages/hooks/src/useRefs.ts create mode 100644 packages/hooks/src/useScrollTo.ts create mode 100644 packages/hooks/src/useWindowSizeFn.ts create mode 100644 packages/hooks/tsconfig.json create mode 100644 packages/types/.eslintrc.js create mode 100644 packages/types/build.config.ts create mode 100644 packages/types/package.json create mode 100644 packages/types/src/index.ts create mode 100644 packages/types/src/utils.ts create mode 100644 packages/types/tsconfig.json create mode 100644 pnpm-lock.yaml create mode 100644 pnpm-workspace.yaml create mode 100644 public/favicon.ico create mode 100644 public/resource/.DS_Store create mode 100644 public/resource/img/logo.png create mode 100644 public/resource/tinymce/icons/default/icons.min.js create mode 100644 public/resource/tinymce/langs/README.md create mode 100644 public/resource/tinymce/langs/en.js create mode 100644 public/resource/tinymce/langs/zh_CN.js create mode 100644 public/resource/tinymce/license.txt create mode 100644 public/resource/tinymce/models/dom/model.min.js create mode 100644 public/resource/tinymce/plugins/advlist/plugin.min.js create mode 100644 public/resource/tinymce/plugins/anchor/plugin.min.js create mode 100644 public/resource/tinymce/plugins/autolink/plugin.min.js create mode 100644 public/resource/tinymce/plugins/autoresize/plugin.min.js create mode 100644 public/resource/tinymce/plugins/autosave/plugin.min.js create mode 100644 public/resource/tinymce/plugins/charmap/plugin.min.js create mode 100644 public/resource/tinymce/plugins/code/plugin.min.js create mode 100644 public/resource/tinymce/plugins/codesample/plugin.min.js create mode 100644 public/resource/tinymce/plugins/directionality/plugin.min.js create mode 100644 public/resource/tinymce/plugins/emoticons/js/emojiimages.js create mode 100644 public/resource/tinymce/plugins/emoticons/js/emojiimages.min.js create mode 100644 public/resource/tinymce/plugins/emoticons/js/emojis.js create mode 100644 public/resource/tinymce/plugins/emoticons/js/emojis.min.js create mode 100644 public/resource/tinymce/plugins/emoticons/plugin.min.js create mode 100644 public/resource/tinymce/plugins/fullscreen/plugin.min.js create mode 100644 public/resource/tinymce/plugins/help/plugin.min.js create mode 100644 public/resource/tinymce/plugins/image/plugin.min.js create mode 100644 public/resource/tinymce/plugins/importcss/plugin.min.js create mode 100644 public/resource/tinymce/plugins/insertdatetime/plugin.min.js create mode 100644 public/resource/tinymce/plugins/link/plugin.min.js create mode 100644 public/resource/tinymce/plugins/lists/plugin.min.js create mode 100644 public/resource/tinymce/plugins/media/plugin.min.js create mode 100644 public/resource/tinymce/plugins/nonbreaking/plugin.min.js create mode 100644 public/resource/tinymce/plugins/pagebreak/plugin.min.js create mode 100644 public/resource/tinymce/plugins/preview/plugin.min.js create mode 100644 public/resource/tinymce/plugins/quickbars/plugin.min.js create mode 100644 public/resource/tinymce/plugins/save/plugin.min.js create mode 100644 public/resource/tinymce/plugins/searchreplace/plugin.min.js create mode 100644 public/resource/tinymce/plugins/table/plugin.min.js create mode 100644 public/resource/tinymce/plugins/template/plugin.min.js create mode 100644 public/resource/tinymce/plugins/visualblocks/plugin.min.js create mode 100644 public/resource/tinymce/plugins/visualchars/plugin.min.js create mode 100644 public/resource/tinymce/plugins/wordcount/plugin.min.js create mode 100644 public/resource/tinymce/skins/content/dark/content.min.css create mode 100644 public/resource/tinymce/skins/content/default/content.min.css create mode 100644 public/resource/tinymce/skins/content/document/content.min.css create mode 100644 public/resource/tinymce/skins/content/tinymce-5-dark/content.min.css create mode 100644 public/resource/tinymce/skins/content/tinymce-5/content.min.css create mode 100644 public/resource/tinymce/skins/content/writer/content.min.css create mode 100644 public/resource/tinymce/skins/ui/oxide-dark/content.inline.min.css create mode 100644 public/resource/tinymce/skins/ui/oxide-dark/content.min.css create mode 100644 public/resource/tinymce/skins/ui/oxide-dark/skin.min.css create mode 100644 public/resource/tinymce/skins/ui/oxide-dark/skin.shadowdom.min.css create mode 100644 public/resource/tinymce/skins/ui/oxide/content.inline.min.css create mode 100644 public/resource/tinymce/skins/ui/oxide/content.min.css create mode 100644 public/resource/tinymce/skins/ui/oxide/skin.min.css create mode 100644 public/resource/tinymce/skins/ui/oxide/skin.shadowdom.min.css create mode 100644 public/resource/tinymce/skins/ui/tinymce-5-dark/content.inline.min.css create mode 100644 public/resource/tinymce/skins/ui/tinymce-5-dark/content.min.css create mode 100644 public/resource/tinymce/skins/ui/tinymce-5-dark/skin.min.css create mode 100644 public/resource/tinymce/skins/ui/tinymce-5-dark/skin.shadowdom.min.css create mode 100644 public/resource/tinymce/skins/ui/tinymce-5/content.inline.min.css create mode 100644 public/resource/tinymce/skins/ui/tinymce-5/content.min.css create mode 100644 public/resource/tinymce/skins/ui/tinymce-5/skin.min.css create mode 100644 public/resource/tinymce/skins/ui/tinymce-5/skin.shadowdom.min.css create mode 100644 public/resource/tinymce/themes/silver/theme.min.js create mode 100644 public/resource/tinymce/tinymce.d.ts create mode 100644 public/resource/tinymce/tinymce.min.js create mode 100644 src/.DS_Store create mode 100644 src/App.vue create mode 100644 src/api/.DS_Store create mode 100644 src/api/basic/common.ts create mode 100644 src/api/basic/customer.ts create mode 100644 src/api/basic/incomeExpense.ts create mode 100644 src/api/basic/member.ts create mode 100644 src/api/basic/model/customerModel.ts create mode 100644 src/api/basic/model/incomeExpenseModel.ts create mode 100644 src/api/basic/model/memberModel.ts create mode 100644 src/api/basic/model/operatorModel.ts create mode 100644 src/api/basic/model/supplierModel.ts create mode 100644 src/api/basic/model/warehouseModel.ts create mode 100644 src/api/basic/operator.ts create mode 100644 src/api/basic/supplier.ts create mode 100644 src/api/basic/warehouse.ts create mode 100644 src/api/financial/account.ts create mode 100644 src/api/financial/advance.ts create mode 100644 src/api/financial/collection.ts create mode 100644 src/api/financial/expense.ts create mode 100644 src/api/financial/income.ts create mode 100644 src/api/financial/model/accountModel.ts create mode 100644 src/api/financial/model/advanceModel.ts create mode 100644 src/api/financial/model/collectionModel.ts create mode 100644 src/api/financial/model/expenseModel.ts create mode 100644 src/api/financial/model/incomeModel.ts create mode 100644 src/api/financial/model/paymentModel.ts create mode 100644 src/api/financial/model/transferModel.ts create mode 100644 src/api/financial/payment.ts create mode 100644 src/api/financial/transfer.ts create mode 100644 src/api/model/baseModel.ts create mode 100644 src/api/product/model/productAttributeModel.ts create mode 100644 src/api/product/model/productCategoryModel.ts create mode 100644 src/api/product/model/productModel.ts create mode 100644 src/api/product/model/productUnitModel.ts create mode 100644 src/api/product/product.ts create mode 100644 src/api/product/productAttribute.ts create mode 100644 src/api/product/productCategory.ts create mode 100644 src/api/product/productUnit.ts create mode 100644 src/api/purchase/model/orderModel.ts create mode 100644 src/api/purchase/model/refundModel.ts create mode 100644 src/api/purchase/model/storageModel.ts create mode 100644 src/api/purchase/order.ts create mode 100644 src/api/purchase/refund.ts create mode 100644 src/api/purchase/storage.ts create mode 100644 src/api/receipt/model/receiptModel.ts create mode 100644 src/api/receipt/receipt.ts create mode 100644 src/api/report/report.ts create mode 100644 src/api/report/reportModel.ts create mode 100644 src/api/retail/model/refundModel.ts create mode 100644 src/api/retail/model/shipmentsModel.ts create mode 100644 src/api/retail/refund.ts create mode 100644 src/api/retail/shipments.ts create mode 100644 src/api/sale/model/orderModel.ts create mode 100644 src/api/sale/model/refundModel.ts create mode 100644 src/api/sale/model/shipmentsModel.ts create mode 100644 src/api/sale/order.ts create mode 100644 src/api/sale/refund.ts create mode 100644 src/api/sale/shipments.ts create mode 100644 src/api/sys/captcha.ts create mode 100644 src/api/sys/config.ts create mode 100644 src/api/sys/dept.ts create mode 100644 src/api/sys/menu.ts create mode 100644 src/api/sys/model/captchaModel.ts create mode 100644 src/api/sys/model/configModel.ts create mode 100644 src/api/sys/model/dpetModel.ts create mode 100644 src/api/sys/model/menuModel.ts create mode 100644 src/api/sys/model/roleModel.ts create mode 100644 src/api/sys/model/uploadModel.ts create mode 100644 src/api/sys/model/userModel.ts create mode 100644 src/api/sys/role.ts create mode 100644 src/api/sys/upload.ts create mode 100644 src/api/sys/user.ts create mode 100644 src/api/warehouse/allotShipments.ts create mode 100644 src/api/warehouse/assemble.ts create mode 100644 src/api/warehouse/disassemble.ts create mode 100644 src/api/warehouse/model/allotShipmentsModel.ts create mode 100644 src/api/warehouse/model/assembleModel.ts create mode 100644 src/api/warehouse/model/disassembleModel.ts create mode 100644 src/api/warehouse/model/shipmentsModel.ts create mode 100644 src/api/warehouse/model/storageModel.ts create mode 100644 src/api/warehouse/shipments.ts create mode 100644 src/api/warehouse/storage.ts create mode 100644 src/assets/.DS_Store create mode 100644 src/assets/icons/download-count.svg create mode 100644 src/assets/icons/dynamic-avatar-1.svg create mode 100644 src/assets/icons/dynamic-avatar-2.svg create mode 100644 src/assets/icons/dynamic-avatar-3.svg create mode 100644 src/assets/icons/dynamic-avatar-4.svg create mode 100644 src/assets/icons/dynamic-avatar-5.svg create mode 100644 src/assets/icons/dynamic-avatar-6.svg create mode 100644 src/assets/icons/moon.svg create mode 100644 src/assets/icons/sun.svg create mode 100644 src/assets/icons/test.svg create mode 100644 src/assets/icons/total-sales.svg create mode 100644 src/assets/icons/transaction.svg create mode 100644 src/assets/icons/visit-count.svg create mode 100644 src/assets/images/demo.png create mode 100644 src/assets/images/header.jpg create mode 100644 src/assets/images/login-page-bg-2.png create mode 100644 src/assets/images/logo.png create mode 100644 src/assets/svg/illustration.svg create mode 100644 src/assets/svg/login-bg-dark.svg create mode 100644 src/assets/svg/login-bg.svg create mode 100644 src/assets/svg/login-box-bg.svg create mode 100644 src/assets/svg/net-error.svg create mode 100644 src/assets/svg/no-data.svg create mode 100644 src/assets/svg/preview/p-rotate.svg create mode 100644 src/assets/svg/preview/resume.svg create mode 100644 src/assets/svg/preview/scale.svg create mode 100644 src/assets/svg/preview/unrotate.svg create mode 100644 src/assets/svg/preview/unscale.svg create mode 100644 src/components/.DS_Store create mode 100644 src/components/Application/index.ts create mode 100644 src/components/Application/src/AppDarkModeToggle.vue create mode 100644 src/components/Application/src/AppLocalePicker.vue create mode 100644 src/components/Application/src/AppLogo.vue create mode 100644 src/components/Application/src/AppProvider.vue create mode 100644 src/components/Application/src/search/AppSearch.vue create mode 100644 src/components/Application/src/search/AppSearchFooter.vue create mode 100644 src/components/Application/src/search/AppSearchKeyItem.vue create mode 100644 src/components/Application/src/search/AppSearchModal.vue create mode 100644 src/components/Application/src/search/useMenuSearch.ts create mode 100644 src/components/Application/src/useAppContext.ts create mode 100644 src/components/Basic/index.ts create mode 100644 src/components/Basic/src/BasicArrow.vue create mode 100644 src/components/Basic/src/BasicHelp.vue create mode 100644 src/components/Basic/src/BasicTitle.vue create mode 100644 src/components/Button/index.ts create mode 100644 src/components/Button/src/BasicButton.vue create mode 100644 src/components/Button/src/PopConfirmButton.vue create mode 100644 src/components/Button/src/props.ts create mode 100644 src/components/ClickOutSide/index.ts create mode 100644 src/components/ClickOutSide/src/ClickOutSide.vue create mode 100644 src/components/Container/index.ts create mode 100644 src/components/Container/src/ScrollContainer.vue create mode 100644 src/components/Container/src/collapse/CollapseContainer.vue create mode 100644 src/components/Container/src/collapse/CollapseHeader.vue create mode 100644 src/components/Container/src/typing.ts create mode 100644 src/components/ContextMenu/index.ts create mode 100644 src/components/ContextMenu/src/ContextMenu.vue create mode 100644 src/components/ContextMenu/src/createContextMenu.ts create mode 100644 src/components/ContextMenu/src/typing.ts create mode 100644 src/components/CountDown/index.ts create mode 100644 src/components/CountDown/src/CountButton.vue create mode 100644 src/components/CountDown/src/CountdownInput.vue create mode 100644 src/components/CountDown/src/useCountdown.ts create mode 100644 src/components/CountTo/index.ts create mode 100644 src/components/CountTo/src/CountTo.vue create mode 100644 src/components/Cropper/index.ts create mode 100644 src/components/Cropper/src/Cropper.vue create mode 100644 src/components/Cropper/src/CropperAvatar.vue create mode 100644 src/components/Cropper/src/CropperModal.vue create mode 100644 src/components/Cropper/src/typing.ts create mode 100644 src/components/Description/index.ts create mode 100644 src/components/Description/src/Description.vue create mode 100644 src/components/Description/src/typing.ts create mode 100644 src/components/Description/src/useDescription.ts create mode 100644 src/components/Drawer/index.ts create mode 100644 src/components/Drawer/src/BasicDrawer.vue create mode 100644 src/components/Drawer/src/components/DrawerFooter.vue create mode 100644 src/components/Drawer/src/components/DrawerHeader.vue create mode 100644 src/components/Drawer/src/props.ts create mode 100644 src/components/Drawer/src/typing.ts create mode 100644 src/components/Drawer/src/useDrawer.ts create mode 100644 src/components/Dropdown/index.ts create mode 100644 src/components/Dropdown/src/Dropdown.vue create mode 100644 src/components/Dropdown/src/typing.ts create mode 100644 src/components/Form/index.ts create mode 100644 src/components/Form/src/BasicForm.vue create mode 100644 src/components/Form/src/componentMap.ts create mode 100644 src/components/Form/src/components/ApiCascader.vue create mode 100644 src/components/Form/src/components/ApiMultipleSelect.vue create mode 100644 src/components/Form/src/components/ApiMultipleTreeSelect.vue create mode 100644 src/components/Form/src/components/ApiRadioGroup.vue create mode 100644 src/components/Form/src/components/ApiSelect.vue create mode 100644 src/components/Form/src/components/ApiTransfer.vue create mode 100644 src/components/Form/src/components/ApiTree.vue create mode 100644 src/components/Form/src/components/ApiTreeSelect.vue create mode 100644 src/components/Form/src/components/FormAction.vue create mode 100644 src/components/Form/src/components/FormItem.vue create mode 100644 src/components/Form/src/components/RadioButtonGroup.vue create mode 100644 src/components/Form/src/helper.ts create mode 100644 src/components/Form/src/hooks/useAdvanced.ts create mode 100644 src/components/Form/src/hooks/useAutoFocus.ts create mode 100644 src/components/Form/src/hooks/useComponentRegister.ts create mode 100644 src/components/Form/src/hooks/useForm.ts create mode 100644 src/components/Form/src/hooks/useFormContext.ts create mode 100644 src/components/Form/src/hooks/useFormEvents.ts create mode 100644 src/components/Form/src/hooks/useFormValues.ts create mode 100644 src/components/Form/src/hooks/useLabelWidth.ts create mode 100644 src/components/Form/src/props.ts create mode 100644 src/components/Form/src/types/form.ts create mode 100644 src/components/Form/src/types/formItem.ts create mode 100644 src/components/Form/src/types/hooks.ts create mode 100644 src/components/Form/src/types/index.ts create mode 100644 src/components/Icon/Icon.vue create mode 100644 src/components/Icon/data/icons.data.ts create mode 100644 src/components/Icon/index.ts create mode 100644 src/components/Icon/src/IconPicker.vue create mode 100644 src/components/Icon/src/SvgIcon.vue create mode 100644 src/components/Loading/index.ts create mode 100644 src/components/Loading/src/Loading.vue create mode 100644 src/components/Loading/src/createLoading.ts create mode 100644 src/components/Loading/src/typing.ts create mode 100644 src/components/Loading/src/useLoading.ts create mode 100644 src/components/Menu/index.ts create mode 100644 src/components/Menu/src/BasicMenu.vue create mode 100644 src/components/Menu/src/components/BasicMenuItem.vue create mode 100644 src/components/Menu/src/components/BasicSubMenuItem.vue create mode 100644 src/components/Menu/src/components/MenuItemContent.vue create mode 100644 src/components/Menu/src/index.less create mode 100644 src/components/Menu/src/props.ts create mode 100644 src/components/Menu/src/types.ts create mode 100644 src/components/Menu/src/useOpenKeys.ts create mode 100644 src/components/Modal/index.ts create mode 100644 src/components/Modal/src/BasicModal.vue create mode 100644 src/components/Modal/src/components/Modal.tsx create mode 100644 src/components/Modal/src/components/ModalClose.vue create mode 100644 src/components/Modal/src/components/ModalFooter.vue create mode 100644 src/components/Modal/src/components/ModalHeader.vue create mode 100644 src/components/Modal/src/components/ModalWrapper.vue create mode 100644 src/components/Modal/src/hooks/useModal.ts create mode 100644 src/components/Modal/src/hooks/useModalContext.ts create mode 100644 src/components/Modal/src/hooks/useModalDrag.ts create mode 100644 src/components/Modal/src/hooks/useModalFullScreen.ts create mode 100644 src/components/Modal/src/index.less create mode 100644 src/components/Modal/src/props.ts create mode 100644 src/components/Modal/src/typing.ts create mode 100644 src/components/Page/index.ts create mode 100644 src/components/Page/src/PageFooter.vue create mode 100644 src/components/Page/src/PageWrapper.vue create mode 100644 src/components/Qrcode/index.ts create mode 100644 src/components/Qrcode/src/Qrcode.vue create mode 100644 src/components/Qrcode/src/drawCanvas.ts create mode 100644 src/components/Qrcode/src/drawLogo.ts create mode 100644 src/components/Qrcode/src/qrcodePlus.ts create mode 100644 src/components/Qrcode/src/toCanvas.ts create mode 100644 src/components/Qrcode/src/typing.ts create mode 100644 src/components/Scrollbar/index.ts create mode 100644 src/components/Scrollbar/src/Scrollbar.vue create mode 100644 src/components/Scrollbar/src/bar.ts create mode 100644 src/components/Scrollbar/src/types.d.ts create mode 100644 src/components/Scrollbar/src/util.ts create mode 100644 src/components/SimpleMenu/index.ts create mode 100644 src/components/SimpleMenu/src/SimpleMenu.vue create mode 100644 src/components/SimpleMenu/src/SimpleMenuTag.vue create mode 100644 src/components/SimpleMenu/src/SimpleSubMenu.vue create mode 100644 src/components/SimpleMenu/src/components/Menu.vue create mode 100644 src/components/SimpleMenu/src/components/MenuCollapseTransition.vue create mode 100644 src/components/SimpleMenu/src/components/MenuItem.vue create mode 100644 src/components/SimpleMenu/src/components/SubMenuItem.vue create mode 100644 src/components/SimpleMenu/src/components/menu.less create mode 100644 src/components/SimpleMenu/src/components/types.ts create mode 100644 src/components/SimpleMenu/src/components/useMenu.ts create mode 100644 src/components/SimpleMenu/src/components/useSimpleMenuContext.ts create mode 100644 src/components/SimpleMenu/src/index.less create mode 100644 src/components/SimpleMenu/src/types.ts create mode 100644 src/components/SimpleMenu/src/useOpenKeys.ts create mode 100644 src/components/StrengthMeter/index.ts create mode 100644 src/components/StrengthMeter/src/StrengthMeter.vue create mode 100644 src/components/Table/index.ts create mode 100644 src/components/Table/src/BasicTable.vue create mode 100644 src/components/Table/src/componentMap.ts create mode 100644 src/components/Table/src/components/EditTableHeaderIcon.vue create mode 100644 src/components/Table/src/components/HeaderCell.vue create mode 100644 src/components/Table/src/components/TableAction.vue create mode 100644 src/components/Table/src/components/TableFooter.vue create mode 100644 src/components/Table/src/components/TableHeader.vue create mode 100644 src/components/Table/src/components/TableImg.vue create mode 100644 src/components/Table/src/components/TableTitle.vue create mode 100644 src/components/Table/src/components/editable/CellComponent.ts create mode 100644 src/components/Table/src/components/editable/EditableCell.vue create mode 100644 src/components/Table/src/components/editable/helper.ts create mode 100644 src/components/Table/src/components/editable/index.ts create mode 100644 src/components/Table/src/components/settings/ColumnSetting.vue create mode 100644 src/components/Table/src/components/settings/FullScreenSetting.vue create mode 100644 src/components/Table/src/components/settings/RedoSetting.vue create mode 100644 src/components/Table/src/components/settings/SizeSetting.vue create mode 100644 src/components/Table/src/components/settings/index.vue create mode 100644 src/components/Table/src/const.ts create mode 100644 src/components/Table/src/hooks/useColumns.ts create mode 100644 src/components/Table/src/hooks/useCustomRow.ts create mode 100644 src/components/Table/src/hooks/useDataSource.ts create mode 100644 src/components/Table/src/hooks/useLoading.ts create mode 100644 src/components/Table/src/hooks/usePagination.tsx create mode 100644 src/components/Table/src/hooks/useRowSelection.ts create mode 100644 src/components/Table/src/hooks/useScrollTo.ts create mode 100644 src/components/Table/src/hooks/useTable.ts create mode 100644 src/components/Table/src/hooks/useTableContext.ts create mode 100644 src/components/Table/src/hooks/useTableExpand.ts create mode 100644 src/components/Table/src/hooks/useTableFooter.ts create mode 100644 src/components/Table/src/hooks/useTableForm.ts create mode 100644 src/components/Table/src/hooks/useTableHeader.ts create mode 100644 src/components/Table/src/hooks/useTableScroll.ts create mode 100644 src/components/Table/src/hooks/useTableStyle.ts create mode 100644 src/components/Table/src/props.ts create mode 100644 src/components/Table/src/types/column.ts create mode 100644 src/components/Table/src/types/componentType.ts create mode 100644 src/components/Table/src/types/pagination.ts create mode 100644 src/components/Table/src/types/table.ts create mode 100644 src/components/Table/src/types/tableAction.ts create mode 100644 src/components/Time/index.ts create mode 100644 src/components/Time/src/Time.vue create mode 100644 src/components/Tools/ImportFileModal.vue create mode 100644 src/components/Transition/index.ts create mode 100644 src/components/Transition/src/CollapseTransition.vue create mode 100644 src/components/Transition/src/CreateTransition.tsx create mode 100644 src/components/Transition/src/ExpandTransition.ts create mode 100644 src/components/Tree/index.ts create mode 100644 src/components/Tree/src/BasicTree.vue create mode 100644 src/components/Tree/src/TreeIcon.ts create mode 100644 src/components/Tree/src/components/TreeHeader.vue create mode 100644 src/components/Tree/src/hooks/useTree.ts create mode 100644 src/components/Tree/src/types/tree.ts create mode 100644 src/components/Tree/style/index.less create mode 100644 src/components/Tree/style/index.ts create mode 100644 src/components/Upload/index.ts create mode 100644 src/components/Upload/src/BasicUpload.vue create mode 100644 src/components/Upload/src/FileList.vue create mode 100644 src/components/Upload/src/ThumbUrl.vue create mode 100644 src/components/Upload/src/UploadModal.vue create mode 100644 src/components/Upload/src/UploadPreviewModal.vue create mode 100644 src/components/Upload/src/data.tsx create mode 100644 src/components/Upload/src/helper.ts create mode 100644 src/components/Upload/src/props.ts create mode 100644 src/components/Upload/src/typing.ts create mode 100644 src/components/Upload/src/useUpload.ts create mode 100644 src/components/VxeTable/index.ts create mode 100644 src/components/VxeTable/src/VxeBasicTable.tsx create mode 100644 src/components/VxeTable/src/componentMap.ts create mode 100644 src/components/VxeTable/src/componentType.ts create mode 100644 src/components/VxeTable/src/components/AApiSelect.tsx create mode 100644 src/components/VxeTable/src/components/AApiTreeSelect.tsx create mode 100644 src/components/VxeTable/src/components/AAutoComplete.tsx create mode 100644 src/components/VxeTable/src/components/AButton.tsx create mode 100644 src/components/VxeTable/src/components/AButtonGroup.tsx create mode 100644 src/components/VxeTable/src/components/ACascader.tsx create mode 100644 src/components/VxeTable/src/components/ACheckboxGroup.tsx create mode 100644 src/components/VxeTable/src/components/ADatePicker.tsx create mode 100644 src/components/VxeTable/src/components/AEmpty.tsx create mode 100644 src/components/VxeTable/src/components/AInput.tsx create mode 100644 src/components/VxeTable/src/components/AInputNumber.tsx create mode 100644 src/components/VxeTable/src/components/AInputSearch.tsx create mode 100644 src/components/VxeTable/src/components/AMonthPicker.tsx create mode 100644 src/components/VxeTable/src/components/ARadioGroup.tsx create mode 100644 src/components/VxeTable/src/components/ARangePicker.tsx create mode 100644 src/components/VxeTable/src/components/ARate.tsx create mode 100644 src/components/VxeTable/src/components/ASelect.tsx create mode 100644 src/components/VxeTable/src/components/ASwitch.tsx create mode 100644 src/components/VxeTable/src/components/ATimePicker.tsx create mode 100644 src/components/VxeTable/src/components/ATreeSelect.tsx create mode 100644 src/components/VxeTable/src/components/AWeekPicker.tsx create mode 100644 src/components/VxeTable/src/components/AYearPicker.tsx create mode 100644 src/components/VxeTable/src/components/common.tsx create mode 100644 src/components/VxeTable/src/components/index.tsx create mode 100644 src/components/VxeTable/src/const.ts create mode 100644 src/components/VxeTable/src/css/common.scss create mode 100644 src/components/VxeTable/src/css/component.scss create mode 100644 src/components/VxeTable/src/css/index.scss create mode 100644 src/components/VxeTable/src/css/scrollbar.scss create mode 100644 src/components/VxeTable/src/css/toolbar.scss create mode 100644 src/components/VxeTable/src/css/variable.scss create mode 100644 src/components/VxeTable/src/emits.ts create mode 100644 src/components/VxeTable/src/helper.ts create mode 100644 src/components/VxeTable/src/methods.ts create mode 100644 src/components/VxeTable/src/props.ts create mode 100644 src/components/VxeTable/src/setting.ts create mode 100644 src/components/VxeTable/src/types.ts create mode 100644 src/components/registerGlobComp.ts create mode 100644 src/design/.DS_Store create mode 100644 src/design/ant/btn.less create mode 100644 src/design/ant/index.less create mode 100644 src/design/ant/input.less create mode 100644 src/design/ant/pagination.less create mode 100644 src/design/ant/table.less create mode 100644 src/design/color.less create mode 100644 src/design/config.less create mode 100644 src/design/dark.less create mode 100644 src/design/entry.css create mode 100644 src/design/index.less create mode 100644 src/design/public.less create mode 100644 src/design/theme.less create mode 100644 src/design/transition/base.less create mode 100644 src/design/transition/fade.less create mode 100644 src/design/transition/index.less create mode 100644 src/design/transition/scale.less create mode 100644 src/design/transition/scroll.less create mode 100644 src/design/transition/slide.less create mode 100644 src/design/transition/zoom.less create mode 100644 src/design/var/breakpoint.less create mode 100644 src/design/var/easing.less create mode 100644 src/design/var/index.less create mode 100644 src/directives/clickOutside.ts create mode 100644 src/directives/ellipsis.ts create mode 100644 src/directives/index.ts create mode 100644 src/directives/loading.ts create mode 100644 src/directives/permission.ts create mode 100644 src/directives/ripple/index.less create mode 100644 src/directives/ripple/index.ts create mode 100644 src/enums/appEnum.ts create mode 100644 src/enums/breakpointEnum.ts create mode 100644 src/enums/cacheEnum.ts create mode 100644 src/enums/exceptionEnum.ts create mode 100644 src/enums/httpEnum.ts create mode 100644 src/enums/menuEnum.ts create mode 100644 src/enums/pageEnum.ts create mode 100644 src/enums/sizeEnum.ts create mode 100644 src/hooks/.DS_Store create mode 100644 src/hooks/component/useFormItem.ts create mode 100644 src/hooks/component/usePageContext.ts create mode 100644 src/hooks/core/useAttrs.ts create mode 100644 src/hooks/core/useContext.ts create mode 100644 src/hooks/event/useBreakpoint.ts create mode 100644 src/hooks/event/useEventListener.ts create mode 100644 src/hooks/event/useScroll.ts create mode 100644 src/hooks/setting/index.ts create mode 100644 src/hooks/setting/useDarkModeTheme.ts create mode 100644 src/hooks/setting/useHeaderSetting.ts create mode 100644 src/hooks/setting/useMenuSetting.ts create mode 100644 src/hooks/setting/useMultipleTabSetting.ts create mode 100644 src/hooks/setting/useRootSetting.ts create mode 100644 src/hooks/setting/useTransitionSetting.ts create mode 100644 src/hooks/web/useAppInject.ts create mode 100644 src/hooks/web/useContentHeight.ts create mode 100644 src/hooks/web/useContextMenu.ts create mode 100644 src/hooks/web/useCopyToClipboard.ts create mode 100644 src/hooks/web/useDesign.ts create mode 100644 src/hooks/web/useECharts.ts create mode 100644 src/hooks/web/useFullContent.ts create mode 100644 src/hooks/web/useI18n.ts create mode 100644 src/hooks/web/useLockPage.ts create mode 100644 src/hooks/web/useMessage.tsx create mode 100644 src/hooks/web/usePage.ts create mode 100644 src/hooks/web/usePagination.ts create mode 100644 src/hooks/web/usePermission.ts create mode 100644 src/hooks/web/useScript.ts create mode 100644 src/hooks/web/useSortable.ts create mode 100644 src/hooks/web/useTabs.ts create mode 100644 src/hooks/web/useTitle.ts create mode 100644 src/hooks/web/useWatermark.ts create mode 100644 src/layouts/.DS_Store create mode 100644 src/layouts/default/content/index.vue create mode 100644 src/layouts/default/content/useContentContext.ts create mode 100644 src/layouts/default/content/useContentViewHeight.ts create mode 100644 src/layouts/default/feature/index.vue create mode 100644 src/layouts/default/footer/index.vue create mode 100644 src/layouts/default/header/MultipleHeader.vue create mode 100644 src/layouts/default/header/components/Breadcrumb.vue create mode 100644 src/layouts/default/header/components/ErrorAction.vue create mode 100644 src/layouts/default/header/components/FullScreen.vue create mode 100644 src/layouts/default/header/components/index.ts create mode 100644 src/layouts/default/header/components/lock/LockModal.vue create mode 100644 src/layouts/default/header/components/notify/NoticeList.vue create mode 100644 src/layouts/default/header/components/notify/data.ts create mode 100644 src/layouts/default/header/components/notify/index.vue create mode 100644 src/layouts/default/header/components/user-dropdown/DropMenuItem.vue create mode 100644 src/layouts/default/header/components/user-dropdown/index.vue create mode 100644 src/layouts/default/header/index.less create mode 100644 src/layouts/default/header/index.vue create mode 100644 src/layouts/default/index.vue create mode 100644 src/layouts/default/menu/index.vue create mode 100644 src/layouts/default/menu/useLayoutMenu.ts create mode 100644 src/layouts/default/setting/SettingDrawer.tsx create mode 100644 src/layouts/default/setting/components/InputNumberItem.vue create mode 100644 src/layouts/default/setting/components/SelectItem.vue create mode 100644 src/layouts/default/setting/components/SettingFooter.vue create mode 100644 src/layouts/default/setting/components/SwitchItem.vue create mode 100644 src/layouts/default/setting/components/ThemeColorPicker.vue create mode 100644 src/layouts/default/setting/components/TypePicker.vue create mode 100644 src/layouts/default/setting/components/index.ts create mode 100644 src/layouts/default/setting/enum.ts create mode 100644 src/layouts/default/setting/handler.ts create mode 100644 src/layouts/default/setting/index.vue create mode 100644 src/layouts/default/sider/DragBar.vue create mode 100644 src/layouts/default/sider/LayoutSider.vue create mode 100644 src/layouts/default/sider/MixSider.vue create mode 100644 src/layouts/default/sider/index.vue create mode 100644 src/layouts/default/sider/useLayoutSider.ts create mode 100644 src/layouts/default/tabs/components/FoldButton.vue create mode 100644 src/layouts/default/tabs/components/TabContent.vue create mode 100644 src/layouts/default/tabs/components/TabRedo.vue create mode 100644 src/layouts/default/tabs/index.less create mode 100644 src/layouts/default/tabs/index.vue create mode 100644 src/layouts/default/tabs/types.ts create mode 100644 src/layouts/default/tabs/useMultipleTabs.ts create mode 100644 src/layouts/default/tabs/useTabDropdown.ts create mode 100644 src/layouts/default/trigger/HeaderTrigger.vue create mode 100644 src/layouts/default/trigger/SiderTrigger.vue create mode 100644 src/layouts/default/trigger/index.vue create mode 100644 src/layouts/iframe/index.vue create mode 100644 src/layouts/iframe/useFrameKeepAlive.ts create mode 100644 src/layouts/page/index.vue create mode 100644 src/layouts/page/transition.ts create mode 100644 src/locales/helper.ts create mode 100644 src/locales/lang/en.ts create mode 100644 src/locales/lang/en/common.ts create mode 100644 src/locales/lang/en/component.ts create mode 100644 src/locales/lang/en/layout.ts create mode 100644 src/locales/lang/en/routes/basic.ts create mode 100644 src/locales/lang/en/routes/dashboard.ts create mode 100644 src/locales/lang/en/routes/demo.ts create mode 100644 src/locales/lang/en/sys.ts create mode 100644 src/locales/lang/zh-CN/antdLocale/DatePicker.ts create mode 100644 src/locales/lang/zh-CN/common.ts create mode 100644 src/locales/lang/zh-CN/component.ts create mode 100644 src/locales/lang/zh-CN/layout.ts create mode 100644 src/locales/lang/zh-CN/routes/basic.ts create mode 100644 src/locales/lang/zh-CN/routes/dashboard.ts create mode 100644 src/locales/lang/zh-CN/routes/demo.ts create mode 100644 src/locales/lang/zh-CN/sys.ts create mode 100644 src/locales/lang/zh_CN.ts create mode 100644 src/locales/setupI18n.ts create mode 100644 src/locales/useLocale.ts create mode 100644 src/logics/.DS_Store create mode 100644 src/logics/error-handle/index.ts create mode 100644 src/logics/initAppConfig.ts create mode 100644 src/logics/mitt/routeChange.ts create mode 100644 src/logics/theme/dark.ts create mode 100644 src/logics/theme/index.ts create mode 100644 src/logics/theme/updateBackground.ts create mode 100644 src/logics/theme/updateColorWeak.ts create mode 100644 src/logics/theme/updateGrayMode.ts create mode 100644 src/logics/theme/util.ts create mode 100644 src/main.ts create mode 100644 src/router/.DS_Store create mode 100644 src/router/constant.ts create mode 100644 src/router/guard/index.ts create mode 100644 src/router/guard/paramMenuGuard.ts create mode 100644 src/router/guard/permissionGuard.ts create mode 100644 src/router/guard/stateGuard.ts create mode 100644 src/router/helper/menuHelper.ts create mode 100644 src/router/helper/routeHelper.ts create mode 100644 src/router/index.ts create mode 100644 src/router/menus/index.ts create mode 100644 src/router/routes/basic.ts create mode 100644 src/router/routes/index.ts create mode 100644 src/router/types.ts create mode 100644 src/settings/componentSetting.ts create mode 100644 src/settings/designSetting.ts create mode 100644 src/settings/encryptionSetting.ts create mode 100644 src/settings/localeSetting.ts create mode 100644 src/settings/projectSetting.ts create mode 100644 src/settings/siteSetting.ts create mode 100644 src/store/index.ts create mode 100644 src/store/modules/app.ts create mode 100644 src/store/modules/errorLog.ts create mode 100644 src/store/modules/locale.ts create mode 100644 src/store/modules/lock.ts create mode 100644 src/store/modules/multipleTab.ts create mode 100644 src/store/modules/permission.ts create mode 100644 src/store/modules/user.ts create mode 100644 src/utils/.DS_Store create mode 100644 src/utils/auth/index.ts create mode 100644 src/utils/bem.ts create mode 100644 src/utils/cache/index.ts create mode 100644 src/utils/cache/memory.ts create mode 100644 src/utils/cache/persistent.ts create mode 100644 src/utils/cache/storageCache.ts create mode 100644 src/utils/cipher.ts create mode 100644 src/utils/color.ts create mode 100644 src/utils/dateUtil.ts create mode 100644 src/utils/domUtils.ts create mode 100644 src/utils/env.ts create mode 100644 src/utils/event/index.ts create mode 100644 src/utils/factory/createAsyncComponent.tsx create mode 100644 src/utils/file/base64Conver.ts create mode 100644 src/utils/file/download.ts create mode 100644 src/utils/helper/treeHelper.ts create mode 100644 src/utils/helper/tsxHelper.tsx create mode 100644 src/utils/http/axios/Axios.ts create mode 100644 src/utils/http/axios/axiosCancel.ts create mode 100644 src/utils/http/axios/axiosRetry.ts create mode 100644 src/utils/http/axios/axiosTransform.ts create mode 100644 src/utils/http/axios/checkStatus.ts create mode 100644 src/utils/http/axios/helper.ts create mode 100644 src/utils/http/axios/index.ts create mode 100644 src/utils/index.ts create mode 100644 src/utils/is.ts create mode 100644 src/utils/lib/echarts.ts create mode 100644 src/utils/log.ts create mode 100644 src/utils/mitt.ts create mode 100644 src/utils/propTypes.ts create mode 100644 src/utils/props.ts create mode 100644 src/utils/tree.ts create mode 100644 src/utils/types.ts create mode 100644 src/utils/uuid.ts create mode 100644 src/views/.DS_Store create mode 100644 src/views/basic/account/BaseSetting.vue create mode 100644 src/views/basic/account/BindEmailModal.vue create mode 100644 src/views/basic/account/BindPhoneModal.vue create mode 100644 src/views/basic/account/MsgNotify.vue create mode 100644 src/views/basic/account/ResetPasswordModal.vue create mode 100644 src/views/basic/account/SecureSetting.vue create mode 100644 src/views/basic/account/data.ts create mode 100644 src/views/basic/account/index.vue create mode 100644 src/views/basic/customer/components/CustomerModal.vue create mode 100644 src/views/basic/customer/customer.data.ts create mode 100644 src/views/basic/customer/index.vue create mode 100644 src/views/basic/income-expense/components/AddEditModal.vue create mode 100644 src/views/basic/income-expense/incomeExpense.data.ts create mode 100644 src/views/basic/income-expense/index.vue create mode 100644 src/views/basic/member/components/MemberModal.vue create mode 100644 src/views/basic/member/index.vue create mode 100644 src/views/basic/member/member.data.ts create mode 100644 src/views/basic/operator/components/OperatorModal.vue create mode 100644 src/views/basic/operator/index.vue create mode 100644 src/views/basic/operator/operator.data.ts create mode 100644 src/views/basic/settlement-account/components/FinancialAccountModal.vue create mode 100644 src/views/basic/settlement-account/components/MultipleAccountsModal.vue create mode 100644 src/views/basic/settlement-account/financialAccount.data.ts create mode 100644 src/views/basic/settlement-account/index.vue create mode 100644 src/views/basic/supplier/components/SupplierModal.vue create mode 100644 src/views/basic/supplier/index.vue create mode 100644 src/views/basic/supplier/supplier.data.ts create mode 100644 src/views/basic/warehouse/components/WarehouseModal.vue create mode 100644 src/views/basic/warehouse/index.vue create mode 100644 src/views/basic/warehouse/warehouse.data.ts create mode 100644 src/views/dashboard/analysis/components/GrowCard.vue create mode 100644 src/views/dashboard/analysis/components/GrowCardFour.vue create mode 100644 src/views/dashboard/analysis/components/GrowCardThree.vue create mode 100644 src/views/dashboard/analysis/components/GrowCardTwo.vue create mode 100644 src/views/dashboard/analysis/components/SalesProductPie.vue create mode 100644 src/views/dashboard/analysis/components/SiteAnalysis.vue create mode 100644 src/views/dashboard/analysis/components/VisitAnalysis.vue create mode 100644 src/views/dashboard/analysis/components/VisitAnalysisBar.vue create mode 100644 src/views/dashboard/analysis/components/VisitRadar.vue create mode 100644 src/views/dashboard/analysis/components/VisitSource.vue create mode 100644 src/views/dashboard/analysis/components/props.ts create mode 100644 src/views/dashboard/analysis/data.ts create mode 100644 src/views/dashboard/analysis/index.vue create mode 100644 src/views/dashboard/workbench/components/DynamicInfo.vue create mode 100644 src/views/dashboard/workbench/components/ProjectCard.vue create mode 100644 src/views/dashboard/workbench/components/QuickNav.vue create mode 100644 src/views/dashboard/workbench/components/SaleRadar.vue create mode 100644 src/views/dashboard/workbench/components/WorkbenchHeader.vue create mode 100644 src/views/dashboard/workbench/components/data.ts create mode 100644 src/views/dashboard/workbench/index.vue create mode 100644 src/views/financial/advance-charge/advance.data.ts create mode 100644 src/views/financial/advance-charge/components/AdvanceChargeModal.vue create mode 100644 src/views/financial/advance-charge/components/ViewAdvanceChargeModal.vue create mode 100644 src/views/financial/advance-charge/index.vue create mode 100644 src/views/financial/collection/addEditCollection.data.ts create mode 100644 src/views/financial/collection/collection.data.ts create mode 100644 src/views/financial/collection/components/AddEditCollectionModal.vue create mode 100644 src/views/financial/collection/components/SaleArrearsModal.vue create mode 100644 src/views/financial/collection/components/ViewCollectionModal.vue create mode 100644 src/views/financial/collection/index.vue create mode 100644 src/views/financial/expense/addEditExpense.data.ts create mode 100644 src/views/financial/expense/components/AddEditExpenseModal.vue create mode 100644 src/views/financial/expense/components/ViewExpenseModal.vue create mode 100644 src/views/financial/expense/expense.data.ts create mode 100644 src/views/financial/expense/index.vue create mode 100644 src/views/financial/income/addEditIncome.data.ts create mode 100644 src/views/financial/income/components/AddEditIncomeModal.vue create mode 100644 src/views/financial/income/components/ViewIncomeModal.vue create mode 100644 src/views/financial/income/income.data.ts create mode 100644 src/views/financial/income/index.vue create mode 100644 src/views/financial/payment/addEditPayment.data.ts create mode 100644 src/views/financial/payment/components/AddEditPaymentModal.vue create mode 100644 src/views/financial/payment/components/PurchaseArrearsModal.vue create mode 100644 src/views/financial/payment/components/ViewPaymentModal.vue create mode 100644 src/views/financial/payment/index.vue create mode 100644 src/views/financial/payment/payment.data.ts create mode 100644 src/views/financial/transfer/addEditTransfer.data.ts create mode 100644 src/views/financial/transfer/components/AddEditTransferModal.vue create mode 100644 src/views/financial/transfer/components/ViewTransferModal.vue create mode 100644 src/views/financial/transfer/index.vue create mode 100644 src/views/financial/transfer/transfer.data.ts create mode 100644 src/views/product/attributes/attributes.data.ts create mode 100644 src/views/product/attributes/components/AttributeModal.vue create mode 100644 src/views/product/attributes/index.vue create mode 100644 src/views/product/category/category.data.ts create mode 100644 src/views/product/category/components/CategoryModal.vue create mode 100644 src/views/product/category/index.vue create mode 100644 src/views/product/info/components/BatchEditModal.vue create mode 100644 src/views/product/info/components/BatchSetPriceModal.vue create mode 100644 src/views/product/info/components/BatchSetStockModal.vue create mode 100644 src/views/product/info/components/ProductInfoModal.vue create mode 100644 src/views/product/info/components/SelectProductModal.vue create mode 100644 src/views/product/info/index.vue create mode 100644 src/views/product/info/info.data.ts create mode 100644 src/views/product/info/model/productInfoModel.ts create mode 100644 src/views/product/units/components/UnitModal.vue create mode 100644 src/views/product/units/index.vue create mode 100644 src/views/product/units/units.data.ts create mode 100644 src/views/purchase/model/addEditModel.ts create mode 100644 src/views/purchase/order/components/AddEditModal.vue create mode 100644 src/views/purchase/order/components/ViewOrderModal.vue create mode 100644 src/views/purchase/order/index.vue create mode 100644 src/views/purchase/order/purchaseOrder.data.ts create mode 100644 src/views/purchase/refund/components/AddEditModal.vue create mode 100644 src/views/purchase/refund/components/ViewRefundModal.vue create mode 100644 src/views/purchase/refund/index.vue create mode 100644 src/views/purchase/refund/purchaseRefund.data.ts create mode 100644 src/views/purchase/storage/components/AddEditModal.vue create mode 100644 src/views/purchase/storage/components/ViewStorageModal.vue create mode 100644 src/views/purchase/storage/index.vue create mode 100644 src/views/purchase/storage/purchaseStorage.data.ts create mode 100644 src/views/receipt/LinkReceiptModal.vue create mode 100644 src/views/receipt/ReceiptDetailModal.vue create mode 100644 src/views/receipt/receipt.data.ts create mode 100644 src/views/report/accountStatistics.vue create mode 100644 src/views/report/customerBill.vue create mode 100644 src/views/report/modal/AccountFlowModal.vue create mode 100644 src/views/report/modal/CustomerBillDetailModal.vue create mode 100644 src/views/report/modal/StockFlowModal.vue create mode 100644 src/views/report/modal/SupplierBillDetailModal.vue create mode 100644 src/views/report/productStock.vue create mode 100644 src/views/report/purchaseStatistics.vue create mode 100644 src/views/report/report.data.ts create mode 100644 src/views/report/retailStatistics.vue create mode 100644 src/views/report/saleStatistics.vue create mode 100644 src/views/report/shipmentsDetail.vue create mode 100644 src/views/report/shipmentsSummary.vue create mode 100644 src/views/report/storageDetail.vue create mode 100644 src/views/report/storageSummary.vue create mode 100644 src/views/report/supplierBill.vue create mode 100644 src/views/retail/refund/components/AddEditModal.vue create mode 100644 src/views/retail/refund/components/ViewRefundModal.vue create mode 100644 src/views/retail/refund/index.vue create mode 100644 src/views/retail/refund/refund.data.ts create mode 100644 src/views/retail/shipments/components/AddEditModal.vue create mode 100644 src/views/retail/shipments/components/ViewShipmentModal.vue create mode 100644 src/views/retail/shipments/index.vue create mode 100644 src/views/retail/shipments/model/addEditModel.ts create mode 100644 src/views/retail/shipments/shipments.data.ts create mode 100644 src/views/sales/model/addEditModel.ts create mode 100644 src/views/sales/order/components/AddEditModal.vue create mode 100644 src/views/sales/order/components/ViewSaleOrderModal.vue create mode 100644 src/views/sales/order/index.vue create mode 100644 src/views/sales/order/sales.data.ts create mode 100644 src/views/sales/refund/components/AddEditModal.vue create mode 100644 src/views/sales/refund/components/ViewSaleRefundModal.vue create mode 100644 src/views/sales/refund/index.vue create mode 100644 src/views/sales/refund/saleRefund.data.ts create mode 100644 src/views/sales/shipments/components/AddEditModal.vue create mode 100644 src/views/sales/shipments/components/ViewSaleShipmentsModal.vue create mode 100644 src/views/sales/shipments/index.vue create mode 100644 src/views/sales/shipments/saleShipments.data.ts create mode 100644 src/views/sys/about/index.vue create mode 100644 src/views/sys/config/config.data.ts create mode 100644 src/views/sys/config/index.vue create mode 100644 src/views/sys/department/components/DeptModal.vue create mode 100644 src/views/sys/department/dept.data.ts create mode 100644 src/views/sys/department/index.vue create mode 100644 src/views/sys/error-log/DetailModal.vue create mode 100644 src/views/sys/error-log/data.tsx create mode 100644 src/views/sys/error-log/index.vue create mode 100644 src/views/sys/exception/Exception.vue create mode 100644 src/views/sys/exception/index.ts create mode 100644 src/views/sys/iframe/FrameBlank.vue create mode 100644 src/views/sys/iframe/index.vue create mode 100644 src/views/sys/lock/LockPage.vue create mode 100644 src/views/sys/lock/index.vue create mode 100644 src/views/sys/lock/useNow.ts create mode 100644 src/views/sys/login/ForgetPasswordForm.vue create mode 100644 src/views/sys/login/Login.vue create mode 100644 src/views/sys/login/LoginForm.vue create mode 100644 src/views/sys/login/LoginFormTitle.vue create mode 100644 src/views/sys/login/MobileForm.vue create mode 100644 src/views/sys/login/QrCodeForm.vue create mode 100644 src/views/sys/login/RegisterForm.vue create mode 100644 src/views/sys/login/SessionTimeoutLogin.vue create mode 100644 src/views/sys/login/useLogin.ts create mode 100644 src/views/sys/menu/MenuDrawer.vue create mode 100644 src/views/sys/menu/index.vue create mode 100644 src/views/sys/menu/menu.data.ts create mode 100644 src/views/sys/redirect/index.vue create mode 100644 src/views/sys/role/components/RoleDrawer.vue create mode 100644 src/views/sys/role/components/RolePermissionModal.vue create mode 100644 src/views/sys/role/index.vue create mode 100644 src/views/sys/role/role.data.ts create mode 100644 src/views/sys/user/account.data.ts create mode 100644 src/views/sys/user/components/AccountDetail.vue create mode 100644 src/views/sys/user/components/AccountModal.vue create mode 100644 src/views/sys/user/components/DeptTree.vue create mode 100644 src/views/sys/user/index.vue create mode 100644 src/views/warehouse/addEditAssembleOrDisassemble.data.ts create mode 100644 src/views/warehouse/addEditStorageShipments.data.ts create mode 100644 src/views/warehouse/allot/allotShipments.data.ts create mode 100644 src/views/warehouse/allot/components/AddEditAllotShipmentsModal.vue create mode 100644 src/views/warehouse/allot/components/ViewAllotShipmentsModal.vue create mode 100644 src/views/warehouse/allot/components/addEditAllotShipments.data.ts create mode 100644 src/views/warehouse/allot/index.vue create mode 100644 src/views/warehouse/assemble/assemble.data.ts create mode 100644 src/views/warehouse/assemble/components/AddEditAssembleModal.vue create mode 100644 src/views/warehouse/assemble/components/ViewAssembleModal.vue create mode 100644 src/views/warehouse/assemble/index.vue create mode 100644 src/views/warehouse/disassemble/components/AddEditDisassembleModal.vue create mode 100644 src/views/warehouse/disassemble/components/ViewDisassembleModal.vue create mode 100644 src/views/warehouse/disassemble/disassemble.data.ts create mode 100644 src/views/warehouse/disassemble/index.vue create mode 100644 src/views/warehouse/shipments/components/AddEditOtherShipmentsModal.vue create mode 100644 src/views/warehouse/shipments/components/ViewOtherShipmentsModal.vue create mode 100644 src/views/warehouse/shipments/index.vue create mode 100644 src/views/warehouse/shipments/otherShipments.data.ts create mode 100644 src/views/warehouse/storage/components/AddEditOtherStorageModal.vue create mode 100644 src/views/warehouse/storage/components/ViewOtherStorageModal.vue create mode 100644 src/views/warehouse/storage/index.vue create mode 100644 src/views/warehouse/storage/otherStorage.data.ts create mode 100644 src/views/workflow/bpmn/index.vue create mode 100644 src/views/workflow/bpmn/zh.ts delete mode 100644 test.txt create mode 100644 tsconfig.json create mode 100644 turbo.json create mode 100644 types/axios.d.ts create mode 100644 types/codemirror.d.ts create mode 100644 types/config.d.ts create mode 100644 types/global.d.ts create mode 100644 types/index.d.ts create mode 100644 types/module.d.ts create mode 100644 types/store.d.ts create mode 100644 types/tree.d.ts create mode 100644 types/utils.d.ts create mode 100644 types/vue-router.d.ts create mode 100644 types/vueuseCore.d.ts create mode 100644 vite.config.ts create mode 100644 wansenai-logo.png diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..98e58e718d3ef60e6767e879233938bf018c2530 GIT binary patch literal 8196 zcmeHMJ#Q2-5Pc@eDH2LV1ByiBf;JLCpDbN$w7XQ|_`SLW*=-P*BoP^Go<> zsHpf2NGMGregbc7vuCe&FA@bpFqZ5&dEV?izg>GX8vthKbhHI*09a)gd*eEXmL`7b zS-Tcy?$8>>10~KThg-YDayrYe{c<+0!j;eqv@Lwt* z=YwSzTLfEq>y8c%t^}Z6=Co`4%{suv*kFrbD{oyWuj#7?6GBZWF^mtV-wK?z2)6Rp zhr{@An2_0o3dOkWjI$07Q+TVRDxeDF3P|nV!wAnX!z8cY&DW-XTK4;cNjc!WY`HH- z?>;}sF{3Lnv*+=50=H|0M~NYh$mT`*9bx5m$Wi+j@Q5&-JZenJ!!iv|B+ug{?L#{u~y>|YQxf6d!{syL%LxM?otXrnxeI4T%FXb-K z9$=E{aQwCn6Z5(Fe)Gfl(mfa1wPIZs;SyfvhvzjT8+kt3G{XHyj#mQ{^V)kK@yc*> ztrp=@URHSZxOYx5;Qkq7m}qtP=~B}l^Pz9Pf1+!|8g*e39``E3u!Ixdv6R8~ttWF& zocr~wT8j`DXU)AyzQ=DQ-wL0RGp@b)v|{rz^~QPW`L*UKKF-~aNb=)T`13*E|5Qtx zD)2iB$l1iUA@%>m?(hE&q=PD;3jCW2nC1R%e}`)ewRN^iskJTpKD#u*Ro=P~4z3)h hb>%p1{SQO_wuDMd5p3lxXV~;ZfRjN7Rp5^*@Dsw$9uNQk literal 0 HcmV?d00001 diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..234f9ca --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +node_modules/ +dist/ +.vscode/ \ No newline at end of file diff --git a/.env b/.env new file mode 100644 index 0000000..7a6f02e --- /dev/null +++ b/.env @@ -0,0 +1,5 @@ +# Configure the name of the global project +VITE_GLOB_APP_TITLE = EAIRP + +# Need to underline here +VITE_GLOB_APP_SHORT_NAME=WanSen_ERP diff --git a/.env.analyze b/.env.analyze new file mode 100644 index 0000000..656b553 --- /dev/null +++ b/.env.analyze @@ -0,0 +1,23 @@ +# Whether to open mock +VITE_USE_MOCK = false + +# public path +VITE_PUBLIC_PATH = / + +# Whether to enable gzip or brotli compression +# Optional: gzip | brotli | none +# If you need multiple forms, you can use `,` to separate +VITE_BUILD_COMPRESS = 'none' + + +# Basic interface address SPA +VITE_GLOB_API_URL=/erp-api + +# File upload address, optional +# It can be forwarded by nginx or write the actual address directly +VITE_GLOB_UPLOAD_URL=/upload + +# Interface prefix +VITE_GLOB_API_URL_PREFIX= + +VITE_ENABLE_ANALYZE = true diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..4e7de53 --- /dev/null +++ b/.env.development @@ -0,0 +1,16 @@ +# Whether to open mock +VITE_USE_MOCK = false + +# public path +VITE_PUBLIC_PATH = / + +VITE_BUILD_COMPRESS = 'none' + +# Delete console +VITE_DROP_CONSOLE = false + +# Basic interface address SPA +VITE_GLOB_API_URL=/erp-api + +# Interface prefix +VITE_GLOB_API_URL_PREFIX= diff --git a/.env.docker b/.env.docker new file mode 100644 index 0000000..8a4caa4 --- /dev/null +++ b/.env.docker @@ -0,0 +1,22 @@ +# Whether to open mock +VITE_USE_MOCK = false + +# public path +VITE_PUBLIC_PATH = / + +# timeout(seconds) +VITE_TIMEOUT = 15 +# Delete console +VITE_DROP_CONSOLE = true + +# Whether to enable gzip or brotli compression +# Optional: gzip | brotli | none +# If you need multiple forms, you can use `,` to separate +VITE_BUILD_COMPRESS = 'none' +VITE_GLOB_API_URL='api_base_url' + +# File upload address, optional +# It can be forwarded by nginx or write the actual address directly +VITE_GLOB_UPLOAD_URL=/files/upload +# Interface prefix +VITE_GLOB_API_URL_PREFIX= \ No newline at end of file diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..effc802 --- /dev/null +++ b/.env.production @@ -0,0 +1,25 @@ +# Whether to open mock +VITE_USE_MOCK = false + +# public path +VITE_PUBLIC_PATH = / + +VITE_BUILD_COMPRESS = 'none' + +# Delete console +VITE_DROP_CONSOLE = false + +# Basic interface address SPA +VITE_GLOB_API_URL=/erp-api + +# Interface prefix +VITE_GLOB_API_URL_PREFIX= + +# Whether to enable image compression +VITE_USE_IMAGEMIN= false + +# use pwa +VITE_USE_PWA = false + +# Is it compatible with older browsers +VITE_LEGACY = false diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..d3f18d8 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,15 @@ +*.sh +node_modules +*.md +*.woff +*.ttf +.vscode +.idea +dist +/public +/docs +.local +/bin +/docker + +/internal/**/dist diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..6f40582 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,15 @@ +/* eslint-env node */ +require('@rushstack/eslint-patch/modern-module-resolution') + +module.exports = { + root: true, + 'extends': [ + 'plugin:vue/vue3-essential', + 'eslint:recommended', + '@vue/eslint-config-typescript', + '@vue/eslint-config-prettier/skip-formatting' + ], + parserOptions: { + ecmaVersion: 'latest' + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9722d32 --- /dev/null +++ b/.gitignore @@ -0,0 +1,110 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# vscode private configuration file +.vscode/redis.json + +.idea + +.vscode diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..6907420 --- /dev/null +++ b/.npmrc @@ -0,0 +1,7 @@ +public-hoist-pattern[]=*eslint* +public-hoist-pattern[]=*prettier* +public-hoist-pattern[]=lint-staged +public-hoist-pattern[]=*stylelint* +public-hoist-pattern[]=@commitlint/cli + +registry=https://registry.npmmirror.com \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..1ff6595 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,17 @@ +dist +.local +.output.js +node_modules + +**/*.svg +**/*.sh + +public +.npmrc + +internal/**/dist + +deploy +docs +docker +mock \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..1acbf9c --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,20 @@ +module.exports = { + printWidth: 100, + semi: true, + vueIndentScriptAndStyle: true, + singleQuote: true, + trailingComma: 'all', + proseWrap: 'never', + // Ignore space sensitivity in HTML tags + htmlWhitespaceSensitivity: 'ignore', + endOfLine: 'auto', + plugins: ['prettier-plugin-packagejson'], + overrides: [ + { + files: '.*rc', + options: { + parser: 'json', + }, + }, + ], +}; diff --git a/.stylelintrc.js b/.stylelintrc.js new file mode 100644 index 0000000..65320e7 --- /dev/null +++ b/.stylelintrc.js @@ -0,0 +1,4 @@ +module.exports = { + root: true, + extends: ['@vben/stylelint-config'], +}; diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..3e94a88 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,24 @@ +FROM node:18.18.0 as build-stage +MAINTAINER WanSen AI +WORKDIR app + +COPY . ./ + +ENV NODE_OPTIONS --max-old-space-size=16384 + +RUN npm install pnpm -g +RUN pnpm install --frozen-lockfile +RUN pnpm build:docker + +RUN echo "Build Success" + +FROM nginx:1.23.4 as production-stage +COPY --from=build-stage /app/dist /usr/share/nginx/html/dist +COPY --from=build-stage /app/nginx.conf /etc/nginx/nginx.conf +EXPOSE 80 + +CMD sed -i "s|api_base_url|$API_BASE_URL|g" /usr/share/nginx/html/dist/assets/index.js && \ + sed -i "s|api_base_url|$API_BASE_URL|g" /usr/share/nginx/html/dist/_app.config.js && \ + nginx -g 'daemon off;' + +RUN echo "Run Success" diff --git a/README.md b/README.md new file mode 100644 index 0000000..c3d7d7a --- /dev/null +++ b/README.md @@ -0,0 +1,113 @@ +

+ +

+

+ Enterprise AI Resource Planning Web +

+
+ + + Crates.io version + + + + + + + + +
+ +
+ Next generation artificial intelligent ERP system. +
+
+ +## Project +[English](README.md) | [简体中文](./README-zh_CN.md) + +### Quick Start + +You can directly use the Docker pull image for quick startup. Here are the commands to pull the front-end image + +### Pull images +```shell +docker pull wansenai/eairp-web:2.0.3 +``` + +### Run Server +Please note the `API_BASE_URL` parameter, this is the address mapped by the back-end interface. +If you are deploying on your server, modify the localhost address here to your server IP. +```shell +docker run --name eairp-web -d -p 3000:80 -e API_BASE_URL=http://localhost:8080/erp-api wansenai/eairp-web:2.0.3 +``` +If you want to deploy the API using Docker, you can also pull the API image +```shell +docker pull wansenai/eairp:2.0.3 +``` +And run API services +```shell +docker run --name eairp -d -p 9998:8088 wansenai/eairp:2.0.3 +``` + +### Online preview +- [eairp preview / 在线预览](https://erp.wansen.cloud/) +- test account (测试账号): wansen +- test password (测试密码): 123456 +- Some functional modules are being developed and improved, please refer to our [to-do list](https://github.com/wansenai/eairp-web/issues/41). It's not easy to generate electricity with love. +- If this project is helpful to you, please click on Star. Thank you. + + 一些功能模块正在开发和改进中, 请参阅我们的[开发计划](https://github.com/wansenai/eairp-web/issues/42), 用爱发电很不容易, 如果这个项目对你有帮助, 请点击Star非常感谢. + +### Repository code +- [wansen-erp](https://github.com/wansenai/wansen-erp) - **Current version** +- [wansen-erp-core](https://github.com/wansenai/wansen-erp-core) - **Current API version** + +## Browser support + +The `Chrome 80+` browser is recommended for local development + +Support modern browsers, not IE + +| [ Edge](http://godban.github.io/browsers-support-badges/)
IE | [ Edge](http://godban.github.io/browsers-support-badges/)
Edge | [Firefox](http://godban.github.io/browsers-support-badges/)
Firefox | [Chrome](http://godban.github.io/browsers-support-badges/)
Chrome | [Safari](http://godban.github.io/browsers-support-badges/)
Safari | +| :-: | :-: | :-: | :-: | :-: | +| not support | last 2 versions | last 2 versions | last 2 versions | last 2 versions | + +## System screenshot (only part) +![](images/login-page-en.png) +![](images/home-page-zh.png) +![](images/user-manage-zh.png) +![](images/add-menu-zh.png) +![](images/role-permission-zh.png) + +## Install and use + +- Get the project code + +```bash +git clone https://github.com/wansenai/wansen-erp.git +``` + +- Installation dependencies + +```bash +cd wansen-erp + +pnpm install + +``` + +- run + +```bash +pnpm serve +``` + +- build + +```bash +pnpm build +``` diff --git a/deploy/default.conf b/deploy/default.conf new file mode 100644 index 0000000..d03d8a6 --- /dev/null +++ b/deploy/default.conf @@ -0,0 +1,18 @@ +server { + listen 80; + listen [::]:80; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + try_files $uri $uri/ /index.html; + } + + location /erp-api/ { + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header REMOTE-HOST $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } +} diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..2fc40ea --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,8 @@ +FROM nginx:1.23.4-alpine + +COPY dist/ /usr/share/nginx/html/ +COPY ../deploy/default.conf /etc/nginx/conf.d/ + +LABEL MAINTAINER="team@wansenai.com" + +EXPOSE 80 diff --git a/docker/Makefile b/docker/Makefile new file mode 100644 index 0000000..1de5a3f --- /dev/null +++ b/docker/Makefile @@ -0,0 +1,25 @@ +VERSION=$(shell git describe --tags --always) + +.PHONY: docker +docker: # Compile and build the docker | 编译并构建 docker 镜像 + pnpm install + pnpm build + docker build -f Dockerfile -t ${DOCKER_USERNAME}/backend-ui:${VERSION} . + +.PHONY: docker-not-build +docker-not-build: # Build the docker without compiling | 不编译直接构建镜像 + docker build -f Dockerfile -t ${DOCKER_USERNAME}/backend-ui:${VERSION} . + +.PHONY: publish-docker +publish-docker: # Publish the docker | 发布镜像 + echo "${DOCKER_PASSWORD}" | docker login --username ${DOCKER_USERNAME} --password-stdin https://${REPO} + docker push ${DOCKER_USERNAME}/backend-ui:${VERSION} + +.PHONY: run-docker +run-docker: # Run the docker image | 运行 docker 镜像 + docker volume create backendui + docker run -d --name ${DOCKER_USERNAME}/backend-ui:${VERSION} -p 80:80 -v backendui:/etc/nginx --network docker-compose_simple-admin ${DOCKER_USERNAME}/backendui:${VERSION} + +.PHONY: help +help: # Show help | 显示帮助 + @grep -E '^[a-zA-Z0-9 -]+:.*#' Makefile | sort | while read -r l; do printf "\033[1;32m$$(echo $$l | cut -f 1 -d':')\033[00m:$$(echo $$l | cut -f 2- -d'#')\n"; done diff --git a/docs/README_ZH.md b/docs/README_ZH.md new file mode 100644 index 0000000..d186c66 --- /dev/null +++ b/docs/README_ZH.md @@ -0,0 +1,24 @@ + +# WanSen ERP UI + +## 项目设置 +``` +npm install -g pnpm + +pnpm install +``` + +### 用于打包生产环境的编译程序 +``` +pnpm build + +pnpm preview +``` + +### 查看打包后的程序 +``` +pnpm preview:dist +``` + +### Vue-Cli 自定义配置 +See [Configuration Reference](https://cli.vuejs.org/config/). diff --git a/docs/template/会员信息模板.xlsx b/docs/template/会员信息模板.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..ab2441abb41b54ae5d993f42dbe7aa676d99659f GIT binary patch literal 18944 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 G;eP-igj%@( literal 0 HcmV?d00001 diff --git a/docs/template/供应商模板.xlsx b/docs/template/供应商模板.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..b04a2043719597c36f8c34d3840cc20c81885f9b GIT binary patch literal 19456 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 literal 0 HcmV?d00001 diff --git a/docs/template/客户信息模板.xlsx b/docs/template/客户信息模板.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..627db504953b550282c507bd6799b46d576418c9 GIT binary patch literal 19456 zcmeHPd0Z67wyvHTU_eoJ5d;QAKsMPol}$7%h$4tFs0fOpq8LzwC;=DZ0xF7eC9Xk@ z#(j(8E{Z6|6_=Q(NKlNsSA!@z@0@OWrkRb{A9_P?he(bv+n?LsF$|gK*G4x_h4N|ImUh8-+MKq!FR}%r*Avz9MLhgYdOeR3T zr$WdGP;)e>Gn%B+O$8Oi>XZEYT_~+X0);vp0|R%3I|@bTjfij{1mI=!5*K^h^dleN^cAD;TYf3LGq#Dt-|U9rIPikMuwl_(%^@sShFEJalay zx;GELn1^4VhhL9}ZpcH|=Ao;q7pDC*Zx5CtCm2Tz31vfS;bGdIID>Cb+(>7_PzDnh z4%JfR4Uc$JRqS!3KS_daK7>cm7v=?Rl?7cPFTUKEG)qwkG&4(nQS~{qAft&R@gP(@ zku)jj2zT=GBE2(dp4zLRGA9NN}Q2>8A znBuC^wRvXzd`!kc&^6>JY`I1eCm7OHluHp#xpb;H)MeEP#sp(R4Tk9*x0X6WEe$3P z;JNg{U~Nm0KeS9U)gtmX!YAArTBo_9FsrocT$xlR@9vPZM4h-g4dg&~>6tJgucZ<~ z8exE<-7yK$DY$r9b-=djhwds8-^;U zJM+-BdFUN^=#DDsxL#uIA1n!$u=(PgOBEg0RW!X=U*DvKNedz}quU9twN&xr`b!lZ z*JP^bxK5+#R|#kn3`;V`KF|VH(s4b<;fJLh!!M&lyXBS(*M2nrVtxIkEtZ1*ooM}W zJ;>6JS{=0_B5j(EYebgL@H2E=H!}2*BN={QnjhDaH2o?W2KmBLlF7_Eg4U?5|8W;n9g&_}MZmOM+*_e==VYqB9+$4ANN;NAxCcYwQ-j5k(cuxUK%Xi$B2!U7 z=DL%UC6NW$Vi%I#jE=oc0Bbr}z0$n$b#p72NeYw&up7z+a!Iaiq1_~qt&juuPfaL4 zlf$lEyJP}7Drj0NXkryKQ4>unt(4*MXp94aTw~z=D*+rK7y(?%qh}pY4mfnkbI8fb zQOqGk!6w*Og)j{^lI^y!Ibcoj@W3RfAl><^4@rfXvI3OOLsz7M9nl3!WapQn6 z$4RUZTO2lyArFWv$OGaJNo;YFMslaQEXYUL1W$ulkjjWp1nJBH@$ggy0t_<8Q=Bfqz-q!Azp@f+ zao9M9JRn^mi3Ld-iF*>PV?jQ`CV?Qsf>cI)B1jMi#KTh+2&)-}O~r9gcs>V15+z%% zz>`b%@X8h|@`mv8771X8&n41DVl%RcQ#%wzqypkMv}_KD66Dg$6-qJG&lS<3L9PZJ z8s=)!p;4|D9UA9~>Chxs8$xZ^?1Y1*x|FjEm9h}%Ko*$7WT6Y2oFYPv%8w)bs1)KzV1rmmDWM)H#ip_%?c^dJDn#^UA~+JGb#>tt09h`cDntxqA~^0cB9?Ly zFBKw&G7%hQQA8VFFo3!!T96c_WG#UaSPN5FRtdxURt2ju&H7fxYK^RG^OsIhMl}Ie zOkq%46C139W68Cn21Iv@>XN)jtXKzapbq5etXO*#`>?oVIG>m)h{@C0GT5SGpQUsj zrlgp#EhvU5467FDfEx$dgBFQR!IVg397UN)DUv-1V?_cjVux%`hbXg|1KZOf44XEw z$BYGqE|E$ZQ|%yQOkr4!VZ&ccsDOB3!K|c#amCBhrZdgVuDKc_3#phWaxoCra6-_E zP#$pD)PYFg*hZqnxJZo65ZM_=i7ch9;LM0$0{Myr)^M@}&|Yd7m7%QwTAc(7?S#-i ze+yay(CQ=@Xk$1>QnD!;K+&ewN;YNtqcxaOtxXY5(WW+PZ7PR$Rc}*O(CyXQR1V!q zy-ig?+p4uG3vCSbq-0YZs1$A5LCL16O)t1 zC3WKG!822aN6u*kG%<}fHfxDVHpJ$F$4zuDCw<>1VSK`+Jo{ zr#f#m-}Fn*cBh_YUpEFbL~Cx7`mz#w^vJd_dB%^FiZ^ox#)AjlL83Rw1H0j*NrJZW9^a{Z~Js*bxq}S-2(^HUMGYe9$u-DFuHvEkj-x` zBZVf5y#9DI`Lh`dT;HuKbkNmL>iG0cx^v@}Qmd~gXgoP%YJWrcF6Qx?`Bve}pTs!Y z9$jAqdNRvCu+3YvunUsA17^_AD)#sQ2Y1W85#`BnOwcE@A1iw zd1hh2+t3V;6Rk_0McLYRse3cv{eyuS+hZ<9CWO^$ z#+@9$MygYKLQ*{bp?{W_tNqsN=CAJ$eHbs?G`ReA-20J72fe*Qj6^#w7w13Rz4OlP zXWlwLQfGq#rq+LP_{oYq-^SGKU)~JAy_wZAmKYDuB?dacOJ(kQDv`*a?J8^v@RG-S+N z?eN+SUxZ&2p4KA$g6G=y>gs>txk#hm(IH_K%M70thV6{Gvc{sI;6Xz_$+d5;7OWEc zRg5S7e)#t7@r`fZp7MP5I)CHF1*=vEzO8-rqUOqHK@W~NpA;_cv7vg)v!id` z-RgVz=&J1cKPm=}Kjik}sPxs%)T3WN)I1URg~wM7udf8H3d(Lc{~+hX^D^pAO>)YK z&uovMD4o;yP-o|9dmkRVQTbxo(dDNcdX()7c7K!c)6;V|1hf27%y!*|HbF-f(FX{2LqM@?vw~)FU-jmyu#EyBl zyXBsup9W_PPq}ocPn2WS%xLGXuM7IPXZ-jy&^mVTf}Y2g4>NrDoBi!To1Y5{&fIYP zzT^_sOVTO5O-RqZ#w*uPxgEHE+kpD#JLk>RowjL4qd3~B;QGagb!D|_GY!UQHtJQ} z=$_{HVA`BVEwq=#m^5#30plRkCzO!x9u8z=wEGbpUWt}Q&V;zt5s~-SB6i694>YB3Qrw= z!}yWQABRJa4osHjY`?hj&zCSRlo-wEz2)SvukT%Z@N7iQiz%TF7H9oW%?e$8Ov7u< z1Ty1nWPHGvSr+FK-)ze8h!|FFGk?##^5u;)&t#geZyEW_JKldzSapEG(9@z{&0g=g zvj4=DL1|?t8m|r7@`L$ES4%-fZRXyn`6uUv+^-usHmk_-x3T*c9(my^cDUthoe(jy z=tf3ivWw<`!dLIjrr(#W9r$PL=X)%iU7hOlW47)jW0GR;&iwuOfz36(e+(1!m@qEX zXqIE&tj%q1R#i-0x%{?K#1_Hk=l$1j%1zpEYwn}dwLetVmSoJ2h_fw7+uf_~Or51& zqS3u|0abNb$%jU7yLE2y7q4O*=6-JK^~F-@yi?uNbu+g75*!`fG5L@0CN|#B5cakU z9#p>i*b|FDyS7*7_p^@+YoFO*+;dgxn|z1x(|M1r^&e2z*A;CE3AMd%*`ZhYz;m6h z1V?YRUJ*C0g{bz{O0ACVY^L@ zElwHztKGJeL*K7I`mMX$5#zDnXD(+(M(N(#GmTAxj-9deRw%x{@Ly4AN_ zQ>Ros^ZRG@KXm=DEx)09@dJs;ip`oQ?{y10mt39E^=QuYioEYPb`Zy9PWWd1lv{h_ z5B0mWzRP)c^OBzX+`ctvJ^NTV9E_IU5Gqes*{Zg8eIl;B zHtB!eci6TCn<}KcPr6mE>U%tAyK`-K(Rkm*5u<-kT)U}LP4wZyO-Y-tT3+1yQ^Pgp zsi=BtV4(0+RAmy~ONFbq1D`pV1dqbFPf>^+>B<{PoFGKO}%nZZ=v09 zvoCJFDxCSdx2{i+ZPeo@y4#$^uCo%3EFWFE^t%ef;U2f$lQ)}*10H_+<%;9uetJAV zxW7r{oSU6T>=-tEeyZ;i<53I49s1bW_IGe~UzXO&zIRda#knyJx!e5KFNpo!X8nec zGo=@M)=$b_^I|16^_1=5M7=3hr0tS^E2O*M`X?llWuz5 z>w7lNsCDUGyenAT;o83Ed9=ZDr=+MTtRHKac3+b^6F z7{RG5J2zA`6(qp!mjtdsuw|{na14Oz_9#Cf!k6rf;B16#k@}OV123^V8@G?sf^sZ#OAr!!;GzAI^n)%|- z$$Sp25RmoZ7X#=1iSTJj5`6wM5k9%XyFT=*_oM00fjme*`1m9PzOI?b;fMg*D3S~` zci0>pM&TEK)UZWqQnMh=hLFm&-ypCr3^fnzDR zR$t9Z|7>7D{=0zQdtIwDA zm-HX8q@`4=|Bif0+5rv&v&Nopv=6M!+M>un$VshV2Js1fa;o*q^qw1rnOh-Hb z@SfB!Zd>8bDIh_bDFTE7MS`{>;Z`hHcTGa={<_sy2P04CJN2)RhODqG4zRD>5fvcu zzKIdDVQ1TJUVStKZUch{LZCIME(KCi-vr$EZasL?ycUGQ+VBArxzpYqcBgMt|ZDY<^81h1}pYO9#xa>&1LwiEWAbDod}~S6MA!#9|#*W(OD~4#MH5F5*KY z5WsgEt?7GxxDt5BP)r(scyYN;V!xnxn(j!`o#^Xynvx4Vtm}ZsW1!14NI6a~K(R^8 zpt)z#S34PZU64KJ9{2Sb_dKX0=YB1mfoOwPOcN9mX9~XtLU$LB1?i9?#jpuj%mOfE zp6dY6LQJyh?@$RDXN;v4(Q$kea$IY99L^ocEq!@h2$f;WiHksPQ5$)>1{}JKGm*zN z;oZf3oVXUW(tVu##GpqnBRRh|)B>A75#YPn>?=cfFBafviKm;7(ZnQ}YE9G77_G=R zj7^$oSaXUreA$Ledk^geT`+w;LL?AU5aavl5|qGfLg*_Kqev*h+?bdE(l8$;CWJIp zm5GTUhHru}F%5{}=*Pq~AqEYxDW(N6tV$+L3^90oHpR3dhI%t;IuOITDHCe}F?=d9 zv6c|S_uQG7F2vA^7(;!#(cd03F$!X6TP7wTVf6RNlt2?Wg^>2O0A)mQN64VyBQ$~r z#JWKVm^3Z8rwrBxGcsa`F?4OXgQ*k9;MamW5MzFfEzwfl=&ubiXXxkN>Ek8l)Cj@I^PU5CCMh`Kqhp?F**TG`3V2~~_hLn-n zBv4>L_R)`}V8{bsBS4oA52bug?-~K6u>cDSp$S4V1-Eb~UJhhGlUm4tX^l9nj1sp2 zPovNm7-sN=JYg8~MYufSzjyy!3t)9)ufi6MJs$fxHX`iPSohd}@f&^YtJp)aUt*l^ z`+rRPulwg%0B0JMCTYDwP=!@a*ZI5Fu7WY{BPMr80>>R|dhO=_K5Uf2I|hW#haHdp zDg-?_daZh(UT-~Y>%gxV(o#UD<<*3&oGJDd%=hkpWXRUTUxoFpacs~g$3qC2>H2q` z4X8B- z$Ei&4xMH0N9>=&HQ0e%T76G#rggC3<|5F1(f+0QkTA%v!nN<{hpPNAce+9~7XBh~K zv}htB$+Np8L-dmzU-?mALDl)HVpns$qNPxN=Z0-zK+{m56#xy(jqMq2;s738F4_vm zY_t*1kb=Q0+5povV6Ku%hSQ7AB>Epf{@(vl_yH<+v;)Y$bZGb4sO-PV{oVZkP1(v| z{^|K+J3!Y69-sf{u>D{aO~eSar>Stk_Je&1=L$QT;z+|j6%IY2FZ72rXiX!aH4O*J zPzXmuZyW(z4oQ%Lj-6-pf;nz1#1-2l_ATtQxGwgFs|&rTc7-c`UyY$R@ug`@AGQYG zFrfHCsu%QT57>3^hn&5j<$FOM{=n}K93F7*2Rt6|mo&Kk4ucS-JYnJf|JnTyct)x? literal 0 HcmV?d00001 diff --git a/images/add-menu-zh.png b/images/add-menu-zh.png new file mode 100644 index 0000000000000000000000000000000000000000..39e482062256cb6e559eec9fc225c0dc6491410b GIT binary patch literal 92146 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 _G}^_>GW9W@hfiq(%4MU!wrAC_fmI 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

  • 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 literal 0 HcmV?d00001 diff --git a/images/register-page-zh.png b/images/register-page-zh.png new file mode 100644 index 0000000000000000000000000000000000000000..d4d3fa19e909f3418692387d8fe357b1aba152ec GIT binary patch literal 194526 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%0A@@9Yz*;ZgZCN( z90I%r$+O_wxTdWWh&C`p~+Z{TzxTGCce)1Kt*WIIaR)zv>#4<{5qS4emb9UVdOwl^zc zw?-F{pm`YEm(yRou=*xz*3e;gCKJIgbn6T*571RTj;joc*=O;gP@jgKGnx*wAq;3vKHfGP8jd7@O()x-VZe2F82 z`*c6|1XxbKNny$*p2Lm(v^R6#m@BSdwNbt+Xo)S=GI9gzYw<9#is5G;7t<6_*d`gU zzQFuvxG#hlsJ2{~?61;Y!!RpB;` z*d-!2=!iY}AHLoW;<4Ei_I%sh97SeE>!+0UMJLKFd}x#`_Wn!M_E?Lz(1v)66|_qw zk|1touHbEclZNuy1NF8?y(7Z6f66v9OD0u27L=7lG0;R!Om`o&c&VX&xP#PihKUW~#pum8%vJYAIjhMH~9jh0_ zD2A7QI)6d3kp0GDCb2|ubYb$7`rwzZX+WjgR}pZ zJ;!%aX8$G#rLX7ret{y^w`=j1)R0+W7RZF9&pPLbF^Ul7fM3U&eIKK}n2rTf;Rbqe zf5HM1g?+T#*DY}<+IOQkNY{%ePZ}Z5!t47yI3Yo;MW2o=M5~YvHcKo&>St9@Yi}mz zey{xehJqjKxbKq%?@A=(e_bQ=tX)Wx#iQol@%|8XOV$fKBm*nYC%Q*`c$e-}WHOQJJK9oVa_DP-<@g2=?R zAwj{3jn5T&@~{2Ya;RvX14Qi}PADO)mV`7=sXgztl~%E}3)DlC9>p)xhNHP%43Q!- z_t@t_GNpuOo=n>QQo#y74r}V zQqB4t}F+>?L0Z)Rt$3qdG?RlHU6B26J}> ztJt|+Mw#!?;3yAickXZLywCNfu&3BP{zq-x|MQ{6*cBet cpcTZkh%onrn4e7GwecI*Z5xZe{O;iY0X(us$N&HU literal 0 HcmV?d00001 diff --git a/images/user-manage-zh.png b/images/user-manage-zh.png new file mode 100644 index 0000000000000000000000000000000000000000..23e21d7d250551c0ff72e1c5a289a462ac60e28a GIT binary patch literal 78390 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%0AfwuVNSooCcs+LhU6T}39x#Fi>)1R=q>bGlEe9A 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⋙lutO|vF>@#F7*6|n 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%0D>mc=D32rTX*H7-?}~tWYZCPbljA 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�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 SJm0<^-z<*$s^rVf`~MH7Oy!*b literal 0 HcmV?d00001 diff --git a/images/user-mgt.png b/images/user-mgt.png new file mode 100644 index 0000000000000000000000000000000000000000..7fb3fcd6924911e4539cceb151b9701fc50124e1 GIT binary patch literal 117563 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 IQ^3jp2OWIj!vFvP literal 0 HcmV?d00001 diff --git a/images/wansenai-logo.png b/images/wansenai-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..1d9126382e1bb4b4ea8db27066e9137250435a6f GIT binary patch literal 7551 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 + + + + + + + <%= VITE_GLOB_APP_TITLE %> + + + +

    + +
    +
    + +
    + +
    +
    <%= VITE_GLOB_APP_TITLE %>
    +
    +
    +
    + + + \ No newline at end of file diff --git a/internal/.DS_Store b/internal/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..ef9e890b814730c6fb786f156826dcf3f42079e6 GIT binary patch literal 6148 zcmeHK!Ab)$5S{2ks}-$ z4r9O=_-_nw?dG&b#lE0+x9fLCH7fZI^}Hw-!||-HR+9XAZ=aZ|E{bVcPvOgl$H&9# z`_+DN^IyfSmfJbrU@1DmuGTn-k~`^rc6%jq@0hQuJG1TZZ09%O{08(4b~j-ChaAIO z+B1=7V%|iq3GY_E&Latv17iSpHcNjXXx11o28@Ak2KapNP{yFx2*#rWCO!dx8M>pO z&2I^g@rpsQ5yS|@NhnZ4ojx&~grnc9Ur=lWC7hf-KAf)X^o8Q$>X_e0cXC0{tTA8= zv>7;-&z$f7>-77-9b{j|fH81T47jWq7b9#*@7A5o@m=eo6DSM&HG(k&Mz7=8;H&ro a8UcZ literal 0 HcmV?d00001 diff --git a/internal/stylelint-config/.eslintignore b/internal/stylelint-config/.eslintignore new file mode 100644 index 0000000..a6a19cd --- /dev/null +++ b/internal/stylelint-config/.eslintignore @@ -0,0 +1,4 @@ + +*.sh +node_modules +dist diff --git a/internal/stylelint-config/build.config.ts b/internal/stylelint-config/build.config.ts new file mode 100644 index 0000000..20c8b54 --- /dev/null +++ b/internal/stylelint-config/build.config.ts @@ -0,0 +1,10 @@ +import { defineBuildConfig } from 'unbuild'; + +export default defineBuildConfig({ + clean: true, + entries: ['src/index'], + declaration: true, + rollup: { + emitCJS: true, + }, +}); diff --git a/internal/stylelint-config/package.json b/internal/stylelint-config/package.json new file mode 100644 index 0000000..b928a1c --- /dev/null +++ b/internal/stylelint-config/package.json @@ -0,0 +1,39 @@ +{ + "name": "@vben/stylelint-config", + "version": "1.0.0", + "private": true, + "license": "MIT", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.cjs" + } + }, + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], + "scripts": { + "clean": "pnpm rimraf node_modules dist", + "stub": "pnpm unbuild --stub" + }, + "devDependencies": { + "postcss": "^8.4.29", + "postcss-html": "^1.5.0", + "postcss-less": "^6.0.0", + "postcss-scss": "^4.0.7", + "prettier": "^2.8.8", + "stylelint": "^15.10.3", + "stylelint-config-property-sort-order-smacss": "^9.1.0", + "stylelint-config-recommended": "^12.0.0", + "stylelint-config-recommended-scss": "^11.0.0", + "stylelint-config-recommended-vue": "^1.5.0", + "stylelint-config-standard": "^33.0.0", + "stylelint-config-standard-scss": "^9.0.0", + "stylelint-order": "^6.0.3", + "stylelint-prettier": "^3.0.0" + } +} diff --git a/internal/stylelint-config/src/index.ts b/internal/stylelint-config/src/index.ts new file mode 100644 index 0000000..3dc0475 --- /dev/null +++ b/internal/stylelint-config/src/index.ts @@ -0,0 +1,91 @@ +export default { + extends: ['stylelint-config-standard', 'stylelint-config-property-sort-order-smacss'], + plugins: ['stylelint-order', 'stylelint-prettier'], + // customSyntax: 'postcss-html', + overrides: [ + { + files: ['**/*.(css|html|vue)'], + customSyntax: 'postcss-html', + }, + { + files: ['*.less', '**/*.less'], + customSyntax: 'postcss-less', + extends: ['stylelint-config-standard', 'stylelint-config-recommended-vue'], + }, + { + files: ['*.scss', '**/*.scss'], + customSyntax: 'postcss-scss', + extends: ['stylelint-config-standard-scss', 'stylelint-config-recommended-vue/scss'], + rule: { + 'scss/percent-placeholder-pattern': null, + }, + }, + ], + rules: { + 'selector-not-notation': null, + 'import-notation': null, + 'function-no-unknown': null, + 'selector-class-pattern': null, + 'selector-pseudo-class-no-unknown': [ + true, + { + ignorePseudoClasses: ['global', 'deep'], + }, + ], + 'selector-pseudo-element-no-unknown': [ + true, + { + ignorePseudoElements: ['v-deep'], + }, + ], + 'at-rule-no-unknown': [ + true, + { + ignoreAtRules: [ + 'tailwind', + 'apply', + 'variants', + 'responsive', + 'screen', + 'function', + 'if', + 'each', + 'include', + 'mixin', + 'extend', + ], + }, + ], + 'no-empty-source': null, + 'string-quotes': null, + 'named-grid-areas-no-invalid': null, + 'no-descending-specificity': null, + 'font-family-no-missing-generic-family-keyword': null, + 'rule-empty-line-before': [ + 'always', + { + ignore: ['after-comment', 'first-nested'], + }, + ], + 'unit-no-unknown': [true, { ignoreUnits: ['rpx'] }], + 'order/order': [ + [ + 'dollar-variables', + 'custom-properties', + 'at-rules', + 'declarations', + { + type: 'at-rule', + name: 'supports', + }, + { + type: 'at-rule', + name: 'media', + }, + 'rules', + ], + { severity: 'error' }, + ], + }, + ignoreFiles: ['**/*.js', '**/*.jsx', '**/*.tsx', '**/*.ts'], +}; diff --git a/internal/stylelint-config/tsconfig.json b/internal/stylelint-config/tsconfig.json new file mode 100644 index 0000000..cd27063 --- /dev/null +++ b/internal/stylelint-config/tsconfig.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@vben/ts-config/node.json", + "include": ["src"] +} diff --git a/internal/ts-config/.eslintignore b/internal/ts-config/.eslintignore new file mode 100644 index 0000000..a6a19cd --- /dev/null +++ b/internal/ts-config/.eslintignore @@ -0,0 +1,4 @@ + +*.sh +node_modules +dist diff --git a/internal/ts-config/base.json b/internal/ts-config/base.json new file mode 100644 index 0000000..ab99195 --- /dev/null +++ b/internal/ts-config/base.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "Base", + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "moduleResolution": "node", + "strict": true, + "declaration": true, + "noImplicitOverride": true, + "noUnusedLocals": true, + "esModuleInterop": true, + "useUnknownInCatchVariables": false, + "composite": false, + "declarationMap": false, + "forceConsistentCasingInFileNames": true, + "inlineSources": false, + "isolatedModules": true, + "skipLibCheck": true, + "noUnusedParameters": false, + "preserveWatchOutput": true, + "experimentalDecorators": true, + "resolveJsonModule": true, + "removeComments": true + }, + "exclude": ["**/node_modules/**", "**/dist/**"] +} diff --git a/internal/ts-config/node-server.json b/internal/ts-config/node-server.json new file mode 100644 index 0000000..e27374a --- /dev/null +++ b/internal/ts-config/node-server.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "Node Server Config", + "extends": "./base.json", + "compilerOptions": { + "module": "commonjs", + "declaration": false, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "target": "es6", + "sourceMap": false, + "esModuleInterop": true, + "outDir": "./dist", + "baseUrl": "./" + }, + "exclude": ["node_modules"] +} diff --git a/internal/ts-config/node.json b/internal/ts-config/node.json new file mode 100644 index 0000000..cdd365f --- /dev/null +++ b/internal/ts-config/node.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "Node Config", + "extends": "./base.json", + "compilerOptions": { + "lib": ["ESNext"], + "noImplicitAny": true, + "sourceMap": true, + "noEmit": true, + "baseUrl": "./" + } +} diff --git a/internal/ts-config/package.json b/internal/ts-config/package.json new file mode 100644 index 0000000..4b23ae9 --- /dev/null +++ b/internal/ts-config/package.json @@ -0,0 +1,17 @@ +{ + "name": "@vben/ts-config", + "version": "1.0.0", + "private": true, + "license": "MIT", + "files": [ + "base.json", + "node.json", + "vue-app.json", + "node-server.json" + ], + "dependencies": { + "@types/node": "^18.17.12", + "unplugin-vue-define-options": "^1.3.17", + "vite": "^4.4.9" + } +} diff --git a/internal/ts-config/vue-app.json b/internal/ts-config/vue-app.json new file mode 100644 index 0000000..ac9636b --- /dev/null +++ b/internal/ts-config/vue-app.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "Vue Application", + "extends": "./base.json", + "compilerOptions": { + "jsx": "preserve", + "lib": ["ESNext", "DOM"], + "noImplicitAny": false + + } +} diff --git a/internal/vite-config/.eslintignore b/internal/vite-config/.eslintignore new file mode 100644 index 0000000..a6a19cd --- /dev/null +++ b/internal/vite-config/.eslintignore @@ -0,0 +1,4 @@ + +*.sh +node_modules +dist diff --git a/internal/vite-config/build.config.ts b/internal/vite-config/build.config.ts new file mode 100644 index 0000000..20c8b54 --- /dev/null +++ b/internal/vite-config/build.config.ts @@ -0,0 +1,10 @@ +import { defineBuildConfig } from 'unbuild'; + +export default defineBuildConfig({ + clean: true, + entries: ['src/index'], + declaration: true, + rollup: { + emitCJS: true, + }, +}); diff --git a/internal/vite-config/package.json b/internal/vite-config/package.json new file mode 100644 index 0000000..5e5b517 --- /dev/null +++ b/internal/vite-config/package.json @@ -0,0 +1,50 @@ +{ + "name": "@vben/vite-config", + "version": "1.0.0", + "private": true, + "license": "MIT", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.cjs" + } + }, + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], + "scripts": { + "clean": "pnpm rimraf .turbo node_modules dist", + "lint": "pnpm eslint .", + "stub": "pnpm unbuild --stub" + }, + "dependencies": { + "@ant-design/colors": "^7.0.0", + "vite": "^4.4.9" + }, + "devDependencies": { + "@types/fs-extra": "^11.0.1", + "@vitejs/plugin-vue": "^4.3.4", + "@vitejs/plugin-vue-jsx": "^3.0.2", + "ant-design-vue": "^4.0.6", + "dayjs": "^1.11.9", + "dotenv": "^16.3.1", + "fs-extra": "^11.1.1", + "less": "^4.2.0", + "picocolors": "^1.0.0", + "pkg-types": "^1.0.3", + "rollup-plugin-visualizer": "^5.9.2", + "sass": "^1.66.1", + "unocss": "^0.55.3", + "unplugin-vue-define-options": "^1.3.17", + "vite-plugin-compression": "^0.5.1", + "vite-plugin-dts": "^2.3.0", + "vite-plugin-html": "^3.2.0", + "vite-plugin-mock": "^3.0.0", + "vite-plugin-purge-icons": "^0.9.2", + "vite-plugin-svg-icons": "^2.0.1" + } +} diff --git a/internal/vite-config/src/config/application.ts b/internal/vite-config/src/config/application.ts new file mode 100644 index 0000000..4b32942 --- /dev/null +++ b/internal/vite-config/src/config/application.ts @@ -0,0 +1,115 @@ +import { resolve } from 'node:path'; + +import dayjs from 'dayjs'; +import { readPackageJSON } from 'pkg-types'; +import { defineConfig, loadEnv, mergeConfig, type UserConfig } from 'vite'; + +import { createPlugins } from '../plugins'; +import { generateModifyVars } from '../utils/modifyVars'; +import { commonConfig } from './common'; + +interface DefineOptions { + overrides?: UserConfig; + options?: { + // + }; +} + +function defineApplicationConfig(defineOptions: DefineOptions = {}) { + const { overrides = {} } = defineOptions; + + return defineConfig(async ({ command, mode }) => { + const root = process.cwd(); + const isBuild = command === 'build'; + const { VITE_USE_MOCK, VITE_BUILD_COMPRESS, VITE_ENABLE_ANALYZE } = loadEnv(mode, root); + + const defineData = await createDefineData(root); + const plugins = await createPlugins({ + isBuild, + root, + enableAnalyze: VITE_ENABLE_ANALYZE === 'true', + enableMock: VITE_USE_MOCK === 'true', + compress: VITE_BUILD_COMPRESS, + }); + + const pathResolve = (pathname: string) => resolve(root, '.', pathname); + + const applicationConfig: UserConfig = { + resolve: { + alias: [ + { + find: 'vue-i18n', + replacement: 'vue-i18n/dist/vue-i18n.cjs.js', + }, + // /@/xxxx => src/xxxx + { + find: /\/@\//, + replacement: pathResolve('src') + '/', + }, + // /#/xxxx => types/xxxx + { + find: /\/#\//, + replacement: pathResolve('types') + '/', + }, + // @/xxxx => src/xxxx + { + find: /@\//, + replacement: pathResolve('src') + '/', + }, + // #/xxxx => types/xxxx + { + find: /#\//, + replacement: pathResolve('types') + '/', + }, + ], + }, + define: defineData, + build: { + target: 'es2015', + cssTarget: 'chrome80', + rollupOptions: { + output: { + // 入口文件名 + entryFileNames: 'assets/[name].js', + manualChunks: { + vue: ['vue', 'pinia', 'vue-router'], + antd: ['ant-design-vue', '@ant-design/icons-vue'], + }, + }, + }, + }, + css: { + preprocessorOptions: { + less: { + modifyVars: generateModifyVars(), + javascriptEnabled: true, + }, + }, + }, + plugins, + }; + + const mergedConfig = mergeConfig(commonConfig(mode), applicationConfig); + + return mergeConfig(mergedConfig, overrides); + }); +} + +async function createDefineData(root: string) { + try { + const pkgJson = await readPackageJSON(root); + const { dependencies, devDependencies, name, version } = pkgJson; + + const __APP_INFO__ = { + pkg: { dependencies, devDependencies, name, version }, + lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss'), + }; + return { + __APP_INFO__: JSON.stringify(__APP_INFO__), + }; + } catch (error) { + return {}; + } +} + +export { defineApplicationConfig }; diff --git a/internal/vite-config/src/config/common.ts b/internal/vite-config/src/config/common.ts new file mode 100644 index 0000000..12fe053 --- /dev/null +++ b/internal/vite-config/src/config/common.ts @@ -0,0 +1,46 @@ +import { + presetAttributify, + presetIcons, + presetTypography, + presetUno, + presetWebFonts, + transformerDirectives, + transformerVariantGroup, +} from 'unocss'; +import UnoCSS from 'unocss/vite'; +import { type UserConfig } from 'vite'; + +const commonConfig: (mode: string) => UserConfig = (mode) => ({ + server: { + host: true, + }, + esbuild: { + drop: mode === 'production' ? ['console', 'debugger'] : [], + }, + build: { + reportCompressedSize: false, + chunkSizeWarningLimit: 1500, + rollupOptions: { + // TODO: Prevent memory overflow + maxParallelFileOps: 3, + }, + }, + plugins: [ + UnoCSS({ + presets: [ + presetUno(), + presetAttributify(), + presetIcons(), + presetTypography(), + presetWebFonts({ + fonts: { + // ... + }, + }), + ], + transformers: [transformerDirectives(), transformerVariantGroup()], + }), + ], +}); + +export { commonConfig }; diff --git a/internal/vite-config/src/config/package.ts b/internal/vite-config/src/config/package.ts new file mode 100644 index 0000000..ab83852 --- /dev/null +++ b/internal/vite-config/src/config/package.ts @@ -0,0 +1,42 @@ +import { readPackageJSON } from 'pkg-types'; +import { defineConfig, mergeConfig, type UserConfig } from 'vite'; +import dts from 'vite-plugin-dts'; + +import { commonConfig } from './common'; + +interface DefineOptions { + overrides?: UserConfig; + options?: { + // + }; +} + +function definePackageConfig(defineOptions: DefineOptions = {}) { + const { overrides = {} } = defineOptions; + const root = process.cwd(); + return defineConfig(async ({ mode }) => { + const { dependencies = {}, peerDependencies = {} } = await readPackageJSON(root); + const packageConfig: UserConfig = { + build: { + lib: { + entry: 'src/index.ts', + formats: ['es'], + fileName: () => 'index.mjs', + }, + rollupOptions: { + external: [...Object.keys(dependencies), ...Object.keys(peerDependencies)], + }, + }, + plugins: [ + dts({ + logLevel: 'error', + }), + ], + }; + const mergedConfig = mergeConfig(commonConfig(mode), packageConfig); + + return mergeConfig(mergedConfig, overrides); + }); +} + +export { definePackageConfig }; diff --git a/internal/vite-config/src/index.ts b/internal/vite-config/src/index.ts new file mode 100644 index 0000000..9ef1e80 --- /dev/null +++ b/internal/vite-config/src/index.ts @@ -0,0 +1,2 @@ +export * from './config/application'; +export * from './config/package'; diff --git a/internal/vite-config/src/plugins/appConfig.ts b/internal/vite-config/src/plugins/appConfig.ts new file mode 100644 index 0000000..541c859 --- /dev/null +++ b/internal/vite-config/src/plugins/appConfig.ts @@ -0,0 +1,96 @@ +import colors from 'picocolors'; +import { readPackageJSON } from 'pkg-types'; +import { type PluginOption } from 'vite'; + +import { getEnvConfig } from '../utils/env'; +import { createContentHash } from '../utils/hash'; + +const GLOBAL_CONFIG_FILE_NAME = '_app.config.js'; +const PLUGIN_NAME = 'app-config'; + +async function createAppConfigPlugin({ + root, + isBuild, +}: { + root: string; + isBuild: boolean; +}): Promise { + let publicPath: string; + let source: string; + if (!isBuild) { + return { + name: PLUGIN_NAME, + }; + } + const { version = '' } = await readPackageJSON(root); + + return { + name: PLUGIN_NAME, + async configResolved(_config) { + let appTitle = _config?.env?.VITE_GLOB_APP_TITLE ?? ''; + appTitle = appTitle.replace(/\s/g, '_').replace(/-/g, '_'); + publicPath = _config.base; + source = await getConfigSource(appTitle); + }, + async transformIndexHtml(html) { + publicPath = publicPath.endsWith('/') ? publicPath : `${publicPath}/`; + + const appConfigSrc = `${ + publicPath || '/' + }${GLOBAL_CONFIG_FILE_NAME}?v=${version}-${createContentHash(source)}}`; + + return { + html, + tags: [ + { + tag: 'script', + attrs: { + src: appConfigSrc, + }, + }, + ], + }; + }, + async generateBundle() { + try { + this.emitFile({ + type: 'asset', + fileName: GLOBAL_CONFIG_FILE_NAME, + source, + }); + + console.log(colors.cyan(`✨configuration file is build successfully!`)); + } catch (error) { + console.log( + colors.red('configuration file configuration file failed to package:\n' + error), + ); + } + }, + }; +} + +/** + * Get the configuration file variable name + * @param env + */ +const getVariableName = (title: string) => { + return `__PRODUCTION__${title || '__APP'}__CONF__`.toUpperCase().replace(/\s/g, ''); +}; + +async function getConfigSource(appTitle: string) { + const config = await getEnvConfig(); + const variableName = getVariableName(appTitle); + const windowVariable = `window.${variableName}`; + // Ensure that the variable will not be modified + let source = `${windowVariable}=${JSON.stringify(config)};`; + source += ` + Object.freeze(${windowVariable}); + Object.defineProperty(window, "${variableName}", { + configurable: false, + writable: false, + }); + `.replace(/\s/g, ''); + return source; +} + +export { createAppConfigPlugin }; \ No newline at end of file diff --git a/internal/vite-config/src/plugins/compress.ts b/internal/vite-config/src/plugins/compress.ts new file mode 100644 index 0000000..8fc1397 --- /dev/null +++ b/internal/vite-config/src/plugins/compress.ts @@ -0,0 +1,38 @@ +/** + * Used to package and output gzip. Note that this does not work properly in Vite, the specific reason is still being investigated + * https://github.com/anncwb/vite-plugin-compression + */ +import type { PluginOption } from 'vite'; +import compressPlugin from 'vite-plugin-compression'; + +export function configCompressPlugin({ + compress, + deleteOriginFile = false, +}: { + compress: string; + deleteOriginFile?: boolean; +}): PluginOption[] { + const compressList = compress.split(','); + + const plugins: PluginOption[] = []; + + if (compressList.includes('gzip')) { + plugins.push( + compressPlugin({ + ext: '.gz', + deleteOriginFile, + }), + ); + } + + if (compressList.includes('brotli')) { + plugins.push( + compressPlugin({ + ext: '.br', + algorithm: 'brotliCompress', + deleteOriginFile, + }), + ); + } + return plugins; +} diff --git a/internal/vite-config/src/plugins/html.ts b/internal/vite-config/src/plugins/html.ts new file mode 100644 index 0000000..a01b43a --- /dev/null +++ b/internal/vite-config/src/plugins/html.ts @@ -0,0 +1,13 @@ +/** + * Plugin to minimize and use ejs template syntax in index.html. + * https://github.com/anncwb/vite-plugin-html + */ +import type { PluginOption } from 'vite'; +import { createHtmlPlugin } from 'vite-plugin-html'; + +export function configHtmlPlugin({ isBuild }: { isBuild: boolean }) { + const htmlPlugin: PluginOption[] = createHtmlPlugin({ + minify: isBuild, + }); + return htmlPlugin; +} diff --git a/internal/vite-config/src/plugins/index.ts b/internal/vite-config/src/plugins/index.ts new file mode 100644 index 0000000..7f32df6 --- /dev/null +++ b/internal/vite-config/src/plugins/index.ts @@ -0,0 +1,61 @@ +import vue from '@vitejs/plugin-vue'; +import vueJsx from '@vitejs/plugin-vue-jsx'; +// @ts-ignore: type unless +import DefineOptions from 'unplugin-vue-define-options/vite'; +import { type PluginOption } from 'vite'; +import purgeIcons from 'vite-plugin-purge-icons'; + +import { createAppConfigPlugin } from './appConfig'; +import { configCompressPlugin } from './compress'; +import { configHtmlPlugin } from './html'; +import { configMockPlugin } from './mock'; +import { configSvgIconsPlugin } from './svgSprite'; +import { configVisualizerConfig } from './visualizer'; + +interface Options { + isBuild: boolean; + root: string; + compress: string; + enableMock?: boolean; + enableAnalyze?: boolean; +} + +async function createPlugins({ isBuild, root, enableMock, compress, enableAnalyze }: Options) { + const vitePlugins: (PluginOption | PluginOption[])[] = [vue(), vueJsx(), DefineOptions()]; + + const appConfigPlugin = await createAppConfigPlugin({ root, isBuild }); + vitePlugins.push(appConfigPlugin); + + // vite-plugin-html + vitePlugins.push(configHtmlPlugin({ isBuild })); + + // vite-plugin-svg-icons + vitePlugins.push(configSvgIconsPlugin({ isBuild })); + + // vite-plugin-purge-icons + vitePlugins.push(purgeIcons()); + + // The following plugins only work in the production environment + if (isBuild) { + // rollup-plugin-gzip + vitePlugins.push( + configCompressPlugin({ + compress, + }), + ); + } + + // rollup-plugin-visualizer + if (enableAnalyze) { + vitePlugins.push(configVisualizerConfig()); + } + + // vite-plugin-mock + if (enableMock) { + vitePlugins.push(configMockPlugin({ isBuild })); + } + + return vitePlugins; +} + +export { createPlugins }; diff --git a/internal/vite-config/src/plugins/mock.ts b/internal/vite-config/src/plugins/mock.ts new file mode 100644 index 0000000..b47899c --- /dev/null +++ b/internal/vite-config/src/plugins/mock.ts @@ -0,0 +1,19 @@ +/** + * Mock plugin for development and production. + * https://github.com/anncwb/vite-plugin-mock + */ +import { viteMockServe } from 'vite-plugin-mock'; + +export function configMockPlugin({ isBuild }: { isBuild: boolean }) { + return viteMockServe({ + ignore: /^_/, + mockPath: 'mock', + localEnabled: !isBuild, + prodEnabled: isBuild, + injectCode: ` + import { setupProdMockServer } from '../mock/_createProductionServer'; + + setupProdMockServer(); + `, + }); +} diff --git a/internal/vite-config/src/plugins/svgSprite.ts b/internal/vite-config/src/plugins/svgSprite.ts new file mode 100644 index 0000000..659e5af --- /dev/null +++ b/internal/vite-config/src/plugins/svgSprite.ts @@ -0,0 +1,17 @@ +/** + * Vite Plugin for fast creating SVG sprites. + * https://github.com/anncwb/vite-plugin-svg-icons + */ + +import { resolve } from 'node:path'; + +import type { PluginOption } from 'vite'; +import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'; + +export function configSvgIconsPlugin({ isBuild }: { isBuild: boolean }) { + const svgIconsPlugin = createSvgIconsPlugin({ + iconDirs: [resolve(process.cwd(), 'src/assets/icons')], + svgoOptions: isBuild, + }); + return svgIconsPlugin as PluginOption; +} diff --git a/internal/vite-config/src/plugins/visualizer.ts b/internal/vite-config/src/plugins/visualizer.ts new file mode 100644 index 0000000..0b6ba62 --- /dev/null +++ b/internal/vite-config/src/plugins/visualizer.ts @@ -0,0 +1,14 @@ +/** + * Package file volume analysis + */ +import visualizer from 'rollup-plugin-visualizer'; +import { type PluginOption } from 'vite'; + +export function configVisualizerConfig() { + return visualizer({ + filename: './node_modules/.cache/visualizer/stats.html', + open: true, + gzipSize: true, + brotliSize: true, + }) as PluginOption; +} diff --git a/internal/vite-config/src/utils/env.ts b/internal/vite-config/src/utils/env.ts new file mode 100644 index 0000000..648d873 --- /dev/null +++ b/internal/vite-config/src/utils/env.ts @@ -0,0 +1,44 @@ +import { join } from 'node:path'; + +import dotenv from 'dotenv'; +import { readFile } from 'fs-extra'; + +/** + * 获取当前环境下生效的配置文件名 + */ +function getConfFiles() { + const script = process.env.npm_lifecycle_script as string; + const reg = new RegExp('--mode ([a-z_\\d]+)'); + const result = reg.exec(script); + if (result) { + const mode = result[1]; + return ['.env', `.env.${mode}`]; + } + return ['.env', '.env.production']; +} + +/** + * Get the environment variables starting with the specified prefix + * @param match prefix + * @param confFiles ext + */ +export async function getEnvConfig(match = 'VITE_GLOB_', confFiles = getConfFiles()) { + let envConfig = {}; + + for (const confFile of confFiles) { + try { + const envPath = await readFile(join(process.cwd(), confFile), { encoding: 'utf8' }); + const env = dotenv.parse(envPath); + envConfig = { ...envConfig, ...env }; + } catch (e) { + console.error(`Error in parsing ${confFile}`, e); + } + } + const reg = new RegExp(`^(${match})`); + Object.keys(envConfig).forEach((key) => { + if (!reg.test(key)) { + Reflect.deleteProperty(envConfig, key); + } + }); + return envConfig; +} diff --git a/internal/vite-config/src/utils/hash.ts b/internal/vite-config/src/utils/hash.ts new file mode 100644 index 0000000..83dc0fd --- /dev/null +++ b/internal/vite-config/src/utils/hash.ts @@ -0,0 +1,8 @@ +import { createHash } from 'node:crypto'; + +function createContentHash(content: string, hashLSize = 12) { + const hash = createHash('sha256').update(content); + return hash.digest('hex').slice(0, hashLSize); +} + +export { createContentHash }; diff --git a/internal/vite-config/src/utils/modifyVars.ts b/internal/vite-config/src/utils/modifyVars.ts new file mode 100644 index 0000000..9fa661f --- /dev/null +++ b/internal/vite-config/src/utils/modifyVars.ts @@ -0,0 +1,47 @@ +import { resolve } from 'node:path'; + +import { generate } from '@ant-design/colors'; +// @ts-ignore: typo +/* import { getThemeVariables } from 'ant-design-vue/dist/theme'; */ +import { theme } from 'ant-design-vue/lib'; +import convertLegacyToken from 'ant-design-vue/lib/theme/convertLegacyToken'; + +const { defaultAlgorithm, defaultSeed } = theme; +const primaryColor = '#0960bd'; + +function generateAntColors(color: string, theme: 'default' | 'dark' = 'default') { + return generate(color, { + theme, + }); +} + +/** + * less global variable + */ +export function generateModifyVars() { + const palettes = generateAntColors(primaryColor); + const primary = palettes[5]; + const primaryColorObj: Record = {}; + + for (let index = 0; index < 10; index++) { + primaryColorObj[`primary-${index + 1}`] = palettes[index]; + } + // const modifyVars = getThemeVariables(); + const mapToken = defaultAlgorithm(defaultSeed); + const v3Token = convertLegacyToken(mapToken); + return { + ...v3Token, + // reference: Avoid repeated references + hack: `true; @import (reference) "${resolve('src/design/config.less')}";`, + 'primary-color': primary, + ...primaryColorObj, + 'info-color': primary, + 'processing-color': primary, + 'success-color': '#55D187', // Success color + 'error-color': '#ED6F6F', // False color + 'warning-color': '#EFBD47', // Warning color + 'font-size-base': '14px', // Main font size + 'border-radius-base': '2px', // Component/float fillet + 'link-color': primary, // Link color + }; +} \ No newline at end of file diff --git a/internal/vite-config/tsconfig.json b/internal/vite-config/tsconfig.json new file mode 100644 index 0000000..cd27063 --- /dev/null +++ b/internal/vite-config/tsconfig.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@vben/ts-config/node.json", + "include": ["src"] +} diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..395501f --- /dev/null +++ b/nginx.conf @@ -0,0 +1,33 @@ +#user nobody; +worker_processes 1; + +#error_log logs/error.log; +#error_log logs/error.log notice; +#error_log logs/error.log info; +#pid logs/nginx.pid; +events { + worker_connections 1024; +} + +http { + include mime.types; + default_type application/octet-stream; + server { + listen 80; + location / { + root /usr/share/nginx/html/dist; + try_files $uri $uri/ /index.html; + index index.html; + # Enable CORS + add_header 'Access-Control-Allow-Origin' '*'; + add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; + add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Max-Age' 1728000; + add_header 'Content-Type' 'text/plain charset=UTF-8'; + add_header 'Content-Length' 0; + return 204; + } + } + } +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..6f5a287 --- /dev/null +++ b/package.json @@ -0,0 +1,152 @@ +{ + "name": "eairp-web", + "version": "1.0.1", + "homepage": "https://github.com/wansenai/wansen-erp-ui", + "bugs": { + "url": "https://github.com/wansenai/wansen-erp-ui/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/wansenai/wansen-erp-ui.git" + }, + "scripts": { + "bootstrap": "pnpm install", + "build": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 pnpm vite build", + "build:analyze": "cross-env NODE_OPTIONS=--max-old-space-size=8192 pnpm vite build --mode analyze", + "build:no-cache": "pnpm store prune && npm run build", + "build:test": "cross-env NODE_OPTIONS=--max-old-space-size=8192 pnpm vite build --mode test", + "build:docker": "vite build --mode docker", + "commit": "czg", + "dev": "pnpm vite", + "preinstall": "npx only-allow pnpm", + "postinstall": "turbo run stub", + "lint": "turbo run lint", + "lint:eslint": "eslint --cache --max-warnings 0 \"{src,mock}/**/*.{vue,ts,tsx}\" --fix", + "lint:prettier": "prettier --write .", + "lint:stylelint": "stylelint \"**/*.{vue,css,less.scss}\" --fix --cache --cache-location node_modules/.cache/stylelint/", + "preview": "npm run build && vite preview", + "reinstall": "rimraf pnpm-lock.yaml && rimraf package.lock.json && rimraf node_modules && npm run bootstrap", + "serve": "npm run dev", + "test:gzip": "npx http-server dist --cors --gzip -c-1", + "type:check": "vue-tsc --noEmit --skipLibCheck" + }, + "lint-staged": { + "*.{js,jsx,ts,tsx}": [ + "eslint --fix", + "prettier --write" + ], + "{!(package)*.json,*.code-snippets,.!(browserslist)*rc}": [ + "prettier --write--parser json" + ], + "package.json": [ + "prettier --write" + ], + "*.vue": [ + "eslint --fix", + "prettier --write", + "stylelint --fix" + ], + "*.{scss,less,styl,html}": [ + "stylelint --fix", + "prettier --write" + ], + "*.md": [ + "prettier --write" + ] + }, + "config": { + "commitizen": { + "path": "node_modules/cz-git" + } + }, + "dependencies": { + "@ant-design/icons-vue": "^6.1.0", + "@axolo/tree-array": "^0.1.0", + "@iconify/iconify": "^3.1.1", + "@logicflow/core": "^1.2.9", + "@logicflow/extension": "^1.2.9", + "@vben/hooks": "workspace:*", + "@vue/shared": "^3.3.4", + "@vueuse/core": "^10.2.1", + "@vueuse/shared": "^10.2.1", + "@zxcvbn-ts/core": "^3.0.2", + "ant-design-vue": "^4.0.6", + "axios": "^1.4.0", + "codemirror": "^5.65.12", + "cropperjs": "^1.5.13", + "crypto-js": "^4.1.1", + "dayjs": "^1.11.9", + "echarts": "^5.4.2", + "exceljs": "^4.3.0", + "intro.js": "^7.0.1", + "lodash-es": "^4.17.21", + "mockjs": "^1.1.0", + "nprogress": "^0.2.0", + "path-to-regexp": "^6.2.1", + "pinia": "2.1.4", + "print-js": "^1.6.0", + "qrcode": "^1.5.3", + "qs": "^6.11.2", + "resize-observer-polyfill": "^1.5.1", + "showdown": "^2.1.0", + "sortablejs": "^1.15.0", + "tinymce": "^5.10.7", + "vditor": "^3.9.4", + "vue": "^3.3.4", + "vue-i18n": "^9.2.2", + "vue-json-pretty": "^2.2.4", + "vue-router": "^4.2.3", + "vue-types": "^5.1.0", + "vuedraggable": "^4.1.0", + "vxe-table": "^4.5.14", + "vxe-table-plugin-export-xlsx": "3.1.0", + "xe-utils": "^3.5.11", + "xlsx": "^0.18.5", + "bpmn-js": "^16.1.0", + "@bpmn-io/properties-panel": "^3.13.0", + "bpmn-js-properties-panel": "^5.6.1", + "camunda-bpmn-moddle": "^7.0.1", + "diagram-js-grid-bg": "^1.0.3", + "diagram-js-minimap": "4.1.0" + }, + "devDependencies": { + "@commitlint/cli": "^17.6.6", + "@commitlint/config-conventional": "^17.6.6", + "@iconify/json": "^2.2.87", + "@purge-icons/generated": "^0.9.0", + "@types/codemirror": "^5.60.8", + "@types/crypto-js": "^4.1.1", + "@types/intro.js": "^5.1.1", + "@types/lodash-es": "^4.17.7", + "@types/mockjs": "^1.0.7", + "@types/nprogress": "^0.2.0", + "@types/qrcode": "^1.5.1", + "@types/qs": "^6.9.7", + "@types/showdown": "^2.0.1", + "@types/sortablejs": "^1.15.1", + "@vben/stylelint-config": "workspace:*", + "@vben/ts-config": "workspace:*", + "@vben/types": "workspace:*", + "@vben/vite-config": "workspace:*", + "@vue/compiler-sfc": "^3.3.4", + "@vue/test-utils": "^2.4.0", + "cross-env": "^7.0.3", + "cz-git": "^1.6.1", + "czg": "^1.6.1", + "lint-staged": "13.2.3", + "prettier": "^2.8.8", + "prettier-plugin-packagejson": "^2.4.4", + "rimraf": "^5.0.1", + "turbo": "^1.10.7", + "typescript": "^5.1.6", + "unbuild": "^1.2.1", + "vite": "^4.4.0", + "vite-plugin-mock": "^2.9.6", + "vue-tsc": "^1.8.4" + }, + "packageManager": "pnpm@8.1.0", + "engines": { + "node": ">=16.15.1", + "pnpm": ">=8.1.0" + } +} diff --git a/packages/.DS_Store b/packages/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..09d66e031cc39d9e6ef0c953b227d7ada95acb01 GIT binary patch literal 6148 zcmeHKK~BR!475uTMO=D99QO-7b6KkJf_|VXMO12|jRYLH?N8t{ocI*uwG}l95jTXu zj_lcZ?O2&aaZE(KeBLgI=0r4u3Qo>pz7W|L9mvEyvdQHdkB5iF>MqsIAl4nflL2{l zr?jJlV^6*3cPVeg(QcipYI8^%cqQ*+|N4H@kJx?_(d>@jkT;~G!V|qvL-+mqXV=}` z(fVzEokr@n5#9Q0sqf+pI0MeWe`5eWTV!^j=++r<2AqMG0r@@zs9-eAisjP*Q$_&b z6z(Ee%Pb)|!7v(TMeIOWQ-PYwHe#@*!yhaz8fHaJC$`~(tuot$!lgQ{A4)iJRCMbM zI0Ib { + hook(); + nextTick(() => { + mounted = true; + }); + }); + + onActivated(() => { + if (mounted) { + hook(); + } + }); +} + +export { onMountedOrActivated }; diff --git a/packages/hooks/src/useAttrs.ts b/packages/hooks/src/useAttrs.ts new file mode 100644 index 0000000..df2118d --- /dev/null +++ b/packages/hooks/src/useAttrs.ts @@ -0,0 +1,43 @@ +import { type Recordable } from '@vben/types'; +import { getCurrentInstance, reactive, shallowRef, watchEffect } from 'vue'; + +interface UseAttrsOptions { + excludeListeners?: boolean; + excludeKeys?: string[]; + excludeDefaultKeys?: boolean; +} + +const DEFAULT_EXCLUDE_KEYS = ['class', 'style']; +const LISTENER_PREFIX = /^on[A-Z]/; + +function entries(obj: Recordable): [string, T][] { + return Object.keys(obj).map((key: string) => [key, obj[key]]); +} + +function useAttrs(options: UseAttrsOptions = {}): Recordable { + const instance = getCurrentInstance(); + if (!instance) return {}; + + const { excludeListeners = false, excludeKeys = [], excludeDefaultKeys = true } = options; + const attrs = shallowRef({}); + const allExcludeKeys = excludeKeys.concat(excludeDefaultKeys ? DEFAULT_EXCLUDE_KEYS : []); + + // Since attrs are not reactive, make it reactive instead of doing in `onUpdated` hook for better performance + instance.attrs = reactive(instance.attrs); + + watchEffect(() => { + const res = entries(instance.attrs).reduce((acm, [key, val]) => { + if (!allExcludeKeys.includes(key) && !(excludeListeners && LISTENER_PREFIX.test(key))) { + acm[key] = val; + } + + return acm; + }, {} as Recordable); + + attrs.value = res; + }); + + return attrs; +} + +export { useAttrs, type UseAttrsOptions }; diff --git a/packages/hooks/src/useRefs.ts b/packages/hooks/src/useRefs.ts new file mode 100644 index 0000000..97f1b4b --- /dev/null +++ b/packages/hooks/src/useRefs.ts @@ -0,0 +1,24 @@ +import type { Ref } from 'vue'; +import { onBeforeUpdate, shallowRef } from 'vue'; + +function useRefs(): { + refs: Ref; + setRefs: (index: number) => (el: HTMLElement) => void; +} { + const refs = shallowRef([]) as Ref; + + onBeforeUpdate(() => { + refs.value = []; + }); + + const setRefs = (index: number) => (el: HTMLElement) => { + refs.value[index] = el; + }; + + return { + refs, + setRefs, + }; +} + +export { useRefs }; diff --git a/packages/hooks/src/useScrollTo.ts b/packages/hooks/src/useScrollTo.ts new file mode 100644 index 0000000..f6a95f4 --- /dev/null +++ b/packages/hooks/src/useScrollTo.ts @@ -0,0 +1,60 @@ +import { shallowRef, unref } from 'vue'; + +interface UseScrollToOptions { + el: any; + to: number; + duration?: number; + callback?: () => any; +} + +function easeInOutQuad(t: number, b: number, c: number, d: number) { + t /= d / 2; + if (t < 1) { + return (c / 2) * t * t + b; + } + t--; + return (-c / 2) * (t * (t - 2) - 1) + b; +} + +function move(el: HTMLElement, amount: number) { + el.scrollTop = amount; +} + +const position = (el: HTMLElement) => { + return el.scrollTop; +}; +function useScrollTo({ el, to, duration = 500, callback }: UseScrollToOptions) { + const isActiveRef = shallowRef(false); + const start = position(el); + const change = to - start; + const increment = 20; + let currentTime = 0; + + const animateScroll = function () { + if (!unref(isActiveRef)) { + return; + } + currentTime += increment; + const val = easeInOutQuad(currentTime, start, change, duration); + move(el, val); + if (currentTime < duration && unref(isActiveRef)) { + requestAnimationFrame(animateScroll); + } else { + if (callback && typeof callback === 'function') { + callback(); + } + } + }; + const run = () => { + isActiveRef.value = true; + animateScroll(); + }; + + const stop = () => { + isActiveRef.value = false; + }; + + return { start: run, stop }; +} + +export { useScrollTo, type UseScrollToOptions }; diff --git a/packages/hooks/src/useWindowSizeFn.ts b/packages/hooks/src/useWindowSizeFn.ts new file mode 100644 index 0000000..d8e7710 --- /dev/null +++ b/packages/hooks/src/useWindowSizeFn.ts @@ -0,0 +1,40 @@ +import { type AnyFunction } from '@vben/types'; +import { tryOnMounted, tryOnUnmounted, useDebounceFn } from '@vueuse/core'; + +interface UseWindowSizeOptions { + wait?: number; + once?: boolean; + immediate?: boolean; + listenerOptions?: AddEventListenerOptions | boolean; +} + +function useWindowSizeFn(fn: AnyFunction, options: UseWindowSizeOptions = {}) { + const { wait = 150, immediate } = options; + let handler = () => { + fn(); + }; + const handleSize = useDebounceFn(handler, wait); + handler = handleSize; + + const start = () => { + if (immediate) { + handler(); + } + window.addEventListener('resize', handler); + }; + + const stop = () => { + window.removeEventListener('resize', handler); + }; + + tryOnMounted(() => { + start(); + }); + + tryOnUnmounted(() => { + stop(); + }); + return { start, stop }; +} + +export { useWindowSizeFn, type UseWindowSizeOptions }; diff --git a/packages/hooks/tsconfig.json b/packages/hooks/tsconfig.json new file mode 100644 index 0000000..8508d50 --- /dev/null +++ b/packages/hooks/tsconfig.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@vben/ts-config/vue-app.json", + "include": ["src"] +} diff --git a/packages/types/.eslintrc.js b/packages/types/.eslintrc.js new file mode 100644 index 0000000..cd27a19 --- /dev/null +++ b/packages/types/.eslintrc.js @@ -0,0 +1,4 @@ +module.exports = { + root: true, + extends: ['@vben/eslint-config/strict'], +}; diff --git a/packages/types/build.config.ts b/packages/types/build.config.ts new file mode 100644 index 0000000..20c8b54 --- /dev/null +++ b/packages/types/build.config.ts @@ -0,0 +1,10 @@ +import { defineBuildConfig } from 'unbuild'; + +export default defineBuildConfig({ + clean: true, + entries: ['src/index'], + declaration: true, + rollup: { + emitCJS: true, + }, +}); diff --git a/packages/types/package.json b/packages/types/package.json new file mode 100644 index 0000000..14f89b2 --- /dev/null +++ b/packages/types/package.json @@ -0,0 +1,22 @@ +{ + "name": "@vben/types", + "version": "1.0.0", + "license": "MIT", + "sideEffects": false, + "exports": { + ".": { + "default": "./src/index.ts" + } + }, + "main": "./src/index.ts", + "module": "./src/index.ts", + "files": [ + "dist" + ], + "scripts": { + "//build": "pnpm unbuild", + "//stub": "pnpm unbuild --stub", + "clean": "pnpm rimraf node_modules dist", + "lint": "pnpm eslint ." + } +} diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts new file mode 100644 index 0000000..04bca77 --- /dev/null +++ b/packages/types/src/index.ts @@ -0,0 +1 @@ +export * from './utils'; diff --git a/packages/types/src/utils.ts b/packages/types/src/utils.ts new file mode 100644 index 0000000..80435fc --- /dev/null +++ b/packages/types/src/utils.ts @@ -0,0 +1,58 @@ +/** + * 任意类型的异步函数 + */ +type AnyPromiseFunction = (...arg: any[]) => PromiseLike; + +/** + * 任意类型的普通函数 + */ +type AnyNormalFunction = (...arg: any[]) => any; + +/** + * 任意类型的函数 + */ +type AnyFunction = AnyNormalFunction | AnyPromiseFunction; + +/** + * T | null 包装 + */ +type Nullable = T | null; + +/** + * T | Not null 包装 + */ +type NonNullable = T extends null | undefined ? never : T; + +/** + * 字符串类型对象 + */ +type Recordable = Record; + +/** + * 字符串类型对象(只读) + */ +interface ReadonlyRecordable { + readonly [key: string]: T; +} + +/** + * setTimeout 返回值类型 + */ +type TimeoutHandle = ReturnType; + +/** + * setInterval 返回值类型 + */ +type IntervalHandle = ReturnType; + +export { + type AnyFunction, + type AnyNormalFunction, + type AnyPromiseFunction, + type IntervalHandle, + type NonNullable, + type Nullable, + type ReadonlyRecordable, + type Recordable, + type TimeoutHandle, +}; diff --git a/packages/types/tsconfig.json b/packages/types/tsconfig.json new file mode 100644 index 0000000..8508d50 --- /dev/null +++ b/packages/types/tsconfig.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@vben/ts-config/vue-app.json", + "include": ["src"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..8ddfbe2 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,15390 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@ant-design/icons-vue': + specifier: ^6.1.0 + version: 6.1.0(vue@3.3.4) + '@axolo/tree-array': + specifier: ^0.1.0 + version: https://registry.npmmirror.com/@axolo/tree-array/-/tree-array-0.1.0.tgz + '@bpmn-io/properties-panel': + specifier: ^3.13.0 + version: 3.13.0(@lezer/common@1.1.2) + '@iconify/iconify': + specifier: ^3.1.1 + version: 3.1.1 + '@logicflow/core': + specifier: ^1.2.9 + version: https://registry.npmmirror.com/@logicflow/core/-/core-1.2.12.tgz + '@logicflow/extension': + specifier: ^1.2.9 + version: https://registry.npmmirror.com/@logicflow/extension/-/extension-1.2.13.tgz(ts-node@10.9.1) + '@vben/hooks': + specifier: workspace:* + version: link:packages/hooks + '@vue/shared': + specifier: ^3.3.4 + version: 3.3.4 + '@vueuse/core': + specifier: ^10.2.1 + version: https://registry.npmmirror.com/@vueuse/core/-/core-10.4.1.tgz(vue@3.3.4) + '@vueuse/shared': + specifier: ^10.2.1 + version: https://registry.npmmirror.com/@vueuse/shared/-/shared-10.4.1.tgz(vue@3.3.4) + '@zxcvbn-ts/core': + specifier: ^3.0.2 + version: https://registry.npmmirror.com/@zxcvbn-ts/core/-/core-3.0.4.tgz + ant-design-vue: + specifier: ^4.0.6 + version: https://registry.npmmirror.com/ant-design-vue/-/ant-design-vue-4.0.6.tgz(vue@3.3.4) + axios: + specifier: ^1.4.0 + version: https://registry.npmmirror.com/axios/-/axios-1.5.0.tgz + bpmn-js: + specifier: ^16.1.0 + version: 16.1.0 + bpmn-js-properties-panel: + specifier: ^5.6.1 + version: 5.6.1(@bpmn-io/properties-panel@3.13.0)(bpmn-js@16.1.0)(camunda-bpmn-js-behaviors@1.2.2)(diagram-js@13.4.0) + camunda-bpmn-moddle: + specifier: ^7.0.1 + version: 7.0.1 + codemirror: + specifier: ^5.65.12 + version: https://registry.npmmirror.com/codemirror/-/codemirror-5.65.15.tgz + cropperjs: + specifier: ^1.5.13 + version: https://registry.npmmirror.com/cropperjs/-/cropperjs-1.6.0.tgz + crypto-js: + specifier: ^4.1.1 + version: 4.1.1 + dayjs: + specifier: ^1.11.9 + version: 1.11.9 + diagram-js-grid-bg: + specifier: ^1.0.3 + version: 1.0.4 + diagram-js-minimap: + specifier: 4.1.0 + version: 4.1.0 + echarts: + specifier: ^5.4.2 + version: https://registry.npmmirror.com/echarts/-/echarts-5.4.3.tgz + exceljs: + specifier: ^4.3.0 + version: 4.3.0 + intro.js: + specifier: ^7.0.1 + version: https://registry.npmmirror.com/intro.js/-/intro.js-7.2.0.tgz + lodash-es: + specifier: ^4.17.21 + version: 4.17.21 + mockjs: + specifier: ^1.1.0 + version: 1.1.0 + nprogress: + specifier: ^0.2.0 + version: 0.2.0 + path-to-regexp: + specifier: ^6.2.1 + version: 6.2.1 + pinia: + specifier: 2.1.4 + version: https://registry.npmmirror.com/pinia/-/pinia-2.1.4.tgz(typescript@5.2.2)(vue@3.3.4) + print-js: + specifier: ^1.6.0 + version: 1.6.0 + qrcode: + specifier: ^1.5.3 + version: 1.5.3 + qs: + specifier: ^6.11.2 + version: 6.11.2 + resize-observer-polyfill: + specifier: ^1.5.1 + version: 1.5.1 + showdown: + specifier: ^2.1.0 + version: 2.1.0 + sortablejs: + specifier: ^1.15.0 + version: 1.15.0 + tinymce: + specifier: ^5.10.7 + version: https://registry.npmmirror.com/tinymce/-/tinymce-5.10.7.tgz + vditor: + specifier: ^3.9.4 + version: https://registry.npmmirror.com/vditor/-/vditor-3.9.5.tgz + vue: + specifier: ^3.3.4 + version: 3.3.4 + vue-i18n: + specifier: ^9.2.2 + version: 9.2.2(vue@3.3.4) + vue-json-pretty: + specifier: ^2.2.4 + version: 2.2.4(vue@3.3.4) + vue-router: + specifier: ^4.2.3 + version: https://registry.npmmirror.com/vue-router/-/vue-router-4.2.4.tgz(vue@3.3.4) + vue-types: + specifier: ^5.1.0 + version: https://registry.npmmirror.com/vue-types/-/vue-types-5.1.1.tgz(vue@3.3.4) + vuedraggable: + specifier: ^4.1.0 + version: https://registry.npmmirror.com/vuedraggable/-/vuedraggable-4.1.0.tgz(vue@3.3.4) + vxe-table: + specifier: ^4.5.14 + version: https://registry.npmmirror.com/vxe-table/-/vxe-table-4.5.14.tgz(vue@3.3.4)(xe-utils@3.5.12) + vxe-table-plugin-export-xlsx: + specifier: 3.1.0 + version: https://registry.npmmirror.com/vxe-table-plugin-export-xlsx/-/vxe-table-plugin-export-xlsx-3.1.0.tgz(vxe-table@4.5.14) + xe-utils: + specifier: ^3.5.11 + version: https://registry.npmmirror.com/xe-utils/-/xe-utils-3.5.12.tgz + xlsx: + specifier: ^0.18.5 + version: 0.18.5 + devDependencies: + '@commitlint/cli': + specifier: ^17.6.6 + version: https://registry.npmmirror.com/@commitlint/cli/-/cli-17.7.1.tgz + '@commitlint/config-conventional': + specifier: ^17.6.6 + version: https://registry.npmmirror.com/@commitlint/config-conventional/-/config-conventional-17.7.0.tgz + '@iconify/json': + specifier: ^2.2.87 + version: https://registry.npmmirror.com/@iconify/json/-/json-2.2.108.tgz + '@purge-icons/generated': + specifier: ^0.9.0 + version: 0.9.0 + '@types/codemirror': + specifier: ^5.60.8 + version: https://registry.npmmirror.com/@types/codemirror/-/codemirror-5.60.9.tgz + '@types/crypto-js': + specifier: ^4.1.1 + version: 4.1.1 + '@types/intro.js': + specifier: ^5.1.1 + version: 5.1.1 + '@types/lodash-es': + specifier: ^4.17.7 + version: https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.8.tgz + '@types/mockjs': + specifier: ^1.0.7 + version: 1.0.7 + '@types/nprogress': + specifier: ^0.2.0 + version: 0.2.0 + '@types/qrcode': + specifier: ^1.5.1 + version: 1.5.1 + '@types/qs': + specifier: ^6.9.7 + version: 6.9.7 + '@types/showdown': + specifier: ^2.0.1 + version: 2.0.1 + '@types/sortablejs': + specifier: ^1.15.1 + version: https://registry.npmmirror.com/@types/sortablejs/-/sortablejs-1.15.2.tgz + '@vben/stylelint-config': + specifier: workspace:* + version: link:internal/stylelint-config + '@vben/ts-config': + specifier: workspace:* + version: link:internal/ts-config + '@vben/types': + specifier: workspace:* + version: link:packages/types + '@vben/vite-config': + specifier: workspace:* + version: link:internal/vite-config + '@vue/compiler-sfc': + specifier: ^3.3.4 + version: 3.3.4 + '@vue/test-utils': + specifier: ^2.4.0 + version: https://registry.npmmirror.com/@vue/test-utils/-/test-utils-2.4.1.tgz(vue@3.3.4) + cross-env: + specifier: ^7.0.3 + version: 7.0.3 + cz-git: + specifier: ^1.6.1 + version: https://registry.npmmirror.com/cz-git/-/cz-git-1.7.1.tgz + czg: + specifier: ^1.6.1 + version: https://registry.npmmirror.com/czg/-/czg-1.7.1.tgz + lint-staged: + specifier: 13.2.3 + version: https://registry.npmmirror.com/lint-staged/-/lint-staged-13.2.3.tgz + prettier: + specifier: ^2.8.8 + version: https://registry.npmmirror.com/prettier/-/prettier-2.8.8.tgz + prettier-plugin-packagejson: + specifier: ^2.4.4 + version: https://registry.npmmirror.com/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.4.5.tgz(prettier@2.8.8) + rimraf: + specifier: ^5.0.1 + version: 5.0.1 + turbo: + specifier: ^1.10.7 + version: https://registry.npmmirror.com/turbo/-/turbo-1.10.14.tgz + typescript: + specifier: ^5.1.6 + version: https://registry.npmmirror.com/typescript/-/typescript-5.2.2.tgz + unbuild: + specifier: ^1.2.1 + version: 1.2.1 + vite: + specifier: ^4.4.0 + version: https://registry.npmmirror.com/vite/-/vite-4.4.9.tgz(@types/node@20.4.7) + vite-plugin-mock: + specifier: ^2.9.6 + version: https://registry.npmmirror.com/vite-plugin-mock/-/vite-plugin-mock-2.9.8.tgz(mockjs@1.1.0)(vite@4.4.9) + vue-tsc: + specifier: ^1.8.4 + version: https://registry.npmmirror.com/vue-tsc/-/vue-tsc-1.8.8.tgz(typescript@5.2.2) + + internal/stylelint-config: + devDependencies: + postcss: + specifier: ^8.4.29 + version: 8.4.29 + postcss-html: + specifier: ^1.5.0 + version: 1.5.0 + postcss-less: + specifier: ^6.0.0 + version: 6.0.0(postcss@8.4.29) + postcss-scss: + specifier: ^4.0.7 + version: 4.0.7(postcss@8.4.29) + prettier: + specifier: ^2.8.8 + version: 2.8.8 + stylelint: + specifier: ^15.10.3 + version: 15.10.3 + stylelint-config-property-sort-order-smacss: + specifier: ^9.1.0 + version: 9.1.0(stylelint@15.10.3) + stylelint-config-recommended: + specifier: ^12.0.0 + version: 12.0.0(stylelint@15.10.3) + stylelint-config-recommended-scss: + specifier: ^11.0.0 + version: 11.0.0(postcss@8.4.29)(stylelint@15.10.3) + stylelint-config-recommended-vue: + specifier: ^1.5.0 + version: 1.5.0(postcss-html@1.5.0)(stylelint@15.10.3) + stylelint-config-standard: + specifier: ^33.0.0 + version: 33.0.0(stylelint@15.10.3) + stylelint-config-standard-scss: + specifier: ^9.0.0 + version: 9.0.0(postcss@8.4.29)(stylelint@15.10.3) + stylelint-order: + specifier: ^6.0.3 + version: 6.0.3(stylelint@15.10.3) + stylelint-prettier: + specifier: ^3.0.0 + version: 3.0.0(prettier@2.8.8)(stylelint@15.10.3) + + internal/ts-config: + dependencies: + '@types/node': + specifier: ^18.17.12 + version: 18.17.12 + unplugin-vue-define-options: + specifier: ^1.3.17 + version: 1.3.17(rollup@3.28.1)(vue@3.3.4) + vite: + specifier: ^4.4.9 + version: 4.4.9(@types/node@18.17.12) + + internal/vite-config: + dependencies: + '@ant-design/colors': + specifier: ^7.0.0 + version: 7.0.0 + vite: + specifier: ^4.4.9 + version: 4.4.9(@types/node@20.4.7)(less@4.2.0)(sass@1.66.1) + devDependencies: + '@types/fs-extra': + specifier: ^11.0.1 + version: 11.0.1 + '@vitejs/plugin-vue': + specifier: ^4.3.4 + version: 4.3.4(vite@4.4.9)(vue@3.3.4) + '@vitejs/plugin-vue-jsx': + specifier: ^3.0.2 + version: 3.0.2(vite@4.4.9)(vue@3.3.4) + ant-design-vue: + specifier: ^4.0.6 + version: https://registry.npmmirror.com/ant-design-vue/-/ant-design-vue-4.0.6.tgz(vue@3.3.4) + dayjs: + specifier: ^1.11.9 + version: 1.11.9 + dotenv: + specifier: ^16.3.1 + version: 16.3.1 + fs-extra: + specifier: ^11.1.1 + version: 11.1.1 + less: + specifier: ^4.2.0 + version: 4.2.0 + picocolors: + specifier: ^1.0.0 + version: 1.0.0 + pkg-types: + specifier: ^1.0.3 + version: 1.0.3 + rollup-plugin-visualizer: + specifier: ^5.9.2 + version: 5.9.2(rollup@3.28.1) + sass: + specifier: ^1.66.1 + version: 1.66.1 + unocss: + specifier: ^0.55.3 + version: 0.55.3(postcss@8.4.29)(rollup@3.28.1)(vite@4.4.9) + unplugin-vue-define-options: + specifier: ^1.3.17 + version: 1.3.17(rollup@3.28.1)(vue@3.3.4) + vite-plugin-compression: + specifier: ^0.5.1 + version: 0.5.1(vite@4.4.9) + vite-plugin-dts: + specifier: ^2.3.0 + version: 2.3.0(@types/node@20.4.7)(rollup@3.28.1)(vite@4.4.9) + vite-plugin-html: + specifier: ^3.2.0 + version: 3.2.0(vite@4.4.9) + vite-plugin-mock: + specifier: ^3.0.0 + version: 3.0.0(esbuild@0.19.2)(mockjs@1.1.0)(vite@4.4.9) + vite-plugin-purge-icons: + specifier: ^0.9.2 + version: 0.9.2(vite@4.4.9) + vite-plugin-svg-icons: + specifier: ^2.0.1 + version: 2.0.1(vite@4.4.9) + + packages/hooks: + dependencies: + '@vueuse/core': + specifier: ^9.13.0 + version: 9.13.0(vue@3.2.47) + vue: + specifier: ^3.2.47 + version: 3.2.47 + devDependencies: + '@vben/types': + specifier: workspace:* + version: link:../types + + packages/types: {} + +packages: + + '@ampproject/remapping@2.2.1': + resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + engines: {node: '>=6.0.0'} + + '@ampproject/remapping@https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.1.tgz': + resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.1.tgz} + name: '@ampproject/remapping' + version: 2.2.1 + engines: {node: '>=6.0.0'} + + '@ant-design/colors@6.0.0': + resolution: {integrity: sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==} + + '@ant-design/colors@7.0.0': + resolution: {integrity: sha512-iVm/9PfGCbC0dSMBrz7oiEXZaaGH7ceU40OJEfKmyuzR9R5CRimJYPlRiFtMQGQcbNMea/ePcoIebi4ASGYXtg==} + + '@ant-design/colors@https://registry.npmmirror.com/@ant-design/colors/-/colors-6.0.0.tgz': + resolution: {integrity: sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@ant-design/colors/-/colors-6.0.0.tgz} + name: '@ant-design/colors' + version: 6.0.0 + + '@ant-design/icons-svg@4.3.1': + resolution: {integrity: sha512-4QBZg8ccyC6LPIRii7A0bZUk3+lEDCLnhB+FVsflGdcWPPmV+j3fire4AwwoqHV/BibgvBmR9ZIo4s867smv+g==} + + '@ant-design/icons-svg@https://registry.npmmirror.com/@ant-design/icons-svg/-/icons-svg-4.3.1.tgz': + resolution: {integrity: sha512-4QBZg8ccyC6LPIRii7A0bZUk3+lEDCLnhB+FVsflGdcWPPmV+j3fire4AwwoqHV/BibgvBmR9ZIo4s867smv+g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@ant-design/icons-svg/-/icons-svg-4.3.1.tgz} + name: '@ant-design/icons-svg' + version: 4.3.1 + + '@ant-design/icons-vue@6.1.0': + resolution: {integrity: sha512-EX6bYm56V+ZrKN7+3MT/ubDkvJ5rK/O2t380WFRflDcVFgsvl3NLH7Wxeau6R8DbrO5jWR6DSTC3B6gYFp77AA==} + peerDependencies: + vue: '>=3.0.3' + + '@ant-design/icons-vue@https://registry.npmmirror.com/@ant-design/icons-vue/-/icons-vue-7.0.0.tgz': + resolution: {integrity: sha512-VEb0r/Jqo2qi9olfBephYlyxbmhQVZ5+tJ3Zw5VaBd5h0wV1zdjGt5mJxSbRRs2mnnOWpsa1s4PeoLwNnkLV/w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@ant-design/icons-vue/-/icons-vue-7.0.0.tgz} + name: '@ant-design/icons-vue' + version: 7.0.0 + peerDependencies: + vue: '>=3.0.3' + + '@antfu/install-pkg@0.1.1': + resolution: {integrity: sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==} + + '@antfu/utils@0.7.6': + resolution: {integrity: sha512-pvFiLP2BeOKA/ZOS6jxx4XhKzdVLHDhGlFEaZ2flWWYf2xOqVniqpk38I04DFRyz+L0ASggl7SkItTc+ZLju4w==} + + '@axolo/tree-array@https://registry.npmmirror.com/@axolo/tree-array/-/tree-array-0.1.0.tgz': + resolution: {integrity: sha512-lmvLattovjw1sqKJNLhPnBTQUm8g7U7FkHG9xUt+hR06YUL9Gtz7zbbe+UQVVGSzwlE7Yf9jiACygMdCxHJRYQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@axolo/tree-array/-/tree-array-0.1.0.tgz} + name: '@axolo/tree-array' + version: 0.1.0 + + '@babel/code-frame@7.21.4': + resolution: {integrity: sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==} + engines: {node: '>=6.9.0'} + + '@babel/code-frame@7.22.13': + resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==, tarball: https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.22.13.tgz} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.22.9': + resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.22.9.tgz': + resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.22.9.tgz} + name: '@babel/compat-data' + version: 7.22.9 + engines: {node: '>=6.9.0'} + + '@babel/core@7.22.11': + resolution: {integrity: sha512-lh7RJrtPdhibbxndr6/xx0w8+CVlY5FJZiaSz908Fpy+G0xkBFTvwLcKJFF4PJxVfGhVWNebikpWGnOoC71juQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz': + resolution: {integrity: sha512-lh7RJrtPdhibbxndr6/xx0w8+CVlY5FJZiaSz908Fpy+G0xkBFTvwLcKJFF4PJxVfGhVWNebikpWGnOoC71juQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz} + name: '@babel/core' + version: 7.22.11 + engines: {node: '>=6.9.0'} + + '@babel/generator@7.22.10': + resolution: {integrity: sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==} + engines: {node: '>=6.9.0'} + + '@babel/generator@https://registry.npmmirror.com/@babel/generator/-/generator-7.22.10.tgz': + resolution: {integrity: sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/generator/-/generator-7.22.10.tgz} + name: '@babel/generator' + version: 7.22.10 + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.22.5': + resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.22.10': + resolution: {integrity: sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz': + resolution: {integrity: sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz} + name: '@babel/helper-compilation-targets' + version: 7.22.10 + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.22.11': + resolution: {integrity: sha512-y1grdYL4WzmUDBRGK0pDbIoFd7UZKoDurDzWEoNMYoj1EL+foGRQNyPWDcC+YyegN5y1DUsFFmzjGijB3nSVAQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-environment-visitor@7.22.5': + resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-environment-visitor@https://registry.npmmirror.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz': + resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz} + name: '@babel/helper-environment-visitor' + version: 7.22.5 + engines: {node: '>=6.9.0'} + + '@babel/helper-function-name@7.22.5': + resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-function-name@https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz': + resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz} + name: '@babel/helper-function-name' + version: 7.22.5 + engines: {node: '>=6.9.0'} + + '@babel/helper-hoist-variables@7.22.5': + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-hoist-variables@https://registry.npmmirror.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz': + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz} + name: '@babel/helper-hoist-variables' + version: 7.22.5 + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.22.5': + resolution: {integrity: sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.22.5': + resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz': + resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz} + name: '@babel/helper-module-imports' + version: 7.22.5 + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.22.9': + resolution: {integrity: sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-module-transforms@https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz': + resolution: {integrity: sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz} + name: '@babel/helper-module-transforms' + version: 7.22.9 + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.22.5': + resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.22.5': + resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz': + resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz} + name: '@babel/helper-plugin-utils' + version: 7.22.5 + engines: {node: '>=6.9.0'} + + '@babel/helper-replace-supers@7.22.9': + resolution: {integrity: sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-simple-access@7.22.5': + resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-simple-access@https://registry.npmmirror.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz': + resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz} + name: '@babel/helper-simple-access' + version: 7.22.5 + engines: {node: '>=6.9.0'} + + '@babel/helper-skip-transparent-expression-wrappers@7.22.5': + resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-split-export-declaration@7.22.6': + resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-split-export-declaration@https://registry.npmmirror.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz': + resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz} + name: '@babel/helper-split-export-declaration' + version: 7.22.6 + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.22.5': + resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz': + resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz} + name: '@babel/helper-string-parser' + version: 7.22.5 + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.19.1': + resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.22.5': + resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz': + resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz} + name: '@babel/helper-validator-identifier' + version: 7.22.5 + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.22.5': + resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz': + resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz} + name: '@babel/helper-validator-option' + version: 7.22.5 + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.22.11': + resolution: {integrity: sha512-vyOXC8PBWaGc5h7GMsNx68OH33cypkEDJCHvYVVgVbbxJDROYVtexSk0gK5iCF1xNjRIN2s8ai7hwkWDq5szWg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@https://registry.npmmirror.com/@babel/helpers/-/helpers-7.22.11.tgz': + resolution: {integrity: sha512-vyOXC8PBWaGc5h7GMsNx68OH33cypkEDJCHvYVVgVbbxJDROYVtexSk0gK5iCF1xNjRIN2s8ai7hwkWDq5szWg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/helpers/-/helpers-7.22.11.tgz} + name: '@babel/helpers' + version: 7.22.11 + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.18.6': + resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.22.13': + resolution: {integrity: sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.22.10': + resolution: {integrity: sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/parser@7.22.13': + resolution: {integrity: sha512-3l6+4YOvc9wx7VlCSw4yQfcBo01ECA8TicQfbnCPuCEpRQrf+gTUyGdxNw+pyTUyywp6JRD1w0YQs9TpBXYlkw==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/parser@https://registry.npmmirror.com/@babel/parser/-/parser-7.22.13.tgz': + resolution: {integrity: sha512-3l6+4YOvc9wx7VlCSw4yQfcBo01ECA8TicQfbnCPuCEpRQrf+gTUyGdxNw+pyTUyywp6JRD1w0YQs9TpBXYlkw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/parser/-/parser-7.22.13.tgz} + name: '@babel/parser' + version: 7.22.13 + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-async-generators@https://registry.npmmirror.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz': + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz} + name: '@babel/plugin-syntax-async-generators' + version: 7.8.4 + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-bigint@https://registry.npmmirror.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz': + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz} + name: '@babel/plugin-syntax-bigint' + version: 7.8.3 + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-properties@https://registry.npmmirror.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz': + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz} + name: '@babel/plugin-syntax-class-properties' + version: 7.12.13 + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@https://registry.npmmirror.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz} + name: '@babel/plugin-syntax-import-meta' + version: 7.10.4 + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-json-strings@https://registry.npmmirror.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz': + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz} + name: '@babel/plugin-syntax-json-strings' + version: 7.8.3 + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.22.5': + resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-logical-assignment-operators@https://registry.npmmirror.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz': + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz} + name: '@babel/plugin-syntax-logical-assignment-operators' + version: 7.10.4 + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-nullish-coalescing-operator@https://registry.npmmirror.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz': + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz} + name: '@babel/plugin-syntax-nullish-coalescing-operator' + version: 7.8.3 + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-numeric-separator@https://registry.npmmirror.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz': + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz} + name: '@babel/plugin-syntax-numeric-separator' + version: 7.10.4 + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-object-rest-spread@https://registry.npmmirror.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz': + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz} + name: '@babel/plugin-syntax-object-rest-spread' + version: 7.8.3 + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-catch-binding@https://registry.npmmirror.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz': + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz} + name: '@babel/plugin-syntax-optional-catch-binding' + version: 7.8.3 + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-chaining@https://registry.npmmirror.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz': + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz} + name: '@babel/plugin-syntax-optional-chaining' + version: 7.8.3 + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-top-level-await@https://registry.npmmirror.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz': + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz} + name: '@babel/plugin-syntax-top-level-await' + version: 7.14.5 + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.22.5': + resolution: {integrity: sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@https://registry.npmmirror.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz': + resolution: {integrity: sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz} + name: '@babel/plugin-syntax-typescript' + version: 7.22.5 + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.22.11': + resolution: {integrity: sha512-0E4/L+7gfvHub7wsbTv03oRtD69X31LByy44fGmFzbZScpupFByMcgCJ0VbBTkzyjSJKuRoGN8tcijOWKTmqOA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@https://registry.npmmirror.com/@babel/runtime/-/runtime-7.22.11.tgz': + resolution: {integrity: sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/runtime/-/runtime-7.22.11.tgz} + name: '@babel/runtime' + version: 7.22.11 + engines: {node: '>=6.9.0'} + + '@babel/standalone@7.22.13': + resolution: {integrity: sha512-JoI61IOKM8jJv8V4yD0HprU/Lnx3Y29bGGULdIdJgvIUS7oCWcl43gtXoLY7nrYZhZerXYncYfDtmq4wUEofcg==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.22.5': + resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} + engines: {node: '>=6.9.0'} + + '@babel/template@https://registry.npmmirror.com/@babel/template/-/template-7.22.5.tgz': + resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/template/-/template-7.22.5.tgz} + name: '@babel/template' + version: 7.22.5 + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.22.11': + resolution: {integrity: sha512-mzAenteTfomcB7mfPtyi+4oe5BZ6MXxWcn4CX+h4IRJ+OOGXBrWU6jDQavkQI9Vuc5P+donFabBfFCcmWka9lQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@https://registry.npmmirror.com/@babel/traverse/-/traverse-7.22.11.tgz': + resolution: {integrity: sha512-mzAenteTfomcB7mfPtyi+4oe5BZ6MXxWcn4CX+h4IRJ+OOGXBrWU6jDQavkQI9Vuc5P+donFabBfFCcmWka9lQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/traverse/-/traverse-7.22.11.tgz} + name: '@babel/traverse' + version: 7.22.11 + engines: {node: '>=6.9.0'} + + '@babel/types@7.22.10': + resolution: {integrity: sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.22.11': + resolution: {integrity: sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==} + engines: {node: '>=6.9.0'} + + '@babel/types@https://registry.npmmirror.com/@babel/types/-/types-7.22.11.tgz': + resolution: {integrity: sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/types/-/types-7.22.11.tgz} + name: '@babel/types' + version: 7.22.11 + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@https://registry.npmmirror.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz} + name: '@bcoe/v8-coverage' + version: 0.2.3 + + '@bpmn-io/cm-theme@0.1.0-alpha.2': + resolution: {integrity: sha512-ZILgiYzxk3KMvxplUXmdRFQo45/JehDPg5k9tWfehmzUOSE13ssyLPil8uCloMQnb3yyzyOWTjb/wzKXTHlFQw==, tarball: https://registry.npmmirror.com/@bpmn-io/cm-theme/-/cm-theme-0.1.0-alpha.2.tgz} + + '@bpmn-io/diagram-js-ui@0.2.2': + resolution: {integrity: sha512-IgOIxOwoqsFB2mMPdXtcbPVPjdYkZ3huW7ipowYLhg5jdRGHlBronQ+LER+lfWro6sPtzEsw7qX8D8Yq9M2S5g==, tarball: https://registry.npmmirror.com/@bpmn-io/diagram-js-ui/-/diagram-js-ui-0.2.2.tgz} + + '@bpmn-io/extract-process-variables@0.8.0': + resolution: {integrity: sha512-yAS7ZYX+D56K+luC36u96eRMLb4VHcPUwTUqMZ/Z/Je2gou2DJLRbuBTHAB4jjKt4wFCHSG4B8Y+TrBciEYf4w==, tarball: https://registry.npmmirror.com/@bpmn-io/extract-process-variables/-/extract-process-variables-0.8.0.tgz} + + '@bpmn-io/feel-editor@1.0.1': + resolution: {integrity: sha512-k6OsR1Ja4FzJD31ZE1NcrjWq01poEQX5SvORVqYiUm3J0pdhFfY6Qyhoe54nk9ONihmKpGEHRtQFOdB8aaUxOw==, tarball: https://registry.npmmirror.com/@bpmn-io/feel-editor/-/feel-editor-1.0.1.tgz} + engines: {node: '>= 16'} + + '@bpmn-io/feel-lint@1.1.0': + resolution: {integrity: sha512-/StDR3LsWWo2lAEup9fLkH1fqXN3wSkvYBo4KzkQW3zp1QKhqI906bIz1ncmJXi6ao5wWH6YEdjvS1G906D9lQ==, tarball: https://registry.npmmirror.com/@bpmn-io/feel-lint/-/feel-lint-1.1.0.tgz} + + '@bpmn-io/properties-panel@3.13.0': + resolution: {integrity: sha512-KaeHwZpWDycSj8mDnDT/iO5TvyL9eYw+oHbj/69BDMblDp4xenUasWKrif5chZdt/B9gGnVtJp4vIdvlauC/XA==, tarball: https://registry.npmmirror.com/@bpmn-io/properties-panel/-/properties-panel-3.13.0.tgz} + + '@codemirror/autocomplete@6.11.1': + resolution: {integrity: sha512-L5UInv8Ffd6BPw0P3EF7JLYAMeEbclY7+6Q11REt8vhih8RuLreKtPy/xk8wPxs4EQgYqzI7cdgpiYwWlbS/ow==, tarball: https://registry.npmmirror.com/@codemirror/autocomplete/-/autocomplete-6.11.1.tgz} + peerDependencies: + '@codemirror/language': ^6.0.0 + '@codemirror/state': ^6.0.0 + '@codemirror/view': ^6.0.0 + '@lezer/common': ^1.0.0 + + '@codemirror/commands@6.3.2': + resolution: {integrity: sha512-tjoi4MCWDNxgIpoLZ7+tezdS9OEB6pkiDKhfKx9ReJ/XBcs2G2RXIu+/FxXBlWsPTsz6C9q/r4gjzrsxpcnqCQ==, tarball: https://registry.npmmirror.com/@codemirror/commands/-/commands-6.3.2.tgz} + + '@codemirror/language@6.9.3': + resolution: {integrity: sha512-qq48pYzoi6ldYWV/52+Z9Ou6QouVI+8YwvxFbUypI33NbjG2UeRHKENRyhwljTTiOqjQ33FjyZj6EREQ9apAOQ==, tarball: https://registry.npmmirror.com/@codemirror/language/-/language-6.9.3.tgz} + + '@codemirror/lint@6.4.2': + resolution: {integrity: sha512-wzRkluWb1ptPKdzlsrbwwjYCPLgzU6N88YBAmlZi8WFyuiEduSd05MnJYNogzyc8rPK7pj6m95ptUApc8sHKVA==, tarball: https://registry.npmmirror.com/@codemirror/lint/-/lint-6.4.2.tgz} + + '@codemirror/state@6.3.3': + resolution: {integrity: sha512-0wufKcTw2dEwEaADajjHf6hBy1sh3M6V0e+q4JKIhLuiMSe5td5HOWpUdvKth1fT1M9VYOboajoBHpkCd7PG7A==, tarball: https://registry.npmmirror.com/@codemirror/state/-/state-6.3.3.tgz} + + '@codemirror/view@6.22.3': + resolution: {integrity: sha512-rqnq+Zospwoi3x1vZ8BGV1MlRsaGljX+6qiGYmIpJ++M+LCC+wjfDaPklhwpWSgv7pr/qx29KiAKQBH5+DOn4w==, tarball: https://registry.npmmirror.com/@codemirror/view/-/view-6.22.3.tgz} + + '@commitlint/cli@https://registry.npmmirror.com/@commitlint/cli/-/cli-17.7.1.tgz': + resolution: {integrity: sha512-BCm/AT06SNCQtvFv921iNhudOHuY16LswT0R3OeolVGLk8oP+Rk9TfQfgjH7QPMjhvp76bNqGFEcpKojxUNW1g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@commitlint/cli/-/cli-17.7.1.tgz} + name: '@commitlint/cli' + version: 17.7.1 + engines: {node: '>=v14'} + hasBin: true + + '@commitlint/config-conventional@https://registry.npmmirror.com/@commitlint/config-conventional/-/config-conventional-17.7.0.tgz': + resolution: {integrity: sha512-iicqh2o6et+9kWaqsQiEYZzfLbtoWv9uZl8kbI8EGfnc0HeGafQBF7AJ0ylN9D/2kj6txltsdyQs8+2fTMwWEw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@commitlint/config-conventional/-/config-conventional-17.7.0.tgz} + name: '@commitlint/config-conventional' + version: 17.7.0 + engines: {node: '>=v14'} + + '@commitlint/config-validator@https://registry.npmmirror.com/@commitlint/config-validator/-/config-validator-17.6.7.tgz': + resolution: {integrity: sha512-vJSncmnzwMvpr3lIcm0I8YVVDJTzyjy7NZAeXbTXy+MPUdAr9pKyyg7Tx/ebOQ9kqzE6O9WT6jg2164br5UdsQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@commitlint/config-validator/-/config-validator-17.6.7.tgz} + name: '@commitlint/config-validator' + version: 17.6.7 + engines: {node: '>=v14'} + + '@commitlint/ensure@https://registry.npmmirror.com/@commitlint/ensure/-/ensure-17.6.7.tgz': + resolution: {integrity: sha512-mfDJOd1/O/eIb/h4qwXzUxkmskXDL9vNPnZ4AKYKiZALz4vHzwMxBSYtyL2mUIDeU9DRSpEUins8SeKtFkYHSw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@commitlint/ensure/-/ensure-17.6.7.tgz} + name: '@commitlint/ensure' + version: 17.6.7 + engines: {node: '>=v14'} + + '@commitlint/execute-rule@https://registry.npmmirror.com/@commitlint/execute-rule/-/execute-rule-17.4.0.tgz': + resolution: {integrity: sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@commitlint/execute-rule/-/execute-rule-17.4.0.tgz} + name: '@commitlint/execute-rule' + version: 17.4.0 + engines: {node: '>=v14'} + + '@commitlint/format@https://registry.npmmirror.com/@commitlint/format/-/format-17.4.4.tgz': + resolution: {integrity: sha512-+IS7vpC4Gd/x+uyQPTAt3hXs5NxnkqAZ3aqrHd5Bx/R9skyCAWusNlNbw3InDbAK6j166D9asQM8fnmYIa+CXQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@commitlint/format/-/format-17.4.4.tgz} + name: '@commitlint/format' + version: 17.4.4 + engines: {node: '>=v14'} + + '@commitlint/is-ignored@https://registry.npmmirror.com/@commitlint/is-ignored/-/is-ignored-17.7.0.tgz': + resolution: {integrity: sha512-043rA7m45tyEfW7Zv2vZHF++176MLHH9h70fnPoYlB1slKBeKl8BwNIlnPg4xBdRBVNPaCqvXxWswx2GR4c9Hw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@commitlint/is-ignored/-/is-ignored-17.7.0.tgz} + name: '@commitlint/is-ignored' + version: 17.7.0 + engines: {node: '>=v14'} + + '@commitlint/lint@https://registry.npmmirror.com/@commitlint/lint/-/lint-17.7.0.tgz': + resolution: {integrity: sha512-TCQihm7/uszA5z1Ux1vw+Nf3yHTgicus/+9HiUQk+kRSQawByxZNESeQoX9ujfVd3r4Sa+3fn0JQAguG4xvvbA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@commitlint/lint/-/lint-17.7.0.tgz} + name: '@commitlint/lint' + version: 17.7.0 + engines: {node: '>=v14'} + + '@commitlint/load@https://registry.npmmirror.com/@commitlint/load/-/load-17.7.1.tgz': + resolution: {integrity: sha512-S/QSOjE1ztdogYj61p6n3UbkUvweR17FQ0zDbNtoTLc+Hz7vvfS7ehoTMQ27hPSjVBpp7SzEcOQu081RLjKHJQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@commitlint/load/-/load-17.7.1.tgz} + name: '@commitlint/load' + version: 17.7.1 + engines: {node: '>=v14'} + + '@commitlint/message@https://registry.npmmirror.com/@commitlint/message/-/message-17.4.2.tgz': + resolution: {integrity: sha512-3XMNbzB+3bhKA1hSAWPCQA3lNxR4zaeQAQcHj0Hx5sVdO6ryXtgUBGGv+1ZCLMgAPRixuc6en+iNAzZ4NzAa8Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@commitlint/message/-/message-17.4.2.tgz} + name: '@commitlint/message' + version: 17.4.2 + engines: {node: '>=v14'} + + '@commitlint/parse@https://registry.npmmirror.com/@commitlint/parse/-/parse-17.7.0.tgz': + resolution: {integrity: sha512-dIvFNUMCUHqq5Abv80mIEjLVfw8QNuA4DS7OWip4pcK/3h5wggmjVnlwGCDvDChkw2TjK1K6O+tAEV78oxjxag==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@commitlint/parse/-/parse-17.7.0.tgz} + name: '@commitlint/parse' + version: 17.7.0 + engines: {node: '>=v14'} + + '@commitlint/read@https://registry.npmmirror.com/@commitlint/read/-/read-17.5.1.tgz': + resolution: {integrity: sha512-7IhfvEvB//p9aYW09YVclHbdf1u7g7QhxeYW9ZHSO8Huzp8Rz7m05aCO1mFG7G8M+7yfFnXB5xOmG18brqQIBg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@commitlint/read/-/read-17.5.1.tgz} + name: '@commitlint/read' + version: 17.5.1 + engines: {node: '>=v14'} + + '@commitlint/resolve-extends@https://registry.npmmirror.com/@commitlint/resolve-extends/-/resolve-extends-17.6.7.tgz': + resolution: {integrity: sha512-PfeoAwLHtbOaC9bGn/FADN156CqkFz6ZKiVDMjuC2N5N0740Ke56rKU7Wxdwya8R8xzLK9vZzHgNbuGhaOVKIg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@commitlint/resolve-extends/-/resolve-extends-17.6.7.tgz} + name: '@commitlint/resolve-extends' + version: 17.6.7 + engines: {node: '>=v14'} + + '@commitlint/rules@https://registry.npmmirror.com/@commitlint/rules/-/rules-17.7.0.tgz': + resolution: {integrity: sha512-J3qTh0+ilUE5folSaoK91ByOb8XeQjiGcdIdiB/8UT1/Rd1itKo0ju/eQVGyFzgTMYt8HrDJnGTmNWwcMR1rmA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@commitlint/rules/-/rules-17.7.0.tgz} + name: '@commitlint/rules' + version: 17.7.0 + engines: {node: '>=v14'} + + '@commitlint/to-lines@https://registry.npmmirror.com/@commitlint/to-lines/-/to-lines-17.4.0.tgz': + resolution: {integrity: sha512-LcIy/6ZZolsfwDUWfN1mJ+co09soSuNASfKEU5sCmgFCvX5iHwRYLiIuoqXzOVDYOy7E7IcHilr/KS0e5T+0Hg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@commitlint/to-lines/-/to-lines-17.4.0.tgz} + name: '@commitlint/to-lines' + version: 17.4.0 + engines: {node: '>=v14'} + + '@commitlint/top-level@https://registry.npmmirror.com/@commitlint/top-level/-/top-level-17.4.0.tgz': + resolution: {integrity: sha512-/1loE/g+dTTQgHnjoCy0AexKAEFyHsR2zRB4NWrZ6lZSMIxAhBJnmCqwao7b4H8888PsfoTBCLBYIw8vGnej8g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@commitlint/top-level/-/top-level-17.4.0.tgz} + name: '@commitlint/top-level' + version: 17.4.0 + engines: {node: '>=v14'} + + '@commitlint/types@https://registry.npmmirror.com/@commitlint/types/-/types-17.4.4.tgz': + resolution: {integrity: sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@commitlint/types/-/types-17.4.4.tgz} + name: '@commitlint/types' + version: 17.4.4 + engines: {node: '>=v14'} + + '@cspotcode/source-map-support@https://registry.npmmirror.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz} + name: '@cspotcode/source-map-support' + version: 0.8.1 + engines: {node: '>=12'} + + '@csstools/css-parser-algorithms@2.3.1': + resolution: {integrity: sha512-xrvsmVUtefWMWQsGgFffqWSK03pZ1vfDki4IVIIUxxDKnGBzqNgv0A7SB1oXtVNEkcVO8xi1ZrTL29HhSu5kGA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + '@csstools/css-tokenizer': ^2.2.0 + + '@csstools/css-tokenizer@2.2.0': + resolution: {integrity: sha512-wErmsWCbsmig8sQKkM6pFhr/oPha1bHfvxsUY5CYSQxwyhA9Ulrs8EqCgClhg4Tgg2XapVstGqSVcz0xOYizZA==} + engines: {node: ^14 || ^16 || >=18} + + '@csstools/media-query-list-parser@2.1.4': + resolution: {integrity: sha512-V/OUXYX91tAC1CDsiY+HotIcJR+vPtzrX8pCplCpT++i8ThZZsq5F5dzZh/bDM3WUOjrvC1ljed1oSJxMfjqhw==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + '@csstools/css-parser-algorithms': ^2.3.1 + '@csstools/css-tokenizer': ^2.2.0 + + '@csstools/selector-specificity@3.0.0': + resolution: {integrity: sha512-hBI9tfBtuPIi885ZsZ32IMEU/5nlZH/KOVYJCOh7gyMxaVLGmLedYqFN6Ui1LXkI8JlC8IsuC0rF0btcRZKd5g==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss-selector-parser: ^6.0.13 + + '@ctrl/tinycolor@3.6.1': + resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==} + engines: {node: '>=10'} + + '@ctrl/tinycolor@https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz': + resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz} + name: '@ctrl/tinycolor' + version: 3.6.1 + engines: {node: '>=10'} + + '@emotion/hash@https://registry.npmmirror.com/@emotion/hash/-/hash-0.9.1.tgz': + resolution: {integrity: sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@emotion/hash/-/hash-0.9.1.tgz} + name: '@emotion/hash' + version: 0.9.1 + + '@emotion/unitless@https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.8.1.tgz': + resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.8.1.tgz} + name: '@emotion/unitless' + version: 0.8.1 + + '@esbuild/android-arm64@0.17.19': + resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==, tarball: https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.18.20': + resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==, tarball: https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.19.2': + resolution: {integrity: sha512-lsB65vAbe90I/Qe10OjkmrdxSX4UJDjosDgb8sZUKcg3oefEuW2OT2Vozz8ef7wrJbMcmhvCC+hciF8jY/uAkw==, tarball: https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.17.19': + resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==, tarball: https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.18.20': + resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==, tarball: https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.19.2': + resolution: {integrity: sha512-tM8yLeYVe7pRyAu9VMi/Q7aunpLwD139EY1S99xbQkT4/q2qa6eA4ige/WJQYdJ8GBL1K33pPFhPfPdJ/WzT8Q==, tarball: https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.17.19': + resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==, tarball: https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.18.20': + resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==, tarball: https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.19.2': + resolution: {integrity: sha512-qK/TpmHt2M/Hg82WXHRc/W/2SGo/l1thtDHZWqFq7oi24AjZ4O/CpPSu6ZuYKFkEgmZlFoa7CooAyYmuvnaG8w==, tarball: https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.17.19': + resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==, tarball: https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.18.20': + resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==, tarball: https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.19.2': + resolution: {integrity: sha512-Ora8JokrvrzEPEpZO18ZYXkH4asCdc1DLdcVy8TGf5eWtPO1Ie4WroEJzwI52ZGtpODy3+m0a2yEX9l+KUn0tA==, tarball: https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.17.19': + resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==, tarball: https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.18.20': + resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==, tarball: https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.19.2': + resolution: {integrity: sha512-tP+B5UuIbbFMj2hQaUr6EALlHOIOmlLM2FK7jeFBobPy2ERdohI4Ka6ZFjZ1ZYsrHE/hZimGuU90jusRE0pwDw==, tarball: https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.17.19': + resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==, tarball: https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.18.20': + resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==, tarball: https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.19.2': + resolution: {integrity: sha512-YbPY2kc0acfzL1VPVK6EnAlig4f+l8xmq36OZkU0jzBVHcOTyQDhnKQaLzZudNJQyymd9OqQezeaBgkTGdTGeQ==, tarball: https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.17.19': + resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==, tarball: https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.18.20': + resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==, tarball: https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.19.2': + resolution: {integrity: sha512-nSO5uZT2clM6hosjWHAsS15hLrwCvIWx+b2e3lZ3MwbYSaXwvfO528OF+dLjas1g3bZonciivI8qKR/Hm7IWGw==, tarball: https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.17.19': + resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==, tarball: https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.18.20': + resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==, tarball: https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.19.2': + resolution: {integrity: sha512-ig2P7GeG//zWlU0AggA3pV1h5gdix0MA3wgB+NsnBXViwiGgY77fuN9Wr5uoCrs2YzaYfogXgsWZbm+HGr09xg==, tarball: https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.17.19': + resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==, tarball: https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.18.20': + resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==, tarball: https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.19.2': + resolution: {integrity: sha512-Odalh8hICg7SOD7XCj0YLpYCEc+6mkoq63UnExDCiRA2wXEmGlK5JVrW50vZR9Qz4qkvqnHcpH+OFEggO3PgTg==, tarball: https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.17.19': + resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==, tarball: https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.18.20': + resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==, tarball: https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.19.2': + resolution: {integrity: sha512-mLfp0ziRPOLSTek0Gd9T5B8AtzKAkoZE70fneiiyPlSnUKKI4lp+mGEnQXcQEHLJAcIYDPSyBvsUbKUG2ri/XQ==, tarball: https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.14.54': + resolution: {integrity: sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==, tarball: https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.17.19': + resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==, tarball: https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.18.20': + resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==, tarball: https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.19.2': + resolution: {integrity: sha512-hn28+JNDTxxCpnYjdDYVMNTR3SKavyLlCHHkufHV91fkewpIyQchS1d8wSbmXhs1fiYDpNww8KTFlJ1dHsxeSw==, tarball: https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.17.19': + resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==, tarball: https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.18.20': + resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==, tarball: https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.19.2': + resolution: {integrity: sha512-KbXaC0Sejt7vD2fEgPoIKb6nxkfYW9OmFUK9XQE4//PvGIxNIfPk1NmlHmMg6f25x57rpmEFrn1OotASYIAaTg==, tarball: https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.17.19': + resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==, tarball: https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.18.20': + resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==, tarball: https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.19.2': + resolution: {integrity: sha512-dJ0kE8KTqbiHtA3Fc/zn7lCd7pqVr4JcT0JqOnbj4LLzYnp+7h8Qi4yjfq42ZlHfhOCM42rBh0EwHYLL6LEzcw==, tarball: https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.17.19': + resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==, tarball: https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.18.20': + resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==, tarball: https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.19.2': + resolution: {integrity: sha512-7Z/jKNFufZ/bbu4INqqCN6DDlrmOTmdw6D0gH+6Y7auok2r02Ur661qPuXidPOJ+FSgbEeQnnAGgsVynfLuOEw==, tarball: https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.17.19': + resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==, tarball: https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.18.20': + resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==, tarball: https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.19.2': + resolution: {integrity: sha512-U+RinR6aXXABFCcAY4gSlv4CL1oOVvSSCdseQmGO66H+XyuQGZIUdhG56SZaDJQcLmrSfRmx5XZOWyCJPRqS7g==, tarball: https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.17.19': + resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==, tarball: https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.18.20': + resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==, tarball: https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.19.2': + resolution: {integrity: sha512-oxzHTEv6VPm3XXNaHPyUTTte+3wGv7qVQtqaZCrgstI16gCuhNOtBXLEBkBREP57YTd68P0VgDgG73jSD8bwXQ==, tarball: https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.17.19': + resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==, tarball: https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.18.20': + resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==, tarball: https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.19.2': + resolution: {integrity: sha512-WNa5zZk1XpTTwMDompZmvQLHszDDDN7lYjEHCUmAGB83Bgs20EMs7ICD+oKeT6xt4phV4NDdSi/8OfjPbSbZfQ==, tarball: https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.17.19': + resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==, tarball: https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.18.20': + resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==, tarball: https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.19.2': + resolution: {integrity: sha512-S6kI1aT3S++Dedb7vxIuUOb3oAxqxk2Rh5rOXOTYnzN8JzW1VzBd+IqPiSpgitu45042SYD3HCoEyhLKQcDFDw==, tarball: https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.17.19': + resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==, tarball: https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.18.20': + resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==, tarball: https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.19.2': + resolution: {integrity: sha512-VXSSMsmb+Z8LbsQGcBMiM+fYObDNRm8p7tkUDMPG/g4fhFX5DEFmjxIEa3N8Zr96SjsJ1woAhF0DUnS3MF3ARw==, tarball: https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.17.19': + resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==, tarball: https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.18.20': + resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==, tarball: https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.19.2': + resolution: {integrity: sha512-5NayUlSAyb5PQYFAU9x3bHdsqB88RC3aM9lKDAz4X1mo/EchMIT1Q+pSeBXNgkfNmRecLXA0O8xP+x8V+g/LKg==, tarball: https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.17.19': + resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==, tarball: https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.18.20': + resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==, tarball: https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.19.2': + resolution: {integrity: sha512-47gL/ek1v36iN0wL9L4Q2MFdujR0poLZMJwhO2/N3gA89jgHp4MR8DKCmwYtGNksbfJb9JoTtbkoe6sDhg2QTA==, tarball: https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.17.19': + resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==, tarball: https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.18.20': + resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==, tarball: https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.19.2': + resolution: {integrity: sha512-tcuhV7ncXBqbt/Ybf0IyrMcwVOAPDckMK9rXNHtF17UTK18OKLpg08glminN06pt2WCoALhXdLfSPbVvK/6fxw==, tarball: https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.19.2.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@fast-csv/format@4.3.5': + resolution: {integrity: sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==} + + '@fast-csv/parse@4.3.6': + resolution: {integrity: sha512-uRsLYksqpbDmWaSmzvJcuApSEe38+6NQZBUsuAyMZKqHxH0g1wcJgsKUvN3WC8tewaqFjBMMGrkHmC+T7k8LvA==} + + '@iconify/iconify@2.1.2': + resolution: {integrity: sha512-QcUzFeEWkE/mW+BVtEGmcWATClcCOIJFiYUD/PiCWuTcdEA297o8D4oN6Ra44WrNOHu1wqNW4J0ioaDIiqaFOQ==} + + '@iconify/iconify@3.1.1': + resolution: {integrity: sha512-1nemfyD/OJzh9ALepH7YfuuP8BdEB24Skhd8DXWh0hzcOxImbb1ZizSZkpCzAwSZSGcJFmscIBaBQu+yLyWaxQ==} + + '@iconify/json@https://registry.npmmirror.com/@iconify/json/-/json-2.2.108.tgz': + resolution: {integrity: sha512-s6iHOPNaTgrl3SxcIHruoE05MiGqhQllZd/pXJlZAC652vzLXfJhCe5SNQiiI3V1RqiXCmdU1Z2dZydk86UaTQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@iconify/json/-/json-2.2.108.tgz} + name: '@iconify/json' + version: 2.2.108 + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/types@https://registry.npmmirror.com/@iconify/types/-/types-2.0.0.tgz': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@iconify/types/-/types-2.0.0.tgz} + name: '@iconify/types' + version: 2.0.0 + + '@iconify/utils@2.1.9': + resolution: {integrity: sha512-mo+A4n3MwLlWlg1SoSO+Dt6pOPWKElk9sSJ6ZpuzbB9OcjxN8RUWxU3ulPwB1nglErWKRam2x4BAohbYF7FiFA==} + + '@intlify/core-base@9.2.2': + resolution: {integrity: sha512-JjUpQtNfn+joMbrXvpR4hTF8iJQ2sEFzzK3KIESOx+f+uwIjgw20igOyaIdhfsVVBCds8ZM64MoeNSx+PHQMkA==} + engines: {node: '>= 14'} + + '@intlify/devtools-if@9.2.2': + resolution: {integrity: sha512-4ttr/FNO29w+kBbU7HZ/U0Lzuh2cRDhP8UlWOtV9ERcjHzuyXVZmjyleESK6eVP60tGC9QtQW9yZE+JeRhDHkg==} + engines: {node: '>= 14'} + + '@intlify/message-compiler@9.2.2': + resolution: {integrity: sha512-IUrQW7byAKN2fMBe8z6sK6riG1pue95e5jfokn8hA5Q3Bqy4MBJ5lJAofUsawQJYHeoPJ7svMDyBaVJ4d0GTtA==} + engines: {node: '>= 14'} + + '@intlify/shared@9.2.2': + resolution: {integrity: sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==} + engines: {node: '>= 14'} + + '@intlify/vue-devtools@9.2.2': + resolution: {integrity: sha512-+dUyqyCHWHb/UcvY1MlIpO87munedm3Gn6E9WWYdWrMuYLcoIoOEVDWSS8xSwtlPU+kA+MEQTP6Q1iI/ocusJg==} + engines: {node: '>= 14'} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@istanbuljs/load-nyc-config@https://registry.npmmirror.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz': + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz} + name: '@istanbuljs/load-nyc-config' + version: 1.1.0 + engines: {node: '>=8'} + + '@istanbuljs/schema@https://registry.npmmirror.com/@istanbuljs/schema/-/schema-0.1.3.tgz': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@istanbuljs/schema/-/schema-0.1.3.tgz} + name: '@istanbuljs/schema' + version: 0.1.3 + engines: {node: '>=8'} + + '@jest/console@https://registry.npmmirror.com/@jest/console/-/console-27.5.1.tgz': + resolution: {integrity: sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@jest/console/-/console-27.5.1.tgz} + name: '@jest/console' + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + '@jest/core@https://registry.npmmirror.com/@jest/core/-/core-27.5.1.tgz': + resolution: {integrity: sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@jest/core/-/core-27.5.1.tgz} + name: '@jest/core' + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/environment@https://registry.npmmirror.com/@jest/environment/-/environment-27.5.1.tgz': + resolution: {integrity: sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@jest/environment/-/environment-27.5.1.tgz} + name: '@jest/environment' + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + '@jest/fake-timers@https://registry.npmmirror.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz': + resolution: {integrity: sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz} + name: '@jest/fake-timers' + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + '@jest/globals@https://registry.npmmirror.com/@jest/globals/-/globals-27.5.1.tgz': + resolution: {integrity: sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@jest/globals/-/globals-27.5.1.tgz} + name: '@jest/globals' + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + '@jest/reporters@https://registry.npmmirror.com/@jest/reporters/-/reporters-27.5.1.tgz': + resolution: {integrity: sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@jest/reporters/-/reporters-27.5.1.tgz} + name: '@jest/reporters' + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/source-map@https://registry.npmmirror.com/@jest/source-map/-/source-map-27.5.1.tgz': + resolution: {integrity: sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@jest/source-map/-/source-map-27.5.1.tgz} + name: '@jest/source-map' + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + '@jest/test-result@https://registry.npmmirror.com/@jest/test-result/-/test-result-27.5.1.tgz': + resolution: {integrity: sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@jest/test-result/-/test-result-27.5.1.tgz} + name: '@jest/test-result' + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + '@jest/test-sequencer@https://registry.npmmirror.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz': + resolution: {integrity: sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz} + name: '@jest/test-sequencer' + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + '@jest/transform@https://registry.npmmirror.com/@jest/transform/-/transform-27.5.1.tgz': + resolution: {integrity: sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@jest/transform/-/transform-27.5.1.tgz} + name: '@jest/transform' + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + '@jest/types@https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz': + resolution: {integrity: sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz} + name: '@jest/types' + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + '@jridgewell/gen-mapping@0.3.3': + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + engines: {node: '>=6.0.0'} + + '@jridgewell/gen-mapping@https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz': + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz} + name: '@jridgewell/gen-mapping' + version: 0.3.3 + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.1': + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz': + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz} + name: '@jridgewell/resolve-uri' + version: 3.1.1 + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.1.2': + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.1.2.tgz': + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.1.2.tgz} + name: '@jridgewell/set-array' + version: 1.1.2 + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.5': + resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + '@jridgewell/sourcemap-codec@https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz} + name: '@jridgewell/sourcemap-codec' + version: 1.4.15 + + '@jridgewell/trace-mapping@0.3.19': + resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==} + + '@jridgewell/trace-mapping@https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz': + resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz} + name: '@jridgewell/trace-mapping' + version: 0.3.19 + + '@jridgewell/trace-mapping@https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz} + name: '@jridgewell/trace-mapping' + version: 0.3.9 + + '@lezer/common@1.1.2': + resolution: {integrity: sha512-V+GqBsga5+cQJMfM0GdnHmg4DgWvLzgMWjbldBg0+jC3k9Gu6nJNZDLJxXEBT1Xj8KhRN4jmbC5CY7SIL++sVw==, tarball: https://registry.npmmirror.com/@lezer/common/-/common-1.1.2.tgz} + + '@lezer/highlight@1.2.0': + resolution: {integrity: sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==, tarball: https://registry.npmmirror.com/@lezer/highlight/-/highlight-1.2.0.tgz} + + '@lezer/lr@1.3.14': + resolution: {integrity: sha512-z5mY4LStlA3yL7aHT/rqgG614cfcvklS+8oFRFBYrs4YaWLJyKKM4+nN6KopToX0o9Hj6zmH6M5kinOYuy06ug==, tarball: https://registry.npmmirror.com/@lezer/lr/-/lr-1.3.14.tgz} + + '@lezer/markdown@1.1.2': + resolution: {integrity: sha512-PCla4SVSoxw95QvznrvQxC8c5Gw/sv7sMWLwJMsHsvUl6jsWeU4UneK7gtOq/fY1BaDTQIbzzSlxVuGLTSRScA==, tarball: https://registry.npmmirror.com/@lezer/markdown/-/markdown-1.1.2.tgz} + + '@logicflow/core@https://registry.npmmirror.com/@logicflow/core/-/core-1.2.12.tgz': + resolution: {integrity: sha512-1Z1MEMNZsHDcNfrDchISqHY8rOnfiFymvypKYQN/J8Z4VfrOb05M7n5pceJh92j+9kILsbxhcaTJLgQh1nbWxA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@logicflow/core/-/core-1.2.12.tgz} + name: '@logicflow/core' + version: 1.2.12 + + '@logicflow/extension@https://registry.npmmirror.com/@logicflow/extension/-/extension-1.2.13.tgz': + resolution: {integrity: sha512-Zy6V1K+7DogO6II5vJ5MO4D6g4bySBQjS3NL83wZP68n3qiPYojgCgSdK5XxarMibult6CBAilJgcAU5tnMyag==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@logicflow/extension/-/extension-1.2.13.tgz} + name: '@logicflow/extension' + version: 1.2.13 + + '@microsoft/api-extractor-model@7.27.6': + resolution: {integrity: sha512-eiCnlayyum1f7fS2nA9pfIod5VCNR1G+Tq84V/ijDrKrOFVa598BLw145nCsGDMoFenV6ajNi2PR5WCwpAxW6Q==} + + '@microsoft/api-extractor@7.36.4': + resolution: {integrity: sha512-21UECq8C/8CpHT23yiqTBQ10egKUacIpxkPyYR7hdswo/M5yTWdBvbq+77YC9uPKQJOUfOD1FImBQ1DzpsdeQQ==} + hasBin: true + + '@microsoft/tsdoc-config@0.16.2': + resolution: {integrity: sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==} + + '@microsoft/tsdoc@0.14.2': + resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.scandir@https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz} + name: '@nodelib/fs.scandir' + version: 2.1.5 + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz} + name: '@nodelib/fs.stat' + version: 2.0.5 + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz} + name: '@nodelib/fs.walk' + version: 1.2.8 + engines: {node: '>= 8'} + + '@one-ini/wasm@https://registry.npmmirror.com/@one-ini/wasm/-/wasm-0.1.1.tgz': + resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@one-ini/wasm/-/wasm-0.1.1.tgz} + name: '@one-ini/wasm' + version: 0.1.1 + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==, tarball: https://registry.npmmirror.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz} + engines: {node: '>=14'} + + '@pkgr/utils@https://registry.npmmirror.com/@pkgr/utils/-/utils-2.4.2.tgz': + resolution: {integrity: sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@pkgr/utils/-/utils-2.4.2.tgz} + name: '@pkgr/utils' + version: 2.4.2 + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@polka/url@1.0.0-next.21': + resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==} + + '@purge-icons/core@0.9.1': + resolution: {integrity: sha512-sx8/a30MbbqQVEqhuMPE1wJpdVRRbEmwEPZpFzVkcDixzX4p+R2A0WVxqkb0xfHUBAVQwrSE2SeAyniIQLqbLw==} + + '@purge-icons/generated@0.9.0': + resolution: {integrity: sha512-s2t+1oVtGDV6KtqfCXtUOhxfeYvOdDF90IVm+nMs/6bUP0HeGZLslguuL/AibpwtfL4FA/oCsIu/RhwapgAdJw==} + + '@rollup/plugin-alias@5.0.0': + resolution: {integrity: sha512-l9hY5chSCjuFRPsnRm16twWBiSApl2uYFLsepQYwtBuAxNMQ/1dJqADld40P0Jkqm65GRTLy/AC6hnpVebtLsA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-commonjs@24.1.0': + resolution: {integrity: sha512-eSL45hjhCWI0jCCXcNtLVqM5N1JlBGvlFfY0m6oOYnLCJ6N0qEXoZql4sY2MOUArzhH4SA/qBpTxvvZp2Sc+DQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.68.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-json@6.0.0': + resolution: {integrity: sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-node-resolve@15.2.1': + resolution: {integrity: sha512-nsbUg588+GDSu8/NS8T4UAshO6xeaOfINNuXeVHcKV02LJtoRaM1SiOacClw4kws1SFiNhdLGxlbMY9ga/zs/w==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-replace@5.0.2': + resolution: {integrity: sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/pluginutils@4.2.1': + resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} + engines: {node: '>= 8.0.0'} + + '@rollup/pluginutils@5.0.3': + resolution: {integrity: sha512-hfllNN4a80rwNQ9QCxhxuHCGHMAvabXqxNdaChUSSadMre7t4iEUI6fFAhBOn/eIYTgYVhBv7vCLsAJ4u3lf3g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/pluginutils@5.0.4': + resolution: {integrity: sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rushstack/node-core-library@3.59.7': + resolution: {integrity: sha512-ln1Drq0h+Hwa1JVA65x5mlSgUrBa1uHL+V89FqVWQgXd1vVIMhrtqtWGQrhTnFHxru5ppX+FY39VWELF/FjQCw==} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + + '@rushstack/rig-package@0.4.1': + resolution: {integrity: sha512-AGRwpqlXNSp9LhUSz4HKI9xCluqQDt/obsQFdv/NYIekF3pTTPzc+HbQsIsjVjYnJ3DcmxOREVMhvrMEjpiq6g==} + + '@rushstack/ts-command-line@4.15.2': + resolution: {integrity: sha512-5+C2uoJY8b+odcZD6coEe2XNC4ZjGB4vCMESbqW/8DHRWC/qIHfANdmN9F1wz/lAgxz72i7xRoVtPY2j7e4gpQ==} + + '@simonwep/pickr@https://registry.npmmirror.com/@simonwep/pickr/-/pickr-1.8.2.tgz': + resolution: {integrity: sha512-/l5w8BIkrpP6n1xsetx9MWPWlU6OblN5YgZZphxan0Tq4BByTCETL6lyIeY8lagalS2Nbt4F2W034KHLIiunKA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@simonwep/pickr/-/pickr-1.8.2.tgz} + name: '@simonwep/pickr' + version: 1.8.2 + + '@sinonjs/commons@https://registry.npmmirror.com/@sinonjs/commons/-/commons-1.8.6.tgz': + resolution: {integrity: sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@sinonjs/commons/-/commons-1.8.6.tgz} + name: '@sinonjs/commons' + version: 1.8.6 + + '@sinonjs/fake-timers@https://registry.npmmirror.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz': + resolution: {integrity: sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz} + name: '@sinonjs/fake-timers' + version: 8.1.0 + + '@tootallnate/once@https://registry.npmmirror.com/@tootallnate/once/-/once-1.1.2.tgz': + resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@tootallnate/once/-/once-1.1.2.tgz} + name: '@tootallnate/once' + version: 1.1.2 + engines: {node: '>= 6'} + + '@trysound/sax@0.2.0': + resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} + engines: {node: '>=10.13.0'} + + '@ts-morph/common@0.19.0': + resolution: {integrity: sha512-Unz/WHmd4pGax91rdIKWi51wnVUW11QttMEPpBiBgIewnc9UQIX7UDLxr5vRlqeByXCwhkF6VabSsI0raWcyAQ==} + + '@tsconfig/node10@https://registry.npmmirror.com/@tsconfig/node10/-/node10-1.0.9.tgz': + resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@tsconfig/node10/-/node10-1.0.9.tgz} + name: '@tsconfig/node10' + version: 1.0.9 + + '@tsconfig/node12@https://registry.npmmirror.com/@tsconfig/node12/-/node12-1.0.11.tgz': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@tsconfig/node12/-/node12-1.0.11.tgz} + name: '@tsconfig/node12' + version: 1.0.11 + + '@tsconfig/node14@https://registry.npmmirror.com/@tsconfig/node14/-/node14-1.0.3.tgz': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@tsconfig/node14/-/node14-1.0.3.tgz} + name: '@tsconfig/node14' + version: 1.0.3 + + '@tsconfig/node16@https://registry.npmmirror.com/@tsconfig/node16/-/node16-1.0.3.tgz': + resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@tsconfig/node16/-/node16-1.0.3.tgz} + name: '@tsconfig/node16' + version: 1.0.3 + + '@types/argparse@1.0.38': + resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} + + '@types/babel__core@https://registry.npmmirror.com/@types/babel__core/-/babel__core-7.20.1.tgz': + resolution: {integrity: sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/babel__core/-/babel__core-7.20.1.tgz} + name: '@types/babel__core' + version: 7.20.1 + + '@types/babel__generator@https://registry.npmmirror.com/@types/babel__generator/-/babel__generator-7.6.4.tgz': + resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/babel__generator/-/babel__generator-7.6.4.tgz} + name: '@types/babel__generator' + version: 7.6.4 + + '@types/babel__template@https://registry.npmmirror.com/@types/babel__template/-/babel__template-7.4.1.tgz': + resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/babel__template/-/babel__template-7.4.1.tgz} + name: '@types/babel__template' + version: 7.4.1 + + '@types/babel__traverse@https://registry.npmmirror.com/@types/babel__traverse/-/babel__traverse-7.20.1.tgz': + resolution: {integrity: sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/babel__traverse/-/babel__traverse-7.20.1.tgz} + name: '@types/babel__traverse' + version: 7.20.1 + + '@types/codemirror@https://registry.npmmirror.com/@types/codemirror/-/codemirror-5.60.9.tgz': + resolution: {integrity: sha512-8RhLhlGo9bAkytFYKDzezorY2ojvGk+4xFEso/6Hc2oR1oE2P9lI+AEkbUW7cDlKcQAK5WJkJRBLTdjBE7xQPA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/codemirror/-/codemirror-5.60.9.tgz} + name: '@types/codemirror' + version: 5.60.9 + + '@types/crypto-js@4.1.1': + resolution: {integrity: sha512-BG7fQKZ689HIoc5h+6D2Dgq1fABRa0RbBWKBd9SP/MVRVXROflpm5fhwyATX5duFmbStzyzyycPB8qUYKDH3NA==} + + '@types/estree@1.0.1': + resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} + + '@types/estree@https://registry.npmmirror.com/@types/estree/-/estree-1.0.1.tgz': + resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/estree/-/estree-1.0.1.tgz} + name: '@types/estree' + version: 1.0.1 + + '@types/fs-extra@11.0.1': + resolution: {integrity: sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==} + + '@types/graceful-fs@https://registry.npmmirror.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz': + resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz} + name: '@types/graceful-fs' + version: 4.1.6 + + '@types/intro.js@5.1.1': + resolution: {integrity: sha512-gxrfhzwHeCZI8PoucIVRCe5cX0j29YYB1YLIfPb87HN1HiAhrl0CGMFuYPzo6Gvn5diAPCHF6XW2SR+Lqxexlg==} + + '@types/istanbul-lib-coverage@https://registry.npmmirror.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz': + resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz} + name: '@types/istanbul-lib-coverage' + version: 2.0.4 + + '@types/istanbul-lib-report@https://registry.npmmirror.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz': + resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz} + name: '@types/istanbul-lib-report' + version: 3.0.0 + + '@types/istanbul-reports@https://registry.npmmirror.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz': + resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz} + name: '@types/istanbul-reports' + version: 3.0.1 + + '@types/jsonfile@6.1.1': + resolution: {integrity: sha512-GSgiRCVeapDN+3pqA35IkQwasaCh/0YFH5dEF6S88iDvEn901DjOeH3/QPY+XYP1DFzDZPvIvfeEgk+7br5png==} + + '@types/lodash-es@https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.8.tgz': + resolution: {integrity: sha512-euY3XQcZmIzSy7YH5+Unb3b2X12Wtk54YWINBvvGQ5SmMvwb11JQskGsfkH/5HXK77Kr8GF0wkVDIxzAisWtog==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.8.tgz} + name: '@types/lodash-es' + version: 4.17.8 + + '@types/lodash@https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.197.tgz': + resolution: {integrity: sha512-BMVOiWs0uNxHVlHBgzTIqJYmj+PgCo4euloGF+5m4okL3rEYzM2EEv78mw8zWSMM57dM7kVIgJ2QDvwHSoCI5g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.197.tgz} + name: '@types/lodash' + version: 4.14.197 + + '@types/minimist@1.2.2': + resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} + + '@types/minimist@https://registry.npmmirror.com/@types/minimist/-/minimist-1.2.2.tgz': + resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/minimist/-/minimist-1.2.2.tgz} + name: '@types/minimist' + version: 1.2.2 + + '@types/mockjs@1.0.7': + resolution: {integrity: sha512-OCxXz6hEaJOVpRwuJMiVY5a6LtJcih+br9gwB/Q8ooOBikvk5FpBQ31OlNimXo3EqKha1Z7PFBni+q9m+8NCWg==} + + '@types/mockjs@https://registry.npmmirror.com/@types/mockjs/-/mockjs-1.0.7.tgz': + resolution: {integrity: sha512-OCxXz6hEaJOVpRwuJMiVY5a6LtJcih+br9gwB/Q8ooOBikvk5FpBQ31OlNimXo3EqKha1Z7PFBni+q9m+8NCWg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/mockjs/-/mockjs-1.0.7.tgz} + name: '@types/mockjs' + version: 1.0.7 + + '@types/mousetrap@https://registry.npmmirror.com/@types/mousetrap/-/mousetrap-1.6.11.tgz': + resolution: {integrity: sha512-F0oAily9Q9QQpv9JKxKn0zMKfOo36KHCW7myYsmUyf2t0g+sBTbG3UleTPoguHdE1z3GLFr3p7/wiOio52QFjQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/mousetrap/-/mousetrap-1.6.11.tgz} + name: '@types/mousetrap' + version: 1.6.11 + + '@types/node@14.18.56': + resolution: {integrity: sha512-+k+57NVS9opgrEn5l9c0gvD1r6C+PtyhVE4BTnMMRwiEA8ZO8uFcs6Yy2sXIy0eC95ZurBtRSvhZiHXBysbl6w==} + + '@types/node@18.17.12': + resolution: {integrity: sha512-d6xjC9fJ/nSnfDeU0AMDsaJyb1iHsqCSOdi84w4u+SlN/UgQdY5tRhpMzaFYsI4mnpvgTivEaQd0yOUhAtOnEQ==} + + '@types/node@20.5.7': + resolution: {integrity: sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==} + + '@types/node@https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz': + resolution: {integrity: sha512-d6xjC9fJ/nSnfDeU0AMDsaJyb1iHsqCSOdi84w4u+SlN/UgQdY5tRhpMzaFYsI4mnpvgTivEaQd0yOUhAtOnEQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz} + name: '@types/node' + version: 18.17.12 + + '@types/node@https://registry.npmmirror.com/@types/node/-/node-20.4.7.tgz': + resolution: {integrity: sha512-bUBrPjEry2QUTsnuEjzjbS7voGWCc30W0qzgMf90GPeDGFRakvrz47ju+oqDAKCXLUCe39u57/ORMl/O/04/9g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/node/-/node-20.4.7.tgz} + name: '@types/node' + version: 20.4.7 + + '@types/normalize-package-data@2.4.1': + resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} + + '@types/normalize-package-data@https://registry.npmmirror.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz': + resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz} + name: '@types/normalize-package-data' + version: 2.4.1 + + '@types/nprogress@0.2.0': + resolution: {integrity: sha512-1cYJrqq9GezNFPsWTZpFut/d4CjpZqA0vhqDUPFWYKF1oIyBz5qnoYMzR+0C/T96t3ebLAC1SSnwrVOm5/j74A==} + + '@types/prettier@https://registry.npmmirror.com/@types/prettier/-/prettier-2.7.3.tgz': + resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/prettier/-/prettier-2.7.3.tgz} + name: '@types/prettier' + version: 2.7.3 + + '@types/qrcode@1.5.1': + resolution: {integrity: sha512-HpSN675K0PmxIDRpjMI3Mc2GiKo3dNu+X/F5SoItiaDS1lVfgC6Wac1c5lQDfKWbTJUSHWiHKzpJpBZG7k9gaA==} + + '@types/qs@6.9.7': + resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} + + '@types/resolve@1.20.2': + resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + + '@types/showdown@2.0.1': + resolution: {integrity: sha512-xdnAw2nFqomkaL0QdtEk0t7yz26UkaVPl4v1pYJvtE1T0fmfQEH3JaxErEhGByEAl3zUZrkNBlneuJp0WJGqEA==} + + '@types/sortablejs@https://registry.npmmirror.com/@types/sortablejs/-/sortablejs-1.15.2.tgz': + resolution: {integrity: sha512-mOIv/EnPMzAZAVbuh9uGjOZ1BBdimP9Y6IPGntsvQJtko5yapSDKB7GwB3AOlF5N3bkpk4sBwQRpS3aEkiUbaA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/sortablejs/-/sortablejs-1.15.2.tgz} + name: '@types/sortablejs' + version: 1.15.2 + + '@types/stack-utils@https://registry.npmmirror.com/@types/stack-utils/-/stack-utils-2.0.1.tgz': + resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/stack-utils/-/stack-utils-2.0.1.tgz} + name: '@types/stack-utils' + version: 2.0.1 + + '@types/svgo@2.6.4': + resolution: {integrity: sha512-l4cmyPEckf8moNYHdJ+4wkHvFxjyW6ulm9l4YGaOxeyBWPhBOT0gvni1InpFPdzx1dKf/2s62qGITwxNWnPQng==} + + '@types/tern@https://registry.npmmirror.com/@types/tern/-/tern-0.23.4.tgz': + resolution: {integrity: sha512-JAUw1iXGO1qaWwEOzxTKJZ/5JxVeON9kvGZ/osgZaJImBnyjyn0cjovPsf6FNLmyGY8Vw9DoXZCMlfMkMwHRWg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/tern/-/tern-0.23.4.tgz} + name: '@types/tern' + version: 0.23.4 + + '@types/web-bluetooth@0.0.16': + resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} + + '@types/web-bluetooth@https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.17.tgz': + resolution: {integrity: sha512-4p9vcSmxAayx72yn70joFoL44c9MO/0+iVEBIQXe3v2h2SiAsEIo/G5v6ObFWvNKRFjbrVadNf9LqEEZeQPzdA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.17.tgz} + name: '@types/web-bluetooth' + version: 0.0.17 + + '@types/yargs-parser@https://registry.npmmirror.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz': + resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz} + name: '@types/yargs-parser' + version: 21.0.0 + + '@types/yargs@https://registry.npmmirror.com/@types/yargs/-/yargs-16.0.5.tgz': + resolution: {integrity: sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/yargs/-/yargs-16.0.5.tgz} + name: '@types/yargs' + version: 16.0.5 + + '@unocss/astro@0.55.3': + resolution: {integrity: sha512-WyRvx1RvT3x4c19jrKYq9dN2KHJ8YYOHUmFKWaPVc9EpkTG802ElWq23Ly5G+tv6l3lITRT+tUVloL4i43Ipiw==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 + peerDependenciesMeta: + vite: + optional: true + + '@unocss/cli@0.55.3': + resolution: {integrity: sha512-r5WcO/L0g8jUlUge/jdRKt1rG8Cm5K46edIHI2GL59uEXYq4T1Llh8gfIMXeP0Geqfml69E1QRNNocwRxYGDcA==} + engines: {node: '>=14'} + hasBin: true + + '@unocss/config@0.55.3': + resolution: {integrity: sha512-d1AK44n8DeYA1gIMaWg5lR/zx2FgVS6luaeMMGm5985VJqZoj7WJAj+Av/BOaEFJEP9ruYO1Hsb2ng2ega0ybQ==} + engines: {node: '>=14'} + + '@unocss/core@0.55.3': + resolution: {integrity: sha512-2hV9QlE/iOM4DHQ7i6L8sMC1t5/OVAz6AfGHjetTXcgbNfDCsHWqE8jhLZ1y2DeUvKwJvj2A09sYbYQ8E27+Gg==} + + '@unocss/extractor-arbitrary-variants@0.55.3': + resolution: {integrity: sha512-ATVNywbUw0DhIT+iau35WQuoij/NPCPd5uKshhs+vnS4c7BVKUMXE1fk9df9AgVPVhwBN4A256EqkcPHrfv70w==} + + '@unocss/inspector@0.55.3': + resolution: {integrity: sha512-AHgjYbeaqSKSMIKkyUqFrXs9qi2hPhkIahMtv4nS0HZDzzrGGHv5lAmdYr4CxJEGs9G1lgrl2g7a4nz23LTRMQ==} + + '@unocss/postcss@0.55.3': + resolution: {integrity: sha512-JWfjtSLGuYFWcZwP3eUT2ItdRwehnpmry36cMSuuPNLXG0SPtklP2LRFahvgH85YhASNDAL2OIHP4jGTlG2Jfw==} + engines: {node: '>=14'} + peerDependencies: + postcss: ^8.4.21 + + '@unocss/preset-attributify@0.55.3': + resolution: {integrity: sha512-h3t6hPIk8pll3LubIIIsgRigvJivK3PX308Pi9Q0IUdw0vFq4S80iLQ1N0kRchQtgOaAIGffo9ux+TCbyunP3A==} + + '@unocss/preset-icons@0.55.3': + resolution: {integrity: sha512-UVpzkvO1ghNBNRMGylgYE73ufRFdU1l3pY11ePV8a/80HWFKL3QNq4Hoqa00M5CEnxBZT8dECTuj+f+l3Pn5wg==} + + '@unocss/preset-mini@0.55.3': + resolution: {integrity: sha512-TsDPatfA3nGybRDHtxWz7mGuXQqzFWqgOZDZlPEq+HQxK2DY5KdVekkq8G3kp8N8Alu/Tf52aDwIBSn/RC2qFg==} + + '@unocss/preset-tagify@0.55.3': + resolution: {integrity: sha512-5nvKAREDkoAkwmbMKBwBDZjrhP2+pMeKMIdd8IOsEWpKbhJThXCRDcMZWuJ+nqm0kGkgZTtqzNso68+WjEwhuw==} + + '@unocss/preset-typography@0.55.3': + resolution: {integrity: sha512-O6YvQQ3b+qbqLVlCASmNFj1PfCkqgWVu+gnMFloFofB9olGix9H0qjsOyC6vJg9m2f9+MzPoNR4s2Du0V8fj5A==} + + '@unocss/preset-uno@0.55.3': + resolution: {integrity: sha512-6/JYKsgsHi24QFU8cXeXvRFmsosXdb6dmjsBma7ywEmzV2187uDDqI6NG/Aah5y5s2/QCyqqQFKN4vfatPARlQ==} + + '@unocss/preset-web-fonts@0.55.3': + resolution: {integrity: sha512-Mmj5HMvGOaDjobGno7rcLHUFHxIorw5kjobYJnEj48Wy7ixkYGQCvwguVZfE3YKsTEYVsMDojxC7ETK6Qae6vQ==} + + '@unocss/preset-wind@0.55.3': + resolution: {integrity: sha512-3K/46j4tRLMspVR4MvY6l7yBe8Eb+csTLOrDFKmj5+uZc7Y4+PTjFqURifrtgEpnwgW9SfXbXjPo/ALzA6x0XA==} + + '@unocss/reset@0.55.3': + resolution: {integrity: sha512-zl3mogr3z6huA5CHZggOljoYFQDTidEw5T6pGPahfHB5qS9DH0UGozg5T9UtYWiidHL3xqyv6ZU27nyIMnlnhg==} + + '@unocss/scope@0.55.3': + resolution: {integrity: sha512-h9OlxjXYwtASw8Lm/ucuWOIlrLFXHH9Cek17kPG3upWPKBMRQJl3GT18jTtPim0mqakhZY+8GQM1itHyOtHkSQ==} + + '@unocss/transformer-attributify-jsx-babel@0.55.3': + resolution: {integrity: sha512-EDmliP9NYJZKg13SdfHfFaE0HroH+mNEEoICqiuvAKr3YVc+qhdk105+xwZDUGEJi/wVf1q8AZ3oEmwpAqtd9g==} + + '@unocss/transformer-attributify-jsx@0.55.3': + resolution: {integrity: sha512-Z+jCSRCxMkAFyjye52rFL+yrIvu6AxwOqhDT8jVLyVGgMFRYm79FP6fsDhsgr/EipHE9Szk+H0yt16aNlPYU4Q==} + + '@unocss/transformer-compile-class@0.55.3': + resolution: {integrity: sha512-g6UgDqTwhbpuyN/tCse2p+bQvyGmEyQk3kOFq8P9P7+mtfOXPmkkVnShDSs2K4FyfTpFGouOSTge0rrJyVj3LQ==} + + '@unocss/transformer-directives@0.55.3': + resolution: {integrity: sha512-9la+Gk7doqTl+drg9RflkFqN7bXavzI119amJ6xa+ZlUm04vaC5WxFMxZD3V29zu505IhGWMOVJNfnV6g4hLvg==} + + '@unocss/transformer-variant-group@0.55.3': + resolution: {integrity: sha512-3Pe04N6If+1o0tsa1n58ysV6Yt7OW6ER6lNtbpyZcuG+gMgjU6u7FsCC+IuZ50aHsXRVpFbFtjMeugN9KaO5ow==} + + '@unocss/vite@0.55.3': + resolution: {integrity: sha512-ykHIBwssTZMQ2FC2wj8+LDrrYkq8PUIekdyeazznX38CNxAwZtwrrtUjieoJkAl6Ebxv8oMadxamqnP/0E8Ygw==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 + + '@vitejs/plugin-vue-jsx@3.0.2': + resolution: {integrity: sha512-obF26P2Z4Ogy3cPp07B4VaW6rpiu0ue4OT2Y15UxT5BZZ76haUY9guOsZV3uWh/I6xc+VeiW+ZVabRE82FyzWw==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.0.0 + vue: ^3.0.0 + + '@vitejs/plugin-vue@4.3.4': + resolution: {integrity: sha512-ciXNIHKPriERBisHFBvnTbfKa6r9SAesOYXeGDzgegcvy9Q4xdScSHAmKbNT0M3O0S9LKhIf5/G+UYG4NnnzYw==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.0.0 + vue: ^3.2.25 + + '@volar/language-core@https://registry.npmmirror.com/@volar/language-core/-/language-core-1.10.1.tgz': + resolution: {integrity: sha512-JnsM1mIPdfGPxmoOcK1c7HYAsL6YOv0TCJ4aW3AXPZN/Jb4R77epDyMZIVudSGjWMbvv/JfUa+rQ+dGKTmgwBA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@volar/language-core/-/language-core-1.10.1.tgz} + name: '@volar/language-core' + version: 1.10.1 + + '@volar/source-map@https://registry.npmmirror.com/@volar/source-map/-/source-map-1.10.1.tgz': + resolution: {integrity: sha512-3/S6KQbqa7pGC8CxPrg69qHLpOvkiPHGJtWPkI/1AXCsktkJ6gIk/5z4hyuMp8Anvs6eS/Kvp/GZa3ut3votKA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@volar/source-map/-/source-map-1.10.1.tgz} + name: '@volar/source-map' + version: 1.10.1 + + '@volar/typescript@https://registry.npmmirror.com/@volar/typescript/-/typescript-1.10.1.tgz': + resolution: {integrity: sha512-+iiO9yUSRHIYjlteT+QcdRq8b44qH19/eiUZtjNtuh6D9ailYM7DVR0zO2sEgJlvCaunw/CF9Ov2KooQBpR4VQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@volar/typescript/-/typescript-1.10.1.tgz} + name: '@volar/typescript' + version: 1.10.1 + + '@vue-macros/common@1.7.2': + resolution: {integrity: sha512-0/2A4kWLTCNEx+DDQKLvs7zXpfjgAbGBZ58SIvDN1DjGXhG4WaIUZtgMqzA6bvc5dNN7RaOatZYubkVumwmjWA==} + engines: {node: '>=16.14.0'} + peerDependencies: + vue: ^2.7.0 || ^3.2.25 + peerDependenciesMeta: + vue: + optional: true + + '@vue/babel-helper-vue-transform-on@1.1.5': + resolution: {integrity: sha512-SgUymFpMoAyWeYWLAY+MkCK3QEROsiUnfaw5zxOVD/M64KQs8D/4oK6Q5omVA2hnvEOE0SCkH2TZxs/jnnUj7w==} + + '@vue/babel-plugin-jsx@1.1.5': + resolution: {integrity: sha512-nKs1/Bg9U1n3qSWnsHhCVQtAzI6aQXqua8j/bZrau8ywT1ilXQbK4FwEJGmU8fV7tcpuFvWmmN7TMmV1OBma1g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@vue/compiler-core@3.2.47': + resolution: {integrity: sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==} + + '@vue/compiler-core@3.3.4': + resolution: {integrity: sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==} + + '@vue/compiler-core@https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.4.tgz': + resolution: {integrity: sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.4.tgz} + name: '@vue/compiler-core' + version: 3.3.4 + + '@vue/compiler-dom@3.2.47': + resolution: {integrity: sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==} + + '@vue/compiler-dom@3.3.4': + resolution: {integrity: sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==} + + '@vue/compiler-dom@https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz': + resolution: {integrity: sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz} + name: '@vue/compiler-dom' + version: 3.3.4 + + '@vue/compiler-sfc@3.2.47': + resolution: {integrity: sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==} + + '@vue/compiler-sfc@3.3.4': + resolution: {integrity: sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==} + + '@vue/compiler-ssr@3.2.47': + resolution: {integrity: sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==} + + '@vue/compiler-ssr@3.3.4': + resolution: {integrity: sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==} + + '@vue/devtools-api@6.5.0': + resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==} + + '@vue/devtools-api@https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.5.0.tgz': + resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.5.0.tgz} + name: '@vue/devtools-api' + version: 6.5.0 + + '@vue/language-core@https://registry.npmmirror.com/@vue/language-core/-/language-core-1.8.8.tgz': + resolution: {integrity: sha512-i4KMTuPazf48yMdYoebTkgSOJdFraE4pQf0B+FTOFkbB+6hAfjrSou/UmYWRsWyZV6r4Rc6DDZdI39CJwL0rWw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/language-core/-/language-core-1.8.8.tgz} + name: '@vue/language-core' + version: 1.8.8 + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@vue/reactivity-transform@3.2.47': + resolution: {integrity: sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==} + + '@vue/reactivity-transform@3.3.4': + resolution: {integrity: sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==} + + '@vue/reactivity@3.2.47': + resolution: {integrity: sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==} + + '@vue/reactivity@3.3.4': + resolution: {integrity: sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==} + + '@vue/reactivity@https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.3.4.tgz': + resolution: {integrity: sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.3.4.tgz} + name: '@vue/reactivity' + version: 3.3.4 + + '@vue/runtime-core@3.2.47': + resolution: {integrity: sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==} + + '@vue/runtime-core@3.3.4': + resolution: {integrity: sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==} + + '@vue/runtime-dom@3.2.47': + resolution: {integrity: sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==} + + '@vue/runtime-dom@3.3.4': + resolution: {integrity: sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==} + + '@vue/server-renderer@3.2.47': + resolution: {integrity: sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==} + peerDependencies: + vue: 3.2.47 + + '@vue/server-renderer@3.3.4': + resolution: {integrity: sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==} + peerDependencies: + vue: 3.3.4 + + '@vue/shared@3.2.47': + resolution: {integrity: sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==} + + '@vue/shared@3.3.4': + resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==} + + '@vue/shared@https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz': + resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz} + name: '@vue/shared' + version: 3.3.4 + + '@vue/test-utils@https://registry.npmmirror.com/@vue/test-utils/-/test-utils-2.4.1.tgz': + resolution: {integrity: sha512-VO8nragneNzUZUah6kOjiFmD/gwRjUauG9DROh6oaOeFwX1cZRUNHhdeogE8635cISigXFTtGLUQWx5KCb0xeg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/test-utils/-/test-utils-2.4.1.tgz} + name: '@vue/test-utils' + version: 2.4.1 + peerDependencies: + '@vue/server-renderer': ^3.0.1 + vue: ^3.0.1 + peerDependenciesMeta: + '@vue/server-renderer': + optional: true + + '@vue/typescript@https://registry.npmmirror.com/@vue/typescript/-/typescript-1.8.8.tgz': + resolution: {integrity: sha512-jUnmMB6egu5wl342eaUH236v8tdcEPXXkPgj+eI/F6JwW/lb+yAU6U07ZbQ3MVabZRlupIlPESB7ajgAGixhow==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/typescript/-/typescript-1.8.8.tgz} + name: '@vue/typescript' + version: 1.8.8 + + '@vueuse/core@9.13.0': + resolution: {integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==} + + '@vueuse/core@https://registry.npmmirror.com/@vueuse/core/-/core-10.4.1.tgz': + resolution: {integrity: sha512-DkHIfMIoSIBjMgRRvdIvxsyboRZQmImofLyOHADqiVbQVilP8VVHDhBX2ZqoItOgu7dWa8oXiNnScOdPLhdEXg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vueuse/core/-/core-10.4.1.tgz} + name: '@vueuse/core' + version: 10.4.1 + + '@vueuse/metadata@9.13.0': + resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==} + + '@vueuse/metadata@https://registry.npmmirror.com/@vueuse/metadata/-/metadata-10.4.1.tgz': + resolution: {integrity: sha512-2Sc8X+iVzeuMGHr6O2j4gv/zxvQGGOYETYXEc41h0iZXIRnRbJZGmY/QP8dvzqUelf8vg0p/yEA5VpCEu+WpZg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vueuse/metadata/-/metadata-10.4.1.tgz} + name: '@vueuse/metadata' + version: 10.4.1 + + '@vueuse/shared@9.13.0': + resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==} + + '@vueuse/shared@https://registry.npmmirror.com/@vueuse/shared/-/shared-10.4.1.tgz': + resolution: {integrity: sha512-vz5hbAM4qA0lDKmcr2y3pPdU+2EVw/yzfRsBdu+6+USGa4PxqSQRYIUC9/NcT06y+ZgaTsyURw2I9qOFaaXHAg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vueuse/shared/-/shared-10.4.1.tgz} + name: '@vueuse/shared' + version: 10.4.1 + + '@zxcvbn-ts/core@https://registry.npmmirror.com/@zxcvbn-ts/core/-/core-3.0.4.tgz': + resolution: {integrity: sha512-aQeiT0F09FuJaAqNrxynlAwZ2mW/1MdXakKWNmGM1Qp/VaY6CnB/GfnMS2T8gB2231Esp1/maCWd8vTG4OuShw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@zxcvbn-ts/core/-/core-3.0.4.tgz} + name: '@zxcvbn-ts/core' + version: 3.0.4 + + JSONStream@https://registry.npmmirror.com/JSONStream/-/JSONStream-1.3.5.tgz: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/JSONStream/-/JSONStream-1.3.5.tgz} + name: JSONStream + version: 1.3.5 + hasBin: true + + abab@https://registry.npmmirror.com/abab/-/abab-2.0.6.tgz: + resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/abab/-/abab-2.0.6.tgz} + name: abab + version: 2.0.6 + + abbrev@https://registry.npmmirror.com/abbrev/-/abbrev-1.1.1.tgz: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/abbrev/-/abbrev-1.1.1.tgz} + name: abbrev + version: 1.1.1 + + acorn-globals@https://registry.npmmirror.com/acorn-globals/-/acorn-globals-6.0.0.tgz: + resolution: {integrity: sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/acorn-globals/-/acorn-globals-6.0.0.tgz} + name: acorn-globals + version: 6.0.0 + + acorn-walk@https://registry.npmmirror.com/acorn-walk/-/acorn-walk-7.2.0.tgz: + resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/acorn-walk/-/acorn-walk-7.2.0.tgz} + name: acorn-walk + version: 7.2.0 + engines: {node: '>=0.4.0'} + + acorn-walk@https://registry.npmmirror.com/acorn-walk/-/acorn-walk-8.2.0.tgz: + resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/acorn-walk/-/acorn-walk-8.2.0.tgz} + name: acorn-walk + version: 8.2.0 + engines: {node: '>=0.4.0'} + + acorn@8.10.0: + resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + engines: {node: '>=0.4.0'} + hasBin: true + + acorn@https://registry.npmmirror.com/acorn/-/acorn-7.4.1.tgz: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/acorn/-/acorn-7.4.1.tgz} + name: acorn + version: 7.4.1 + engines: {node: '>=0.4.0'} + hasBin: true + + acorn@https://registry.npmmirror.com/acorn/-/acorn-8.10.0.tgz: + resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/acorn/-/acorn-8.10.0.tgz} + name: acorn + version: 8.10.0 + engines: {node: '>=0.4.0'} + hasBin: true + + adler-32@1.3.1: + resolution: {integrity: sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==} + engines: {node: '>=0.8'} + + agent-base@https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz} + name: agent-base + version: 6.0.2 + engines: {node: '>= 6.0.0'} + + aggregate-error@https://registry.npmmirror.com/aggregate-error/-/aggregate-error-3.1.0.tgz: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/aggregate-error/-/aggregate-error-3.1.0.tgz} + name: aggregate-error + version: 3.1.0 + engines: {node: '>=8'} + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ajv@8.12.0: + resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} + + ajv@https://registry.npmmirror.com/ajv/-/ajv-8.12.0.tgz: + resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ajv/-/ajv-8.12.0.tgz} + name: ajv + version: 8.12.0 + + ansi-escapes@https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz} + name: ansi-escapes + version: 4.3.2 + engines: {node: '>=8'} + + ansi-regex@2.1.1: + resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} + engines: {node: '>=0.10.0'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + ansi-regex@https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz} + name: ansi-regex + version: 5.0.1 + engines: {node: '>=8'} + + ansi-regex@https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.0.1.tgz: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.0.1.tgz} + name: ansi-regex + version: 6.0.1 + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@https://registry.npmmirror.com/ansi-styles/-/ansi-styles-2.2.1.tgz: + resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-2.2.1.tgz} + name: ansi-styles + version: 2.2.1 + engines: {node: '>=0.10.0'} + + ansi-styles@https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz} + name: ansi-styles + version: 3.2.1 + engines: {node: '>=4'} + + ansi-styles@https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz} + name: ansi-styles + version: 4.3.0 + engines: {node: '>=8'} + + ansi-styles@https://registry.npmmirror.com/ansi-styles/-/ansi-styles-5.2.0.tgz: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-5.2.0.tgz} + name: ansi-styles + version: 5.2.0 + engines: {node: '>=10'} + + ansi-styles@https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.1.tgz: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.1.tgz} + name: ansi-styles + version: 6.2.1 + engines: {node: '>=12'} + + ant-design-vue@https://registry.npmmirror.com/ant-design-vue/-/ant-design-vue-4.0.6.tgz: + resolution: {integrity: sha512-6kh3b8Ito9SAbOKTW0wyfcCnd859uhQQlttjo8RjMj6YjLK52yNO2TdgYRwed06scUm5RwEnQ2JKMxYYoeG1MA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ant-design-vue/-/ant-design-vue-4.0.6.tgz} + name: ant-design-vue + version: 4.0.6 + engines: {node: '>=12.22.0'} + peerDependencies: + vue: '>=3.2.0' + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + anymatch@https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz} + name: anymatch + version: 3.1.3 + engines: {node: '>= 8'} + + archiver-utils@2.1.0: + resolution: {integrity: sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==} + engines: {node: '>= 6'} + + archiver@5.3.2: + resolution: {integrity: sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==} + engines: {node: '>= 10'} + + arg@https://registry.npmmirror.com/arg/-/arg-4.1.3.tgz: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/arg/-/arg-4.1.3.tgz} + name: arg + version: 4.1.3 + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + argparse@https://registry.npmmirror.com/argparse/-/argparse-1.0.10.tgz: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/argparse/-/argparse-1.0.10.tgz} + name: argparse + version: 1.0.10 + + argparse@https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz} + name: argparse + version: 2.0.1 + + arr-diff@4.0.0: + resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} + engines: {node: '>=0.10.0'} + + arr-flatten@1.1.0: + resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} + engines: {node: '>=0.10.0'} + + arr-union@3.1.0: + resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} + engines: {node: '>=0.10.0'} + + array-ify@https://registry.npmmirror.com/array-ify/-/array-ify-1.0.0.tgz: + resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/array-ify/-/array-ify-1.0.0.tgz} + name: array-ify + version: 1.0.0 + + array-move@3.0.1: + resolution: {integrity: sha512-H3Of6NIn2nNU1gsVDqDnYKY/LCdWvCMMOWifNGhKcVQgiZ6nOek39aESOvro6zmueP07exSl93YLvkN4fZOkSg==, tarball: https://registry.npmmirror.com/array-move/-/array-move-3.0.1.tgz} + engines: {node: '>=10'} + + array-tree-filter@https://registry.npmmirror.com/array-tree-filter/-/array-tree-filter-2.1.0.tgz: + resolution: {integrity: sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/array-tree-filter/-/array-tree-filter-2.1.0.tgz} + name: array-tree-filter + version: 2.1.0 + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + array-unique@0.3.2: + resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} + engines: {node: '>=0.10.0'} + + arrify@1.0.1: + resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} + engines: {node: '>=0.10.0'} + + arrify@https://registry.npmmirror.com/arrify/-/arrify-1.0.1.tgz: + resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/arrify/-/arrify-1.0.1.tgz} + name: arrify + version: 1.0.1 + engines: {node: '>=0.10.0'} + + assign-symbols@1.0.0: + resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} + engines: {node: '>=0.10.0'} + + ast-kit@0.10.0: + resolution: {integrity: sha512-8y01XClpURgvxTJmM4AY2oHa1B/6iysALB9yJM1j4ak3Z2ZsnU0ewjDZzqOHdbNdit6hC0DGZNrBqNuCrv51fQ==} + engines: {node: '>=16.14.0'} + + ast-kit@0.9.5: + resolution: {integrity: sha512-kbL7ERlqjXubdDd+szuwdlQ1xUxEz9mCz1+m07ftNVStgwRb2RWw+U6oKo08PAvOishMxiqz1mlJyLl8yQx2Qg==} + engines: {node: '>=16.14.0'} + + ast-walker-scope@0.5.0: + resolution: {integrity: sha512-NsyHMxBh4dmdEHjBo1/TBZvCKxffmZxRYhmclfu0PP6Aftre47jOHYaYaNqJcV0bxihxFXhDkzLHUwHc0ocd0Q==} + engines: {node: '>=16.14.0'} + + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + + astral-regex@https://registry.npmmirror.com/astral-regex/-/astral-regex-2.0.0.tgz: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/astral-regex/-/astral-regex-2.0.0.tgz} + name: astral-regex + version: 2.0.0 + engines: {node: '>=8'} + + async-validator@https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz: + resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz} + name: async-validator + version: 4.2.5 + + async@3.2.4: + resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} + + asynckit@https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz} + name: asynckit + version: 0.4.0 + + atob@2.1.2: + resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} + engines: {node: '>= 4.5.0'} + hasBin: true + + axios@https://registry.npmmirror.com/axios/-/axios-0.26.1.tgz: + resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/axios/-/axios-0.26.1.tgz} + name: axios + version: 0.26.1 + + axios@https://registry.npmmirror.com/axios/-/axios-1.5.0.tgz: + resolution: {integrity: sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/axios/-/axios-1.5.0.tgz} + name: axios + version: 1.5.0 + + babel-jest@https://registry.npmmirror.com/babel-jest/-/babel-jest-27.5.1.tgz: + resolution: {integrity: sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/babel-jest/-/babel-jest-27.5.1.tgz} + name: babel-jest + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + + babel-plugin-istanbul@https://registry.npmmirror.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz} + name: babel-plugin-istanbul + version: 6.1.1 + engines: {node: '>=8'} + + babel-plugin-jest-hoist@https://registry.npmmirror.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz: + resolution: {integrity: sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz} + name: babel-plugin-jest-hoist + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + babel-preset-current-node-syntax@https://registry.npmmirror.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz: + resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz} + name: babel-preset-current-node-syntax + version: 1.0.1 + peerDependencies: + '@babel/core': ^7.0.0 + + babel-preset-jest@https://registry.npmmirror.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz: + resolution: {integrity: sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz} + name: babel-preset-jest + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@2.0.0: + resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==} + + balanced-match@https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz} + name: balanced-match + version: 1.0.2 + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + base@0.11.2: + resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} + engines: {node: '>=0.10.0'} + + big-integer@1.6.51: + resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} + engines: {node: '>=0.6'} + + big-integer@https://registry.npmmirror.com/big-integer/-/big-integer-1.6.51.tgz: + resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/big-integer/-/big-integer-1.6.51.tgz} + name: big-integer + version: 1.6.51 + engines: {node: '>=0.6'} + + big.js@5.2.2: + resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} + + binary-extensions@2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + + binary-extensions@https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz} + name: binary-extensions + version: 2.2.0 + engines: {node: '>=8'} + + binary@0.3.0: + resolution: {integrity: sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + bluebird@3.4.7: + resolution: {integrity: sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==} + + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + bplist-parser@https://registry.npmmirror.com/bplist-parser/-/bplist-parser-0.2.0.tgz: + resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/bplist-parser/-/bplist-parser-0.2.0.tgz} + name: bplist-parser + version: 0.2.0 + engines: {node: '>= 5.10.0'} + + bpmn-js-properties-panel@5.6.1: + resolution: {integrity: sha512-UzW2/O7HsBNoYYSDA0Rc9CWnyTfMmxliwlsA3aTPVwvVQAkCiU2O3OBsX+XiX5INK2/0RLF7hfNRlO3Ef2h5bw==, tarball: https://registry.npmmirror.com/bpmn-js-properties-panel/-/bpmn-js-properties-panel-5.6.1.tgz} + peerDependencies: + '@bpmn-io/properties-panel': '>= 3.7' + bpmn-js: '>= 11.5' + camunda-bpmn-js-behaviors: '>= 0.4' + diagram-js: '>= 11.9' + + bpmn-js@16.1.0: + resolution: {integrity: sha512-K1REegXEPuKisZteFodNna2m2CMKx5aTljqa89V5UprN5AMRqcEKB2L+1gH0m6iQpTMy4NTxZQi8yY2D2PrLWQ==, tarball: https://registry.npmmirror.com/bpmn-js/-/bpmn-js-16.1.0.tgz} + + bpmn-moddle@8.0.1: + resolution: {integrity: sha512-mwZcrWhi52+JH5Oq58WwKYcUxQ1ZMiDQuzt1bpqiqEEFFnQLqCgtLwEXQuDXFmAuQPdMAghyPzqdOZQqIQVesw==, tarball: https://registry.npmmirror.com/bpmn-moddle/-/bpmn-moddle-8.0.1.tgz} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + brace-expansion@https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz} + name: brace-expansion + version: 1.1.11 + + brace-expansion@https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz} + name: brace-expansion + version: 2.0.1 + + braces@2.3.2: + resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} + engines: {node: '>=0.10.0'} + + braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + + braces@https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz} + name: braces + version: 3.0.2 + engines: {node: '>=8'} + + browser-process-hrtime@https://registry.npmmirror.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz: + resolution: {integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz} + name: browser-process-hrtime + version: 1.0.0 + + browserslist@4.21.10: + resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + browserslist@https://registry.npmmirror.com/browserslist/-/browserslist-4.21.10.tgz: + resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/browserslist/-/browserslist-4.21.10.tgz} + name: browserslist + version: 4.21.10 + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bser@https://registry.npmmirror.com/bser/-/bser-2.1.1.tgz: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/bser/-/bser-2.1.1.tgz} + name: bser + version: 2.1.1 + + buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer-from@https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz} + name: buffer-from + version: 1.1.2 + + buffer-indexof-polyfill@1.0.2: + resolution: {integrity: sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==} + engines: {node: '>=0.10'} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + buffers@0.1.1: + resolution: {integrity: sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==} + engines: {node: '>=0.2.0'} + + builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + + bundle-name@https://registry.npmmirror.com/bundle-name/-/bundle-name-3.0.0.tgz: + resolution: {integrity: sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/bundle-name/-/bundle-name-3.0.0.tgz} + name: bundle-name + version: 3.0.0 + engines: {node: '>=12'} + + bundle-require@4.0.1: + resolution: {integrity: sha512-9NQkRHlNdNpDBGmLpngF3EFDcwodhMUuLz9PaWYciVcQF9SE4LFjM2DB/xV1Li5JiuDMv7ZUWuC3rGbqR0MAXQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.17' + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + cache-base@1.0.1: + resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} + engines: {node: '>=0.10.0'} + + call-bind@1.0.2: + resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + callsites@https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz} + name: callsites + version: 3.1.0 + engines: {node: '>=6'} + + camel-case@4.1.2: + resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} + + camelcase-keys@7.0.2: + resolution: {integrity: sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==} + engines: {node: '>=12'} + + camelcase-keys@https://registry.npmmirror.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz: + resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz} + name: camelcase-keys + version: 6.2.2 + engines: {node: '>=8'} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + camelcase@https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz} + name: camelcase + version: 5.3.1 + engines: {node: '>=6'} + + camelcase@https://registry.npmmirror.com/camelcase/-/camelcase-6.3.0.tgz: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/camelcase/-/camelcase-6.3.0.tgz} + name: camelcase + version: 6.3.0 + engines: {node: '>=10'} + + camunda-bpmn-js-behaviors@1.2.2: + resolution: {integrity: sha512-BYbiKH5L3tMqpFOnmlIOp2QR/8ewNG0UOIOVafBYuZCiBOXr/XMl86gOF0aT994xdOGKO/6gdqc7+p8baAxcEw==, tarball: https://registry.npmmirror.com/camunda-bpmn-js-behaviors/-/camunda-bpmn-js-behaviors-1.2.2.tgz} + peerDependencies: + bpmn-js: '>= 9' + camunda-bpmn-moddle: '>= 7' + zeebe-bpmn-moddle: '>= 0.18' + + camunda-bpmn-moddle@7.0.1: + resolution: {integrity: sha512-Br8Diu6roMpziHdpl66Dhnm0DTnCFMrSD9zwLV08LpD52QA0UsXxU87XfHf08HjuB7ly0Hd1bvajZRpf9hbmYQ==, tarball: https://registry.npmmirror.com/camunda-bpmn-moddle/-/camunda-bpmn-moddle-7.0.1.tgz} + + caniuse-lite@1.0.30001524: + resolution: {integrity: sha512-Jj917pJtYg9HSJBF95HVX3Cdr89JUyLT4IZ8SvM5aDRni95swKgYi3TgYLH5hnGfPE/U1dg6IfZ50UsIlLkwSA==} + + caniuse-lite@https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001524.tgz: + resolution: {integrity: sha512-Jj917pJtYg9HSJBF95HVX3Cdr89JUyLT4IZ8SvM5aDRni95swKgYi3TgYLH5hnGfPE/U1dg6IfZ50UsIlLkwSA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001524.tgz} + name: caniuse-lite + version: 1.0.30001524 + + cfb@1.2.2: + resolution: {integrity: sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==} + engines: {node: '>=0.8'} + + chainsaw@0.1.0: + resolution: {integrity: sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + chalk@https://registry.npmmirror.com/chalk/-/chalk-1.1.3.tgz: + resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/chalk/-/chalk-1.1.3.tgz} + name: chalk + version: 1.1.3 + engines: {node: '>=0.10.0'} + + chalk@https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz} + name: chalk + version: 2.4.2 + engines: {node: '>=4'} + + chalk@https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz} + name: chalk + version: 4.1.2 + engines: {node: '>=10'} + + chalk@https://registry.npmmirror.com/chalk/-/chalk-5.2.0.tgz: + resolution: {integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/chalk/-/chalk-5.2.0.tgz} + name: chalk + version: 5.2.0 + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + char-regex@https://registry.npmmirror.com/char-regex/-/char-regex-1.0.2.tgz: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/char-regex/-/char-regex-1.0.2.tgz} + name: char-regex + version: 1.0.2 + engines: {node: '>=10'} + + chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + + chokidar@https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz} + name: chokidar + version: 3.5.3 + engines: {node: '>= 8.10.0'} + + ci-info@https://registry.npmmirror.com/ci-info/-/ci-info-3.8.0.tgz: + resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ci-info/-/ci-info-3.8.0.tgz} + name: ci-info + version: 3.8.0 + engines: {node: '>=8'} + + citty@0.1.3: + resolution: {integrity: sha512-tb6zTEb2BDSrzFedqFYFUKUuKNaxVJWCm7o02K4kADGkBDyyiz7D40rDMpguczdZyAN3aetd5fhpB01HkreNyg==} + + cjs-module-lexer@https://registry.npmmirror.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz: + resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz} + name: cjs-module-lexer + version: 1.2.3 + + class-utils@0.3.6: + resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} + engines: {node: '>=0.10.0'} + + classnames@2.3.2: + resolution: {integrity: sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==, tarball: https://registry.npmmirror.com/classnames/-/classnames-2.3.2.tgz} + + clean-css@5.3.2: + resolution: {integrity: sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==} + engines: {node: '>= 10.0'} + + clean-stack@https://registry.npmmirror.com/clean-stack/-/clean-stack-2.2.0.tgz: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/clean-stack/-/clean-stack-2.2.0.tgz} + name: clean-stack + version: 2.2.0 + engines: {node: '>=6'} + + cli-cursor@https://registry.npmmirror.com/cli-cursor/-/cli-cursor-3.1.0.tgz: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/cli-cursor/-/cli-cursor-3.1.0.tgz} + name: cli-cursor + version: 3.1.0 + engines: {node: '>=8'} + + cli-truncate@https://registry.npmmirror.com/cli-truncate/-/cli-truncate-2.1.0.tgz: + resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/cli-truncate/-/cli-truncate-2.1.0.tgz} + name: cli-truncate + version: 2.1.0 + engines: {node: '>=8'} + + cli-truncate@https://registry.npmmirror.com/cli-truncate/-/cli-truncate-3.1.0.tgz: + resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/cli-truncate/-/cli-truncate-3.1.0.tgz} + name: cli-truncate + version: 3.1.0 + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + cliui@https://registry.npmmirror.com/cliui/-/cliui-7.0.4.tgz: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/cliui/-/cliui-7.0.4.tgz} + name: cliui + version: 7.0.4 + + cliui@https://registry.npmmirror.com/cliui/-/cliui-8.0.1.tgz: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/cliui/-/cliui-8.0.1.tgz} + name: cliui + version: 8.0.1 + engines: {node: '>=12'} + + clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + + clsx@2.0.0: + resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==, tarball: https://registry.npmmirror.com/clsx/-/clsx-2.0.0.tgz} + engines: {node: '>=6'} + + co@https://registry.npmmirror.com/co/-/co-4.6.0.tgz: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/co/-/co-4.6.0.tgz} + name: co + version: 4.6.0 + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + code-block-writer@12.0.0: + resolution: {integrity: sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==} + + codemirror@https://registry.npmmirror.com/codemirror/-/codemirror-5.65.15.tgz: + resolution: {integrity: sha512-YC4EHbbwQeubZzxLl5G4nlbLc1T21QTrKGaOal/Pkm9dVDMZXMH7+ieSPEOZCtO9I68i8/oteJKOxzHC2zR+0g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/codemirror/-/codemirror-5.65.15.tgz} + name: codemirror + version: 5.65.15 + + codepage@1.15.0: + resolution: {integrity: sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==} + engines: {node: '>=0.8'} + + collect-v8-coverage@https://registry.npmmirror.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz: + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz} + name: collect-v8-coverage + version: 1.0.2 + + collection-visit@1.0.0: + resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} + engines: {node: '>=0.10.0'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-convert@https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz} + name: color-convert + version: 1.9.3 + + color-convert@https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz} + name: color-convert + version: 2.0.1 + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-name@https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz} + name: color-name + version: 1.1.3 + + color-name@https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz} + name: color-name + version: 1.1.4 + + colord@2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + colorette@https://registry.npmmirror.com/colorette/-/colorette-2.0.20.tgz: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/colorette/-/colorette-2.0.20.tgz} + name: colorette + version: 2.0.20 + + colors@1.2.5: + resolution: {integrity: sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==} + engines: {node: '>=0.1.90'} + + combined-stream@https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz} + name: combined-stream + version: 1.0.8 + engines: {node: '>= 0.8'} + + commander@11.0.0: + resolution: {integrity: sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==} + engines: {node: '>=16'} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + + commander@https://registry.npmmirror.com/commander/-/commander-10.0.1.tgz: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/commander/-/commander-10.0.1.tgz} + name: commander + version: 10.0.1 + engines: {node: '>=14'} + + commander@https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz} + name: commander + version: 2.20.3 + + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + + compare-func@https://registry.npmmirror.com/compare-func/-/compare-func-2.0.0.tgz: + resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/compare-func/-/compare-func-2.0.0.tgz} + name: compare-func + version: 2.0.0 + + component-emitter@1.3.0: + resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} + + component-event@0.2.1: + resolution: {integrity: sha512-wGA++isMqiDq1jPYeyv2as/Bt/u+3iLW0rEa+8NQ82jAv3TgqMiCM+B2SaBdn2DfLilLjjq736YcezihRYhfxw==, tarball: https://registry.npmmirror.com/component-event/-/component-event-0.2.1.tgz} + + compress-commons@4.1.1: + resolution: {integrity: sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==} + engines: {node: '>= 10'} + + compute-scroll-into-view@https://registry.npmmirror.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz: + resolution: {integrity: sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz} + name: compute-scroll-into-view + version: 1.0.20 + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + config-chain@https://registry.npmmirror.com/config-chain/-/config-chain-1.1.13.tgz: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/config-chain/-/config-chain-1.1.13.tgz} + name: config-chain + version: 1.1.13 + + connect-history-api-fallback@1.6.0: + resolution: {integrity: sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==} + engines: {node: '>=0.8'} + + connect@3.7.0: + resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==} + engines: {node: '>= 0.10.0'} + + connect@https://registry.npmmirror.com/connect/-/connect-3.7.0.tgz: + resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/connect/-/connect-3.7.0.tgz} + name: connect + version: 3.7.0 + engines: {node: '>= 0.10.0'} + + consola@2.15.3: + resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==} + + consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} + + conventional-changelog-angular@https://registry.npmmirror.com/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz: + resolution: {integrity: sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz} + name: conventional-changelog-angular + version: 6.0.0 + engines: {node: '>=14'} + + conventional-changelog-conventionalcommits@https://registry.npmmirror.com/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz: + resolution: {integrity: sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz} + name: conventional-changelog-conventionalcommits + version: 6.1.0 + engines: {node: '>=14'} + + conventional-commits-parser@https://registry.npmmirror.com/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz: + resolution: {integrity: sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz} + name: conventional-commits-parser + version: 4.0.0 + engines: {node: '>=14'} + hasBin: true + + convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + + convert-source-map@https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.9.0.tgz: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.9.0.tgz} + name: convert-source-map + version: 1.9.0 + + copy-anything@2.0.6: + resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==} + + copy-descriptor@0.1.1: + resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} + engines: {node: '>=0.10.0'} + + core-js@https://registry.npmmirror.com/core-js/-/core-js-3.32.1.tgz: + resolution: {integrity: sha512-lqufgNn9NLnESg5mQeYsxQP5w7wrViSj0jr/kv6ECQiByzQkrn1MKvV0L3acttpDqfQrHLwr2KCMgX5b8X+lyQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/core-js/-/core-js-3.32.1.tgz} + name: core-js + version: 3.32.1 + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + + cosmiconfig-typescript-loader@https://registry.npmmirror.com/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.4.0.tgz: + resolution: {integrity: sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.4.0.tgz} + name: cosmiconfig-typescript-loader + version: 4.4.0 + engines: {node: '>=v14.21.3'} + peerDependencies: + '@types/node': '*' + cosmiconfig: '>=7' + ts-node: '>=10' + typescript: '>=4' + + cosmiconfig@8.2.0: + resolution: {integrity: sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==} + engines: {node: '>=14'} + + cosmiconfig@https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-8.2.0.tgz: + resolution: {integrity: sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-8.2.0.tgz} + name: cosmiconfig + version: 8.2.0 + engines: {node: '>=14'} + + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + crc32-stream@4.0.2: + resolution: {integrity: sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==} + engines: {node: '>= 10'} + + create-require@https://registry.npmmirror.com/create-require/-/create-require-1.1.1.tgz: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/create-require/-/create-require-1.1.1.tgz} + name: create-require + version: 1.1.1 + + crelt@1.0.6: + resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==, tarball: https://registry.npmmirror.com/crelt/-/crelt-1.0.6.tgz} + + cropperjs@https://registry.npmmirror.com/cropperjs/-/cropperjs-1.6.0.tgz: + resolution: {integrity: sha512-BzLU/ecrfsbflwxgu+o7sQTrTlo52pVRZkTVrugEK5uyj6n8qKwAHP4s6+DWHqlXLqQ5B9+cM2MKeXiNfAsF6Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/cropperjs/-/cropperjs-1.6.0.tgz} + name: cropperjs + version: 1.6.0 + + cross-env@7.0.3: + resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} + engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} + hasBin: true + + cross-fetch@3.1.8: + resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + cross-spawn@https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz} + name: cross-spawn + version: 7.0.3 + engines: {node: '>= 8'} + + crypto-js@4.1.1: + resolution: {integrity: sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==} + + css-functions-list@3.2.0: + resolution: {integrity: sha512-d/jBMPyYybkkLVypgtGv12R+pIFw4/f/IHtCTxWpZc8ofTYOPigIgmA6vu5rMHartZC+WuXhBUHfnyNUIQSYrg==} + engines: {node: '>=12.22'} + + css-property-sort-order-smacss@2.2.0: + resolution: {integrity: sha512-nXutswsivIEBOrPo/OZw2KQjFPLvtg68aovJf6Kqrm3L6FmTvvFPaeDrk83hh0+pRJGuP3PeKJwMS0E6DFipdQ==} + + css-select@4.3.0: + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} + + css-tree@1.1.3: + resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} + engines: {node: '>=8.0.0'} + + css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csso@4.2.0: + resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==} + engines: {node: '>=8.0.0'} + + cssom@https://registry.npmmirror.com/cssom/-/cssom-0.3.8.tgz: + resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/cssom/-/cssom-0.3.8.tgz} + name: cssom + version: 0.3.8 + + cssom@https://registry.npmmirror.com/cssom/-/cssom-0.4.4.tgz: + resolution: {integrity: sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/cssom/-/cssom-0.4.4.tgz} + name: cssom + version: 0.4.4 + + cssstyle@https://registry.npmmirror.com/cssstyle/-/cssstyle-2.3.0.tgz: + resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/cssstyle/-/cssstyle-2.3.0.tgz} + name: cssstyle + version: 2.3.0 + engines: {node: '>=8'} + + csstype@2.6.21: + resolution: {integrity: sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==} + + csstype@3.1.2: + resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} + + csstype@https://registry.npmmirror.com/csstype/-/csstype-3.1.2.tgz: + resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/csstype/-/csstype-3.1.2.tgz} + name: csstype + version: 3.1.2 + + cz-git@https://registry.npmmirror.com/cz-git/-/cz-git-1.7.1.tgz: + resolution: {integrity: sha512-NMe4REukCS7op1YA1jixRXOgII8Um2/Ii8TeyFEOISgp2ZzeobzkMOP8dXSrTQ3bvmm7YpPOdr2301yJkOJcbA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/cz-git/-/cz-git-1.7.1.tgz} + name: cz-git + version: 1.7.1 + engines: {node: '>=v12.20.0'} + + czg@https://registry.npmmirror.com/czg/-/czg-1.7.1.tgz: + resolution: {integrity: sha512-KP93cTbZxgWYDKJzZpjnLe0sy/2FwyegatnrOaqsath04WinvsdhZl5QCGkxTKBY2DavpKloIBW/WGZzCKmrlA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/czg/-/czg-1.7.1.tgz} + name: czg + version: 1.7.1 + engines: {node: '>=v12.20.0'} + hasBin: true + + dargs@https://registry.npmmirror.com/dargs/-/dargs-7.0.0.tgz: + resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/dargs/-/dargs-7.0.0.tgz} + name: dargs + version: 7.0.0 + engines: {node: '>=8'} + + data-urls@https://registry.npmmirror.com/data-urls/-/data-urls-2.0.0.tgz: + resolution: {integrity: sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/data-urls/-/data-urls-2.0.0.tgz} + name: data-urls + version: 2.0.0 + engines: {node: '>=10'} + + dayjs@1.11.9: + resolution: {integrity: sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==} + + dayjs@https://registry.npmmirror.com/dayjs/-/dayjs-1.11.9.tgz: + resolution: {integrity: sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/dayjs/-/dayjs-1.11.9.tgz} + name: dayjs + version: 1.11.9 + + de-indent@https://registry.npmmirror.com/de-indent/-/de-indent-1.0.2.tgz: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/de-indent/-/de-indent-1.0.2.tgz} + name: de-indent + version: 1.0.2 + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz} + name: debug + version: 2.6.9 + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz} + name: debug + version: 3.2.7 + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz} + name: debug + version: 4.3.4 + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize-keys@1.1.1: + resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} + engines: {node: '>=0.10.0'} + + decamelize-keys@https://registry.npmmirror.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz: + resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz} + name: decamelize-keys + version: 1.1.1 + engines: {node: '>=0.10.0'} + + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + decamelize@5.0.1: + resolution: {integrity: sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==} + engines: {node: '>=10'} + + decamelize@https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz} + name: decamelize + version: 1.2.0 + engines: {node: '>=0.10.0'} + + decimal.js@https://registry.npmmirror.com/decimal.js/-/decimal.js-10.4.3.tgz: + resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/decimal.js/-/decimal.js-10.4.3.tgz} + name: decimal.js + version: 10.4.3 + + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + + dedent@https://registry.npmmirror.com/dedent/-/dedent-0.7.0.tgz: + resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/dedent/-/dedent-0.7.0.tgz} + name: dedent + version: 0.7.0 + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + deepmerge@https://registry.npmmirror.com/deepmerge/-/deepmerge-4.3.1.tgz: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/deepmerge/-/deepmerge-4.3.1.tgz} + name: deepmerge + version: 4.3.1 + engines: {node: '>=0.10.0'} + + default-browser-id@https://registry.npmmirror.com/default-browser-id/-/default-browser-id-3.0.0.tgz: + resolution: {integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/default-browser-id/-/default-browser-id-3.0.0.tgz} + name: default-browser-id + version: 3.0.0 + engines: {node: '>=12'} + + default-browser@https://registry.npmmirror.com/default-browser/-/default-browser-4.0.0.tgz: + resolution: {integrity: sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/default-browser/-/default-browser-4.0.0.tgz} + name: default-browser + version: 4.0.0 + engines: {node: '>=14.16'} + + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + + define-lazy-prop@https://registry.npmmirror.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz} + name: define-lazy-prop + version: 3.0.0 + engines: {node: '>=12'} + + define-property@0.2.5: + resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} + engines: {node: '>=0.10.0'} + + define-property@1.0.0: + resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} + engines: {node: '>=0.10.0'} + + define-property@2.0.2: + resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} + engines: {node: '>=0.10.0'} + + defu@6.1.2: + resolution: {integrity: sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ==} + + delayed-stream@https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz} + name: delayed-stream + version: 1.0.0 + engines: {node: '>=0.4.0'} + + destr@2.0.1: + resolution: {integrity: sha512-M1Ob1zPSIvlARiJUkKqvAZ3VAqQY6Jcuth/pBKQ2b1dX/Qx0OnJ8Vux6J2H5PTMQeRzWrrbTu70VxBfv/OPDJA==} + + detect-indent@https://registry.npmmirror.com/detect-indent/-/detect-indent-7.0.1.tgz: + resolution: {integrity: sha512-Mc7QhQ8s+cLrnUfU/Ji94vG/r8M26m8f++vyres4ZoojaRDpZ1eSIh/EpzLNwlWuvzSZ3UbDFspjFvTDXe6e/g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/detect-indent/-/detect-indent-7.0.1.tgz} + name: detect-indent + version: 7.0.1 + engines: {node: '>=12.20'} + + detect-newline@https://registry.npmmirror.com/detect-newline/-/detect-newline-3.1.0.tgz: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/detect-newline/-/detect-newline-3.1.0.tgz} + name: detect-newline + version: 3.1.0 + engines: {node: '>=8'} + + detect-newline@https://registry.npmmirror.com/detect-newline/-/detect-newline-4.0.0.tgz: + resolution: {integrity: sha512-1aXUEPdfGdzVPFpzGJJNgq9o81bGg1s09uxTWsqBlo9PI332uyJRQq13+LK/UN4JfxJbFdCXonUFQ9R/p7yCtw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/detect-newline/-/detect-newline-4.0.0.tgz} + name: detect-newline + version: 4.0.0 + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + diagram-js-direct-editing@2.1.1: + resolution: {integrity: sha512-XuNWIpcuUMayp/MZhNRLyJT7zikSvGr8RZWNrHsDpwOIjoRgfYmmJp8WRFCIflMSBHjFg62sqLNM/nXRKrZ2qw==, tarball: https://registry.npmmirror.com/diagram-js-direct-editing/-/diagram-js-direct-editing-2.1.1.tgz} + peerDependencies: + diagram-js: '*' + + diagram-js-grid-bg@1.0.4: + resolution: {integrity: sha512-9epW59tRJkDNKdy/u8Er0GCmKOo1tMRYVBiAng0GOc4+FmJQKhnAHH+EF77v0XOdGDLHe6ljVD+gwEzs3kuKYQ==, tarball: https://registry.npmmirror.com/diagram-js-grid-bg/-/diagram-js-grid-bg-1.0.4.tgz} + + diagram-js-minimap@4.1.0: + resolution: {integrity: sha512-osuQ7ETbhmlqoMU2g7OsXRYEeyXJihGbhv5WtcsSAN4vvxSrqZm7ndwXoHPV1Q1j3e2kfOuBRU2X4WUG0qewig==, tarball: https://registry.npmmirror.com/diagram-js-minimap/-/diagram-js-minimap-4.1.0.tgz} + + diagram-js@13.4.0: + resolution: {integrity: sha512-JI6UI74J3TgRcgBhuZZJso//bUdh22rcVu9XSf1EBVisKPt9c+woKzOrr/79OutXvft+1NOLNEiBg58kZ8p7+Q==, tarball: https://registry.npmmirror.com/diagram-js/-/diagram-js-13.4.0.tgz} + + didi@10.0.1: + resolution: {integrity: sha512-rddmyUjpIh8pIu9OVtqQjGkZB4jNOaaRMz9AClSH3WUEOoJctxpFmqjTButmI5na5sSIDpfjABe34wEvEhrjcg==, tarball: https://registry.npmmirror.com/didi/-/didi-10.0.1.tgz} + engines: {node: '>= 16'} + + diff-match-patch@https://registry.npmmirror.com/diff-match-patch/-/diff-match-patch-1.0.5.tgz: + resolution: {integrity: sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/diff-match-patch/-/diff-match-patch-1.0.5.tgz} + name: diff-match-patch + version: 1.0.5 + + diff-sequences@https://registry.npmmirror.com/diff-sequences/-/diff-sequences-27.5.1.tgz: + resolution: {integrity: sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/diff-sequences/-/diff-sequences-27.5.1.tgz} + name: diff-sequences + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + diff@https://registry.npmmirror.com/diff/-/diff-4.0.2.tgz: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/diff/-/diff-4.0.2.tgz} + name: diff + version: 4.0.2 + engines: {node: '>=0.3.1'} + + dijkstrajs@1.0.3: + resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dir-glob@https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz} + name: dir-glob + version: 3.0.1 + engines: {node: '>=8'} + + dom-align@https://registry.npmmirror.com/dom-align/-/dom-align-1.12.4.tgz: + resolution: {integrity: sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/dom-align/-/dom-align-1.12.4.tgz} + name: dom-align + version: 1.12.4 + + dom-scroll-into-view@https://registry.npmmirror.com/dom-scroll-into-view/-/dom-scroll-into-view-2.0.1.tgz: + resolution: {integrity: sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/dom-scroll-into-view/-/dom-scroll-into-view-2.0.1.tgz} + name: dom-scroll-into-view + version: 2.0.1 + + dom-serializer@0.2.2: + resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==} + + dom-serializer@1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + dom-zindex@https://registry.npmmirror.com/dom-zindex/-/dom-zindex-1.0.1.tgz: + resolution: {integrity: sha512-M/MERVDZ8hguvjl6MAlLWSLYLS7PzEyXaTb5gEeJ+SF+e9iUC0sdvlzqe91MMDHBoy+nqw7wKcUOrDSyvMCrRg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/dom-zindex/-/dom-zindex-1.0.1.tgz} + name: dom-zindex + version: 1.0.1 + + domelementtype@1.3.1: + resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domexception@https://registry.npmmirror.com/domexception/-/domexception-2.0.1.tgz: + resolution: {integrity: sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/domexception/-/domexception-2.0.1.tgz} + name: domexception + version: 2.0.1 + engines: {node: '>=8'} + + domhandler@2.4.2: + resolution: {integrity: sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==} + + domhandler@4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} + engines: {node: '>= 4'} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domify@1.4.2: + resolution: {integrity: sha512-m4yreHcUWHBncGVV7U+yQzc12vIlq0jMrtHZ5mW6dQMiL/7skSYNVX9wqKwOtyO9SGCgevrAFEgOCAHmamHTUA==, tarball: https://registry.npmmirror.com/domify/-/domify-1.4.2.tgz} + + domutils@1.7.0: + resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==} + + domutils@2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + + domutils@3.1.0: + resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + + dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + + dot-prop@https://registry.npmmirror.com/dot-prop/-/dot-prop-5.3.0.tgz: + resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/dot-prop/-/dot-prop-5.3.0.tgz} + name: dot-prop + version: 5.3.0 + engines: {node: '>=8'} + + dotenv-expand@8.0.3: + resolution: {integrity: sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg==} + engines: {node: '>=12'} + + dotenv@16.3.1: + resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} + engines: {node: '>=12'} + + duplexer2@0.1.4: + resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} + + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + + eastasianwidth@https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz} + name: eastasianwidth + version: 0.2.0 + + echarts@https://registry.npmmirror.com/echarts/-/echarts-5.4.3.tgz: + resolution: {integrity: sha512-mYKxLxhzy6zyTi/FaEbJMOZU1ULGEQHaeIeuMR5L+JnJTpz+YR03mnnpBhbR4+UYJAgiXgpyTVLffPAjOTLkZA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/echarts/-/echarts-5.4.3.tgz} + name: echarts + version: 5.4.3 + + editorconfig@https://registry.npmmirror.com/editorconfig/-/editorconfig-1.0.4.tgz: + resolution: {integrity: sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/editorconfig/-/editorconfig-1.0.4.tgz} + name: editorconfig + version: 1.0.4 + engines: {node: '>=14'} + hasBin: true + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + ee-first@https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz} + name: ee-first + version: 1.1.1 + + ejs@3.1.9: + resolution: {integrity: sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==} + engines: {node: '>=0.10.0'} + hasBin: true + + electron-to-chromium@1.4.505: + resolution: {integrity: sha512-0A50eL5BCCKdxig2SsCXhpuztnB9PfUgRMojj5tMvt8O54lbwz3t6wNgnpiTRosw5QjlJB7ixhVyeg8daLQwSQ==} + + electron-to-chromium@https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.505.tgz: + resolution: {integrity: sha512-0A50eL5BCCKdxig2SsCXhpuztnB9PfUgRMojj5tMvt8O54lbwz3t6wNgnpiTRosw5QjlJB7ixhVyeg8daLQwSQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.505.tgz} + name: electron-to-chromium + version: 1.4.505 + + emittery@https://registry.npmmirror.com/emittery/-/emittery-0.8.1.tgz: + resolution: {integrity: sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/emittery/-/emittery-0.8.1.tgz} + name: emittery + version: 0.8.1 + engines: {node: '>=10'} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz} + name: emoji-regex + version: 8.0.0 + + emoji-regex@https://registry.npmmirror.com/emoji-regex/-/emoji-regex-9.2.2.tgz: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/emoji-regex/-/emoji-regex-9.2.2.tgz} + name: emoji-regex + version: 9.2.2 + + emojis-list@3.0.0: + resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} + engines: {node: '>= 4'} + + encode-utf8@1.0.3: + resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} + + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + encodeurl@https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz} + name: encodeurl + version: 1.0.2 + engines: {node: '>= 0.8'} + + end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + + entities@1.1.2: + resolution: {integrity: sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==} + + entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + errno@0.1.8: + resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==, tarball: https://registry.npmmirror.com/errno/-/errno-0.1.8.tgz} + hasBin: true + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + error-ex@https://registry.npmmirror.com/error-ex/-/error-ex-1.3.2.tgz: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/error-ex/-/error-ex-1.3.2.tgz} + name: error-ex + version: 1.3.2 + + esbuild-android-64@0.14.54: + resolution: {integrity: sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==, tarball: https://registry.npmmirror.com/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + esbuild-android-arm64@0.14.54: + resolution: {integrity: sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==, tarball: https://registry.npmmirror.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + esbuild-darwin-64@0.14.54: + resolution: {integrity: sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==, tarball: https://registry.npmmirror.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + esbuild-darwin-arm64@0.14.54: + resolution: {integrity: sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==, tarball: https://registry.npmmirror.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + esbuild-freebsd-64@0.14.54: + resolution: {integrity: sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==, tarball: https://registry.npmmirror.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + esbuild-freebsd-arm64@0.14.54: + resolution: {integrity: sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==, tarball: https://registry.npmmirror.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + esbuild-linux-32@0.14.54: + resolution: {integrity: sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==, tarball: https://registry.npmmirror.com/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + esbuild-linux-64@0.14.54: + resolution: {integrity: sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==, tarball: https://registry.npmmirror.com/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + esbuild-linux-arm64@0.14.54: + resolution: {integrity: sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==, tarball: https://registry.npmmirror.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + esbuild-linux-arm@0.14.54: + resolution: {integrity: sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==, tarball: https://registry.npmmirror.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + esbuild-linux-mips64le@0.14.54: + resolution: {integrity: sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==, tarball: https://registry.npmmirror.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + esbuild-linux-ppc64le@0.14.54: + resolution: {integrity: sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==, tarball: https://registry.npmmirror.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + esbuild-linux-riscv64@0.14.54: + resolution: {integrity: sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==, tarball: https://registry.npmmirror.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + esbuild-linux-s390x@0.14.54: + resolution: {integrity: sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==, tarball: https://registry.npmmirror.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + esbuild-netbsd-64@0.14.54: + resolution: {integrity: sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==, tarball: https://registry.npmmirror.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + esbuild-openbsd-64@0.14.54: + resolution: {integrity: sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==, tarball: https://registry.npmmirror.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + esbuild-sunos-64@0.14.54: + resolution: {integrity: sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==, tarball: https://registry.npmmirror.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + esbuild-windows-32@0.14.54: + resolution: {integrity: sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==, tarball: https://registry.npmmirror.com/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + esbuild-windows-64@0.14.54: + resolution: {integrity: sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==, tarball: https://registry.npmmirror.com/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + esbuild-windows-arm64@0.14.54: + resolution: {integrity: sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==, tarball: https://registry.npmmirror.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + esbuild@0.17.19: + resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} + engines: {node: '>=12'} + hasBin: true + + esbuild@0.18.20: + resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} + engines: {node: '>=12'} + hasBin: true + + esbuild@0.19.2: + resolution: {integrity: sha512-G6hPax8UbFakEj3hWO0Vs52LQ8k3lnBhxZWomUJDxfz3rZTLqF5k/FCzuNdLx2RbpBiQQF9H9onlDDH1lZsnjg==, tarball: https://registry.npmmirror.com/esbuild/-/esbuild-0.19.2.tgz} + engines: {node: '>=12'} + hasBin: true + + esbuild@https://registry.npmmirror.com/esbuild/-/esbuild-0.14.54.tgz: + resolution: {integrity: sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild/-/esbuild-0.14.54.tgz} + name: esbuild + version: 0.14.54 + engines: {node: '>=12'} + hasBin: true + + esbuild@https://registry.npmmirror.com/esbuild/-/esbuild-0.18.20.tgz: + resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild/-/esbuild-0.18.20.tgz} + name: esbuild + version: 0.18.20 + engines: {node: '>=12'} + hasBin: true + + escalade@3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + + escalade@https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz} + name: escalade + version: 3.1.1 + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-html@https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz} + name: escape-html + version: 1.0.3 + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz} + name: escape-string-regexp + version: 2.0.0 + engines: {node: '>=8'} + + escodegen@https://registry.npmmirror.com/escodegen/-/escodegen-2.1.0.tgz: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/escodegen/-/escodegen-2.1.0.tgz} + name: escodegen + version: 2.1.0 + engines: {node: '>=6.0'} + hasBin: true + + esprima@https://registry.npmmirror.com/esprima/-/esprima-4.0.1.tgz: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esprima/-/esprima-4.0.1.tgz} + name: esprima + version: 4.0.1 + engines: {node: '>=4'} + hasBin: true + + estraverse@https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz} + name: estraverse + version: 5.3.0 + engines: {node: '>=4.0'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + estree-walker@https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz} + name: estree-walker + version: 2.0.2 + + esutils@https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz} + name: esutils + version: 2.0.3 + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + exceljs@4.3.0: + resolution: {integrity: sha512-hTAeo5b5TPvf8Z02I2sKIT4kSfCnOO2bCxYX8ABqODCdAjppI3gI9VYiGCQQYVcBaBSKlFDMKlAQRqC+kV9O8w==} + engines: {node: '>=8.3.0'} + + execa@https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz} + name: execa + version: 5.1.1 + engines: {node: '>=10'} + + execa@https://registry.npmmirror.com/execa/-/execa-7.2.0.tgz: + resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/execa/-/execa-7.2.0.tgz} + name: execa + version: 7.2.0 + engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} + + exit@https://registry.npmmirror.com/exit/-/exit-0.1.2.tgz: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/exit/-/exit-0.1.2.tgz} + name: exit + version: 0.1.2 + engines: {node: '>= 0.8.0'} + + expand-brackets@2.1.4: + resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} + engines: {node: '>=0.10.0'} + + expect@https://registry.npmmirror.com/expect/-/expect-27.5.1.tgz: + resolution: {integrity: sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/expect/-/expect-27.5.1.tgz} + name: expect + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend-shallow@3.0.2: + resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} + engines: {node: '>=0.10.0'} + + extglob@2.0.4: + resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} + engines: {node: '>=0.10.0'} + + fast-csv@4.3.6: + resolution: {integrity: sha512-2RNSpuwwsJGP0frGsOmTb9oUF+VkFSM4SyLTDgwf2ciHWTarN0lQTC+F2f/t5J9QjW+c65VFIAAu85GsvMIusw==} + engines: {node: '>=10.0.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-deep-equal@https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz} + name: fast-deep-equal + version: 3.1.3 + + fast-diff@1.2.0: + resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==} + + fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + + fast-glob@https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.1.tgz: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.1.tgz} + name: fast-glob + version: 3.3.1 + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-json-stable-stringify@https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz} + name: fast-json-stable-stringify + version: 2.1.0 + + fastest-levenshtein@1.0.16: + resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} + engines: {node: '>= 4.9.1'} + + fastest-levenshtein@https://registry.npmmirror.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz: + resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz} + name: fastest-levenshtein + version: 1.0.16 + engines: {node: '>= 4.9.1'} + + fastq@1.15.0: + resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + + fastq@https://registry.npmmirror.com/fastq/-/fastq-1.15.0.tgz: + resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/fastq/-/fastq-1.15.0.tgz} + name: fastq + version: 1.15.0 + + fb-watchman@https://registry.npmmirror.com/fb-watchman/-/fb-watchman-2.0.2.tgz: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/fb-watchman/-/fb-watchman-2.0.2.tgz} + name: fb-watchman + version: 2.0.2 + + feelers@1.2.0: + resolution: {integrity: sha512-EPw88XH1UUt4A5JmBrJN3dmCMAxSi54juFuNoGwPKIDz70x9VYJhrECYsDfcx+CbIVNPuoEkt9hlx07bfA1+4A==, tarball: https://registry.npmmirror.com/feelers/-/feelers-1.2.0.tgz} + + feelin@2.3.0: + resolution: {integrity: sha512-QDXCQRIV6AeLYUZoSlCAM+LEIv5k0+G4UJ+hRvTG42nCsW9YWPeVFNDInJDMGC+NimA6wW+1PKKDY6X8FcKJqg==, tarball: https://registry.npmmirror.com/feelin/-/feelin-2.3.0.tgz} + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + filelist@1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + + fill-range@4.0.0: + resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==} + engines: {node: '>=0.10.0'} + + fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + + fill-range@https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz} + name: fill-range + version: 7.0.1 + engines: {node: '>=8'} + + finalhandler@1.1.2: + resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==} + engines: {node: '>= 0.8'} + + finalhandler@https://registry.npmmirror.com/finalhandler/-/finalhandler-1.1.2.tgz: + resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/finalhandler/-/finalhandler-1.1.2.tgz} + name: finalhandler + version: 1.1.2 + engines: {node: '>= 0.8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + find-up@https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz} + name: find-up + version: 4.1.0 + engines: {node: '>=8'} + + find-up@https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz} + name: find-up + version: 5.0.0 + engines: {node: '>=10'} + + flat-cache@3.1.0: + resolution: {integrity: sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==} + engines: {node: '>=12.0.0'} + + flatted@3.2.7: + resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} + + focus-trap@7.5.4: + resolution: {integrity: sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==, tarball: https://registry.npmmirror.com/focus-trap/-/focus-trap-7.5.4.tgz} + + follow-redirects@https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz: + resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz} + name: follow-redirects + version: 1.15.2 + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-in@1.0.2: + resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} + engines: {node: '>=0.10.0'} + + foreground-child@3.1.1: + resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + engines: {node: '>=14'} + + form-data@https://registry.npmmirror.com/form-data/-/form-data-3.0.1.tgz: + resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/form-data/-/form-data-3.0.1.tgz} + name: form-data + version: 3.0.1 + engines: {node: '>= 6'} + + form-data@https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz} + name: form-data + version: 4.0.0 + engines: {node: '>= 6'} + + frac@1.1.2: + resolution: {integrity: sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==} + engines: {node: '>=0.8'} + + fragment-cache@0.2.1: + resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} + engines: {node: '>=0.10.0'} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + + fs-extra@11.1.1: + resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} + engines: {node: '>=14.14'} + + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@https://registry.npmmirror.com/fs-extra/-/fs-extra-11.1.1.tgz: + resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/fs-extra/-/fs-extra-11.1.1.tgz} + name: fs-extra + version: 11.1.1 + engines: {node: '>=14.14'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fs.realpath@https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz} + name: fs.realpath + version: 1.0.0 + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, tarball: https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + fstream@1.0.12: + resolution: {integrity: sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==} + engines: {node: '>=0.6'} + + function-bind@1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + + function-bind@https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz} + name: function-bind + version: 1.1.1 + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + gensync@https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz} + name: gensync + version: 1.0.0-beta.2 + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-caller-file@https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz} + name: get-caller-file + version: 2.0.5 + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.2.0: + resolution: {integrity: sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==} + + get-intrinsic@1.2.1: + resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} + + get-package-type@https://registry.npmmirror.com/get-package-type/-/get-package-type-0.1.0.tgz: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/get-package-type/-/get-package-type-0.1.0.tgz} + name: get-package-type + version: 0.1.0 + engines: {node: '>=8.0.0'} + + get-stdin@https://registry.npmmirror.com/get-stdin/-/get-stdin-9.0.0.tgz: + resolution: {integrity: sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/get-stdin/-/get-stdin-9.0.0.tgz} + name: get-stdin + version: 9.0.0 + engines: {node: '>=12'} + + get-stream@https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz} + name: get-stream + version: 6.0.1 + engines: {node: '>=10'} + + get-value@2.0.6: + resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} + engines: {node: '>=0.10.0'} + + git-hooks-list@https://registry.npmmirror.com/git-hooks-list/-/git-hooks-list-3.1.0.tgz: + resolution: {integrity: sha512-LF8VeHeR7v+wAbXqfgRlTSX/1BJR9Q1vEMR8JAz1cEg6GX07+zyj3sAdDvYjj/xnlIfVuGgj4qBei1K3hKH+PA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/git-hooks-list/-/git-hooks-list-3.1.0.tgz} + name: git-hooks-list + version: 3.1.0 + + git-raw-commits@https://registry.npmmirror.com/git-raw-commits/-/git-raw-commits-2.0.11.tgz: + resolution: {integrity: sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/git-raw-commits/-/git-raw-commits-2.0.11.tgz} + name: git-raw-commits + version: 2.0.11 + engines: {node: '>=10'} + hasBin: true + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz} + name: glob-parent + version: 5.1.2 + engines: {node: '>= 6'} + + glob@10.3.3: + resolution: {integrity: sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + + glob@https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz} + name: glob + version: 7.2.3 + + glob@https://registry.npmmirror.com/glob/-/glob-8.1.0.tgz: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/glob/-/glob-8.1.0.tgz} + name: glob + version: 8.1.0 + engines: {node: '>=12'} + + global-dirs@https://registry.npmmirror.com/global-dirs/-/global-dirs-0.1.1.tgz: + resolution: {integrity: sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/global-dirs/-/global-dirs-0.1.1.tgz} + name: global-dirs + version: 0.1.1 + engines: {node: '>=4'} + + global-modules@2.0.0: + resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==} + engines: {node: '>=6'} + + global-prefix@3.0.0: + resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} + engines: {node: '>=6'} + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globals@https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz} + name: globals + version: 11.12.0 + engines: {node: '>=4'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + globby@13.2.2: + resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + globby@https://registry.npmmirror.com/globby/-/globby-13.2.2.tgz: + resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/globby/-/globby-13.2.2.tgz} + name: globby + version: 13.2.2 + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + globjoin@0.1.4: + resolution: {integrity: sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==} + + graceful-fs@4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, tarball: https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz} + + gzip-size@6.0.0: + resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} + engines: {node: '>=10'} + + hammerjs@2.0.8: + resolution: {integrity: sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==, tarball: https://registry.npmmirror.com/hammerjs/-/hammerjs-2.0.8.tgz} + engines: {node: '>=0.8.0'} + + hard-rejection@2.1.0: + resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} + engines: {node: '>=6'} + + hard-rejection@https://registry.npmmirror.com/hard-rejection/-/hard-rejection-2.1.0.tgz: + resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/hard-rejection/-/hard-rejection-2.1.0.tgz} + name: hard-rejection + version: 2.1.0 + engines: {node: '>=6'} + + has-ansi@2.0.0: + resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==} + engines: {node: '>=0.10.0'} + + has-flag@1.0.0: + resolution: {integrity: sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==} + engines: {node: '>=0.10.0'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-flag@https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz} + name: has-flag + version: 3.0.0 + engines: {node: '>=4'} + + has-flag@https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz} + name: has-flag + version: 4.0.0 + engines: {node: '>=8'} + + has-proto@1.0.1: + resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + has-value@0.3.1: + resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==} + engines: {node: '>=0.10.0'} + + has-value@1.0.0: + resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==} + engines: {node: '>=0.10.0'} + + has-values@0.1.4: + resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==} + engines: {node: '>=0.10.0'} + + has-values@1.0.0: + resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} + engines: {node: '>=0.10.0'} + + has@1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + + has@https://registry.npmmirror.com/has/-/has-1.0.3.tgz: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/has/-/has-1.0.3.tgz} + name: has + version: 1.0.3 + engines: {node: '>= 0.4.0'} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + he@https://registry.npmmirror.com/he/-/he-1.2.0.tgz: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/he/-/he-1.2.0.tgz} + name: he + version: 1.2.0 + hasBin: true + + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + + hosted-git-info@4.1.0: + resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} + engines: {node: '>=10'} + + hosted-git-info@https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz} + name: hosted-git-info + version: 2.8.9 + + hosted-git-info@https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz: + resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz} + name: hosted-git-info + version: 4.1.0 + engines: {node: '>=10'} + + htm@3.1.1: + resolution: {integrity: sha512-983Vyg8NwUE7JkZ6NmOqpCZ+sh1bKv2iYTlUkzlWmA5JD2acKoxd4KVxbMmxX/85mtfdnDmTFoNKcg5DGAvxNQ==, tarball: https://registry.npmmirror.com/htm/-/htm-3.1.1.tgz} + + html-encoding-sniffer@https://registry.npmmirror.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz: + resolution: {integrity: sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz} + name: html-encoding-sniffer + version: 2.0.1 + engines: {node: '>=10'} + + html-escaper@https://registry.npmmirror.com/html-escaper/-/html-escaper-2.0.2.tgz: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/html-escaper/-/html-escaper-2.0.2.tgz} + name: html-escaper + version: 2.0.2 + + html-minifier-terser@6.1.0: + resolution: {integrity: sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==} + engines: {node: '>=12'} + hasBin: true + + html-tags@3.3.1: + resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} + engines: {node: '>=8'} + + htmlparser2@3.10.1: + resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==} + + htmlparser2@8.0.2: + resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + + http-proxy-agent@https://registry.npmmirror.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz: + resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz} + name: http-proxy-agent + version: 4.0.1 + engines: {node: '>= 6'} + + https-proxy-agent@https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz} + name: https-proxy-agent + version: 5.0.1 + engines: {node: '>= 6'} + + human-signals@https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz} + name: human-signals + version: 2.1.0 + engines: {node: '>=10.17.0'} + + human-signals@https://registry.npmmirror.com/human-signals/-/human-signals-4.3.1.tgz: + resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/human-signals/-/human-signals-4.3.1.tgz} + name: human-signals + version: 4.3.1 + engines: {node: '>=14.18.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + iconv-lite@https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz} + name: iconv-lite + version: 0.4.24 + engines: {node: '>=0.10.0'} + + ids@1.0.5: + resolution: {integrity: sha512-XQ0yom/4KWTL29sLG+tyuycy7UmeaM/79GRtSJq6IG9cJGIPeBz5kwDCguie3TwxaMNIc3WtPi0cTa1XYHicpw==, tarball: https://registry.npmmirror.com/ids/-/ids-1.0.5.tgz} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.2.4: + resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + engines: {node: '>= 4'} + + ignore@https://registry.npmmirror.com/ignore/-/ignore-5.2.4.tgz: + resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ignore/-/ignore-5.2.4.tgz} + name: ignore + version: 5.2.4 + engines: {node: '>= 4'} + + image-size@0.5.5: + resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==, tarball: https://registry.npmmirror.com/image-size/-/image-size-0.5.5.tgz} + engines: {node: '>=0.10.0'} + hasBin: true + + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + + immutable@4.3.4: + resolution: {integrity: sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + import-fresh@https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz} + name: import-fresh + version: 3.3.0 + engines: {node: '>=6'} + + import-lazy@4.0.0: + resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} + engines: {node: '>=8'} + + import-local@https://registry.npmmirror.com/import-local/-/import-local-3.1.0.tgz: + resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/import-local/-/import-local-3.1.0.tgz} + name: import-local + version: 3.1.0 + engines: {node: '>=8'} + hasBin: true + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + imurmurhash@https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz} + name: imurmurhash + version: 0.1.4 + engines: {node: '>=0.8.19'} + + indent-string@5.0.0: + resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} + engines: {node: '>=12'} + + indent-string@https://registry.npmmirror.com/indent-string/-/indent-string-4.0.0.tgz: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/indent-string/-/indent-string-4.0.0.tgz} + name: indent-string + version: 4.0.0 + engines: {node: '>=8'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + + inflight@https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz} + name: inflight + version: 1.0.6 + + inherits-browser@0.1.0: + resolution: {integrity: sha512-CJHHvW3jQ6q7lzsXPpapLdMx5hDpSF3FSh45pwsj6bKxJJ8Nl8v43i5yXnr3BdfOimGHKyniewQtnAIp3vyJJw==, tarball: https://registry.npmmirror.com/inherits-browser/-/inherits-browser-0.1.0.tgz} + + inherits@https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz} + name: inherits + version: 2.0.4 + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz} + name: ini + version: 1.3.8 + + intro.js@https://registry.npmmirror.com/intro.js/-/intro.js-7.2.0.tgz: + resolution: {integrity: sha512-qbMfaB70rOXVBceIWNYnYTpVTiZsvQh/MIkfdQbpA9di9VBfj1GigUPfcCv3aOfsbrtPcri8vTLTA4FcEDcHSQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/intro.js/-/intro.js-7.2.0.tgz} + name: intro.js + version: 7.2.0 + + is-accessor-descriptor@0.1.6: + resolution: {integrity: sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==} + engines: {node: '>=0.10.0'} + + is-accessor-descriptor@1.0.0: + resolution: {integrity: sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==} + engines: {node: '>=0.10.0'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-arrayish@https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.2.1.tgz: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.2.1.tgz} + name: is-arrayish + version: 0.2.1 + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-binary-path@https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz} + name: is-binary-path + version: 2.1.0 + engines: {node: '>=8'} + + is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + + is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + + is-core-module@2.11.0: + resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} + + is-core-module@2.13.0: + resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} + + is-core-module@https://registry.npmmirror.com/is-core-module/-/is-core-module-2.13.0.tgz: + resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-core-module/-/is-core-module-2.13.0.tgz} + name: is-core-module + version: 2.13.0 + + is-data-descriptor@0.1.4: + resolution: {integrity: sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==} + engines: {node: '>=0.10.0'} + + is-data-descriptor@1.0.0: + resolution: {integrity: sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==} + engines: {node: '>=0.10.0'} + + is-descriptor@0.1.6: + resolution: {integrity: sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==} + engines: {node: '>=0.10.0'} + + is-descriptor@1.0.2: + resolution: {integrity: sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==} + engines: {node: '>=0.10.0'} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-docker@https://registry.npmmirror.com/is-docker/-/is-docker-2.2.1.tgz: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-docker/-/is-docker-2.2.1.tgz} + name: is-docker + version: 2.2.1 + engines: {node: '>=8'} + hasBin: true + + is-docker@https://registry.npmmirror.com/is-docker/-/is-docker-3.0.0.tgz: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-docker/-/is-docker-3.0.0.tgz} + name: is-docker + version: 3.0.0 + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-extendable@1.0.1: + resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} + engines: {node: '>=0.10.0'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-extglob@https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz} + name: is-extglob + version: 2.1.1 + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-fullwidth-code-point@https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz} + name: is-fullwidth-code-point + version: 3.0.0 + engines: {node: '>=8'} + + is-fullwidth-code-point@https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz} + name: is-fullwidth-code-point + version: 4.0.0 + engines: {node: '>=12'} + + is-generator-fn@https://registry.npmmirror.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz} + name: is-generator-fn + version: 2.1.0 + engines: {node: '>=6'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-glob@https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz} + name: is-glob + version: 4.0.3 + engines: {node: '>=0.10.0'} + + is-inside-container@https://registry.npmmirror.com/is-inside-container/-/is-inside-container-1.0.0.tgz: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-inside-container/-/is-inside-container-1.0.0.tgz} + name: is-inside-container + version: 1.0.0 + engines: {node: '>=14.16'} + hasBin: true + + is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + + is-number@3.0.0: + resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-number@https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz} + name: is-number + version: 7.0.0 + engines: {node: '>=0.12.0'} + + is-obj@https://registry.npmmirror.com/is-obj/-/is-obj-2.0.0.tgz: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-obj/-/is-obj-2.0.0.tgz} + name: is-obj + version: 2.0.0 + engines: {node: '>=8'} + + is-plain-obj@1.1.0: + resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} + engines: {node: '>=0.10.0'} + + is-plain-obj@https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz: + resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz} + name: is-plain-obj + version: 1.1.0 + engines: {node: '>=0.10.0'} + + is-plain-obj@https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz} + name: is-plain-obj + version: 4.1.0 + engines: {node: '>=12'} + + is-plain-object@5.0.0: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} + engines: {node: '>=0.10.0'} + + is-plain-object@https://registry.npmmirror.com/is-plain-object/-/is-plain-object-2.0.4.tgz: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-plain-object/-/is-plain-object-2.0.4.tgz} + name: is-plain-object + version: 2.0.4 + engines: {node: '>=0.10.0'} + + is-plain-object@https://registry.npmmirror.com/is-plain-object/-/is-plain-object-3.0.1.tgz: + resolution: {integrity: sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-plain-object/-/is-plain-object-3.0.1.tgz} + name: is-plain-object + version: 3.0.1 + engines: {node: '>=0.10.0'} + + is-plain-object@https://registry.npmmirror.com/is-plain-object/-/is-plain-object-5.0.0.tgz: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-plain-object/-/is-plain-object-5.0.0.tgz} + name: is-plain-object + version: 5.0.0 + engines: {node: '>=0.10.0'} + + is-potential-custom-element-name@https://registry.npmmirror.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz} + name: is-potential-custom-element-name + version: 1.0.1 + + is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + + is-stream@https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz} + name: is-stream + version: 2.0.1 + engines: {node: '>=8'} + + is-stream@https://registry.npmmirror.com/is-stream/-/is-stream-3.0.0.tgz: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-stream/-/is-stream-3.0.0.tgz} + name: is-stream + version: 3.0.0 + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-text-path@https://registry.npmmirror.com/is-text-path/-/is-text-path-1.0.1.tgz: + resolution: {integrity: sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-text-path/-/is-text-path-1.0.1.tgz} + name: is-text-path + version: 1.0.1 + engines: {node: '>=0.10.0'} + + is-typedarray@https://registry.npmmirror.com/is-typedarray/-/is-typedarray-1.0.0.tgz: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-typedarray/-/is-typedarray-1.0.0.tgz} + name: is-typedarray + version: 1.0.0 + + is-what@3.14.1: + resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + is-wsl@https://registry.npmmirror.com/is-wsl/-/is-wsl-2.2.0.tgz: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-wsl/-/is-wsl-2.2.0.tgz} + name: is-wsl + version: 2.2.0 + engines: {node: '>=8'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isexe@https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz} + name: isexe + version: 2.0.0 + + isobject@2.1.0: + resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} + engines: {node: '>=0.10.0'} + + isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + + istanbul-lib-coverage@https://registry.npmmirror.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz: + resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz} + name: istanbul-lib-coverage + version: 3.2.0 + engines: {node: '>=8'} + + istanbul-lib-instrument@https://registry.npmmirror.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz} + name: istanbul-lib-instrument + version: 5.2.1 + engines: {node: '>=8'} + + istanbul-lib-report@https://registry.npmmirror.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz} + name: istanbul-lib-report + version: 3.0.1 + engines: {node: '>=10'} + + istanbul-lib-source-maps@https://registry.npmmirror.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz} + name: istanbul-lib-source-maps + version: 4.0.1 + engines: {node: '>=10'} + + istanbul-reports@https://registry.npmmirror.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz: + resolution: {integrity: sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz} + name: istanbul-reports + version: 3.1.6 + engines: {node: '>=8'} + + jackspeak@2.3.1: + resolution: {integrity: sha512-4iSY3Bh1Htv+kLhiiZunUhQ+OYXIn0ze3ulq8JeWrFKmhPAJSySV2+kdtRh2pGcCeF0s6oR8Oc+pYZynJj4t8A==} + engines: {node: '>=14'} + + jake@10.8.7: + resolution: {integrity: sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==} + engines: {node: '>=10'} + hasBin: true + + jest-changed-files@https://registry.npmmirror.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz: + resolution: {integrity: sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz} + name: jest-changed-files + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-circus@https://registry.npmmirror.com/jest-circus/-/jest-circus-27.5.1.tgz: + resolution: {integrity: sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-circus/-/jest-circus-27.5.1.tgz} + name: jest-circus + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-cli@https://registry.npmmirror.com/jest-cli/-/jest-cli-27.5.1.tgz: + resolution: {integrity: sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-cli/-/jest-cli-27.5.1.tgz} + name: jest-cli + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest-config@https://registry.npmmirror.com/jest-config/-/jest-config-27.5.1.tgz: + resolution: {integrity: sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-config/-/jest-config-27.5.1.tgz} + name: jest-config + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + ts-node: '>=9.0.0' + peerDependenciesMeta: + ts-node: + optional: true + + jest-diff@https://registry.npmmirror.com/jest-diff/-/jest-diff-27.5.1.tgz: + resolution: {integrity: sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-diff/-/jest-diff-27.5.1.tgz} + name: jest-diff + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-docblock@https://registry.npmmirror.com/jest-docblock/-/jest-docblock-27.5.1.tgz: + resolution: {integrity: sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-docblock/-/jest-docblock-27.5.1.tgz} + name: jest-docblock + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-each@https://registry.npmmirror.com/jest-each/-/jest-each-27.5.1.tgz: + resolution: {integrity: sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-each/-/jest-each-27.5.1.tgz} + name: jest-each + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-environment-jsdom@https://registry.npmmirror.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz: + resolution: {integrity: sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz} + name: jest-environment-jsdom + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-environment-node@https://registry.npmmirror.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz: + resolution: {integrity: sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz} + name: jest-environment-node + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-get-type@https://registry.npmmirror.com/jest-get-type/-/jest-get-type-27.5.1.tgz: + resolution: {integrity: sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-get-type/-/jest-get-type-27.5.1.tgz} + name: jest-get-type + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-haste-map@https://registry.npmmirror.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz: + resolution: {integrity: sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz} + name: jest-haste-map + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-jasmine2@https://registry.npmmirror.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz: + resolution: {integrity: sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz} + name: jest-jasmine2 + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-leak-detector@https://registry.npmmirror.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz: + resolution: {integrity: sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz} + name: jest-leak-detector + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-matcher-utils@https://registry.npmmirror.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz: + resolution: {integrity: sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz} + name: jest-matcher-utils + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-message-util@https://registry.npmmirror.com/jest-message-util/-/jest-message-util-27.5.1.tgz: + resolution: {integrity: sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-message-util/-/jest-message-util-27.5.1.tgz} + name: jest-message-util + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-mock@https://registry.npmmirror.com/jest-mock/-/jest-mock-27.5.1.tgz: + resolution: {integrity: sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-mock/-/jest-mock-27.5.1.tgz} + name: jest-mock + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-pnp-resolver@https://registry.npmmirror.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz: + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz} + name: jest-pnp-resolver + version: 1.2.3 + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + + jest-regex-util@https://registry.npmmirror.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz: + resolution: {integrity: sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz} + name: jest-regex-util + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-resolve-dependencies@https://registry.npmmirror.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz: + resolution: {integrity: sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz} + name: jest-resolve-dependencies + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-resolve@https://registry.npmmirror.com/jest-resolve/-/jest-resolve-27.5.1.tgz: + resolution: {integrity: sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-resolve/-/jest-resolve-27.5.1.tgz} + name: jest-resolve + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-runner@https://registry.npmmirror.com/jest-runner/-/jest-runner-27.5.1.tgz: + resolution: {integrity: sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-runner/-/jest-runner-27.5.1.tgz} + name: jest-runner + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-runtime@https://registry.npmmirror.com/jest-runtime/-/jest-runtime-27.5.1.tgz: + resolution: {integrity: sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-runtime/-/jest-runtime-27.5.1.tgz} + name: jest-runtime + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-serializer@https://registry.npmmirror.com/jest-serializer/-/jest-serializer-27.5.1.tgz: + resolution: {integrity: sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-serializer/-/jest-serializer-27.5.1.tgz} + name: jest-serializer + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-snapshot@https://registry.npmmirror.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz: + resolution: {integrity: sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz} + name: jest-snapshot + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-util@https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz: + resolution: {integrity: sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz} + name: jest-util + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-validate@https://registry.npmmirror.com/jest-validate/-/jest-validate-27.5.1.tgz: + resolution: {integrity: sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-validate/-/jest-validate-27.5.1.tgz} + name: jest-validate + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-watcher@https://registry.npmmirror.com/jest-watcher/-/jest-watcher-27.5.1.tgz: + resolution: {integrity: sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-watcher/-/jest-watcher-27.5.1.tgz} + name: jest-watcher + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-worker@https://registry.npmmirror.com/jest-worker/-/jest-worker-27.5.1.tgz: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest-worker/-/jest-worker-27.5.1.tgz} + name: jest-worker + version: 27.5.1 + engines: {node: '>= 10.13.0'} + + jest@https://registry.npmmirror.com/jest/-/jest-27.5.1.tgz: + resolution: {integrity: sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jest/-/jest-27.5.1.tgz} + name: jest + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jiti@1.19.3: + resolution: {integrity: sha512-5eEbBDQT/jF1xg6l36P+mWGGoH9Spuy0PCdSr2dtWRDGC6ph/w9ZCL4lmESW8f8F7MwT3XKescfP0wnZWAKL9w==} + hasBin: true + + jju@1.4.0: + resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + + js-base64@2.6.4: + resolution: {integrity: sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==} + + js-beautify@https://registry.npmmirror.com/js-beautify/-/js-beautify-1.14.9.tgz: + resolution: {integrity: sha512-coM7xq1syLcMyuVGyToxcj2AlzhkDjmfklL8r0JgJ7A76wyGMpJ1oA35mr4APdYNO/o/4YY8H54NQIJzhMbhBg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/js-beautify/-/js-beautify-1.14.9.tgz} + name: js-beautify + version: 1.14.9 + engines: {node: '>=12'} + hasBin: true + + js-tokens@8.0.1: + resolution: {integrity: sha512-3AGrZT6tuMm1ZWWn9mLXh7XMfi2YtiLNPALCVxBCiUVq0LD1OQMxV/AdS/s7rLJU5o9i/jBZw/N4vXXL5dm29A==} + + js-tokens@https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz} + name: js-tokens + version: 4.0.0 + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + js-yaml@https://registry.npmmirror.com/js-yaml/-/js-yaml-3.14.1.tgz: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/js-yaml/-/js-yaml-3.14.1.tgz} + name: js-yaml + version: 3.14.1 + hasBin: true + + js-yaml@https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.0.tgz: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.0.tgz} + name: js-yaml + version: 4.1.0 + hasBin: true + + jsdom@https://registry.npmmirror.com/jsdom/-/jsdom-16.7.0.tgz: + resolution: {integrity: sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jsdom/-/jsdom-16.7.0.tgz} + name: jsdom + version: 16.7.0 + engines: {node: '>=10'} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + + jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + + jsesc@https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz} + name: jsesc + version: 2.5.2 + engines: {node: '>=4'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-parse-even-better-errors@https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz} + name: json-parse-even-better-errors + version: 2.3.1 + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema-traverse@https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz} + name: json-schema-traverse + version: 1.0.0 + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + json5@https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz} + name: json5 + version: 2.2.3 + engines: {node: '>=6'} + hasBin: true + + jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + jsonfile@https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz} + name: jsonfile + version: 6.1.0 + + jsonparse@https://registry.npmmirror.com/jsonparse/-/jsonparse-1.3.1.tgz: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jsonparse/-/jsonparse-1.3.1.tgz} + name: jsonparse + version: 1.3.1 + engines: {'0': node >= 0.2.0} + + jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + + keyv@4.5.3: + resolution: {integrity: sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==} + + kind-of@3.2.2: + resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} + engines: {node: '>=0.10.0'} + + kind-of@4.0.0: + resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==} + engines: {node: '>=0.10.0'} + + kind-of@5.1.0: + resolution: {integrity: sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==} + engines: {node: '>=0.10.0'} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + kind-of@https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz} + name: kind-of + version: 6.0.3 + engines: {node: '>=0.10.0'} + + kleur@https://registry.npmmirror.com/kleur/-/kleur-3.0.3.tgz: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/kleur/-/kleur-3.0.3.tgz} + name: kleur + version: 3.0.3 + engines: {node: '>=6'} + + known-css-properties@0.28.0: + resolution: {integrity: sha512-9pSL5XB4J+ifHP0e0jmmC98OGC1nL8/JjS+fi6mnTlIf//yt/MfVLtKg7S6nCtj/8KTcWX7nRlY0XywoYY1ISQ==} + + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + + lang-feel@1.1.0: + resolution: {integrity: sha512-UxQoWm8G8ne9D+xrVJ4wgVM2nIiggpdCQxX8SAw+ISNFUsehm7xtwohELgXGN8dCZ6C69fsMreAjI+jPURFKdQ==, tarball: https://registry.npmmirror.com/lang-feel/-/lang-feel-1.1.0.tgz} + + lazystream@1.0.1: + resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} + engines: {node: '>= 0.6.3'} + + less@4.2.0: + resolution: {integrity: sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA==} + engines: {node: '>=6'} + hasBin: true + + leven@https://registry.npmmirror.com/leven/-/leven-3.1.0.tgz: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/leven/-/leven-3.1.0.tgz} + name: leven + version: 3.1.0 + engines: {node: '>=6'} + + lezer-feel@1.2.3: + resolution: {integrity: sha512-KDWoIEZ79yP7Afk94YGV2NGdY0nLvkRB1rk9EoWWNiVJitdqNVsi1rtk/X6Gwokrrt823D9sNMeHxvV46Uh7Hw==, tarball: https://registry.npmmirror.com/lezer-feel/-/lezer-feel-1.2.3.tgz} + + lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + + lilconfig@https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz} + name: lilconfig + version: 2.1.0 + engines: {node: '>=10'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + lines-and-columns@https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz} + name: lines-and-columns + version: 1.2.4 + + lint-staged@https://registry.npmmirror.com/lint-staged/-/lint-staged-13.2.3.tgz: + resolution: {integrity: sha512-zVVEXLuQIhr1Y7R7YAWx4TZLdvuzk7DnmrsTNL0fax6Z3jrpFcas+vKbzxhhvp6TA55m1SQuWkpzI1qbfDZbAg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/lint-staged/-/lint-staged-13.2.3.tgz} + name: lint-staged + version: 13.2.3 + engines: {node: ^14.13.1 || >=16.0.0} + hasBin: true + + listenercount@1.0.1: + resolution: {integrity: sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==} + + listr2@https://registry.npmmirror.com/listr2/-/listr2-5.0.8.tgz: + resolution: {integrity: sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/listr2/-/listr2-5.0.8.tgz} + name: listr2 + version: 5.0.8 + engines: {node: ^14.13.1 || >=16.0.0} + peerDependencies: + enquirer: '>= 2.3.0 < 3' + peerDependenciesMeta: + enquirer: + optional: true + + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + loader-utils@1.4.2: + resolution: {integrity: sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==} + engines: {node: '>=4.0.0'} + + local-pkg@0.4.3: + resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} + engines: {node: '>=14'} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + locate-path@https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz} + name: locate-path + version: 5.0.0 + engines: {node: '>=8'} + + locate-path@https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz} + name: locate-path + version: 6.0.0 + engines: {node: '>=10'} + + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + + lodash-es@https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz} + name: lodash-es + version: 4.17.21 + + lodash.camelcase@https://registry.npmmirror.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz} + name: lodash.camelcase + version: 4.3.0 + + lodash.defaults@4.2.0: + resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} + + lodash.difference@4.5.0: + resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==} + + lodash.escaperegexp@4.1.2: + resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==} + + lodash.flatten@4.4.0: + resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} + + lodash.get@4.4.2: + resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} + + lodash.groupby@4.6.0: + resolution: {integrity: sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==} + + lodash.isboolean@3.0.3: + resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + + lodash.isfunction@https://registry.npmmirror.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz: + resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz} + name: lodash.isfunction + version: 3.0.9 + + lodash.isnil@4.0.0: + resolution: {integrity: sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.isplainobject@https://registry.npmmirror.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz} + name: lodash.isplainobject + version: 4.0.6 + + lodash.isundefined@3.0.1: + resolution: {integrity: sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA==} + + lodash.kebabcase@https://registry.npmmirror.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz: + resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz} + name: lodash.kebabcase + version: 4.1.1 + + lodash.merge@https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz} + name: lodash.merge + version: 4.6.2 + + lodash.mergewith@https://registry.npmmirror.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz: + resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz} + name: lodash.mergewith + version: 4.6.2 + + lodash.snakecase@https://registry.npmmirror.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz: + resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz} + name: lodash.snakecase + version: 4.1.1 + + lodash.startcase@https://registry.npmmirror.com/lodash.startcase/-/lodash.startcase-4.4.0.tgz: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/lodash.startcase/-/lodash.startcase-4.4.0.tgz} + name: lodash.startcase + version: 4.4.0 + + lodash.truncate@4.4.2: + resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + + lodash.union@4.6.0: + resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} + + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + + lodash.uniq@https://registry.npmmirror.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz} + name: lodash.uniq + version: 4.5.0 + + lodash.upperfirst@https://registry.npmmirror.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz: + resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz} + name: lodash.upperfirst + version: 4.3.1 + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + lodash@https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz} + name: lodash + version: 4.17.21 + + log-update@https://registry.npmmirror.com/log-update/-/log-update-4.0.0.tgz: + resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/log-update/-/log-update-4.0.0.tgz} + name: log-update + version: 4.0.0 + engines: {node: '>=10'} + + loose-envify@https://registry.npmmirror.com/loose-envify/-/loose-envify-1.4.0.tgz: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/loose-envify/-/loose-envify-1.4.0.tgz} + name: loose-envify + version: 1.4.0 + hasBin: true + + lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + + lru-cache@10.0.1: + resolution: {integrity: sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==} + engines: {node: 14 || >=16.14} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + lru-cache@https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz} + name: lru-cache + version: 5.1.1 + + lru-cache@https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz} + name: lru-cache + version: 6.0.0 + engines: {node: '>=10'} + + luxon@3.4.4: + resolution: {integrity: sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==, tarball: https://registry.npmmirror.com/luxon/-/luxon-3.4.4.tgz} + engines: {node: '>=12'} + + magic-string-ast@0.3.0: + resolution: {integrity: sha512-0shqecEPgdFpnI3AP90epXyxZy9g6CRZ+SZ7BcqFwYmtFEnZ1jpevcV5HoyVnlDS9gCnc1UIg3Rsvp3Ci7r8OA==} + engines: {node: '>=16.14.0'} + + magic-string@0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + + magic-string@0.27.0: + resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} + engines: {node: '>=12'} + + magic-string@0.29.0: + resolution: {integrity: sha512-WcfidHrDjMY+eLjlU+8OvwREqHwpgCeKVBUpQ3OhYYuvfaYCUgcbuBzappNzZvg/v8onU3oQj+BYpkOJe9Iw4Q==} + engines: {node: '>=12'} + + magic-string@0.30.2: + resolution: {integrity: sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug==} + engines: {node: '>=12'} + + magic-string@0.30.3: + resolution: {integrity: sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==} + engines: {node: '>=12'} + + make-dir@2.1.0: + resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==, tarball: https://registry.npmmirror.com/make-dir/-/make-dir-2.1.0.tgz} + engines: {node: '>=6'} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==, tarball: https://registry.npmmirror.com/make-dir/-/make-dir-4.0.0.tgz} + engines: {node: '>=10'} + + make-error@https://registry.npmmirror.com/make-error/-/make-error-1.3.6.tgz: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/make-error/-/make-error-1.3.6.tgz} + name: make-error + version: 1.3.6 + + makeerror@https://registry.npmmirror.com/makeerror/-/makeerror-1.0.12.tgz: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/makeerror/-/makeerror-1.0.12.tgz} + name: makeerror + version: 1.0.12 + + map-cache@0.2.2: + resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} + engines: {node: '>=0.10.0'} + + map-obj@1.0.1: + resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} + engines: {node: '>=0.10.0'} + + map-obj@4.3.0: + resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} + engines: {node: '>=8'} + + map-obj@https://registry.npmmirror.com/map-obj/-/map-obj-1.0.1.tgz: + resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/map-obj/-/map-obj-1.0.1.tgz} + name: map-obj + version: 1.0.1 + engines: {node: '>=0.10.0'} + + map-obj@https://registry.npmmirror.com/map-obj/-/map-obj-4.3.0.tgz: + resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/map-obj/-/map-obj-4.3.0.tgz} + name: map-obj + version: 4.3.0 + engines: {node: '>=8'} + + map-visit@1.0.0: + resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} + engines: {node: '>=0.10.0'} + + mathml-tag-names@2.1.3: + resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==} + + mdn-data@2.0.14: + resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} + + mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + + meow@10.1.5: + resolution: {integrity: sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + meow@https://registry.npmmirror.com/meow/-/meow-8.1.2.tgz: + resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/meow/-/meow-8.1.2.tgz} + name: meow + version: 8.1.2 + engines: {node: '>=10'} + + merge-options@1.0.1: + resolution: {integrity: sha512-iuPV41VWKWBIOpBsjoxjDZw8/GbSfZ2mk7N1453bwMrfzdrIk7EzBd+8UVR6rkw67th7xnk9Dytl3J+lHPdxvg==} + engines: {node: '>=4'} + + merge-stream@https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz} + name: merge-stream + version: 2.0.0 + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + merge2@https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz} + name: merge2 + version: 1.4.1 + engines: {node: '>= 8'} + + micromatch@3.1.0: + resolution: {integrity: sha512-3StSelAE+hnRvMs8IdVW7Uhk8CVed5tp+kLLGlBP6WiRAXS21GPGu/Nat4WNPXj2Eoc24B02SaeoyozPMfj0/g==} + engines: {node: '>=0.10.0'} + + micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + + micromatch@https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz} + name: micromatch + version: 4.0.5 + engines: {node: '>=8.6'} + + mime-db@https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz} + name: mime-db + version: 1.52.0 + engines: {node: '>= 0.6'} + + mime-types@https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz} + name: mime-types + version: 2.1.35 + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==, tarball: https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz} + engines: {node: '>=4'} + hasBin: true + + mimic-fn@https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz} + name: mimic-fn + version: 2.1.0 + engines: {node: '>=6'} + + mimic-fn@https://registry.npmmirror.com/mimic-fn/-/mimic-fn-4.0.0.tgz: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/mimic-fn/-/mimic-fn-4.0.0.tgz} + name: mimic-fn + version: 4.0.0 + engines: {node: '>=12'} + + min-dash@4.1.1: + resolution: {integrity: sha512-r+Z6vxXLSGr+otyCPx9NKPCSixw7LdfZREPTmqfd2a/d5D6w4NCdOxRJs+HyFO6v2pQkyHroGSiINWECK+OWPg==, tarball: https://registry.npmmirror.com/min-dash/-/min-dash-4.1.1.tgz} + + min-dom@4.1.0: + resolution: {integrity: sha512-1lj1EyoSwY/UmTeT/hhPiZTsq+vK9D+8FAJ/53iK5jT1otkG9rJTixSKdjmTieEvdfES+sKbbTptzaQJhnacjA==, tarball: https://registry.npmmirror.com/min-dom/-/min-dom-4.1.0.tgz} + + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + + min-indent@https://registry.npmmirror.com/min-indent/-/min-indent-1.0.1.tgz: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/min-indent/-/min-indent-1.0.1.tgz} + name: min-indent + version: 1.0.1 + engines: {node: '>=4'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + + minimatch@7.4.6: + resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==} + engines: {node: '>=10'} + + minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + + minimatch@https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz} + name: minimatch + version: 3.1.2 + + minimatch@https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz} + name: minimatch + version: 5.1.6 + engines: {node: '>=10'} + + minimatch@https://registry.npmmirror.com/minimatch/-/minimatch-9.0.1.tgz: + resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/minimatch/-/minimatch-9.0.1.tgz} + name: minimatch + version: 9.0.1 + engines: {node: '>=16 || 14 >=14.17'} + + minimatch@https://registry.npmmirror.com/minimatch/-/minimatch-9.0.3.tgz: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/minimatch/-/minimatch-9.0.3.tgz} + name: minimatch + version: 9.0.3 + engines: {node: '>=16 || 14 >=14.17'} + + minimist-options@4.1.0: + resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} + engines: {node: '>= 6'} + + minimist-options@https://registry.npmmirror.com/minimist-options/-/minimist-options-4.1.0.tgz: + resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/minimist-options/-/minimist-options-4.1.0.tgz} + name: minimist-options + version: 4.1.0 + engines: {node: '>= 6'} + + minimist@1.2.7: + resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} + + minimist@https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz} + name: minimist + version: 1.2.8 + + minipass@7.0.3: + resolution: {integrity: sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==} + engines: {node: '>=16 || 14 >=14.17'} + + mixin-deep@1.3.2: + resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} + engines: {node: '>=0.10.0'} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + mkdirp@2.1.6: + resolution: {integrity: sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==} + engines: {node: '>=10'} + hasBin: true + + mkdist@1.3.0: + resolution: {integrity: sha512-ZQrUvcL7LkRdzMREpDyg9AT18N9Tl5jc2qeKAUeEw0KGsgykbHbuRvysGAzTuGtwuSg0WQyNit5jh/k+Er3JEg==} + hasBin: true + peerDependencies: + sass: ^1.63.6 + typescript: '>=5.1.6' + peerDependenciesMeta: + sass: + optional: true + typescript: + optional: true + + mlly@1.4.1: + resolution: {integrity: sha512-SCDs78Q2o09jiZiE2WziwVBEqXQ02XkGdUy45cbJf+BpYRIjArXRJ1Wbowxkb+NaM9DWvS3UC9GiO/6eqvQ/pg==} + + mockjs@1.1.0: + resolution: {integrity: sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==} + hasBin: true + + moddle-xml@10.1.0: + resolution: {integrity: sha512-erWckwLt+dYskewKXJso9u+aAZ5172lOiYxSOqKCPTy7L/xmqH1PoeoA7eVC7oJTt3PqF5TkZzUmbjGH6soQBg==, tarball: https://registry.npmmirror.com/moddle-xml/-/moddle-xml-10.1.0.tgz} + + moddle@6.2.3: + resolution: {integrity: sha512-bLVN+ZHL3aKnhxc19XtjUfvdJsS3EsiEJC7bT6YPD11qYmTzvsxrGgyYz1Ouof7TZuGw0lDJ1OLmEnxcpQWk3Q==, tarball: https://registry.npmmirror.com/moddle/-/moddle-6.2.3.tgz} + + mousetrap@https://registry.npmmirror.com/mousetrap/-/mousetrap-1.6.5.tgz: + resolution: {integrity: sha512-QNo4kEepaIBwiT8CDhP98umTetp+JNfQYBWvC1pc6/OAibuXtRcxZ58Qz8skvEHYvURne/7R8T5VoOI7rDsEUA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/mousetrap/-/mousetrap-1.6.5.tgz} + name: mousetrap + version: 1.6.5 + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + mrmime@1.0.1: + resolution: {integrity: sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==} + engines: {node: '>=10'} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz} + name: ms + version: 2.0.0 + + ms@https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz} + name: ms + version: 2.1.2 + + ms@https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz} + name: ms + version: 2.1.3 + + muggle-string@https://registry.npmmirror.com/muggle-string/-/muggle-string-0.3.1.tgz: + resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/muggle-string/-/muggle-string-0.3.1.tgz} + name: muggle-string + version: 0.3.1 + + nanoid@3.3.6: + resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@https://registry.npmmirror.com/nanoid/-/nanoid-3.3.6.tgz: + resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/nanoid/-/nanoid-3.3.6.tgz} + name: nanoid + version: 3.3.6 + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanomatch@1.2.13: + resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} + engines: {node: '>=0.10.0'} + + nanopop@https://registry.npmmirror.com/nanopop/-/nanopop-2.3.0.tgz: + resolution: {integrity: sha512-fzN+T2K7/Ah25XU02MJkPZ5q4Tj5FpjmIYq4rvoHX4yb16HzFdCO6JxFFn5Y/oBhQ8no8fUZavnyIv9/+xkBBw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/nanopop/-/nanopop-2.3.0.tgz} + name: nanopop + version: 2.3.0 + + natural-compare@https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz} + name: natural-compare + version: 1.4.0 + + needle@3.2.0: + resolution: {integrity: sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==, tarball: https://registry.npmmirror.com/needle/-/needle-3.2.0.tgz} + engines: {node: '>= 4.4.x'} + hasBin: true + + no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + + node-fetch-native@1.4.0: + resolution: {integrity: sha512-F5kfEj95kX8tkDhUCYdV8dg3/8Olx/94zB8+ZNthFs6Bz31UpUi8Xh40TN3thLwXgrwXry1pEg9lJ++tLWTcqA==} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-html-parser@5.4.2: + resolution: {integrity: sha512-RaBPP3+51hPne/OolXxcz89iYvQvKOydaqoePpOgXcrOKZhjVIzmpKZz+Hd/RBO2/zN2q6CNJhQzucVz+u3Jyw==} + + node-int64@https://registry.npmmirror.com/node-int64/-/node-int64-0.4.0.tgz: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/node-int64/-/node-int64-0.4.0.tgz} + name: node-int64 + version: 0.4.0 + + node-releases@2.0.13: + resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} + + node-releases@https://registry.npmmirror.com/node-releases/-/node-releases-2.0.13.tgz: + resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/node-releases/-/node-releases-2.0.13.tgz} + name: node-releases + version: 2.0.13 + + nopt@https://registry.npmmirror.com/nopt/-/nopt-6.0.0.tgz: + resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/nopt/-/nopt-6.0.0.tgz} + name: nopt + version: 6.0.0 + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + hasBin: true + + normalize-package-data@3.0.3: + resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} + engines: {node: '>=10'} + + normalize-package-data@https://registry.npmmirror.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz} + name: normalize-package-data + version: 2.5.0 + + normalize-package-data@https://registry.npmmirror.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz: + resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz} + name: normalize-package-data + version: 3.0.3 + engines: {node: '>=10'} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-path@https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz} + name: normalize-path + version: 3.0.0 + engines: {node: '>=0.10.0'} + + npm-run-path@https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz} + name: npm-run-path + version: 4.0.1 + engines: {node: '>=8'} + + npm-run-path@https://registry.npmmirror.com/npm-run-path/-/npm-run-path-5.1.0.tgz: + resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/npm-run-path/-/npm-run-path-5.1.0.tgz} + name: npm-run-path + version: 5.1.0 + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + nprogress@0.2.0: + resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + nwsapi@https://registry.npmmirror.com/nwsapi/-/nwsapi-2.2.7.tgz: + resolution: {integrity: sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/nwsapi/-/nwsapi-2.2.7.tgz} + name: nwsapi + version: 2.2.7 + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-copy@0.1.0: + resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} + engines: {node: '>=0.10.0'} + + object-inspect@1.12.3: + resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + + object-inspect@https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.3.tgz: + resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.3.tgz} + name: object-inspect + version: 1.12.3 + + object-refs@0.4.0: + resolution: {integrity: sha512-6kJqKWryKZmtte6QYvouas0/EIJKPI1/MMIuRsiBlNuhIMfqYTggzX2F1AJ2+cDs288xyi9GL7FyasHINR98BQ==, tarball: https://registry.npmmirror.com/object-refs/-/object-refs-0.4.0.tgz} + + object-visit@1.0.1: + resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} + engines: {node: '>=0.10.0'} + + object.pick@1.3.0: + resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} + engines: {node: '>=0.10.0'} + + ofetch@1.3.3: + resolution: {integrity: sha512-s1ZCMmQWXy4b5K/TW9i/DtiN8Ku+xCiHcjQ6/J/nDdssirrQNOoB165Zu8EqLMA2lln1JUth9a0aW9Ap2ctrUg==} + + on-finished@2.3.0: + resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==} + engines: {node: '>= 0.8'} + + on-finished@https://registry.npmmirror.com/on-finished/-/on-finished-2.3.0.tgz: + resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/on-finished/-/on-finished-2.3.0.tgz} + name: on-finished + version: 2.3.0 + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + once@https://registry.npmmirror.com/once/-/once-1.4.0.tgz: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/once/-/once-1.4.0.tgz} + name: once + version: 1.4.0 + + onetime@https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz} + name: onetime + version: 5.1.2 + engines: {node: '>=6'} + + onetime@https://registry.npmmirror.com/onetime/-/onetime-6.0.0.tgz: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/onetime/-/onetime-6.0.0.tgz} + name: onetime + version: 6.0.0 + engines: {node: '>=12'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + + open@https://registry.npmmirror.com/open/-/open-9.1.0.tgz: + resolution: {integrity: sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/open/-/open-9.1.0.tgz} + name: open + version: 9.1.0 + engines: {node: '>=14.16'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-limit@https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz} + name: p-limit + version: 2.3.0 + engines: {node: '>=6'} + + p-limit@https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz} + name: p-limit + version: 3.1.0 + engines: {node: '>=10'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-locate@https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz} + name: p-locate + version: 4.1.0 + engines: {node: '>=8'} + + p-locate@https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz} + name: p-locate + version: 5.0.0 + engines: {node: '>=10'} + + p-map@https://registry.npmmirror.com/p-map/-/p-map-4.0.0.tgz: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/p-map/-/p-map-4.0.0.tgz} + name: p-map + version: 4.0.0 + engines: {node: '>=10'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + p-try@https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz} + name: p-try + version: 2.2.0 + engines: {node: '>=6'} + + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + + param-case@3.0.4: + resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parent-module@https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz} + name: parent-module + version: 1.0.1 + engines: {node: '>=6'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse-json@https://registry.npmmirror.com/parse-json/-/parse-json-5.2.0.tgz: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/parse-json/-/parse-json-5.2.0.tgz} + name: parse-json + version: 5.2.0 + engines: {node: '>=8'} + + parse-node-version@1.0.1: + resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==} + engines: {node: '>= 0.10'} + + parse5@https://registry.npmmirror.com/parse5/-/parse5-6.0.1.tgz: + resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/parse5/-/parse5-6.0.1.tgz} + name: parse5 + version: 6.0.1 + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + parseurl@https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz} + name: parseurl + version: 1.3.3 + engines: {node: '>= 0.8'} + + pascal-case@3.1.2: + resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + + pascalcase@0.1.1: + resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} + engines: {node: '>=0.10.0'} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-exists@https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz} + name: path-exists + version: 4.0.0 + engines: {node: '>=8'} + + path-intersection@3.0.0: + resolution: {integrity: sha512-Rdnfb33F9+qadWe3ZyzDpw3KSXQhsK1MByL44QzSDIQtMAujd0zFx9f+kt4SaQp1JOoXl5pl5K28EoEuAEgarA==, tarball: https://registry.npmmirror.com/path-intersection/-/path-intersection-3.0.0.tgz} + engines: {node: '>= 14.20'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz} + name: path-key + version: 3.1.1 + engines: {node: '>=8'} + + path-key@https://registry.npmmirror.com/path-key/-/path-key-4.0.0.tgz: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/path-key/-/path-key-4.0.0.tgz} + name: path-key + version: 4.0.0 + engines: {node: '>=12'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-parse@https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz} + name: path-parse + version: 1.0.7 + + path-scurry@1.10.1: + resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} + engines: {node: '>=16 || 14 >=14.17'} + + path-to-regexp@6.2.1: + resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} + + path-to-regexp@https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz: + resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz} + name: path-to-regexp + version: 6.2.1 + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + path-type@https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz} + name: path-type + version: 4.0.0 + engines: {node: '>=8'} + + pathe@0.2.0: + resolution: {integrity: sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==} + + pathe@1.1.1: + resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==} + + pathe@https://registry.npmmirror.com/pathe/-/pathe-1.1.1.tgz: + resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/pathe/-/pathe-1.1.1.tgz} + name: pathe + version: 1.1.1 + + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + + picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + + picocolors@https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz} + name: picocolors + version: 1.0.0 + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz} + name: picomatch + version: 2.3.1 + engines: {node: '>=8.6'} + + pidtree@https://registry.npmmirror.com/pidtree/-/pidtree-0.6.0.tgz: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/pidtree/-/pidtree-0.6.0.tgz} + name: pidtree + version: 0.6.0 + engines: {node: '>=0.10'} + hasBin: true + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + pinia@https://registry.npmmirror.com/pinia/-/pinia-2.1.4.tgz: + resolution: {integrity: sha512-vYlnDu+Y/FXxv1ABo1vhjC+IbqvzUdiUC3sfDRrRyY2CQSrqqaa+iiHmqtARFxJVqWQMCJfXx1PBvFs9aJVLXQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/pinia/-/pinia-2.1.4.tgz} + name: pinia + version: 2.1.4 + peerDependencies: + '@vue/composition-api': ^1.4.0 + typescript: '>=4.4.4' + vue: ^2.6.14 || ^3.3.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + typescript: + optional: true + + pirates@https://registry.npmmirror.com/pirates/-/pirates-4.0.6.tgz: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/pirates/-/pirates-4.0.6.tgz} + name: pirates + version: 4.0.6 + engines: {node: '>= 6'} + + pkg-dir@https://registry.npmmirror.com/pkg-dir/-/pkg-dir-4.2.0.tgz: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/pkg-dir/-/pkg-dir-4.2.0.tgz} + name: pkg-dir + version: 4.2.0 + engines: {node: '>=8'} + + pkg-types@1.0.3: + resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} + + pngjs@5.0.0: + resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} + engines: {node: '>=10.13.0'} + + posix-character-classes@0.1.1: + resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} + engines: {node: '>=0.10.0'} + + postcss-html@1.5.0: + resolution: {integrity: sha512-kCMRWJRHKicpA166kc2lAVUGxDZL324bkj/pVOb6RhjB0Z5Krl7mN0AsVkBhVIRZZirY0lyQXG38HCVaoKVNoA==} + engines: {node: ^12 || >=14} + + postcss-less@6.0.0: + resolution: {integrity: sha512-FPX16mQLyEjLzEuuJtxA8X3ejDLNGGEG503d2YGZR5Ask1SpDN8KmZUMpzCvyalWRywAn1n1VOA5dcqfCLo5rg==} + engines: {node: '>=12'} + peerDependencies: + postcss: ^8.3.5 + + postcss-media-query-parser@0.2.3: + resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==} + + postcss-prefix-selector@1.16.0: + resolution: {integrity: sha512-rdVMIi7Q4B0XbXqNUEI+Z4E+pueiu/CS5E6vRCQommzdQ/sgsS4dK42U7GX8oJR+TJOtT+Qv3GkNo6iijUMp3Q==} + peerDependencies: + postcss: '>4 <9' + + postcss-resolve-nested-selector@0.1.1: + resolution: {integrity: sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==} + + postcss-safe-parser@6.0.0: + resolution: {integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.3.3 + + postcss-scss@4.0.7: + resolution: {integrity: sha512-xPv2GseoyXPa58Nro7M73ZntttusuCmZdeOojUFR5PZDz2BR62vfYx1w9TyOnp1+nYFowgOMipsCBhxzVkAEPw==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.4.19 + + postcss-selector-parser@6.0.13: + resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==} + engines: {node: '>=4'} + + postcss-sorting@8.0.2: + resolution: {integrity: sha512-M9dkSrmU00t/jK7rF6BZSZauA5MAaBW4i5EnJXspMwt4iqTh/L9j6fgMnbElEOfyRyfLfVbIHj/R52zHzAPe1Q==} + peerDependencies: + postcss: ^8.4.20 + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@5.2.18: + resolution: {integrity: sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==} + engines: {node: '>=0.12'} + + postcss@8.4.29: + resolution: {integrity: sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==} + engines: {node: ^10 || ^12 || >=14} + + postcss@https://registry.npmmirror.com/postcss/-/postcss-8.4.29.tgz: + resolution: {integrity: sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/postcss/-/postcss-8.4.29.tgz} + name: postcss + version: 8.4.29 + engines: {node: ^10 || ^12 || >=14} + + posthtml-parser@0.2.1: + resolution: {integrity: sha512-nPC53YMqJnc/+1x4fRYFfm81KV2V+G9NZY+hTohpYg64Ay7NemWWcV4UWuy/SgMupqQ3kJ88M/iRfZmSnxT+pw==} + + posthtml-rename-id@1.0.12: + resolution: {integrity: sha512-UKXf9OF/no8WZo9edRzvuMenb6AD5hDLzIepJW+a4oJT+T/Lx7vfMYWT4aWlGNQh0WMhnUx1ipN9OkZ9q+ddEw==} + + posthtml-render@1.4.0: + resolution: {integrity: sha512-W1779iVHGfq0Fvh2PROhCe2QhB8mEErgqzo1wpIt36tCgChafP+hbXIhLDOM8ePJrZcFs0vkNEtdibEWVqChqw==} + engines: {node: '>=10'} + + posthtml-svg-mode@1.0.3: + resolution: {integrity: sha512-hEqw9NHZ9YgJ2/0G7CECOeuLQKZi8HjWLkBaSVtOWjygQ9ZD8P7tqeowYs7WrFdKsWEKG7o+IlsPY8jrr0CJpQ==} + + posthtml@0.9.2: + resolution: {integrity: sha512-spBB5sgC4cv2YcW03f/IAUN1pgDJWNWD8FzkyY4mArLUMJW+KlQhlmUdKAHQuPfb00Jl5xIfImeOsf6YL8QK7Q==} + engines: {node: '>=0.10.0'} + + preact@10.17.1: + resolution: {integrity: sha512-X9BODrvQ4Ekwv9GURm9AKAGaomqXmip7NQTZgY7gcNmr7XE83adOMJvd3N42id1tMFU7ojiynRsYnY6/BRFxLA==, tarball: https://registry.npmmirror.com/preact/-/preact-10.17.1.tgz} + + preact@https://registry.npmmirror.com/preact/-/preact-10.17.1.tgz: + resolution: {integrity: sha512-X9BODrvQ4Ekwv9GURm9AKAGaomqXmip7NQTZgY7gcNmr7XE83adOMJvd3N42id1tMFU7ojiynRsYnY6/BRFxLA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/preact/-/preact-10.17.1.tgz} + name: preact + version: 10.17.1 + + prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + + prettier-plugin-packagejson@https://registry.npmmirror.com/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.4.5.tgz: + resolution: {integrity: sha512-glG71jE1gO3y5+JNAhC8X+4yrlN28rub6Aj461SKbaPie9RgMiHKcInH2Moi2VGOfkTXaEHBhg4uVMBqa+kBUA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.4.5.tgz} + name: prettier-plugin-packagejson + version: 2.4.5 + peerDependencies: + prettier: '>= 1.16.0' + peerDependenciesMeta: + prettier: + optional: true + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + + prettier@https://registry.npmmirror.com/prettier/-/prettier-2.8.8.tgz: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/prettier/-/prettier-2.8.8.tgz} + name: prettier + version: 2.8.8 + engines: {node: '>=10.13.0'} + hasBin: true + + pretty-bytes@6.1.1: + resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} + engines: {node: ^14.13.1 || >=16.0.0} + + pretty-format@https://registry.npmmirror.com/pretty-format/-/pretty-format-27.5.1.tgz: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/pretty-format/-/pretty-format-27.5.1.tgz} + name: pretty-format + version: 27.5.1 + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + print-js@1.6.0: + resolution: {integrity: sha512-BfnOIzSKbqGRtO4o0rnj/K3681BSd2QUrsIZy/+WdCIugjIswjmx3lDEZpXB2ruGf9d4b3YNINri81+J0FsBWg==} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + prompts@https://registry.npmmirror.com/prompts/-/prompts-2.4.2.tgz: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/prompts/-/prompts-2.4.2.tgz} + name: prompts + version: 2.4.2 + engines: {node: '>= 6'} + + proto-list@https://registry.npmmirror.com/proto-list/-/proto-list-1.2.4.tgz: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/proto-list/-/proto-list-1.2.4.tgz} + name: proto-list + version: 1.2.4 + + proxy-from-env@https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz} + name: proxy-from-env + version: 1.1.0 + + prr@1.0.1: + resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} + + psl@https://registry.npmmirror.com/psl/-/psl-1.9.0.tgz: + resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/psl/-/psl-1.9.0.tgz} + name: psl + version: 1.9.0 + + punycode@2.3.0: + resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + engines: {node: '>=6'} + + punycode@https://registry.npmmirror.com/punycode/-/punycode-2.3.0.tgz: + resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/punycode/-/punycode-2.3.0.tgz} + name: punycode + version: 2.3.0 + engines: {node: '>=6'} + + qrcode@1.5.3: + resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} + engines: {node: '>=10.13.0'} + hasBin: true + + qs@6.11.2: + resolution: {integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==} + engines: {node: '>=0.6'} + + query-string@4.3.4: + resolution: {integrity: sha512-O2XLNDBIg1DnTOa+2XrIwSiXEV8h2KImXUnjhhn2+UsvZ+Es2uyd5CCRTNQlDGbzUQOW3aYCBx9rVA6dzsiY7Q==} + engines: {node: '>=0.10.0'} + + querystringify@https://registry.npmmirror.com/querystringify/-/querystringify-2.2.0.tgz: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/querystringify/-/querystringify-2.2.0.tgz} + name: querystringify + version: 2.2.0 + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + queue-microtask@https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz} + name: queue-microtask + version: 1.2.3 + + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + + quick-lru@https://registry.npmmirror.com/quick-lru/-/quick-lru-4.0.1.tgz: + resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/quick-lru/-/quick-lru-4.0.1.tgz} + name: quick-lru + version: 4.0.1 + engines: {node: '>=8'} + + react-is@https://registry.npmmirror.com/react-is/-/react-is-17.0.2.tgz: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/react-is/-/react-is-17.0.2.tgz} + name: react-is + version: 17.0.2 + + read-pkg-up@8.0.0: + resolution: {integrity: sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==} + engines: {node: '>=12'} + + read-pkg-up@https://registry.npmmirror.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz} + name: read-pkg-up + version: 7.0.1 + engines: {node: '>=8'} + + read-pkg@6.0.0: + resolution: {integrity: sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==} + engines: {node: '>=12'} + + read-pkg@https://registry.npmmirror.com/read-pkg/-/read-pkg-5.2.0.tgz: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/read-pkg/-/read-pkg-5.2.0.tgz} + name: read-pkg + version: 5.2.0 + engines: {node: '>=8'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readable-stream@https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz} + name: readable-stream + version: 3.6.2 + engines: {node: '>= 6'} + + readdir-glob@1.1.3: + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz} + name: readdirp + version: 3.6.0 + engines: {node: '>=8.10.0'} + + redent@4.0.0: + resolution: {integrity: sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==} + engines: {node: '>=12'} + + redent@https://registry.npmmirror.com/redent/-/redent-3.0.0.tgz: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/redent/-/redent-3.0.0.tgz} + name: redent + version: 3.0.0 + engines: {node: '>=8'} + + regenerator-runtime@https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz: + resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz} + name: regenerator-runtime + version: 0.14.0 + + regex-not@1.0.2: + resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} + engines: {node: '>=0.10.0'} + + relateurl@0.2.7: + resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} + engines: {node: '>= 0.10'} + + repeat-element@1.1.4: + resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} + engines: {node: '>=0.10.0'} + + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-directory@https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz} + name: require-directory + version: 2.1.1 + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + require-from-string@https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz} + name: require-from-string + version: 2.0.2 + engines: {node: '>=0.10.0'} + + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + + requires-port@https://registry.npmmirror.com/requires-port/-/requires-port-1.0.0.tgz: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/requires-port/-/requires-port-1.0.0.tgz} + name: requires-port + version: 1.0.0 + + resize-observer-polyfill@1.5.1: + resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} + + resize-observer-polyfill@https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz: + resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz} + name: resize-observer-polyfill + version: 1.5.1 + + resolve-cwd@https://registry.npmmirror.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz} + name: resolve-cwd + version: 3.0.0 + engines: {node: '>=8'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve-from@https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz} + name: resolve-from + version: 4.0.0 + engines: {node: '>=4'} + + resolve-from@https://registry.npmmirror.com/resolve-from/-/resolve-from-5.0.0.tgz: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/resolve-from/-/resolve-from-5.0.0.tgz} + name: resolve-from + version: 5.0.0 + engines: {node: '>=8'} + + resolve-global@https://registry.npmmirror.com/resolve-global/-/resolve-global-1.0.0.tgz: + resolution: {integrity: sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/resolve-global/-/resolve-global-1.0.0.tgz} + name: resolve-global + version: 1.0.0 + engines: {node: '>=8'} + + resolve-url@0.2.1: + resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} + deprecated: https://github.com/lydell/resolve-url#deprecated + + resolve.exports@https://registry.npmmirror.com/resolve.exports/-/resolve.exports-1.1.1.tgz: + resolution: {integrity: sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/resolve.exports/-/resolve.exports-1.1.1.tgz} + name: resolve.exports + version: 1.1.1 + engines: {node: '>=10'} + + resolve@1.19.0: + resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==} + + resolve@1.22.4: + resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==} + hasBin: true + + resolve@https://registry.npmmirror.com/resolve/-/resolve-1.22.4.tgz: + resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/resolve/-/resolve-1.22.4.tgz} + name: resolve + version: 1.22.4 + hasBin: true + + restore-cursor@https://registry.npmmirror.com/restore-cursor/-/restore-cursor-3.1.0.tgz: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/restore-cursor/-/restore-cursor-3.1.0.tgz} + name: restore-cursor + version: 3.1.0 + engines: {node: '>=8'} + + ret@0.1.15: + resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} + engines: {node: '>=0.12'} + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + reusify@https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz} + name: reusify + version: 1.0.4 + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rfdc@https://registry.npmmirror.com/rfdc/-/rfdc-1.3.0.tgz: + resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/rfdc/-/rfdc-1.3.0.tgz} + name: rfdc + version: 1.3.0 + + rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + hasBin: true + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + + rimraf@5.0.1: + resolution: {integrity: sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==} + engines: {node: '>=14'} + hasBin: true + + rimraf@https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz} + name: rimraf + version: 3.0.2 + hasBin: true + + rollup-plugin-dts@5.3.1: + resolution: {integrity: sha512-gusMi+Z4gY/JaEQeXnB0RUdU82h1kF0WYzCWgVmV4p3hWXqelaKuCvcJawfeg+EKn2T1Ie+YWF2OiN1/L8bTVg==} + engines: {node: '>=v14.21.3'} + peerDependencies: + rollup: ^3.0 + typescript: ^4.1 || ^5.0 + + rollup-plugin-purge-icons@0.9.1: + resolution: {integrity: sha512-hRDKBsPUz47UMdBufki2feTmBF2ClEJlYqL7N6vpVAHSLd7V2BJUaNKOF7YYbLMofVVF+9hm44YSkYO6k9hUgg==} + engines: {node: '>= 12'} + + rollup-plugin-visualizer@5.9.2: + resolution: {integrity: sha512-waHktD5mlWrYFrhOLbti4YgQCn1uR24nYsNuXxg7LkPH8KdTXVWR9DNY1WU0QqokyMixVXJS4J04HNrVTMP01A==} + engines: {node: '>=14'} + hasBin: true + peerDependencies: + rollup: 2.x || 3.x + peerDependenciesMeta: + rollup: + optional: true + + rollup@3.28.1: + resolution: {integrity: sha512-R9OMQmIHJm9znrU3m3cpE8uhN0fGdXiawME7aZIpQqvpS/85+Vt1Hq1/yVIcYfOmaQiHjvXkQAoJukvLpau6Yw==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + + rollup@https://registry.npmmirror.com/rollup/-/rollup-3.28.1.tgz: + resolution: {integrity: sha512-R9OMQmIHJm9znrU3m3cpE8uhN0fGdXiawME7aZIpQqvpS/85+Vt1Hq1/yVIcYfOmaQiHjvXkQAoJukvLpau6Yw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/rollup/-/rollup-3.28.1.tgz} + name: rollup + version: 3.28.1 + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + + run-applescript@https://registry.npmmirror.com/run-applescript/-/run-applescript-5.0.0.tgz: + resolution: {integrity: sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/run-applescript/-/run-applescript-5.0.0.tgz} + name: run-applescript + version: 5.0.0 + engines: {node: '>=12'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + run-parallel@https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz} + name: run-parallel + version: 1.2.0 + + rxjs@https://registry.npmmirror.com/rxjs/-/rxjs-7.8.1.tgz: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/rxjs/-/rxjs-7.8.1.tgz} + name: rxjs + version: 7.8.1 + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-buffer@https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz} + name: safe-buffer + version: 5.2.1 + + safe-regex@1.1.0: + resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + safer-buffer@https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz} + name: safer-buffer + version: 2.1.2 + + sass@1.66.1: + resolution: {integrity: sha512-50c+zTsZOJVgFfTgwwEzkjA3/QACgdNsKueWPyAR0mRINIvLAStVQBbPg14iuqEQ74NPDbXzJARJ/O4SI1zftA==} + engines: {node: '>=14.0.0'} + hasBin: true + + sax@1.2.4: + resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} + + saxen@8.1.2: + resolution: {integrity: sha512-xUOiiFbc3Ow7p8KMxwsGICPx46ZQvy3+qfNVhrkwfz3Vvq45eGt98Ft5IQaA1R/7Tb5B5MKh9fUR9x3c3nDTxw==, tarball: https://registry.npmmirror.com/saxen/-/saxen-8.1.2.tgz} + + saxes@5.0.1: + resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==} + engines: {node: '>=10'} + + saxes@https://registry.npmmirror.com/saxes/-/saxes-5.0.1.tgz: + resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/saxes/-/saxes-5.0.1.tgz} + name: saxes + version: 5.0.1 + engines: {node: '>=10'} + + scroll-into-view-if-needed@https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz: + resolution: {integrity: sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz} + name: scroll-into-view-if-needed + version: 2.2.31 + + scule@1.0.0: + resolution: {integrity: sha512-4AsO/FrViE/iDNEPaAQlb77tf0csuq27EsVpy6ett584EcRTp6pTDLoGWVxCD77y5iU5FauOvhsI4o1APwPoSQ==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + + semver@https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz} + name: semver + version: 5.7.2 + hasBin: true + + semver@https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz} + name: semver + version: 6.3.1 + hasBin: true + + semver@https://registry.npmmirror.com/semver/-/semver-7.5.4.tgz: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/semver/-/semver-7.5.4.tgz} + name: semver + version: 7.5.4 + engines: {node: '>=10'} + hasBin: true + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + set-value@2.0.1: + resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} + engines: {node: '>=0.10.0'} + + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + + shallow-equal@https://registry.npmmirror.com/shallow-equal/-/shallow-equal-1.2.1.tgz: + resolution: {integrity: sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/shallow-equal/-/shallow-equal-1.2.1.tgz} + name: shallow-equal + version: 1.2.1 + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-command@https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz} + name: shebang-command + version: 2.0.0 + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shebang-regex@https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz} + name: shebang-regex + version: 3.0.0 + engines: {node: '>=8'} + + showdown@2.1.0: + resolution: {integrity: sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==} + hasBin: true + + side-channel@1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + signal-exit@https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz} + name: signal-exit + version: 3.0.7 + + sirv@2.0.3: + resolution: {integrity: sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==} + engines: {node: '>= 10'} + + sisteransi@https://registry.npmmirror.com/sisteransi/-/sisteransi-1.0.5.tgz: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/sisteransi/-/sisteransi-1.0.5.tgz} + name: sisteransi + version: 1.0.5 + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slash@4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + + slash@https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz} + name: slash + version: 3.0.0 + engines: {node: '>=8'} + + slash@https://registry.npmmirror.com/slash/-/slash-4.0.0.tgz: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/slash/-/slash-4.0.0.tgz} + name: slash + version: 4.0.0 + engines: {node: '>=12'} + + slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + + slice-ansi@https://registry.npmmirror.com/slice-ansi/-/slice-ansi-3.0.0.tgz: + resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/slice-ansi/-/slice-ansi-3.0.0.tgz} + name: slice-ansi + version: 3.0.0 + engines: {node: '>=8'} + + slice-ansi@https://registry.npmmirror.com/slice-ansi/-/slice-ansi-4.0.0.tgz: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/slice-ansi/-/slice-ansi-4.0.0.tgz} + name: slice-ansi + version: 4.0.0 + engines: {node: '>=10'} + + slice-ansi@https://registry.npmmirror.com/slice-ansi/-/slice-ansi-5.0.0.tgz: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/slice-ansi/-/slice-ansi-5.0.0.tgz} + name: slice-ansi + version: 5.0.0 + engines: {node: '>=12'} + + snapdragon-node@2.1.1: + resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} + engines: {node: '>=0.10.0'} + + snapdragon-util@3.0.1: + resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} + engines: {node: '>=0.10.0'} + + snapdragon@0.8.2: + resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} + engines: {node: '>=0.10.0'} + + sort-object-keys@https://registry.npmmirror.com/sort-object-keys/-/sort-object-keys-1.1.3.tgz: + resolution: {integrity: sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/sort-object-keys/-/sort-object-keys-1.1.3.tgz} + name: sort-object-keys + version: 1.1.3 + + sort-package-json@https://registry.npmmirror.com/sort-package-json/-/sort-package-json-2.5.1.tgz: + resolution: {integrity: sha512-vx/KoZxm8YNMUqdlw7SGTfqR5pqZ/sUfgOuRtDILiOy/3AvzhAibyUe2cY3OpLs3oRSow9up4yLVtQaM24rbDQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/sort-package-json/-/sort-package-json-2.5.1.tgz} + name: sort-package-json + version: 2.5.1 + hasBin: true + + sortablejs@1.15.0: + resolution: {integrity: sha512-bv9qgVMjUMf89wAvM6AxVvS/4MX3sPeN0+agqShejLU5z5GX4C75ow1O2e5k4L6XItUyAK3gH6AxSbXrOM5e8w==} + + sortablejs@https://registry.npmmirror.com/sortablejs/-/sortablejs-1.14.0.tgz: + resolution: {integrity: sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/sortablejs/-/sortablejs-1.14.0.tgz} + name: sortablejs + version: 1.14.0 + + source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + + source-map-js@https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz} + name: source-map-js + version: 1.0.2 + engines: {node: '>=0.10.0'} + + source-map-resolve@0.5.3: + resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} + deprecated: See https://github.com/lydell/source-map-resolve#deprecated + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map-support@https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz} + name: source-map-support + version: 0.5.21 + + source-map-url@0.4.1: + resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} + deprecated: See https://github.com/lydell/source-map-url#deprecated + + source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==, tarball: https://registry.npmmirror.com/source-map/-/source-map-0.5.7.tgz} + engines: {node: '>=0.10.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, tarball: https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz} + engines: {node: '>=0.10.0'} + + source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + + sourcemap-codec@1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead + + spdx-correct@3.1.1: + resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==} + + spdx-correct@https://registry.npmmirror.com/spdx-correct/-/spdx-correct-3.1.1.tgz: + resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/spdx-correct/-/spdx-correct-3.1.1.tgz} + name: spdx-correct + version: 3.1.1 + + spdx-exceptions@2.3.0: + resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} + + spdx-exceptions@https://registry.npmmirror.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz: + resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz} + name: spdx-exceptions + version: 2.3.0 + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-expression-parse@https://registry.npmmirror.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz} + name: spdx-expression-parse + version: 3.0.1 + + spdx-license-ids@3.0.12: + resolution: {integrity: sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==} + + spdx-license-ids@https://registry.npmmirror.com/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz: + resolution: {integrity: sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz} + name: spdx-license-ids + version: 3.0.12 + + split-string@3.1.0: + resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} + engines: {node: '>=0.10.0'} + + split2@https://registry.npmmirror.com/split2/-/split2-3.2.2.tgz: + resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/split2/-/split2-3.2.2.tgz} + name: split2 + version: 3.2.2 + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + sprintf-js@https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz} + name: sprintf-js + version: 1.0.3 + + ssf@0.11.2: + resolution: {integrity: sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==} + engines: {node: '>=0.8'} + + stable@0.1.8: + resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} + deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' + + stack-utils@https://registry.npmmirror.com/stack-utils/-/stack-utils-2.0.6.tgz: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/stack-utils/-/stack-utils-2.0.6.tgz} + name: stack-utils + version: 2.0.6 + engines: {node: '>=10'} + + static-extend@0.1.2: + resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} + engines: {node: '>=0.10.0'} + + statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + + statuses@https://registry.npmmirror.com/statuses/-/statuses-1.5.0.tgz: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/statuses/-/statuses-1.5.0.tgz} + name: statuses + version: 1.5.0 + engines: {node: '>= 0.6'} + + strict-uri-encode@1.1.0: + resolution: {integrity: sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==} + engines: {node: '>=0.10.0'} + + string-argv@https://registry.npmmirror.com/string-argv/-/string-argv-0.3.2.tgz: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/string-argv/-/string-argv-0.3.2.tgz} + name: string-argv + version: 0.3.2 + engines: {node: '>=0.6.19'} + + string-length@https://registry.npmmirror.com/string-length/-/string-length-4.0.2.tgz: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/string-length/-/string-length-4.0.2.tgz} + name: string-length + version: 4.0.2 + engines: {node: '>=10'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz} + name: string-width + version: 4.2.3 + engines: {node: '>=8'} + + string-width@https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz} + name: string-width + version: 5.1.2 + engines: {node: '>=12'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + string_decoder@https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz} + name: string_decoder + version: 1.3.0 + + strip-ansi@3.0.1: + resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} + engines: {node: '>=0.10.0'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-ansi@https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz} + name: strip-ansi + version: 6.0.1 + engines: {node: '>=8'} + + strip-ansi@https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.0.tgz: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.0.tgz} + name: strip-ansi + version: 7.1.0 + engines: {node: '>=12'} + + strip-bom@https://registry.npmmirror.com/strip-bom/-/strip-bom-4.0.0.tgz: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/strip-bom/-/strip-bom-4.0.0.tgz} + name: strip-bom + version: 4.0.0 + engines: {node: '>=8'} + + strip-final-newline@https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz} + name: strip-final-newline + version: 2.0.0 + engines: {node: '>=6'} + + strip-final-newline@https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz} + name: strip-final-newline + version: 3.0.0 + engines: {node: '>=12'} + + strip-indent@4.0.0: + resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} + engines: {node: '>=12'} + + strip-indent@https://registry.npmmirror.com/strip-indent/-/strip-indent-3.0.0.tgz: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/strip-indent/-/strip-indent-3.0.0.tgz} + name: strip-indent + version: 3.0.0 + engines: {node: '>=8'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strip-json-comments@https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz} + name: strip-json-comments + version: 3.1.1 + engines: {node: '>=8'} + + style-mod@4.1.0: + resolution: {integrity: sha512-Ca5ib8HrFn+f+0n4N4ScTIA9iTOQ7MaGS1ylHcoVqW9J7w2w8PzN6g9gKmTYgGEBH8e120+RCmhpje6jC5uGWA==, tarball: https://registry.npmmirror.com/style-mod/-/style-mod-4.1.0.tgz} + + style-search@0.1.0: + resolution: {integrity: sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==} + + stylelint-config-html@1.1.0: + resolution: {integrity: sha512-IZv4IVESjKLumUGi+HWeb7skgO6/g4VMuAYrJdlqQFndgbj6WJAXPhaysvBiXefX79upBdQVumgYcdd17gCpjQ==} + engines: {node: ^12 || >=14} + peerDependencies: + postcss-html: ^1.0.0 + stylelint: '>=14.0.0' + + stylelint-config-property-sort-order-smacss@9.1.0: + resolution: {integrity: sha512-TijYeDoDgHAFjpn9NnziQrmUCGrm2AM4e1HzsdI2mCWBRkQRuewc343YqDwdFgQ5eHoMZ3JRL02i72W3vktuDA==} + peerDependencies: + stylelint: ^14.0.0 || ^15.0.0 + + stylelint-config-recommended-scss@11.0.0: + resolution: {integrity: sha512-EDghTDU7aOv2LTsRZvcT1w8mcjUaMhuy+t38iV5I/0Qiu6ixdkRwhLEMul3K/fnB2v9Nwqvb3xpvJfPH+HduDw==} + peerDependencies: + postcss: ^8.3.3 + stylelint: ^15.5.0 + peerDependenciesMeta: + postcss: + optional: true + + stylelint-config-recommended-vue@1.5.0: + resolution: {integrity: sha512-65TAK/clUqkNtkZLcuytoxU0URQYlml+30Nhop7sRkCZ/mtWdXt7T+spPSB3KMKlb+82aEVJ4OrcstyDBdbosg==} + engines: {node: ^12 || >=14} + peerDependencies: + postcss-html: ^1.0.0 + stylelint: '>=14.0.0' + + stylelint-config-recommended@12.0.0: + resolution: {integrity: sha512-x6x8QNARrGO2sG6iURkzqL+Dp+4bJorPMMRNPScdvaUK8PsynriOcMW7AFDKqkWAS5wbue/u8fUT/4ynzcmqdQ==} + peerDependencies: + stylelint: ^15.5.0 + + stylelint-config-standard-scss@9.0.0: + resolution: {integrity: sha512-yPKpJsrZn4ybuQZx/DkEHuCjw7pJginErE/47dFhCnrvD48IJ4UYec8tSiCuJWMA3HRjbIa3nh5ZeSauDGuVAg==} + peerDependencies: + postcss: ^8.3.3 + stylelint: ^15.5.0 + peerDependenciesMeta: + postcss: + optional: true + + stylelint-config-standard@33.0.0: + resolution: {integrity: sha512-eyxnLWoXImUn77+ODIuW9qXBDNM+ALN68L3wT1lN2oNspZ7D9NVGlNHb2QCUn4xDug6VZLsh0tF8NyoYzkgTzg==} + peerDependencies: + stylelint: ^15.5.0 + + stylelint-order@6.0.3: + resolution: {integrity: sha512-1j1lOb4EU/6w49qZeT2SQVJXm0Ht+Qnq9GMfUa3pMwoyojIWfuA+JUDmoR97Bht1RLn4ei0xtLGy87M7d29B1w==} + peerDependencies: + stylelint: ^14.0.0 || ^15.0.0 + + stylelint-prettier@3.0.0: + resolution: {integrity: sha512-kIks1xw6np0zElokMT2kP6ar3S4MBoj6vUtPJuND1pFELMpZxVS/0uHPR4HDAVn0WAD3I5oF0IA3qBFxBpMkLg==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + prettier: '>=2.0.0' + stylelint: '>=14.0.0' + + stylelint-scss@4.7.0: + resolution: {integrity: sha512-TSUgIeS0H3jqDZnby1UO1Qv3poi1N8wUYIJY6D1tuUq2MN3lwp/rITVo0wD+1SWTmRm0tNmGO0b7nKInnqF6Hg==} + peerDependencies: + stylelint: ^14.5.1 || ^15.0.0 + + stylelint@15.10.3: + resolution: {integrity: sha512-aBQMMxYvFzJJwkmg+BUUg3YfPyeuCuKo2f+LOw7yYbU8AZMblibwzp9OV4srHVeQldxvSFdz0/Xu8blq2AesiA==} + engines: {node: ^14.13.1 || >=16.0.0} + hasBin: true + + stylis@https://registry.npmmirror.com/stylis/-/stylis-4.3.0.tgz: + resolution: {integrity: sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/stylis/-/stylis-4.3.0.tgz} + name: stylis + version: 4.3.0 + + supports-color@3.2.3: + resolution: {integrity: sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==} + engines: {node: '>=0.8.0'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@https://registry.npmmirror.com/supports-color/-/supports-color-2.0.0.tgz: + resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/supports-color/-/supports-color-2.0.0.tgz} + name: supports-color + version: 2.0.0 + engines: {node: '>=0.8.0'} + + supports-color@https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz} + name: supports-color + version: 5.5.0 + engines: {node: '>=4'} + + supports-color@https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz} + name: supports-color + version: 7.2.0 + engines: {node: '>=8'} + + supports-color@https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz} + name: supports-color + version: 8.1.1 + engines: {node: '>=10'} + + supports-hyperlinks@3.0.0: + resolution: {integrity: sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==} + engines: {node: '>=14.18'} + + supports-hyperlinks@https://registry.npmmirror.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz: + resolution: {integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz} + name: supports-hyperlinks + version: 2.3.0 + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + supports-preserve-symlinks-flag@https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz} + name: supports-preserve-symlinks-flag + version: 1.0.0 + engines: {node: '>= 0.4'} + + svg-baker@1.7.0: + resolution: {integrity: sha512-nibslMbkXOIkqKVrfcncwha45f97fGuAOn1G99YwnwTj8kF9YiM6XexPcUso97NxOm6GsP0SIvYVIosBis1xLg==} + + svg-tags@1.0.0: + resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} + + svgo@2.8.0: + resolution: {integrity: sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==} + engines: {node: '>=10.13.0'} + hasBin: true + + symbol-tree@https://registry.npmmirror.com/symbol-tree/-/symbol-tree-3.2.4.tgz: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/symbol-tree/-/symbol-tree-3.2.4.tgz} + name: symbol-tree + version: 3.2.4 + + synckit@https://registry.npmmirror.com/synckit/-/synckit-0.8.5.tgz: + resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/synckit/-/synckit-0.8.5.tgz} + name: synckit + version: 0.8.5 + engines: {node: ^14.18.0 || >=16.0.0} + + tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==, tarball: https://registry.npmmirror.com/tabbable/-/tabbable-6.2.0.tgz} + + table@6.8.1: + resolution: {integrity: sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==} + engines: {node: '>=10.0.0'} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + terminal-link@https://registry.npmmirror.com/terminal-link/-/terminal-link-2.1.1.tgz: + resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/terminal-link/-/terminal-link-2.1.1.tgz} + name: terminal-link + version: 2.1.1 + engines: {node: '>=8'} + + terser@5.19.3: + resolution: {integrity: sha512-pQzJ9UJzM0IgmT4FAtYI6+VqFf0lj/to58AV0Xfgg0Up37RyPG7Al+1cepC6/BVuAxR9oNb41/DL4DEoHJvTdg==} + engines: {node: '>=10'} + hasBin: true + + test-exclude@https://registry.npmmirror.com/test-exclude/-/test-exclude-6.0.0.tgz: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/test-exclude/-/test-exclude-6.0.0.tgz} + name: test-exclude + version: 6.0.0 + engines: {node: '>=8'} + + text-extensions@https://registry.npmmirror.com/text-extensions/-/text-extensions-1.9.0.tgz: + resolution: {integrity: sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/text-extensions/-/text-extensions-1.9.0.tgz} + name: text-extensions + version: 1.9.0 + engines: {node: '>=0.10'} + + throat@https://registry.npmmirror.com/throat/-/throat-6.0.2.tgz: + resolution: {integrity: sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/throat/-/throat-6.0.2.tgz} + name: throat + version: 6.0.2 + + throttle-debounce@https://registry.npmmirror.com/throttle-debounce/-/throttle-debounce-5.0.0.tgz: + resolution: {integrity: sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/throttle-debounce/-/throttle-debounce-5.0.0.tgz} + name: throttle-debounce + version: 5.0.0 + engines: {node: '>=12.22'} + + through2@https://registry.npmmirror.com/through2/-/through2-4.0.2.tgz: + resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/through2/-/through2-4.0.2.tgz} + name: through2 + version: 4.0.2 + + through@https://registry.npmmirror.com/through/-/through-2.3.8.tgz: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/through/-/through-2.3.8.tgz} + name: through + version: 2.3.8 + + tiny-svg@3.0.1: + resolution: {integrity: sha512-P8T4iwiW1t95vpHVHqrD36Brn7TqFYCPSHIWk9WLJtYK1X4aDd+5cgqcAADIWSjf1/i5idKnpCh9mim8hEdRBg==, tarball: https://registry.npmmirror.com/tiny-svg/-/tiny-svg-3.0.1.tgz} + + tinymce@https://registry.npmmirror.com/tinymce/-/tinymce-5.10.7.tgz: + resolution: {integrity: sha512-9UUjaO0R7FxcFo0oxnd1lMs7H+D0Eh+dDVo5hKbVe1a+VB0nit97vOqlinj+YwgoBDt6/DSCUoWqAYlLI8BLYA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/tinymce/-/tinymce-5.10.7.tgz} + name: tinymce + version: 5.10.7 + + titleize@https://registry.npmmirror.com/titleize/-/titleize-3.0.0.tgz: + resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/titleize/-/titleize-3.0.0.tgz} + name: titleize + version: 3.0.0 + engines: {node: '>=12'} + + tmp@0.2.1: + resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==} + engines: {node: '>=8.17.0'} + + tmpl@https://registry.npmmirror.com/tmpl/-/tmpl-1.0.5.tgz: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/tmpl/-/tmpl-1.0.5.tgz} + name: tmpl + version: 1.0.5 + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + to-fast-properties@https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz} + name: to-fast-properties + version: 2.0.0 + engines: {node: '>=4'} + + to-object-path@0.3.0: + resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} + engines: {node: '>=0.10.0'} + + to-regex-range@2.1.1: + resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==} + engines: {node: '>=0.10.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + to-regex-range@https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz} + name: to-regex-range + version: 5.0.1 + engines: {node: '>=8.0'} + + to-regex@3.0.2: + resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} + engines: {node: '>=0.10.0'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + tough-cookie@https://registry.npmmirror.com/tough-cookie/-/tough-cookie-4.1.3.tgz: + resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/tough-cookie/-/tough-cookie-4.1.3.tgz} + name: tough-cookie + version: 4.1.3 + engines: {node: '>=6'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + tr46@https://registry.npmmirror.com/tr46/-/tr46-2.1.0.tgz: + resolution: {integrity: sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/tr46/-/tr46-2.1.0.tgz} + name: tr46 + version: 2.1.0 + engines: {node: '>=8'} + + traverse@0.3.9: + resolution: {integrity: sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==} + + traverse@0.6.7: + resolution: {integrity: sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==} + + trim-newlines@4.1.1: + resolution: {integrity: sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ==} + engines: {node: '>=12'} + + trim-newlines@https://registry.npmmirror.com/trim-newlines/-/trim-newlines-3.0.1.tgz: + resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/trim-newlines/-/trim-newlines-3.0.1.tgz} + name: trim-newlines + version: 3.0.1 + engines: {node: '>=8'} + + ts-morph@18.0.0: + resolution: {integrity: sha512-Kg5u0mk19PIIe4islUI/HWRvm9bC1lHejK4S0oh1zaZ77TMZAEmQC0sHQYiu2RgCQFZKXz1fMVi/7nOOeirznA==} + + ts-node@https://registry.npmmirror.com/ts-node/-/ts-node-10.9.1.tgz: + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ts-node/-/ts-node-10.9.1.tgz} + name: ts-node + version: 10.9.1 + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + + tslib@https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz: + resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz} + name: tslib + version: 2.3.0 + + tslib@https://registry.npmmirror.com/tslib/-/tslib-2.6.2.tgz: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/tslib/-/tslib-2.6.2.tgz} + name: tslib + version: 2.6.2 + + turbo-darwin-64@1.10.14: + resolution: {integrity: sha512-I8RtFk1b9UILAExPdG/XRgGQz95nmXPE7OiGb6ytjtNIR5/UZBS/xVX/7HYpCdmfriKdVwBKhalCoV4oDvAGEg==, tarball: https://registry.npmmirror.com/turbo-darwin-64/-/turbo-darwin-64-1.10.14.tgz} + cpu: [x64] + os: [darwin] + + turbo-darwin-arm64@1.10.14: + resolution: {integrity: sha512-KAdUWryJi/XX7OD0alOuOa0aJ5TLyd4DNIYkHPHYcM6/d7YAovYvxRNwmx9iv6Vx6IkzTnLeTiUB8zy69QkG9Q==, tarball: https://registry.npmmirror.com/turbo-darwin-arm64/-/turbo-darwin-arm64-1.10.14.tgz} + cpu: [arm64] + os: [darwin] + + turbo-linux-64@1.10.14: + resolution: {integrity: sha512-BOBzoREC2u4Vgpap/WDxM6wETVqVMRcM8OZw4hWzqCj2bqbQ6L0wxs1LCLWVrghQf93JBQtIGAdFFLyCSBXjWQ==, tarball: https://registry.npmmirror.com/turbo-linux-64/-/turbo-linux-64-1.10.14.tgz} + cpu: [x64] + os: [linux] + + turbo-linux-arm64@1.10.14: + resolution: {integrity: sha512-D8T6XxoTdN5D4V5qE2VZG+/lbZX/89BkAEHzXcsSUTRjrwfMepT3d2z8aT6hxv4yu8EDdooZq/2Bn/vjMI32xw==, tarball: https://registry.npmmirror.com/turbo-linux-arm64/-/turbo-linux-arm64-1.10.14.tgz} + cpu: [arm64] + os: [linux] + + turbo-windows-64@1.10.14: + resolution: {integrity: sha512-zKNS3c1w4i6432N0cexZ20r/aIhV62g69opUn82FLVs/zk3Ie0GVkSB6h0rqIvMalCp7enIR87LkPSDGz9K4UA==, tarball: https://registry.npmmirror.com/turbo-windows-64/-/turbo-windows-64-1.10.14.tgz} + cpu: [x64] + os: [win32] + + turbo-windows-arm64@1.10.14: + resolution: {integrity: sha512-rkBwrTPTxNSOUF7of8eVvvM+BkfkhA2OvpHM94if8tVsU+khrjglilp8MTVPHlyS9byfemPAmFN90oRIPB05BA==, tarball: https://registry.npmmirror.com/turbo-windows-arm64/-/turbo-windows-arm64-1.10.14.tgz} + cpu: [arm64] + os: [win32] + + turbo@https://registry.npmmirror.com/turbo/-/turbo-1.10.14.tgz: + resolution: {integrity: sha512-hr9wDNYcsee+vLkCDIm8qTtwhJ6+UAMJc3nIY6+PNgUTtXcQgHxCq8BGoL7gbABvNWv76CNbK5qL4Lp9G3ZYRA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/turbo/-/turbo-1.10.14.tgz} + name: turbo + version: 1.10.14 + hasBin: true + + type-detect@https://registry.npmmirror.com/type-detect/-/type-detect-4.0.8.tgz: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/type-detect/-/type-detect-4.0.8.tgz} + name: type-detect + version: 4.0.8 + engines: {node: '>=4'} + + type-fest@1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + + type-fest@https://registry.npmmirror.com/type-fest/-/type-fest-0.18.1.tgz: + resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/type-fest/-/type-fest-0.18.1.tgz} + name: type-fest + version: 0.18.1 + engines: {node: '>=10'} + + type-fest@https://registry.npmmirror.com/type-fest/-/type-fest-0.21.3.tgz: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/type-fest/-/type-fest-0.21.3.tgz} + name: type-fest + version: 0.21.3 + engines: {node: '>=10'} + + type-fest@https://registry.npmmirror.com/type-fest/-/type-fest-0.6.0.tgz: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/type-fest/-/type-fest-0.6.0.tgz} + name: type-fest + version: 0.6.0 + engines: {node: '>=8'} + + type-fest@https://registry.npmmirror.com/type-fest/-/type-fest-0.8.1.tgz: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/type-fest/-/type-fest-0.8.1.tgz} + name: type-fest + version: 0.8.1 + engines: {node: '>=8'} + + typedarray-to-buffer@https://registry.npmmirror.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz} + name: typedarray-to-buffer + version: 3.1.5 + + typescript@https://registry.npmmirror.com/typescript/-/typescript-5.0.4.tgz: + resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/typescript/-/typescript-5.0.4.tgz} + name: typescript + version: 5.0.4 + engines: {node: '>=12.20'} + hasBin: true + + typescript@https://registry.npmmirror.com/typescript/-/typescript-5.2.2.tgz: + resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/typescript/-/typescript-5.2.2.tgz} + name: typescript + version: 5.2.2 + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.3.0: + resolution: {integrity: sha512-bRn3CsoojyNStCZe0BG0Mt4Nr/4KF+rhFlnNXybgqt5pXHNFRlqinSoQaTrGyzE4X8aHplSb+TorH+COin9Yxw==} + + unbuild@1.2.1: + resolution: {integrity: sha512-J4efk69Aye43tWcBPCsLK7TIRppGrEN4pAlDzRKo3HSE6MgTSTBxSEuE3ccx7ixc62JvGQ/CoFXYqqF2AHozow==} + hasBin: true + + unconfig@0.3.10: + resolution: {integrity: sha512-tj317lhIq2iZF/NXrJnU1t2UaGUKKz1eL1sK2t63Oq66V9BxqvZV12m55fp/fpQJ+DDmVlLgo7cnLVOZkhlO/A==} + + union-value@1.0.1: + resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} + engines: {node: '>=0.10.0'} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + universalify@2.0.0: + resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} + engines: {node: '>= 10.0.0'} + + universalify@https://registry.npmmirror.com/universalify/-/universalify-0.2.0.tgz: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/universalify/-/universalify-0.2.0.tgz} + name: universalify + version: 0.2.0 + engines: {node: '>= 4.0.0'} + + universalify@https://registry.npmmirror.com/universalify/-/universalify-2.0.0.tgz: + resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/universalify/-/universalify-2.0.0.tgz} + name: universalify + version: 2.0.0 + engines: {node: '>= 10.0.0'} + + unocss@0.55.3: + resolution: {integrity: sha512-laHtypsgqXQ8798h8cYO1fkxPumSQG8Y7GDvvSY1TWmha+mbl1YzbHqakxiJvoThJrMFLiwmpZ2vD7KFbzfGfg==} + engines: {node: '>=14'} + peerDependencies: + '@unocss/webpack': 0.55.3 + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 + peerDependenciesMeta: + '@unocss/webpack': + optional: true + vite: + optional: true + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + unpipe@https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz} + name: unpipe + version: 1.0.0 + engines: {node: '>= 0.8'} + + unplugin-vue-define-options@1.3.17: + resolution: {integrity: sha512-spyaVoPTsPo4+yCKWMH9C4h+FYzL/XTm2ypT/Y6G9+0Np/pENHSACeN9HXQwtKlS+O1ID3QNg7XYDHHMAh/xLQ==} + engines: {node: '>=16.14.0'} + + unplugin@1.4.0: + resolution: {integrity: sha512-5x4eIEL6WgbzqGtF9UV8VEC/ehKptPXDS6L2b0mv4FRMkJxRtjaJfOWDd6a8+kYbqsjklix7yWP0N3SUepjXcg==} + + unset-value@1.0.0: + resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} + engines: {node: '>=0.10.0'} + + untildify@https://registry.npmmirror.com/untildify/-/untildify-4.0.0.tgz: + resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/untildify/-/untildify-4.0.0.tgz} + name: untildify + version: 4.0.0 + engines: {node: '>=8'} + + untyped@1.4.0: + resolution: {integrity: sha512-Egkr/s4zcMTEuulcIb7dgURS6QpN7DyqQYdf+jBtiaJvQ+eRsrtWUoX84SbvQWuLkXsOjM+8sJC9u6KoMK/U7Q==} + hasBin: true + + unzipper@0.10.14: + resolution: {integrity: sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==} + + update-browserslist-db@1.0.11: + resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + update-browserslist-db@https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz: + resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz} + name: update-browserslist-db + version: 1.0.11 + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + uri-js@https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz} + name: uri-js + version: 4.4.1 + + urix@0.1.0: + resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} + deprecated: Please see https://github.com/lydell/urix#deprecated + + url-parse@https://registry.npmmirror.com/url-parse/-/url-parse-1.5.10.tgz: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/url-parse/-/url-parse-1.5.10.tgz} + name: url-parse + version: 1.5.10 + + use@3.1.1: + resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} + engines: {node: '>=0.10.0'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + util-deprecate@https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz} + name: util-deprecate + version: 1.0.2 + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + utils-merge@https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz} + name: utils-merge + version: 1.0.1 + engines: {node: '>= 0.4.0'} + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + v8-compile-cache-lib@https://registry.npmmirror.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz} + name: v8-compile-cache-lib + version: 3.0.1 + + v8-to-istanbul@https://registry.npmmirror.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz: + resolution: {integrity: sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz} + name: v8-to-istanbul + version: 8.1.1 + engines: {node: '>=10.12.0'} + + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + validate-npm-package-license@https://registry.npmmirror.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz} + name: validate-npm-package-license + version: 3.0.4 + + validator@13.11.0: + resolution: {integrity: sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==} + engines: {node: '>= 0.10'} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vditor@https://registry.npmmirror.com/vditor/-/vditor-3.9.5.tgz: + resolution: {integrity: sha512-yRFyEOoJ0GQGAjfzDBV9ZKemCleqspSf3Jg3XtKVj8RwnjnF6oScLQCAwSgRzCamYl+F+rIX9at0c3tEsatY/A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vditor/-/vditor-3.9.5.tgz} + name: vditor + version: 3.9.5 + + vite-plugin-compression@0.5.1: + resolution: {integrity: sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg==} + peerDependencies: + vite: '>=2.0.0' + + vite-plugin-dts@2.3.0: + resolution: {integrity: sha512-WbJgGtsStgQhdm3EosYmIdTGbag5YQpZ3HXWUAPCDyoXI5qN6EY0V7NXq0lAmnv9hVQsvh0htbYcg0Or5Db9JQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: '>=2.9.0' + + vite-plugin-html@3.2.0: + resolution: {integrity: sha512-2VLCeDiHmV/BqqNn5h2V+4280KRgQzCFN47cst3WiNK848klESPQnzuC3okH5XHtgwHH/6s1Ho/YV6yIO0pgoQ==} + peerDependencies: + vite: '>=2.0.0' + + vite-plugin-mock@3.0.0: + resolution: {integrity: sha512-Ibwlga2CSgkoFHFtPW3T/l0fwsGVz9Ss5i7HauBQDyDFfMKgbQXh9wKDLksLZHyai9rkDanxJtIcxbD0bUHCfw==} + engines: {node: '>=16.0.0'} + peerDependencies: + mockjs: '>=1.1.0' + vite: '>=4.0.0' + + vite-plugin-mock@https://registry.npmmirror.com/vite-plugin-mock/-/vite-plugin-mock-2.9.8.tgz: + resolution: {integrity: sha512-YTQM5Sn7t+/DNOwTkr+W26QGTCk1PrDkhGHslTJ90lIPJhJtDTwuSkEYMAuLP9TcVQ/qExTFx/x/GE3kxJ05sw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vite-plugin-mock/-/vite-plugin-mock-2.9.8.tgz} + name: vite-plugin-mock + version: 2.9.8 + engines: {node: '>=12.0.0'} + peerDependencies: + mockjs: '>=1.1.0' + vite: '>=2.0.0' + + vite-plugin-purge-icons@0.9.2: + resolution: {integrity: sha512-vxJEMyNyckqLr/4HPsW9P6BMLUvOVMvjjFz3jLl4Wke1KWE8ITJUxIUwodxaOmEp9L2lxVk5an3TYeycZCfqFw==} + engines: {node: '>= 12'} + peerDependencies: + vite: ^2.0.0 || ^3.0.0 || ^4.0.0 + + vite-plugin-svg-icons@2.0.1: + resolution: {integrity: sha512-6ktD+DhV6Rz3VtedYvBKKVA2eXF+sAQVaKkKLDSqGUfnhqXl3bj5PPkVTl3VexfTuZy66PmINi8Q6eFnVfRUmA==} + peerDependencies: + vite: '>=2.0.0' + + vite@4.4.9: + resolution: {integrity: sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vite@https://registry.npmmirror.com/vite/-/vite-4.4.9.tgz: + resolution: {integrity: sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vite/-/vite-4.4.9.tgz} + name: vite + version: 4.4.9 + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vue-component-type-helpers@https://registry.npmmirror.com/vue-component-type-helpers/-/vue-component-type-helpers-1.8.4.tgz: + resolution: {integrity: sha512-6bnLkn8O0JJyiFSIF0EfCogzeqNXpnjJ0vW/SZzNHfe6sPx30lTtTXlE5TFs2qhJlAtDFybStVNpL73cPe3OMQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vue-component-type-helpers/-/vue-component-type-helpers-1.8.4.tgz} + name: vue-component-type-helpers + version: 1.8.4 + + vue-demi@0.14.0: + resolution: {integrity: sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-demi@https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.6.tgz: + resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.6.tgz} + name: vue-demi + version: 0.14.6 + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-i18n@9.2.2: + resolution: {integrity: sha512-yswpwtj89rTBhegUAv9Mu37LNznyu3NpyLQmozF3i1hYOhwpG8RjcjIFIIfnu+2MDZJGSZPXaKWvnQA71Yv9TQ==} + engines: {node: '>= 14'} + peerDependencies: + vue: ^3.0.0 + + vue-json-pretty@2.2.4: + resolution: {integrity: sha512-JX80b3QDrspcH43C53CdtYeq/froApQGSV5y43bEMWFj2LGOxB96aH1VmvrFA21nD1WTP6nwfFMQqGXuS4jyFQ==} + engines: {node: '>= 10.0.0', npm: '>= 5.0.0'} + peerDependencies: + vue: '>=3.0.0' + + vue-router@https://registry.npmmirror.com/vue-router/-/vue-router-4.2.4.tgz: + resolution: {integrity: sha512-9PISkmaCO02OzPVOMq2w82ilty6+xJmQrarYZDkjZBfl4RvYAlt4PKnEX21oW4KTtWfa9OuO/b3qk1Od3AEdCQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vue-router/-/vue-router-4.2.4.tgz} + name: vue-router + version: 4.2.4 + peerDependencies: + vue: ^3.2.0 + + vue-template-compiler@https://registry.npmmirror.com/vue-template-compiler/-/vue-template-compiler-2.7.14.tgz: + resolution: {integrity: sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vue-template-compiler/-/vue-template-compiler-2.7.14.tgz} + name: vue-template-compiler + version: 2.7.14 + + vue-tsc@https://registry.npmmirror.com/vue-tsc/-/vue-tsc-1.8.8.tgz: + resolution: {integrity: sha512-bSydNFQsF7AMvwWsRXD7cBIXaNs/KSjvzWLymq/UtKE36697sboX4EccSHFVxvgdBlI1frYPc/VMKJNB7DFeDQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vue-tsc/-/vue-tsc-1.8.8.tgz} + name: vue-tsc + version: 1.8.8 + hasBin: true + peerDependencies: + typescript: '*' + + vue-types@https://registry.npmmirror.com/vue-types/-/vue-types-3.0.2.tgz: + resolution: {integrity: sha512-IwUC0Aq2zwaXqy74h4WCvFCUtoV0iSWr0snWnE9TnU18S66GAQyqQbRf2qfJtUuiFsBf6qp0MEwdonlwznlcrw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vue-types/-/vue-types-3.0.2.tgz} + name: vue-types + version: 3.0.2 + engines: {node: '>=10.15.0'} + peerDependencies: + vue: ^3.0.0 + + vue-types@https://registry.npmmirror.com/vue-types/-/vue-types-5.1.1.tgz: + resolution: {integrity: sha512-FMY/JCLWePXgGIcMDqYdJsQm1G0CDxEjq6W0+tZMJZlX37q/61eSGSIa/XFRwa9T7kkKXuxxl94/2kgxyWQqKw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vue-types/-/vue-types-5.1.1.tgz} + name: vue-types + version: 5.1.1 + engines: {node: '>=14.0.0'} + peerDependencies: + vue: ^2.0.0 || ^3.0.0 + peerDependenciesMeta: + vue: + optional: true + + vue@3.2.47: + resolution: {integrity: sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==} + + vue@3.3.4: + resolution: {integrity: sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==} + + vuedraggable@https://registry.npmmirror.com/vuedraggable/-/vuedraggable-4.1.0.tgz: + resolution: {integrity: sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vuedraggable/-/vuedraggable-4.1.0.tgz} + name: vuedraggable + version: 4.1.0 + peerDependencies: + vue: ^3.0.1 + + vxe-table-plugin-export-xlsx@https://registry.npmmirror.com/vxe-table-plugin-export-xlsx/-/vxe-table-plugin-export-xlsx-3.1.0.tgz: + resolution: {integrity: sha512-ieEsN6h+QaKHgwQ6k1MtjvW17T+FCS9Bw2Xhg67HKIbuLMS+SprcF+EBrMtHIOfzQ2i41KAoLsCvXRbd5uChAA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vxe-table-plugin-export-xlsx/-/vxe-table-plugin-export-xlsx-3.1.0.tgz} + name: vxe-table-plugin-export-xlsx + version: 3.1.0 + peerDependencies: + vxe-table: ^4.5.0 + + vxe-table@https://registry.npmmirror.com/vxe-table/-/vxe-table-4.5.14.tgz: + resolution: {integrity: sha512-S+6pAYQsoY5DZj9qLXQLDKcA/+AO5CSrs9tGn+/By8WxYWJNLw3i5cjbXsriUaJeuj8Qi1aYfdhrNfeMCwE9Iw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vxe-table/-/vxe-table-4.5.14.tgz} + name: vxe-table + version: 4.5.14 + peerDependencies: + vue: ^3.2.28 + xe-utils: ^3.5.0 + + w3c-hr-time@https://registry.npmmirror.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz: + resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz} + name: w3c-hr-time + version: 1.0.2 + deprecated: Use your platform's native performance.now() and performance.timeOrigin. + + w3c-keyname@2.2.8: + resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==, tarball: https://registry.npmmirror.com/w3c-keyname/-/w3c-keyname-2.2.8.tgz} + + w3c-xmlserializer@https://registry.npmmirror.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz: + resolution: {integrity: sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz} + name: w3c-xmlserializer + version: 2.0.0 + engines: {node: '>=10'} + + walker@https://registry.npmmirror.com/walker/-/walker-1.0.8.tgz: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/walker/-/walker-1.0.8.tgz} + name: walker + version: 1.0.8 + + warning@https://registry.npmmirror.com/warning/-/warning-4.0.3.tgz: + resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/warning/-/warning-4.0.3.tgz} + name: warning + version: 4.0.3 + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + webidl-conversions@https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz: + resolution: {integrity: sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz} + name: webidl-conversions + version: 5.0.0 + engines: {node: '>=8'} + + webidl-conversions@https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz: + resolution: {integrity: sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz} + name: webidl-conversions + version: 6.1.0 + engines: {node: '>=10.4'} + + webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + + webpack-virtual-modules@0.5.0: + resolution: {integrity: sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==} + + whatwg-encoding@https://registry.npmmirror.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz: + resolution: {integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz} + name: whatwg-encoding + version: 1.0.5 + + whatwg-mimetype@https://registry.npmmirror.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz: + resolution: {integrity: sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz} + name: whatwg-mimetype + version: 2.3.0 + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + whatwg-url@https://registry.npmmirror.com/whatwg-url/-/whatwg-url-8.7.0.tgz: + resolution: {integrity: sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/whatwg-url/-/whatwg-url-8.7.0.tgz} + name: whatwg-url + version: 8.7.0 + engines: {node: '>=10'} + + which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + which@https://registry.npmmirror.com/which/-/which-2.0.2.tgz: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/which/-/which-2.0.2.tgz} + name: which + version: 2.0.2 + engines: {node: '>= 8'} + hasBin: true + + wmf@1.0.2: + resolution: {integrity: sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==} + engines: {node: '>=0.8'} + + word@0.3.0: + resolution: {integrity: sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==} + engines: {node: '>=0.8'} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz} + name: wrap-ansi + version: 6.2.0 + engines: {node: '>=8'} + + wrap-ansi@https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz} + name: wrap-ansi + version: 7.0.0 + engines: {node: '>=10'} + + wrap-ansi@https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz} + name: wrap-ansi + version: 8.1.0 + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + wrappy@https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz} + name: wrappy + version: 1.0.2 + + write-file-atomic@5.0.1: + resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + write-file-atomic@https://registry.npmmirror.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz: + resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz} + name: write-file-atomic + version: 3.0.3 + + ws@https://registry.npmmirror.com/ws/-/ws-7.5.9.tgz: + resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ws/-/ws-7.5.9.tgz} + name: ws + version: 7.5.9 + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xe-utils@https://registry.npmmirror.com/xe-utils/-/xe-utils-3.5.12.tgz: + resolution: {integrity: sha512-g+KntGC41vYJ+GzDngy28LIGAu3kSfhQxiprYxv1P6jP3DRVLNnTruBFD4WIVmMF2AUm1o23IMyAcQ10m2XSyQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/xe-utils/-/xe-utils-3.5.12.tgz} + name: xe-utils + version: 3.5.12 + + xlsx@0.18.5: + resolution: {integrity: sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==} + engines: {node: '>=0.8'} + hasBin: true + + xml-name-validator@https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz: + resolution: {integrity: sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz} + name: xml-name-validator + version: 3.0.0 + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + + xmlchars@https://registry.npmmirror.com/xmlchars/-/xmlchars-2.2.0.tgz: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/xmlchars/-/xmlchars-2.2.0.tgz} + name: xmlchars + version: 2.2.0 + + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + y18n@https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz} + name: y18n + version: 5.0.8 + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yallist@https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz} + name: yallist + version: 3.1.1 + + yallist@https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz} + name: yallist + version: 4.0.0 + + yaml@https://registry.npmmirror.com/yaml/-/yaml-2.3.2.tgz: + resolution: {integrity: sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/yaml/-/yaml-2.3.2.tgz} + name: yaml + version: 2.3.2 + engines: {node: '>= 14'} + + yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + + yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs-parser@https://registry.npmmirror.com/yargs-parser/-/yargs-parser-20.2.9.tgz: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/yargs-parser/-/yargs-parser-20.2.9.tgz} + name: yargs-parser + version: 20.2.9 + engines: {node: '>=10'} + + yargs-parser@https://registry.npmmirror.com/yargs-parser/-/yargs-parser-21.1.1.tgz: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/yargs-parser/-/yargs-parser-21.1.1.tgz} + name: yargs-parser + version: 21.1.1 + engines: {node: '>=12'} + + yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yargs@https://registry.npmmirror.com/yargs/-/yargs-16.2.0.tgz: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/yargs/-/yargs-16.2.0.tgz} + name: yargs + version: 16.2.0 + engines: {node: '>=10'} + + yargs@https://registry.npmmirror.com/yargs/-/yargs-17.7.2.tgz: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/yargs/-/yargs-17.7.2.tgz} + name: yargs + version: 17.7.2 + engines: {node: '>=12'} + + yn@https://registry.npmmirror.com/yn/-/yn-3.1.1.tgz: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/yn/-/yn-3.1.1.tgz} + name: yn + version: 3.1.1 + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yocto-queue@https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz} + name: yocto-queue + version: 0.1.0 + engines: {node: '>=10'} + + z-schema@5.0.5: + resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} + engines: {node: '>=8.0.0'} + hasBin: true + + zeebe-bpmn-moddle@1.0.0: + resolution: {integrity: sha512-ZXEe+0s6Z1jf0hfK4VfRr71p4FcXkYz+MxVx6vMCiey2KVZqY1uj6KCpzK9+tEJzTdxGRS3FymK3oxAkjzs1GA==, tarball: https://registry.npmmirror.com/zeebe-bpmn-moddle/-/zeebe-bpmn-moddle-1.0.0.tgz} + + zip-stream@4.1.0: + resolution: {integrity: sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==} + engines: {node: '>= 10'} + + zrender@https://registry.npmmirror.com/zrender/-/zrender-5.4.4.tgz: + resolution: {integrity: sha512-0VxCNJ7AGOMCWeHVyTrGzUgrK4asT4ml9PEkeGirAkKNYXYzoPJCLvmyfdoOXcjTHPs10OZVMfD1Rwg16AZyYw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/zrender/-/zrender-5.4.4.tgz} + name: zrender + version: 5.4.4 + +snapshots: + + '@ampproject/remapping@2.2.1': + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.19 + + '@ampproject/remapping@https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.1.tgz': + dependencies: + '@jridgewell/gen-mapping': https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz + '@jridgewell/trace-mapping': https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz + + '@ant-design/colors@6.0.0': + dependencies: + '@ctrl/tinycolor': https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz + + '@ant-design/colors@7.0.0': + dependencies: + '@ctrl/tinycolor': 3.6.1 + + '@ant-design/colors@https://registry.npmmirror.com/@ant-design/colors/-/colors-6.0.0.tgz': + dependencies: + '@ctrl/tinycolor': https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz + + '@ant-design/icons-svg@4.3.1': {} + + '@ant-design/icons-svg@https://registry.npmmirror.com/@ant-design/icons-svg/-/icons-svg-4.3.1.tgz': {} + + '@ant-design/icons-vue@6.1.0(vue@3.3.4)': + dependencies: + '@ant-design/colors': 6.0.0 + '@ant-design/icons-svg': 4.3.1 + vue: 3.3.4 + + '@ant-design/icons-vue@https://registry.npmmirror.com/@ant-design/icons-vue/-/icons-vue-7.0.0.tgz(vue@3.3.4)': + dependencies: + '@ant-design/colors': https://registry.npmmirror.com/@ant-design/colors/-/colors-6.0.0.tgz + '@ant-design/icons-svg': https://registry.npmmirror.com/@ant-design/icons-svg/-/icons-svg-4.3.1.tgz + vue: 3.3.4 + + '@antfu/install-pkg@0.1.1': + dependencies: + execa: https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz + find-up: 5.0.0 + + '@antfu/utils@0.7.6': {} + + '@axolo/tree-array@https://registry.npmmirror.com/@axolo/tree-array/-/tree-array-0.1.0.tgz': {} + + '@babel/code-frame@7.21.4': + dependencies: + '@babel/highlight': 7.18.6 + + '@babel/code-frame@7.22.13': + dependencies: + '@babel/highlight': 7.22.13 + chalk: https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz + + '@babel/compat-data@7.22.9': {} + + '@babel/compat-data@https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.22.9.tgz': {} + + '@babel/core@7.22.11': + dependencies: + '@ampproject/remapping': 2.2.1 + '@babel/code-frame': 7.22.13 + '@babel/generator': 7.22.10 + '@babel/helper-compilation-targets': 7.22.10 + '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.11) + '@babel/helpers': 7.22.11 + '@babel/parser': 7.22.13 + '@babel/template': 7.22.5 + '@babel/traverse': 7.22.11 + '@babel/types': 7.22.11 + convert-source-map: 1.9.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/core@https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz': + dependencies: + '@ampproject/remapping': https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.1.tgz + '@babel/code-frame': 7.22.13 + '@babel/generator': https://registry.npmmirror.com/@babel/generator/-/generator-7.22.10.tgz + '@babel/helper-compilation-targets': https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz + '@babel/helper-module-transforms': https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz(@babel/core@7.22.11) + '@babel/helpers': https://registry.npmmirror.com/@babel/helpers/-/helpers-7.22.11.tgz + '@babel/parser': https://registry.npmmirror.com/@babel/parser/-/parser-7.22.13.tgz + '@babel/template': https://registry.npmmirror.com/@babel/template/-/template-7.22.5.tgz + '@babel/traverse': https://registry.npmmirror.com/@babel/traverse/-/traverse-7.22.11.tgz + '@babel/types': https://registry.npmmirror.com/@babel/types/-/types-7.22.11.tgz + convert-source-map: https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.9.0.tgz + debug: https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz + gensync: https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz + json5: https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz + semver: https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.22.10': + dependencies: + '@babel/types': 7.22.11 + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.19 + jsesc: 2.5.2 + + '@babel/generator@https://registry.npmmirror.com/@babel/generator/-/generator-7.22.10.tgz': + dependencies: + '@babel/types': https://registry.npmmirror.com/@babel/types/-/types-7.22.11.tgz + '@jridgewell/gen-mapping': https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz + '@jridgewell/trace-mapping': https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz + jsesc: https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz + + '@babel/helper-annotate-as-pure@7.22.5': + dependencies: + '@babel/types': 7.22.11 + + '@babel/helper-compilation-targets@7.22.10': + dependencies: + '@babel/compat-data': 7.22.9 + '@babel/helper-validator-option': 7.22.5 + browserslist: 4.21.10 + lru-cache: 5.1.1 + semver: https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz + + '@babel/helper-compilation-targets@https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz': + dependencies: + '@babel/compat-data': https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.22.9.tgz + '@babel/helper-validator-option': https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz + browserslist: https://registry.npmmirror.com/browserslist/-/browserslist-4.21.10.tgz + lru-cache: https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz + semver: https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz + + '@babel/helper-create-class-features-plugin@7.22.11(@babel/core@7.22.11)': + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-member-expression-to-functions': 7.22.5 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-replace-supers': 7.22.9(@babel/core@7.22.11) + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + semver: https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz + + '@babel/helper-environment-visitor@7.22.5': {} + + '@babel/helper-environment-visitor@https://registry.npmmirror.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz': {} + + '@babel/helper-function-name@7.22.5': + dependencies: + '@babel/template': 7.22.5 + '@babel/types': 7.22.11 + + '@babel/helper-function-name@https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz': + dependencies: + '@babel/template': https://registry.npmmirror.com/@babel/template/-/template-7.22.5.tgz + '@babel/types': https://registry.npmmirror.com/@babel/types/-/types-7.22.11.tgz + + '@babel/helper-hoist-variables@7.22.5': + dependencies: + '@babel/types': 7.22.11 + + '@babel/helper-hoist-variables@https://registry.npmmirror.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz': + dependencies: + '@babel/types': https://registry.npmmirror.com/@babel/types/-/types-7.22.11.tgz + + '@babel/helper-member-expression-to-functions@7.22.5': + dependencies: + '@babel/types': 7.22.11 + + '@babel/helper-module-imports@7.22.5': + dependencies: + '@babel/types': 7.22.11 + + '@babel/helper-module-imports@https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz': + dependencies: + '@babel/types': https://registry.npmmirror.com/@babel/types/-/types-7.22.11.tgz + + '@babel/helper-module-transforms@7.22.9(@babel/core@7.22.11)': + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-module-imports': 7.22.5 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.5 + + '@babel/helper-module-transforms@https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz(@babel/core@7.22.11)': + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + '@babel/helper-environment-visitor': https://registry.npmmirror.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz + '@babel/helper-module-imports': https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz + '@babel/helper-simple-access': https://registry.npmmirror.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz + '@babel/helper-split-export-declaration': https://registry.npmmirror.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz + '@babel/helper-validator-identifier': https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz + + '@babel/helper-optimise-call-expression@7.22.5': + dependencies: + '@babel/types': 7.22.11 + + '@babel/helper-plugin-utils@7.22.5': {} + + '@babel/helper-plugin-utils@https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz': {} + + '@babel/helper-replace-supers@7.22.9(@babel/core@7.22.11)': + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-member-expression-to-functions': 7.22.5 + '@babel/helper-optimise-call-expression': 7.22.5 + + '@babel/helper-simple-access@7.22.5': + dependencies: + '@babel/types': 7.22.11 + + '@babel/helper-simple-access@https://registry.npmmirror.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz': + dependencies: + '@babel/types': https://registry.npmmirror.com/@babel/types/-/types-7.22.11.tgz + + '@babel/helper-skip-transparent-expression-wrappers@7.22.5': + dependencies: + '@babel/types': 7.22.11 + + '@babel/helper-split-export-declaration@7.22.6': + dependencies: + '@babel/types': 7.22.11 + + '@babel/helper-split-export-declaration@https://registry.npmmirror.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz': + dependencies: + '@babel/types': https://registry.npmmirror.com/@babel/types/-/types-7.22.11.tgz + + '@babel/helper-string-parser@7.22.5': {} + + '@babel/helper-string-parser@https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz': {} + + '@babel/helper-validator-identifier@7.19.1': {} + + '@babel/helper-validator-identifier@7.22.5': {} + + '@babel/helper-validator-identifier@https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz': {} + + '@babel/helper-validator-option@7.22.5': {} + + '@babel/helper-validator-option@https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz': {} + + '@babel/helpers@7.22.11': + dependencies: + '@babel/template': 7.22.5 + '@babel/traverse': 7.22.11 + '@babel/types': 7.22.11 + transitivePeerDependencies: + - supports-color + + '@babel/helpers@https://registry.npmmirror.com/@babel/helpers/-/helpers-7.22.11.tgz': + dependencies: + '@babel/template': https://registry.npmmirror.com/@babel/template/-/template-7.22.5.tgz + '@babel/traverse': https://registry.npmmirror.com/@babel/traverse/-/traverse-7.22.11.tgz + '@babel/types': https://registry.npmmirror.com/@babel/types/-/types-7.22.11.tgz + transitivePeerDependencies: + - supports-color + + '@babel/highlight@7.18.6': + dependencies: + '@babel/helper-validator-identifier': 7.19.1 + chalk: https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz + js-tokens: https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz + + '@babel/highlight@7.22.13': + dependencies: + '@babel/helper-validator-identifier': 7.22.5 + chalk: https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz + js-tokens: https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz + + '@babel/parser@7.22.10': + dependencies: + '@babel/types': 7.22.10 + + '@babel/parser@7.22.13': + dependencies: + '@babel/types': 7.22.11 + + '@babel/parser@https://registry.npmmirror.com/@babel/parser/-/parser-7.22.13.tgz': + dependencies: + '@babel/types': https://registry.npmmirror.com/@babel/types/-/types-7.22.11.tgz + + '@babel/plugin-syntax-async-generators@https://registry.npmmirror.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz(@babel/core@7.22.11)': + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + '@babel/helper-plugin-utils': https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz + + '@babel/plugin-syntax-bigint@https://registry.npmmirror.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz(@babel/core@7.22.11)': + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + '@babel/helper-plugin-utils': https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz + + '@babel/plugin-syntax-class-properties@https://registry.npmmirror.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz(@babel/core@7.22.11)': + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + '@babel/helper-plugin-utils': https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz + + '@babel/plugin-syntax-import-meta@https://registry.npmmirror.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz(@babel/core@7.22.11)': + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + '@babel/helper-plugin-utils': https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz + + '@babel/plugin-syntax-json-strings@https://registry.npmmirror.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz(@babel/core@7.22.11)': + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + '@babel/helper-plugin-utils': https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz + + '@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.22.11)': + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-plugin-utils': 7.22.5 + + '@babel/plugin-syntax-logical-assignment-operators@https://registry.npmmirror.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz(@babel/core@7.22.11)': + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + '@babel/helper-plugin-utils': https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz + + '@babel/plugin-syntax-nullish-coalescing-operator@https://registry.npmmirror.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz(@babel/core@7.22.11)': + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + '@babel/helper-plugin-utils': https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz + + '@babel/plugin-syntax-numeric-separator@https://registry.npmmirror.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz(@babel/core@7.22.11)': + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + '@babel/helper-plugin-utils': https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz + + '@babel/plugin-syntax-object-rest-spread@https://registry.npmmirror.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz(@babel/core@7.22.11)': + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + '@babel/helper-plugin-utils': https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz + + '@babel/plugin-syntax-optional-catch-binding@https://registry.npmmirror.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz(@babel/core@7.22.11)': + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + '@babel/helper-plugin-utils': https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz + + '@babel/plugin-syntax-optional-chaining@https://registry.npmmirror.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz(@babel/core@7.22.11)': + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + '@babel/helper-plugin-utils': https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz + + '@babel/plugin-syntax-top-level-await@https://registry.npmmirror.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz(@babel/core@7.22.11)': + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + '@babel/helper-plugin-utils': https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz + + '@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.22.11)': + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-plugin-utils': 7.22.5 + + '@babel/plugin-syntax-typescript@https://registry.npmmirror.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz(@babel/core@7.22.11)': + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + '@babel/helper-plugin-utils': https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz + + '@babel/plugin-transform-typescript@7.22.11(@babel/core@7.22.11)': + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.22.11(@babel/core@7.22.11) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.22.11) + + '@babel/runtime@https://registry.npmmirror.com/@babel/runtime/-/runtime-7.22.11.tgz': + dependencies: + regenerator-runtime: https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz + + '@babel/standalone@7.22.13': {} + + '@babel/template@7.22.5': + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/parser': 7.22.13 + '@babel/types': 7.22.11 + + '@babel/template@https://registry.npmmirror.com/@babel/template/-/template-7.22.5.tgz': + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/parser': https://registry.npmmirror.com/@babel/parser/-/parser-7.22.13.tgz + '@babel/types': https://registry.npmmirror.com/@babel/types/-/types-7.22.11.tgz + + '@babel/traverse@7.22.11': + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/generator': 7.22.10 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.22.13 + '@babel/types': 7.22.11 + debug: https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/traverse@https://registry.npmmirror.com/@babel/traverse/-/traverse-7.22.11.tgz': + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/generator': https://registry.npmmirror.com/@babel/generator/-/generator-7.22.10.tgz + '@babel/helper-environment-visitor': https://registry.npmmirror.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz + '@babel/helper-function-name': https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz + '@babel/helper-hoist-variables': https://registry.npmmirror.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz + '@babel/helper-split-export-declaration': https://registry.npmmirror.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz + '@babel/parser': https://registry.npmmirror.com/@babel/parser/-/parser-7.22.13.tgz + '@babel/types': https://registry.npmmirror.com/@babel/types/-/types-7.22.11.tgz + debug: https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz + globals: https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz + transitivePeerDependencies: + - supports-color + + '@babel/types@7.22.10': + dependencies: + '@babel/helper-string-parser': 7.22.5 + '@babel/helper-validator-identifier': 7.22.5 + to-fast-properties: 2.0.0 + + '@babel/types@7.22.11': + dependencies: + '@babel/helper-string-parser': 7.22.5 + '@babel/helper-validator-identifier': 7.22.5 + to-fast-properties: 2.0.0 + + '@babel/types@https://registry.npmmirror.com/@babel/types/-/types-7.22.11.tgz': + dependencies: + '@babel/helper-string-parser': https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz + '@babel/helper-validator-identifier': https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz + to-fast-properties: https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz + + '@bcoe/v8-coverage@https://registry.npmmirror.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz': {} + + '@bpmn-io/cm-theme@0.1.0-alpha.2': + dependencies: + '@codemirror/language': 6.9.3 + '@codemirror/view': 6.22.3 + '@lezer/highlight': 1.2.0 + + '@bpmn-io/diagram-js-ui@0.2.2': + dependencies: + htm: 3.1.1 + preact: 10.17.1 + + '@bpmn-io/extract-process-variables@0.8.0': + dependencies: + min-dash: 4.1.1 + + '@bpmn-io/feel-editor@1.0.1(@lezer/common@1.1.2)': + dependencies: + '@bpmn-io/feel-lint': 1.1.0 + '@codemirror/autocomplete': 6.11.1(@codemirror/language@6.9.3)(@codemirror/state@6.3.3)(@codemirror/view@6.22.3)(@lezer/common@1.1.2) + '@codemirror/commands': 6.3.2 + '@codemirror/language': 6.9.3 + '@codemirror/lint': 6.4.2 + '@codemirror/state': 6.3.3 + '@codemirror/view': 6.22.3 + '@lezer/highlight': 1.2.0 + lang-feel: 1.1.0 + min-dom: 4.1.0 + transitivePeerDependencies: + - '@lezer/common' + + '@bpmn-io/feel-lint@1.1.0': + dependencies: + '@codemirror/language': 6.9.3 + lezer-feel: 1.2.3 + + '@bpmn-io/properties-panel@3.13.0(@lezer/common@1.1.2)': + dependencies: + '@bpmn-io/feel-editor': 1.0.1(@lezer/common@1.1.2) + '@codemirror/view': 6.22.3 + classnames: 2.3.2 + feelers: 1.2.0 + focus-trap: 7.5.4 + min-dash: 4.1.1 + min-dom: 4.1.0 + transitivePeerDependencies: + - '@lezer/common' + + '@codemirror/autocomplete@6.11.1(@codemirror/language@6.9.3)(@codemirror/state@6.3.3)(@codemirror/view@6.22.3)(@lezer/common@1.1.2)': + dependencies: + '@codemirror/language': 6.9.3 + '@codemirror/state': 6.3.3 + '@codemirror/view': 6.22.3 + '@lezer/common': 1.1.2 + + '@codemirror/commands@6.3.2': + dependencies: + '@codemirror/language': 6.9.3 + '@codemirror/state': 6.3.3 + '@codemirror/view': 6.22.3 + '@lezer/common': 1.1.2 + + '@codemirror/language@6.9.3': + dependencies: + '@codemirror/state': 6.3.3 + '@codemirror/view': 6.22.3 + '@lezer/common': 1.1.2 + '@lezer/highlight': 1.2.0 + '@lezer/lr': 1.3.14 + style-mod: 4.1.0 + + '@codemirror/lint@6.4.2': + dependencies: + '@codemirror/state': 6.3.3 + '@codemirror/view': 6.22.3 + crelt: 1.0.6 + + '@codemirror/state@6.3.3': {} + + '@codemirror/view@6.22.3': + dependencies: + '@codemirror/state': 6.3.3 + style-mod: 4.1.0 + w3c-keyname: 2.2.8 + + '@commitlint/cli@https://registry.npmmirror.com/@commitlint/cli/-/cli-17.7.1.tgz': + dependencies: + '@commitlint/format': https://registry.npmmirror.com/@commitlint/format/-/format-17.4.4.tgz + '@commitlint/lint': https://registry.npmmirror.com/@commitlint/lint/-/lint-17.7.0.tgz + '@commitlint/load': https://registry.npmmirror.com/@commitlint/load/-/load-17.7.1.tgz + '@commitlint/read': https://registry.npmmirror.com/@commitlint/read/-/read-17.5.1.tgz + '@commitlint/types': https://registry.npmmirror.com/@commitlint/types/-/types-17.4.4.tgz + execa: https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz + lodash.isfunction: https://registry.npmmirror.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz + resolve-from: https://registry.npmmirror.com/resolve-from/-/resolve-from-5.0.0.tgz + resolve-global: https://registry.npmmirror.com/resolve-global/-/resolve-global-1.0.0.tgz + yargs: https://registry.npmmirror.com/yargs/-/yargs-17.7.2.tgz + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + + '@commitlint/config-conventional@https://registry.npmmirror.com/@commitlint/config-conventional/-/config-conventional-17.7.0.tgz': + dependencies: + conventional-changelog-conventionalcommits: https://registry.npmmirror.com/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz + + '@commitlint/config-validator@https://registry.npmmirror.com/@commitlint/config-validator/-/config-validator-17.6.7.tgz': + dependencies: + '@commitlint/types': https://registry.npmmirror.com/@commitlint/types/-/types-17.4.4.tgz + ajv: https://registry.npmmirror.com/ajv/-/ajv-8.12.0.tgz + + '@commitlint/ensure@https://registry.npmmirror.com/@commitlint/ensure/-/ensure-17.6.7.tgz': + dependencies: + '@commitlint/types': https://registry.npmmirror.com/@commitlint/types/-/types-17.4.4.tgz + lodash.camelcase: https://registry.npmmirror.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz + lodash.kebabcase: https://registry.npmmirror.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz + lodash.snakecase: https://registry.npmmirror.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz + lodash.startcase: https://registry.npmmirror.com/lodash.startcase/-/lodash.startcase-4.4.0.tgz + lodash.upperfirst: https://registry.npmmirror.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz + + '@commitlint/execute-rule@https://registry.npmmirror.com/@commitlint/execute-rule/-/execute-rule-17.4.0.tgz': {} + + '@commitlint/format@https://registry.npmmirror.com/@commitlint/format/-/format-17.4.4.tgz': + dependencies: + '@commitlint/types': https://registry.npmmirror.com/@commitlint/types/-/types-17.4.4.tgz + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + + '@commitlint/is-ignored@https://registry.npmmirror.com/@commitlint/is-ignored/-/is-ignored-17.7.0.tgz': + dependencies: + '@commitlint/types': https://registry.npmmirror.com/@commitlint/types/-/types-17.4.4.tgz + semver: https://registry.npmmirror.com/semver/-/semver-7.5.4.tgz + + '@commitlint/lint@https://registry.npmmirror.com/@commitlint/lint/-/lint-17.7.0.tgz': + dependencies: + '@commitlint/is-ignored': https://registry.npmmirror.com/@commitlint/is-ignored/-/is-ignored-17.7.0.tgz + '@commitlint/parse': https://registry.npmmirror.com/@commitlint/parse/-/parse-17.7.0.tgz + '@commitlint/rules': https://registry.npmmirror.com/@commitlint/rules/-/rules-17.7.0.tgz + '@commitlint/types': https://registry.npmmirror.com/@commitlint/types/-/types-17.4.4.tgz + + '@commitlint/load@https://registry.npmmirror.com/@commitlint/load/-/load-17.7.1.tgz': + dependencies: + '@commitlint/config-validator': https://registry.npmmirror.com/@commitlint/config-validator/-/config-validator-17.6.7.tgz + '@commitlint/execute-rule': https://registry.npmmirror.com/@commitlint/execute-rule/-/execute-rule-17.4.0.tgz + '@commitlint/resolve-extends': https://registry.npmmirror.com/@commitlint/resolve-extends/-/resolve-extends-17.6.7.tgz + '@commitlint/types': https://registry.npmmirror.com/@commitlint/types/-/types-17.4.4.tgz + '@types/node': https://registry.npmmirror.com/@types/node/-/node-20.4.7.tgz + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + cosmiconfig: https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-8.2.0.tgz + cosmiconfig-typescript-loader: https://registry.npmmirror.com/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.4.0.tgz(@types/node@20.4.7)(cosmiconfig@8.2.0)(ts-node@10.9.1)(typescript@5.2.2) + lodash.isplainobject: https://registry.npmmirror.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz + lodash.merge: https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz + lodash.uniq: https://registry.npmmirror.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz + resolve-from: https://registry.npmmirror.com/resolve-from/-/resolve-from-5.0.0.tgz + ts-node: https://registry.npmmirror.com/ts-node/-/ts-node-10.9.1.tgz(@types/node@20.4.7)(typescript@5.2.2) + typescript: https://registry.npmmirror.com/typescript/-/typescript-5.2.2.tgz + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + + '@commitlint/message@https://registry.npmmirror.com/@commitlint/message/-/message-17.4.2.tgz': {} + + '@commitlint/parse@https://registry.npmmirror.com/@commitlint/parse/-/parse-17.7.0.tgz': + dependencies: + '@commitlint/types': https://registry.npmmirror.com/@commitlint/types/-/types-17.4.4.tgz + conventional-changelog-angular: https://registry.npmmirror.com/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz + conventional-commits-parser: https://registry.npmmirror.com/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz + + '@commitlint/read@https://registry.npmmirror.com/@commitlint/read/-/read-17.5.1.tgz': + dependencies: + '@commitlint/top-level': https://registry.npmmirror.com/@commitlint/top-level/-/top-level-17.4.0.tgz + '@commitlint/types': https://registry.npmmirror.com/@commitlint/types/-/types-17.4.4.tgz + fs-extra: https://registry.npmmirror.com/fs-extra/-/fs-extra-11.1.1.tgz + git-raw-commits: https://registry.npmmirror.com/git-raw-commits/-/git-raw-commits-2.0.11.tgz + minimist: https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz + + '@commitlint/resolve-extends@https://registry.npmmirror.com/@commitlint/resolve-extends/-/resolve-extends-17.6.7.tgz': + dependencies: + '@commitlint/config-validator': https://registry.npmmirror.com/@commitlint/config-validator/-/config-validator-17.6.7.tgz + '@commitlint/types': https://registry.npmmirror.com/@commitlint/types/-/types-17.4.4.tgz + import-fresh: https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz + lodash.mergewith: https://registry.npmmirror.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz + resolve-from: https://registry.npmmirror.com/resolve-from/-/resolve-from-5.0.0.tgz + resolve-global: https://registry.npmmirror.com/resolve-global/-/resolve-global-1.0.0.tgz + + '@commitlint/rules@https://registry.npmmirror.com/@commitlint/rules/-/rules-17.7.0.tgz': + dependencies: + '@commitlint/ensure': https://registry.npmmirror.com/@commitlint/ensure/-/ensure-17.6.7.tgz + '@commitlint/message': https://registry.npmmirror.com/@commitlint/message/-/message-17.4.2.tgz + '@commitlint/to-lines': https://registry.npmmirror.com/@commitlint/to-lines/-/to-lines-17.4.0.tgz + '@commitlint/types': https://registry.npmmirror.com/@commitlint/types/-/types-17.4.4.tgz + execa: https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz + + '@commitlint/to-lines@https://registry.npmmirror.com/@commitlint/to-lines/-/to-lines-17.4.0.tgz': {} + + '@commitlint/top-level@https://registry.npmmirror.com/@commitlint/top-level/-/top-level-17.4.0.tgz': + dependencies: + find-up: https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz + + '@commitlint/types@https://registry.npmmirror.com/@commitlint/types/-/types-17.4.4.tgz': + dependencies: + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + + '@cspotcode/source-map-support@https://registry.npmmirror.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz': + dependencies: + '@jridgewell/trace-mapping': https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz + + '@csstools/css-parser-algorithms@2.3.1(@csstools/css-tokenizer@2.2.0)': + dependencies: + '@csstools/css-tokenizer': 2.2.0 + + '@csstools/css-tokenizer@2.2.0': {} + + '@csstools/media-query-list-parser@2.1.4(@csstools/css-parser-algorithms@2.3.1)(@csstools/css-tokenizer@2.2.0)': + dependencies: + '@csstools/css-parser-algorithms': 2.3.1(@csstools/css-tokenizer@2.2.0) + '@csstools/css-tokenizer': 2.2.0 + + '@csstools/selector-specificity@3.0.0(postcss-selector-parser@6.0.13)': + dependencies: + postcss-selector-parser: 6.0.13 + + '@ctrl/tinycolor@3.6.1': {} + + '@ctrl/tinycolor@https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz': {} + + '@emotion/hash@https://registry.npmmirror.com/@emotion/hash/-/hash-0.9.1.tgz': {} + + '@emotion/unitless@https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.8.1.tgz': {} + + '@esbuild/android-arm64@0.17.19': + optional: true + + '@esbuild/android-arm64@0.18.20': + optional: true + + '@esbuild/android-arm64@0.19.2': + optional: true + + '@esbuild/android-arm@0.17.19': + optional: true + + '@esbuild/android-arm@0.18.20': + optional: true + + '@esbuild/android-arm@0.19.2': + optional: true + + '@esbuild/android-x64@0.17.19': + optional: true + + '@esbuild/android-x64@0.18.20': + optional: true + + '@esbuild/android-x64@0.19.2': + optional: true + + '@esbuild/darwin-arm64@0.17.19': + optional: true + + '@esbuild/darwin-arm64@0.18.20': + optional: true + + '@esbuild/darwin-arm64@0.19.2': + optional: true + + '@esbuild/darwin-x64@0.17.19': + optional: true + + '@esbuild/darwin-x64@0.18.20': + optional: true + + '@esbuild/darwin-x64@0.19.2': + optional: true + + '@esbuild/freebsd-arm64@0.17.19': + optional: true + + '@esbuild/freebsd-arm64@0.18.20': + optional: true + + '@esbuild/freebsd-arm64@0.19.2': + optional: true + + '@esbuild/freebsd-x64@0.17.19': + optional: true + + '@esbuild/freebsd-x64@0.18.20': + optional: true + + '@esbuild/freebsd-x64@0.19.2': + optional: true + + '@esbuild/linux-arm64@0.17.19': + optional: true + + '@esbuild/linux-arm64@0.18.20': + optional: true + + '@esbuild/linux-arm64@0.19.2': + optional: true + + '@esbuild/linux-arm@0.17.19': + optional: true + + '@esbuild/linux-arm@0.18.20': + optional: true + + '@esbuild/linux-arm@0.19.2': + optional: true + + '@esbuild/linux-ia32@0.17.19': + optional: true + + '@esbuild/linux-ia32@0.18.20': + optional: true + + '@esbuild/linux-ia32@0.19.2': + optional: true + + '@esbuild/linux-loong64@0.14.54': + optional: true + + '@esbuild/linux-loong64@0.17.19': + optional: true + + '@esbuild/linux-loong64@0.18.20': + optional: true + + '@esbuild/linux-loong64@0.19.2': + optional: true + + '@esbuild/linux-mips64el@0.17.19': + optional: true + + '@esbuild/linux-mips64el@0.18.20': + optional: true + + '@esbuild/linux-mips64el@0.19.2': + optional: true + + '@esbuild/linux-ppc64@0.17.19': + optional: true + + '@esbuild/linux-ppc64@0.18.20': + optional: true + + '@esbuild/linux-ppc64@0.19.2': + optional: true + + '@esbuild/linux-riscv64@0.17.19': + optional: true + + '@esbuild/linux-riscv64@0.18.20': + optional: true + + '@esbuild/linux-riscv64@0.19.2': + optional: true + + '@esbuild/linux-s390x@0.17.19': + optional: true + + '@esbuild/linux-s390x@0.18.20': + optional: true + + '@esbuild/linux-s390x@0.19.2': + optional: true + + '@esbuild/linux-x64@0.17.19': + optional: true + + '@esbuild/linux-x64@0.18.20': + optional: true + + '@esbuild/linux-x64@0.19.2': + optional: true + + '@esbuild/netbsd-x64@0.17.19': + optional: true + + '@esbuild/netbsd-x64@0.18.20': + optional: true + + '@esbuild/netbsd-x64@0.19.2': + optional: true + + '@esbuild/openbsd-x64@0.17.19': + optional: true + + '@esbuild/openbsd-x64@0.18.20': + optional: true + + '@esbuild/openbsd-x64@0.19.2': + optional: true + + '@esbuild/sunos-x64@0.17.19': + optional: true + + '@esbuild/sunos-x64@0.18.20': + optional: true + + '@esbuild/sunos-x64@0.19.2': + optional: true + + '@esbuild/win32-arm64@0.17.19': + optional: true + + '@esbuild/win32-arm64@0.18.20': + optional: true + + '@esbuild/win32-arm64@0.19.2': + optional: true + + '@esbuild/win32-ia32@0.17.19': + optional: true + + '@esbuild/win32-ia32@0.18.20': + optional: true + + '@esbuild/win32-ia32@0.19.2': + optional: true + + '@esbuild/win32-x64@0.17.19': + optional: true + + '@esbuild/win32-x64@0.18.20': + optional: true + + '@esbuild/win32-x64@0.19.2': + optional: true + + '@fast-csv/format@4.3.5': + dependencies: + '@types/node': 14.18.56 + lodash.escaperegexp: 4.1.2 + lodash.isboolean: 3.0.3 + lodash.isequal: 4.5.0 + lodash.isfunction: https://registry.npmmirror.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz + lodash.isnil: 4.0.0 + + '@fast-csv/parse@4.3.6': + dependencies: + '@types/node': 14.18.56 + lodash.escaperegexp: 4.1.2 + lodash.groupby: 4.6.0 + lodash.isfunction: https://registry.npmmirror.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz + lodash.isnil: 4.0.0 + lodash.isundefined: 3.0.1 + lodash.uniq: 4.5.0 + + '@iconify/iconify@2.1.2': + dependencies: + cross-fetch: 3.1.8 + transitivePeerDependencies: + - encoding + + '@iconify/iconify@3.1.1': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify/json@https://registry.npmmirror.com/@iconify/json/-/json-2.2.108.tgz': + dependencies: + '@iconify/types': https://registry.npmmirror.com/@iconify/types/-/types-2.0.0.tgz + pathe: https://registry.npmmirror.com/pathe/-/pathe-1.1.1.tgz + + '@iconify/types@2.0.0': {} + + '@iconify/types@https://registry.npmmirror.com/@iconify/types/-/types-2.0.0.tgz': {} + + '@iconify/utils@2.1.9': + dependencies: + '@antfu/install-pkg': 0.1.1 + '@antfu/utils': 0.7.6 + '@iconify/types': https://registry.npmmirror.com/@iconify/types/-/types-2.0.0.tgz + debug: https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz + kolorist: 1.8.0 + local-pkg: 0.4.3 + transitivePeerDependencies: + - supports-color + + '@intlify/core-base@9.2.2': + dependencies: + '@intlify/devtools-if': 9.2.2 + '@intlify/message-compiler': 9.2.2 + '@intlify/shared': 9.2.2 + '@intlify/vue-devtools': 9.2.2 + + '@intlify/devtools-if@9.2.2': + dependencies: + '@intlify/shared': 9.2.2 + + '@intlify/message-compiler@9.2.2': + dependencies: + '@intlify/shared': 9.2.2 + source-map: 0.6.1 + + '@intlify/shared@9.2.2': {} + + '@intlify/vue-devtools@9.2.2': + dependencies: + '@intlify/core-base': 9.2.2 + '@intlify/shared': 9.2.2 + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@istanbuljs/load-nyc-config@https://registry.npmmirror.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz': + dependencies: + camelcase: https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz + find-up: https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz + get-package-type: https://registry.npmmirror.com/get-package-type/-/get-package-type-0.1.0.tgz + js-yaml: https://registry.npmmirror.com/js-yaml/-/js-yaml-3.14.1.tgz + resolve-from: https://registry.npmmirror.com/resolve-from/-/resolve-from-5.0.0.tgz + + '@istanbuljs/schema@https://registry.npmmirror.com/@istanbuljs/schema/-/schema-0.1.3.tgz': {} + + '@jest/console@https://registry.npmmirror.com/@jest/console/-/console-27.5.1.tgz': + dependencies: + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + '@types/node': https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + jest-message-util: https://registry.npmmirror.com/jest-message-util/-/jest-message-util-27.5.1.tgz + jest-util: https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz + slash: https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz + + '@jest/core@https://registry.npmmirror.com/@jest/core/-/core-27.5.1.tgz(ts-node@10.9.1)': + dependencies: + '@jest/console': https://registry.npmmirror.com/@jest/console/-/console-27.5.1.tgz + '@jest/reporters': https://registry.npmmirror.com/@jest/reporters/-/reporters-27.5.1.tgz + '@jest/test-result': https://registry.npmmirror.com/@jest/test-result/-/test-result-27.5.1.tgz + '@jest/transform': https://registry.npmmirror.com/@jest/transform/-/transform-27.5.1.tgz + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + '@types/node': https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz + ansi-escapes: https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + emittery: https://registry.npmmirror.com/emittery/-/emittery-0.8.1.tgz + exit: https://registry.npmmirror.com/exit/-/exit-0.1.2.tgz + graceful-fs: 4.2.11 + jest-changed-files: https://registry.npmmirror.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz + jest-config: https://registry.npmmirror.com/jest-config/-/jest-config-27.5.1.tgz(ts-node@10.9.1) + jest-haste-map: https://registry.npmmirror.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz + jest-message-util: https://registry.npmmirror.com/jest-message-util/-/jest-message-util-27.5.1.tgz + jest-regex-util: https://registry.npmmirror.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz + jest-resolve: https://registry.npmmirror.com/jest-resolve/-/jest-resolve-27.5.1.tgz + jest-resolve-dependencies: https://registry.npmmirror.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz + jest-runner: https://registry.npmmirror.com/jest-runner/-/jest-runner-27.5.1.tgz + jest-runtime: https://registry.npmmirror.com/jest-runtime/-/jest-runtime-27.5.1.tgz + jest-snapshot: https://registry.npmmirror.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz + jest-util: https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz + jest-validate: https://registry.npmmirror.com/jest-validate/-/jest-validate-27.5.1.tgz + jest-watcher: https://registry.npmmirror.com/jest-watcher/-/jest-watcher-27.5.1.tgz + micromatch: https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz + rimraf: https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz + slash: https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz + strip-ansi: https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - ts-node + - utf-8-validate + + '@jest/environment@https://registry.npmmirror.com/@jest/environment/-/environment-27.5.1.tgz': + dependencies: + '@jest/fake-timers': https://registry.npmmirror.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + '@types/node': https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz + jest-mock: https://registry.npmmirror.com/jest-mock/-/jest-mock-27.5.1.tgz + + '@jest/fake-timers@https://registry.npmmirror.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz': + dependencies: + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + '@sinonjs/fake-timers': https://registry.npmmirror.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz + '@types/node': https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz + jest-message-util: https://registry.npmmirror.com/jest-message-util/-/jest-message-util-27.5.1.tgz + jest-mock: https://registry.npmmirror.com/jest-mock/-/jest-mock-27.5.1.tgz + jest-util: https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz + + '@jest/globals@https://registry.npmmirror.com/@jest/globals/-/globals-27.5.1.tgz': + dependencies: + '@jest/environment': https://registry.npmmirror.com/@jest/environment/-/environment-27.5.1.tgz + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + expect: https://registry.npmmirror.com/expect/-/expect-27.5.1.tgz + + '@jest/reporters@https://registry.npmmirror.com/@jest/reporters/-/reporters-27.5.1.tgz': + dependencies: + '@bcoe/v8-coverage': https://registry.npmmirror.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz + '@jest/console': https://registry.npmmirror.com/@jest/console/-/console-27.5.1.tgz + '@jest/test-result': https://registry.npmmirror.com/@jest/test-result/-/test-result-27.5.1.tgz + '@jest/transform': https://registry.npmmirror.com/@jest/transform/-/transform-27.5.1.tgz + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + '@types/node': https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + collect-v8-coverage: https://registry.npmmirror.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz + exit: https://registry.npmmirror.com/exit/-/exit-0.1.2.tgz + glob: https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz + graceful-fs: 4.2.11 + istanbul-lib-coverage: https://registry.npmmirror.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz + istanbul-lib-instrument: https://registry.npmmirror.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz + istanbul-lib-report: https://registry.npmmirror.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz + istanbul-lib-source-maps: https://registry.npmmirror.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz + istanbul-reports: https://registry.npmmirror.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz + jest-haste-map: https://registry.npmmirror.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz + jest-resolve: https://registry.npmmirror.com/jest-resolve/-/jest-resolve-27.5.1.tgz + jest-util: https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz + jest-worker: https://registry.npmmirror.com/jest-worker/-/jest-worker-27.5.1.tgz + slash: https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz + source-map: 0.6.1 + string-length: https://registry.npmmirror.com/string-length/-/string-length-4.0.2.tgz + terminal-link: https://registry.npmmirror.com/terminal-link/-/terminal-link-2.1.1.tgz + v8-to-istanbul: https://registry.npmmirror.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz + transitivePeerDependencies: + - supports-color + + '@jest/source-map@https://registry.npmmirror.com/@jest/source-map/-/source-map-27.5.1.tgz': + dependencies: + callsites: https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz + graceful-fs: 4.2.11 + source-map: 0.6.1 + + '@jest/test-result@https://registry.npmmirror.com/@jest/test-result/-/test-result-27.5.1.tgz': + dependencies: + '@jest/console': https://registry.npmmirror.com/@jest/console/-/console-27.5.1.tgz + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + '@types/istanbul-lib-coverage': https://registry.npmmirror.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz + collect-v8-coverage: https://registry.npmmirror.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz + + '@jest/test-sequencer@https://registry.npmmirror.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz': + dependencies: + '@jest/test-result': https://registry.npmmirror.com/@jest/test-result/-/test-result-27.5.1.tgz + graceful-fs: 4.2.11 + jest-haste-map: https://registry.npmmirror.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz + jest-runtime: https://registry.npmmirror.com/jest-runtime/-/jest-runtime-27.5.1.tgz + transitivePeerDependencies: + - supports-color + + '@jest/transform@https://registry.npmmirror.com/@jest/transform/-/transform-27.5.1.tgz': + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + babel-plugin-istanbul: https://registry.npmmirror.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + convert-source-map: https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.9.0.tgz + fast-json-stable-stringify: https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz + graceful-fs: 4.2.11 + jest-haste-map: https://registry.npmmirror.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz + jest-regex-util: https://registry.npmmirror.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz + jest-util: https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz + micromatch: https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz + pirates: https://registry.npmmirror.com/pirates/-/pirates-4.0.6.tgz + slash: https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz + source-map: 0.6.1 + write-file-atomic: https://registry.npmmirror.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz + transitivePeerDependencies: + - supports-color + + '@jest/types@https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz': + dependencies: + '@types/istanbul-lib-coverage': https://registry.npmmirror.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz + '@types/istanbul-reports': https://registry.npmmirror.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz + '@types/node': https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz + '@types/yargs': https://registry.npmmirror.com/@types/yargs/-/yargs-16.0.5.tgz + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + + '@jridgewell/gen-mapping@0.3.3': + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.19 + + '@jridgewell/gen-mapping@https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz': + dependencies: + '@jridgewell/set-array': https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.1.2.tgz + '@jridgewell/sourcemap-codec': https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz + '@jridgewell/trace-mapping': https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz + + '@jridgewell/resolve-uri@3.1.1': {} + + '@jridgewell/resolve-uri@https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz': {} + + '@jridgewell/set-array@1.1.2': {} + + '@jridgewell/set-array@https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.1.2.tgz': {} + + '@jridgewell/source-map@0.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.19 + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@jridgewell/sourcemap-codec@https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz': {} + + '@jridgewell/trace-mapping@0.3.19': + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + + '@jridgewell/trace-mapping@https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz': + dependencies: + '@jridgewell/resolve-uri': https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz + '@jridgewell/sourcemap-codec': https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz + + '@jridgewell/trace-mapping@https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz': + dependencies: + '@jridgewell/resolve-uri': https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz + '@jridgewell/sourcemap-codec': https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz + + '@lezer/common@1.1.2': {} + + '@lezer/highlight@1.2.0': + dependencies: + '@lezer/common': 1.1.2 + + '@lezer/lr@1.3.14': + dependencies: + '@lezer/common': 1.1.2 + + '@lezer/markdown@1.1.2': + dependencies: + '@lezer/common': 1.1.2 + '@lezer/highlight': 1.2.0 + + '@logicflow/core@https://registry.npmmirror.com/@logicflow/core/-/core-1.2.12.tgz': + dependencies: + '@types/mousetrap': https://registry.npmmirror.com/@types/mousetrap/-/mousetrap-1.6.11.tgz + mousetrap: https://registry.npmmirror.com/mousetrap/-/mousetrap-1.6.5.tgz + preact: https://registry.npmmirror.com/preact/-/preact-10.17.1.tgz + + '@logicflow/extension@https://registry.npmmirror.com/@logicflow/extension/-/extension-1.2.13.tgz(ts-node@10.9.1)': + dependencies: + '@logicflow/core': https://registry.npmmirror.com/@logicflow/core/-/core-1.2.12.tgz + jest: https://registry.npmmirror.com/jest/-/jest-27.5.1.tgz(ts-node@10.9.1) + lodash-es: https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz + preact: https://registry.npmmirror.com/preact/-/preact-10.17.1.tgz + transitivePeerDependencies: + - bufferutil + - canvas + - node-notifier + - supports-color + - ts-node + - utf-8-validate + + '@microsoft/api-extractor-model@7.27.6(@types/node@20.4.7)': + dependencies: + '@microsoft/tsdoc': 0.14.2 + '@microsoft/tsdoc-config': 0.16.2 + '@rushstack/node-core-library': 3.59.7(@types/node@20.4.7) + transitivePeerDependencies: + - '@types/node' + + '@microsoft/api-extractor@7.36.4(@types/node@20.4.7)': + dependencies: + '@microsoft/api-extractor-model': 7.27.6(@types/node@20.4.7) + '@microsoft/tsdoc': 0.14.2 + '@microsoft/tsdoc-config': 0.16.2 + '@rushstack/node-core-library': 3.59.7(@types/node@20.4.7) + '@rushstack/rig-package': 0.4.1 + '@rushstack/ts-command-line': 4.15.2 + colors: 1.2.5 + lodash: 4.17.21 + resolve: 1.22.4 + semver: 7.5.4 + source-map: 0.6.1 + typescript: https://registry.npmmirror.com/typescript/-/typescript-5.0.4.tgz + transitivePeerDependencies: + - '@types/node' + + '@microsoft/tsdoc-config@0.16.2': + dependencies: + '@microsoft/tsdoc': 0.14.2 + ajv: 6.12.6 + jju: 1.4.0 + resolve: 1.19.0 + + '@microsoft/tsdoc@0.14.2': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.scandir@https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz': + dependencies: + '@nodelib/fs.stat': https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz + run-parallel: https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.stat@https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.15.0 + + '@nodelib/fs.walk@https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz': + dependencies: + '@nodelib/fs.scandir': https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz + fastq: https://registry.npmmirror.com/fastq/-/fastq-1.15.0.tgz + + '@one-ini/wasm@https://registry.npmmirror.com/@one-ini/wasm/-/wasm-0.1.1.tgz': {} + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@pkgr/utils@https://registry.npmmirror.com/@pkgr/utils/-/utils-2.4.2.tgz': + dependencies: + cross-spawn: https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz + fast-glob: https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.1.tgz + is-glob: https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz + open: https://registry.npmmirror.com/open/-/open-9.1.0.tgz + picocolors: https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz + tslib: https://registry.npmmirror.com/tslib/-/tslib-2.6.2.tgz + + '@polka/url@1.0.0-next.21': {} + + '@purge-icons/core@0.9.1': + dependencies: + '@iconify/iconify': 2.1.2 + axios: https://registry.npmmirror.com/axios/-/axios-0.26.1.tgz(debug@4.3.4) + debug: https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz + fast-glob: 3.3.1 + fs-extra: 10.1.0 + transitivePeerDependencies: + - encoding + - supports-color + + '@purge-icons/generated@0.9.0': + dependencies: + '@iconify/iconify': 3.1.1 + + '@rollup/plugin-alias@5.0.0(rollup@3.28.1)': + dependencies: + rollup: 3.28.1 + slash: 4.0.0 + + '@rollup/plugin-commonjs@24.1.0(rollup@3.28.1)': + dependencies: + '@rollup/pluginutils': 5.0.4(rollup@3.28.1) + commondir: 1.0.1 + estree-walker: 2.0.2 + glob: 8.1.0 + is-reference: 1.2.1 + magic-string: 0.27.0 + rollup: 3.28.1 + + '@rollup/plugin-json@6.0.0(rollup@3.28.1)': + dependencies: + '@rollup/pluginutils': 5.0.4(rollup@3.28.1) + rollup: 3.28.1 + + '@rollup/plugin-node-resolve@15.2.1(rollup@3.28.1)': + dependencies: + '@rollup/pluginutils': 5.0.4(rollup@3.28.1) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-builtin-module: 3.2.1 + is-module: 1.0.0 + resolve: 1.22.4 + rollup: 3.28.1 + + '@rollup/plugin-replace@5.0.2(rollup@3.28.1)': + dependencies: + '@rollup/pluginutils': 5.0.4(rollup@3.28.1) + magic-string: 0.27.0 + rollup: 3.28.1 + + '@rollup/pluginutils@4.2.1': + dependencies: + estree-walker: 2.0.2 + picomatch: 2.3.1 + + '@rollup/pluginutils@5.0.3(rollup@3.28.1)': + dependencies: + '@types/estree': https://registry.npmmirror.com/@types/estree/-/estree-1.0.1.tgz + estree-walker: 2.0.2 + picomatch: https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz + rollup: 3.28.1 + + '@rollup/pluginutils@5.0.4(rollup@3.28.1)': + dependencies: + '@types/estree': 1.0.1 + estree-walker: 2.0.2 + picomatch: 2.3.1 + rollup: 3.28.1 + + '@rushstack/node-core-library@3.59.7(@types/node@20.4.7)': + dependencies: + '@types/node': https://registry.npmmirror.com/@types/node/-/node-20.4.7.tgz + colors: 1.2.5 + fs-extra: 7.0.1 + import-lazy: 4.0.0 + jju: 1.4.0 + resolve: 1.22.4 + semver: 7.5.4 + z-schema: 5.0.5 + + '@rushstack/rig-package@0.4.1': + dependencies: + resolve: 1.22.4 + strip-json-comments: 3.1.1 + + '@rushstack/ts-command-line@4.15.2': + dependencies: + '@types/argparse': 1.0.38 + argparse: 1.0.10 + colors: 1.2.5 + string-argv: https://registry.npmmirror.com/string-argv/-/string-argv-0.3.2.tgz + + '@simonwep/pickr@https://registry.npmmirror.com/@simonwep/pickr/-/pickr-1.8.2.tgz': + dependencies: + core-js: https://registry.npmmirror.com/core-js/-/core-js-3.32.1.tgz + nanopop: https://registry.npmmirror.com/nanopop/-/nanopop-2.3.0.tgz + + '@sinonjs/commons@https://registry.npmmirror.com/@sinonjs/commons/-/commons-1.8.6.tgz': + dependencies: + type-detect: https://registry.npmmirror.com/type-detect/-/type-detect-4.0.8.tgz + + '@sinonjs/fake-timers@https://registry.npmmirror.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz': + dependencies: + '@sinonjs/commons': https://registry.npmmirror.com/@sinonjs/commons/-/commons-1.8.6.tgz + + '@tootallnate/once@https://registry.npmmirror.com/@tootallnate/once/-/once-1.1.2.tgz': {} + + '@trysound/sax@0.2.0': {} + + '@ts-morph/common@0.19.0': + dependencies: + fast-glob: https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.1.tgz + minimatch: 7.4.6 + mkdirp: 2.1.6 + path-browserify: 1.0.1 + + '@tsconfig/node10@https://registry.npmmirror.com/@tsconfig/node10/-/node10-1.0.9.tgz': {} + + '@tsconfig/node12@https://registry.npmmirror.com/@tsconfig/node12/-/node12-1.0.11.tgz': {} + + '@tsconfig/node14@https://registry.npmmirror.com/@tsconfig/node14/-/node14-1.0.3.tgz': {} + + '@tsconfig/node16@https://registry.npmmirror.com/@tsconfig/node16/-/node16-1.0.3.tgz': {} + + '@types/argparse@1.0.38': {} + + '@types/babel__core@https://registry.npmmirror.com/@types/babel__core/-/babel__core-7.20.1.tgz': + dependencies: + '@babel/parser': https://registry.npmmirror.com/@babel/parser/-/parser-7.22.13.tgz + '@babel/types': https://registry.npmmirror.com/@babel/types/-/types-7.22.11.tgz + '@types/babel__generator': https://registry.npmmirror.com/@types/babel__generator/-/babel__generator-7.6.4.tgz + '@types/babel__template': https://registry.npmmirror.com/@types/babel__template/-/babel__template-7.4.1.tgz + '@types/babel__traverse': https://registry.npmmirror.com/@types/babel__traverse/-/babel__traverse-7.20.1.tgz + + '@types/babel__generator@https://registry.npmmirror.com/@types/babel__generator/-/babel__generator-7.6.4.tgz': + dependencies: + '@babel/types': https://registry.npmmirror.com/@babel/types/-/types-7.22.11.tgz + + '@types/babel__template@https://registry.npmmirror.com/@types/babel__template/-/babel__template-7.4.1.tgz': + dependencies: + '@babel/parser': https://registry.npmmirror.com/@babel/parser/-/parser-7.22.13.tgz + '@babel/types': https://registry.npmmirror.com/@babel/types/-/types-7.22.11.tgz + + '@types/babel__traverse@https://registry.npmmirror.com/@types/babel__traverse/-/babel__traverse-7.20.1.tgz': + dependencies: + '@babel/types': https://registry.npmmirror.com/@babel/types/-/types-7.22.11.tgz + + '@types/codemirror@https://registry.npmmirror.com/@types/codemirror/-/codemirror-5.60.9.tgz': + dependencies: + '@types/tern': https://registry.npmmirror.com/@types/tern/-/tern-0.23.4.tgz + + '@types/crypto-js@4.1.1': {} + + '@types/estree@1.0.1': {} + + '@types/estree@https://registry.npmmirror.com/@types/estree/-/estree-1.0.1.tgz': {} + + '@types/fs-extra@11.0.1': + dependencies: + '@types/jsonfile': 6.1.1 + '@types/node': 20.5.7 + + '@types/graceful-fs@https://registry.npmmirror.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz': + dependencies: + '@types/node': https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz + + '@types/intro.js@5.1.1': {} + + '@types/istanbul-lib-coverage@https://registry.npmmirror.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz': {} + + '@types/istanbul-lib-report@https://registry.npmmirror.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz': + dependencies: + '@types/istanbul-lib-coverage': https://registry.npmmirror.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz + + '@types/istanbul-reports@https://registry.npmmirror.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz': + dependencies: + '@types/istanbul-lib-report': https://registry.npmmirror.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz + + '@types/jsonfile@6.1.1': + dependencies: + '@types/node': 20.5.7 + + '@types/lodash-es@https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.8.tgz': + dependencies: + '@types/lodash': https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.197.tgz + + '@types/lodash@https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.197.tgz': {} + + '@types/minimist@1.2.2': {} + + '@types/minimist@https://registry.npmmirror.com/@types/minimist/-/minimist-1.2.2.tgz': {} + + '@types/mockjs@1.0.7': {} + + '@types/mockjs@https://registry.npmmirror.com/@types/mockjs/-/mockjs-1.0.7.tgz': {} + + '@types/mousetrap@https://registry.npmmirror.com/@types/mousetrap/-/mousetrap-1.6.11.tgz': {} + + '@types/node@14.18.56': {} + + '@types/node@18.17.12': {} + + '@types/node@20.5.7': {} + + '@types/node@https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz': {} + + '@types/node@https://registry.npmmirror.com/@types/node/-/node-20.4.7.tgz': {} + + '@types/normalize-package-data@2.4.1': {} + + '@types/normalize-package-data@https://registry.npmmirror.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz': {} + + '@types/nprogress@0.2.0': {} + + '@types/prettier@https://registry.npmmirror.com/@types/prettier/-/prettier-2.7.3.tgz': {} + + '@types/qrcode@1.5.1': + dependencies: + '@types/node': 20.5.7 + + '@types/qs@6.9.7': {} + + '@types/resolve@1.20.2': {} + + '@types/showdown@2.0.1': {} + + '@types/sortablejs@https://registry.npmmirror.com/@types/sortablejs/-/sortablejs-1.15.2.tgz': {} + + '@types/stack-utils@https://registry.npmmirror.com/@types/stack-utils/-/stack-utils-2.0.1.tgz': {} + + '@types/svgo@2.6.4': + dependencies: + '@types/node': 20.5.7 + + '@types/tern@https://registry.npmmirror.com/@types/tern/-/tern-0.23.4.tgz': + dependencies: + '@types/estree': https://registry.npmmirror.com/@types/estree/-/estree-1.0.1.tgz + + '@types/web-bluetooth@0.0.16': {} + + '@types/web-bluetooth@https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.17.tgz': {} + + '@types/yargs-parser@https://registry.npmmirror.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz': {} + + '@types/yargs@https://registry.npmmirror.com/@types/yargs/-/yargs-16.0.5.tgz': + dependencies: + '@types/yargs-parser': https://registry.npmmirror.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz + + '@unocss/astro@0.55.3(rollup@3.28.1)(vite@4.4.9)': + dependencies: + '@unocss/core': 0.55.3 + '@unocss/reset': 0.55.3 + '@unocss/vite': 0.55.3(rollup@3.28.1)(vite@4.4.9) + vite: 4.4.9(@types/node@20.4.7)(less@4.2.0)(sass@1.66.1) + transitivePeerDependencies: + - rollup + + '@unocss/cli@0.55.3(rollup@3.28.1)': + dependencies: + '@ampproject/remapping': 2.2.1 + '@rollup/pluginutils': 5.0.4(rollup@3.28.1) + '@unocss/config': 0.55.3 + '@unocss/core': 0.55.3 + '@unocss/preset-uno': 0.55.3 + cac: 6.7.14 + chokidar: 3.5.3 + colorette: 2.0.20 + consola: 3.2.3 + fast-glob: 3.3.1 + magic-string: 0.30.3 + pathe: https://registry.npmmirror.com/pathe/-/pathe-1.1.1.tgz + perfect-debounce: 1.0.0 + transitivePeerDependencies: + - rollup + + '@unocss/config@0.55.3': + dependencies: + '@unocss/core': 0.55.3 + unconfig: 0.3.10 + + '@unocss/core@0.55.3': {} + + '@unocss/extractor-arbitrary-variants@0.55.3': + dependencies: + '@unocss/core': 0.55.3 + + '@unocss/inspector@0.55.3': + dependencies: + gzip-size: 6.0.0 + sirv: 2.0.3 + + '@unocss/postcss@0.55.3(postcss@8.4.29)': + dependencies: + '@unocss/config': 0.55.3 + '@unocss/core': 0.55.3 + css-tree: 2.3.1 + fast-glob: 3.3.1 + magic-string: 0.30.3 + postcss: 8.4.29 + + '@unocss/preset-attributify@0.55.3': + dependencies: + '@unocss/core': 0.55.3 + + '@unocss/preset-icons@0.55.3': + dependencies: + '@iconify/utils': 2.1.9 + '@unocss/core': 0.55.3 + ofetch: 1.3.3 + transitivePeerDependencies: + - supports-color + + '@unocss/preset-mini@0.55.3': + dependencies: + '@unocss/core': 0.55.3 + '@unocss/extractor-arbitrary-variants': 0.55.3 + + '@unocss/preset-tagify@0.55.3': + dependencies: + '@unocss/core': 0.55.3 + + '@unocss/preset-typography@0.55.3': + dependencies: + '@unocss/core': 0.55.3 + '@unocss/preset-mini': 0.55.3 + + '@unocss/preset-uno@0.55.3': + dependencies: + '@unocss/core': 0.55.3 + '@unocss/preset-mini': 0.55.3 + '@unocss/preset-wind': 0.55.3 + + '@unocss/preset-web-fonts@0.55.3': + dependencies: + '@unocss/core': 0.55.3 + ofetch: 1.3.3 + + '@unocss/preset-wind@0.55.3': + dependencies: + '@unocss/core': 0.55.3 + '@unocss/preset-mini': 0.55.3 + + '@unocss/reset@0.55.3': {} + + '@unocss/scope@0.55.3': {} + + '@unocss/transformer-attributify-jsx-babel@0.55.3': + dependencies: + '@unocss/core': 0.55.3 + + '@unocss/transformer-attributify-jsx@0.55.3': + dependencies: + '@unocss/core': 0.55.3 + + '@unocss/transformer-compile-class@0.55.3': + dependencies: + '@unocss/core': 0.55.3 + + '@unocss/transformer-directives@0.55.3': + dependencies: + '@unocss/core': 0.55.3 + css-tree: 2.3.1 + + '@unocss/transformer-variant-group@0.55.3': + dependencies: + '@unocss/core': 0.55.3 + + '@unocss/vite@0.55.3(rollup@3.28.1)(vite@4.4.9)': + dependencies: + '@ampproject/remapping': 2.2.1 + '@rollup/pluginutils': 5.0.4(rollup@3.28.1) + '@unocss/config': 0.55.3 + '@unocss/core': 0.55.3 + '@unocss/inspector': 0.55.3 + '@unocss/scope': 0.55.3 + '@unocss/transformer-directives': 0.55.3 + chokidar: 3.5.3 + fast-glob: 3.3.1 + magic-string: 0.30.3 + vite: 4.4.9(@types/node@20.4.7)(less@4.2.0)(sass@1.66.1) + transitivePeerDependencies: + - rollup + + '@vitejs/plugin-vue-jsx@3.0.2(vite@4.4.9)(vue@3.3.4)': + dependencies: + '@babel/core': 7.22.11 + '@babel/plugin-transform-typescript': 7.22.11(@babel/core@7.22.11) + '@vue/babel-plugin-jsx': 1.1.5(@babel/core@7.22.11) + vite: 4.4.9(@types/node@20.4.7)(less@4.2.0)(sass@1.66.1) + vue: 3.3.4 + transitivePeerDependencies: + - supports-color + + '@vitejs/plugin-vue@4.3.4(vite@4.4.9)(vue@3.3.4)': + dependencies: + vite: 4.4.9(@types/node@20.4.7)(less@4.2.0)(sass@1.66.1) + vue: 3.3.4 + + '@volar/language-core@https://registry.npmmirror.com/@volar/language-core/-/language-core-1.10.1.tgz': + dependencies: + '@volar/source-map': https://registry.npmmirror.com/@volar/source-map/-/source-map-1.10.1.tgz + + '@volar/source-map@https://registry.npmmirror.com/@volar/source-map/-/source-map-1.10.1.tgz': + dependencies: + muggle-string: https://registry.npmmirror.com/muggle-string/-/muggle-string-0.3.1.tgz + + '@volar/typescript@https://registry.npmmirror.com/@volar/typescript/-/typescript-1.10.1.tgz': + dependencies: + '@volar/language-core': https://registry.npmmirror.com/@volar/language-core/-/language-core-1.10.1.tgz + + '@vue-macros/common@1.7.2(rollup@3.28.1)(vue@3.3.4)': + dependencies: + '@babel/types': 7.22.11 + '@rollup/pluginutils': 5.0.4(rollup@3.28.1) + '@vue/compiler-sfc': 3.3.4 + ast-kit: 0.10.0(rollup@3.28.1) + local-pkg: 0.4.3 + magic-string-ast: 0.3.0 + vue: 3.3.4 + transitivePeerDependencies: + - rollup + + '@vue/babel-helper-vue-transform-on@1.1.5': {} + + '@vue/babel-plugin-jsx@1.1.5(@babel/core@7.22.11)': + dependencies: + '@babel/core': 7.22.11 + '@babel/helper-module-imports': 7.22.5 + '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.11) + '@babel/template': 7.22.5 + '@babel/traverse': 7.22.11 + '@babel/types': 7.22.11 + '@vue/babel-helper-vue-transform-on': 1.1.5 + camelcase: 6.3.0 + html-tags: 3.3.1 + svg-tags: 1.0.0 + transitivePeerDependencies: + - supports-color + + '@vue/compiler-core@3.2.47': + dependencies: + '@babel/parser': 7.22.10 + '@vue/shared': 3.2.47 + estree-walker: 2.0.2 + source-map: 0.6.1 + + '@vue/compiler-core@3.3.4': + dependencies: + '@babel/parser': 7.22.13 + '@vue/shared': 3.3.4 + estree-walker: 2.0.2 + source-map-js: 1.0.2 + + '@vue/compiler-core@https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.4.tgz': + dependencies: + '@babel/parser': https://registry.npmmirror.com/@babel/parser/-/parser-7.22.13.tgz + '@vue/shared': https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz + estree-walker: https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz + source-map-js: https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz + + '@vue/compiler-dom@3.2.47': + dependencies: + '@vue/compiler-core': 3.2.47 + '@vue/shared': 3.2.47 + + '@vue/compiler-dom@3.3.4': + dependencies: + '@vue/compiler-core': 3.3.4 + '@vue/shared': 3.3.4 + + '@vue/compiler-dom@https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz': + dependencies: + '@vue/compiler-core': https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.4.tgz + '@vue/shared': https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz + + '@vue/compiler-sfc@3.2.47': + dependencies: + '@babel/parser': 7.22.10 + '@vue/compiler-core': 3.2.47 + '@vue/compiler-dom': 3.2.47 + '@vue/compiler-ssr': 3.2.47 + '@vue/reactivity-transform': 3.2.47 + '@vue/shared': 3.2.47 + estree-walker: 2.0.2 + magic-string: 0.25.9 + postcss: 8.4.29 + source-map: 0.6.1 + + '@vue/compiler-sfc@3.3.4': + dependencies: + '@babel/parser': 7.22.13 + '@vue/compiler-core': 3.3.4 + '@vue/compiler-dom': 3.3.4 + '@vue/compiler-ssr': 3.3.4 + '@vue/reactivity-transform': 3.3.4 + '@vue/shared': 3.3.4 + estree-walker: 2.0.2 + magic-string: 0.30.3 + postcss: 8.4.29 + source-map-js: 1.0.2 + + '@vue/compiler-ssr@3.2.47': + dependencies: + '@vue/compiler-dom': 3.2.47 + '@vue/shared': 3.2.47 + + '@vue/compiler-ssr@3.3.4': + dependencies: + '@vue/compiler-dom': 3.3.4 + '@vue/shared': 3.3.4 + + '@vue/devtools-api@6.5.0': {} + + '@vue/devtools-api@https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.5.0.tgz': {} + + '@vue/language-core@https://registry.npmmirror.com/@vue/language-core/-/language-core-1.8.8.tgz(typescript@5.2.2)': + dependencies: + '@volar/language-core': https://registry.npmmirror.com/@volar/language-core/-/language-core-1.10.1.tgz + '@volar/source-map': https://registry.npmmirror.com/@volar/source-map/-/source-map-1.10.1.tgz + '@vue/compiler-dom': https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz + '@vue/reactivity': https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.3.4.tgz + '@vue/shared': https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz + minimatch: https://registry.npmmirror.com/minimatch/-/minimatch-9.0.3.tgz + muggle-string: https://registry.npmmirror.com/muggle-string/-/muggle-string-0.3.1.tgz + typescript: https://registry.npmmirror.com/typescript/-/typescript-5.2.2.tgz + vue-template-compiler: https://registry.npmmirror.com/vue-template-compiler/-/vue-template-compiler-2.7.14.tgz + + '@vue/reactivity-transform@3.2.47': + dependencies: + '@babel/parser': 7.22.10 + '@vue/compiler-core': 3.2.47 + '@vue/shared': 3.2.47 + estree-walker: 2.0.2 + magic-string: 0.25.9 + + '@vue/reactivity-transform@3.3.4': + dependencies: + '@babel/parser': 7.22.13 + '@vue/compiler-core': 3.3.4 + '@vue/shared': 3.3.4 + estree-walker: 2.0.2 + magic-string: 0.30.3 + + '@vue/reactivity@3.2.47': + dependencies: + '@vue/shared': 3.2.47 + + '@vue/reactivity@3.3.4': + dependencies: + '@vue/shared': 3.3.4 + + '@vue/reactivity@https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.3.4.tgz': + dependencies: + '@vue/shared': https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz + + '@vue/runtime-core@3.2.47': + dependencies: + '@vue/reactivity': 3.2.47 + '@vue/shared': 3.2.47 + + '@vue/runtime-core@3.3.4': + dependencies: + '@vue/reactivity': 3.3.4 + '@vue/shared': 3.3.4 + + '@vue/runtime-dom@3.2.47': + dependencies: + '@vue/runtime-core': 3.2.47 + '@vue/shared': 3.2.47 + csstype: 2.6.21 + + '@vue/runtime-dom@3.3.4': + dependencies: + '@vue/runtime-core': 3.3.4 + '@vue/shared': 3.3.4 + csstype: 3.1.2 + + '@vue/server-renderer@3.2.47(vue@3.2.47)': + dependencies: + '@vue/compiler-ssr': 3.2.47 + '@vue/shared': 3.2.47 + vue: 3.2.47 + + '@vue/server-renderer@3.3.4(vue@3.3.4)': + dependencies: + '@vue/compiler-ssr': 3.3.4 + '@vue/shared': 3.3.4 + vue: 3.3.4 + + '@vue/shared@3.2.47': {} + + '@vue/shared@3.3.4': {} + + '@vue/shared@https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz': {} + + '@vue/test-utils@https://registry.npmmirror.com/@vue/test-utils/-/test-utils-2.4.1.tgz(vue@3.3.4)': + dependencies: + js-beautify: https://registry.npmmirror.com/js-beautify/-/js-beautify-1.14.9.tgz + vue: 3.3.4 + vue-component-type-helpers: https://registry.npmmirror.com/vue-component-type-helpers/-/vue-component-type-helpers-1.8.4.tgz + + '@vue/typescript@https://registry.npmmirror.com/@vue/typescript/-/typescript-1.8.8.tgz(typescript@5.2.2)': + dependencies: + '@volar/typescript': https://registry.npmmirror.com/@volar/typescript/-/typescript-1.10.1.tgz + '@vue/language-core': https://registry.npmmirror.com/@vue/language-core/-/language-core-1.8.8.tgz(typescript@5.2.2) + transitivePeerDependencies: + - typescript + + '@vueuse/core@9.13.0(vue@3.2.47)': + dependencies: + '@types/web-bluetooth': 0.0.16 + '@vueuse/metadata': 9.13.0 + '@vueuse/shared': 9.13.0(vue@3.2.47) + vue-demi: 0.14.0(vue@3.2.47) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/core@https://registry.npmmirror.com/@vueuse/core/-/core-10.4.1.tgz(vue@3.3.4)': + dependencies: + '@types/web-bluetooth': https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.17.tgz + '@vueuse/metadata': https://registry.npmmirror.com/@vueuse/metadata/-/metadata-10.4.1.tgz + '@vueuse/shared': https://registry.npmmirror.com/@vueuse/shared/-/shared-10.4.1.tgz(vue@3.3.4) + vue-demi: https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.6.tgz(vue@3.3.4) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/metadata@9.13.0': {} + + '@vueuse/metadata@https://registry.npmmirror.com/@vueuse/metadata/-/metadata-10.4.1.tgz': {} + + '@vueuse/shared@9.13.0(vue@3.2.47)': + dependencies: + vue-demi: 0.14.0(vue@3.2.47) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/shared@https://registry.npmmirror.com/@vueuse/shared/-/shared-10.4.1.tgz(vue@3.3.4)': + dependencies: + vue-demi: https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.6.tgz(vue@3.3.4) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@zxcvbn-ts/core@https://registry.npmmirror.com/@zxcvbn-ts/core/-/core-3.0.4.tgz': + dependencies: + fastest-levenshtein: https://registry.npmmirror.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz + + JSONStream@https://registry.npmmirror.com/JSONStream/-/JSONStream-1.3.5.tgz: + dependencies: + jsonparse: https://registry.npmmirror.com/jsonparse/-/jsonparse-1.3.1.tgz + through: https://registry.npmmirror.com/through/-/through-2.3.8.tgz + + abab@https://registry.npmmirror.com/abab/-/abab-2.0.6.tgz: {} + + abbrev@https://registry.npmmirror.com/abbrev/-/abbrev-1.1.1.tgz: {} + + acorn-globals@https://registry.npmmirror.com/acorn-globals/-/acorn-globals-6.0.0.tgz: + dependencies: + acorn: https://registry.npmmirror.com/acorn/-/acorn-7.4.1.tgz + acorn-walk: https://registry.npmmirror.com/acorn-walk/-/acorn-walk-7.2.0.tgz + + acorn-walk@https://registry.npmmirror.com/acorn-walk/-/acorn-walk-7.2.0.tgz: {} + + acorn-walk@https://registry.npmmirror.com/acorn-walk/-/acorn-walk-8.2.0.tgz: {} + + acorn@8.10.0: {} + + acorn@https://registry.npmmirror.com/acorn/-/acorn-7.4.1.tgz: {} + + acorn@https://registry.npmmirror.com/acorn/-/acorn-8.10.0.tgz: {} + + adler-32@1.3.1: {} + + agent-base@https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz: + dependencies: + debug: https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz + transitivePeerDependencies: + - supports-color + + aggregate-error@https://registry.npmmirror.com/aggregate-error/-/aggregate-error-3.1.0.tgz: + dependencies: + clean-stack: https://registry.npmmirror.com/clean-stack/-/clean-stack-2.2.0.tgz + indent-string: https://registry.npmmirror.com/indent-string/-/indent-string-4.0.0.tgz + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.12.0: + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + + ajv@https://registry.npmmirror.com/ajv/-/ajv-8.12.0.tgz: + dependencies: + fast-deep-equal: https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz + json-schema-traverse: https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz + require-from-string: https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz + uri-js: https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz + + ansi-escapes@https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz: + dependencies: + type-fest: https://registry.npmmirror.com/type-fest/-/type-fest-0.21.3.tgz + + ansi-regex@2.1.1: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-regex@https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz: {} + + ansi-regex@https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.0.1.tgz: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@https://registry.npmmirror.com/ansi-styles/-/ansi-styles-2.2.1.tgz: {} + + ansi-styles@https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz: + dependencies: + color-convert: https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz + + ansi-styles@https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz: + dependencies: + color-convert: https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz + + ansi-styles@https://registry.npmmirror.com/ansi-styles/-/ansi-styles-5.2.0.tgz: {} + + ansi-styles@https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.1.tgz: {} + + ant-design-vue@https://registry.npmmirror.com/ant-design-vue/-/ant-design-vue-4.0.6.tgz(vue@3.3.4): + dependencies: + '@ant-design/colors': https://registry.npmmirror.com/@ant-design/colors/-/colors-6.0.0.tgz + '@ant-design/icons-vue': https://registry.npmmirror.com/@ant-design/icons-vue/-/icons-vue-7.0.0.tgz(vue@3.3.4) + '@babel/runtime': https://registry.npmmirror.com/@babel/runtime/-/runtime-7.22.11.tgz + '@ctrl/tinycolor': https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz + '@emotion/hash': https://registry.npmmirror.com/@emotion/hash/-/hash-0.9.1.tgz + '@emotion/unitless': https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.8.1.tgz + '@simonwep/pickr': https://registry.npmmirror.com/@simonwep/pickr/-/pickr-1.8.2.tgz + array-tree-filter: https://registry.npmmirror.com/array-tree-filter/-/array-tree-filter-2.1.0.tgz + async-validator: https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz + csstype: https://registry.npmmirror.com/csstype/-/csstype-3.1.2.tgz + dayjs: https://registry.npmmirror.com/dayjs/-/dayjs-1.11.9.tgz + dom-align: https://registry.npmmirror.com/dom-align/-/dom-align-1.12.4.tgz + dom-scroll-into-view: https://registry.npmmirror.com/dom-scroll-into-view/-/dom-scroll-into-view-2.0.1.tgz + lodash: https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz + lodash-es: https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz + resize-observer-polyfill: https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz + scroll-into-view-if-needed: https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz + shallow-equal: https://registry.npmmirror.com/shallow-equal/-/shallow-equal-1.2.1.tgz + stylis: https://registry.npmmirror.com/stylis/-/stylis-4.3.0.tgz + throttle-debounce: https://registry.npmmirror.com/throttle-debounce/-/throttle-debounce-5.0.0.tgz + vue: 3.3.4 + vue-types: https://registry.npmmirror.com/vue-types/-/vue-types-3.0.2.tgz(vue@3.3.4) + warning: https://registry.npmmirror.com/warning/-/warning-4.0.3.tgz + + anymatch@3.1.3: + dependencies: + normalize-path: https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz + picomatch: 2.3.1 + + anymatch@https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz: + dependencies: + normalize-path: https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz + picomatch: https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz + + archiver-utils@2.1.0: + dependencies: + glob: 7.2.3 + graceful-fs: 4.2.11 + lazystream: 1.0.1 + lodash.defaults: 4.2.0 + lodash.difference: 4.5.0 + lodash.flatten: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.union: 4.6.0 + normalize-path: https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz + readable-stream: 2.3.8 + + archiver@5.3.2: + dependencies: + archiver-utils: 2.1.0 + async: 3.2.4 + buffer-crc32: 0.2.13 + readable-stream: 3.6.2 + readdir-glob: 1.1.3 + tar-stream: 2.2.0 + zip-stream: 4.1.0 + + arg@https://registry.npmmirror.com/arg/-/arg-4.1.3.tgz: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + argparse@https://registry.npmmirror.com/argparse/-/argparse-1.0.10.tgz: + dependencies: + sprintf-js: https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz + + argparse@https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz: {} + + arr-diff@4.0.0: {} + + arr-flatten@1.1.0: {} + + arr-union@3.1.0: {} + + array-ify@https://registry.npmmirror.com/array-ify/-/array-ify-1.0.0.tgz: {} + + array-move@3.0.1: {} + + array-tree-filter@https://registry.npmmirror.com/array-tree-filter/-/array-tree-filter-2.1.0.tgz: {} + + array-union@2.1.0: {} + + array-unique@0.3.2: {} + + arrify@1.0.1: {} + + arrify@https://registry.npmmirror.com/arrify/-/arrify-1.0.1.tgz: {} + + assign-symbols@1.0.0: {} + + ast-kit@0.10.0(rollup@3.28.1): + dependencies: + '@babel/parser': 7.22.13 + '@rollup/pluginutils': 5.0.4(rollup@3.28.1) + pathe: https://registry.npmmirror.com/pathe/-/pathe-1.1.1.tgz + transitivePeerDependencies: + - rollup + + ast-kit@0.9.5(rollup@3.28.1): + dependencies: + '@babel/parser': 7.22.10 + '@rollup/pluginutils': 5.0.3(rollup@3.28.1) + pathe: https://registry.npmmirror.com/pathe/-/pathe-1.1.1.tgz + transitivePeerDependencies: + - rollup + + ast-walker-scope@0.5.0(rollup@3.28.1): + dependencies: + '@babel/parser': 7.22.13 + ast-kit: 0.9.5(rollup@3.28.1) + transitivePeerDependencies: + - rollup + + astral-regex@2.0.0: {} + + astral-regex@https://registry.npmmirror.com/astral-regex/-/astral-regex-2.0.0.tgz: {} + + async-validator@https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz: {} + + async@3.2.4: {} + + asynckit@https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz: {} + + atob@2.1.2: {} + + axios@https://registry.npmmirror.com/axios/-/axios-0.26.1.tgz(debug@4.3.4): + dependencies: + follow-redirects: https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz(debug@4.3.4) + transitivePeerDependencies: + - debug + + axios@https://registry.npmmirror.com/axios/-/axios-1.5.0.tgz: + dependencies: + follow-redirects: https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz(debug@4.3.4) + form-data: https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz + proxy-from-env: https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz + transitivePeerDependencies: + - debug + + babel-jest@https://registry.npmmirror.com/babel-jest/-/babel-jest-27.5.1.tgz(@babel/core@7.22.11): + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + '@jest/transform': https://registry.npmmirror.com/@jest/transform/-/transform-27.5.1.tgz + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + '@types/babel__core': https://registry.npmmirror.com/@types/babel__core/-/babel__core-7.20.1.tgz + babel-plugin-istanbul: https://registry.npmmirror.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz + babel-preset-jest: https://registry.npmmirror.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz(@babel/core@7.22.11) + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + graceful-fs: 4.2.11 + slash: https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz + transitivePeerDependencies: + - supports-color + + babel-plugin-istanbul@https://registry.npmmirror.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz: + dependencies: + '@babel/helper-plugin-utils': https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz + '@istanbuljs/load-nyc-config': https://registry.npmmirror.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz + '@istanbuljs/schema': https://registry.npmmirror.com/@istanbuljs/schema/-/schema-0.1.3.tgz + istanbul-lib-instrument: https://registry.npmmirror.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz + test-exclude: https://registry.npmmirror.com/test-exclude/-/test-exclude-6.0.0.tgz + transitivePeerDependencies: + - supports-color + + babel-plugin-jest-hoist@https://registry.npmmirror.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz: + dependencies: + '@babel/template': https://registry.npmmirror.com/@babel/template/-/template-7.22.5.tgz + '@babel/types': https://registry.npmmirror.com/@babel/types/-/types-7.22.11.tgz + '@types/babel__core': https://registry.npmmirror.com/@types/babel__core/-/babel__core-7.20.1.tgz + '@types/babel__traverse': https://registry.npmmirror.com/@types/babel__traverse/-/babel__traverse-7.20.1.tgz + + babel-preset-current-node-syntax@https://registry.npmmirror.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz(@babel/core@7.22.11): + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + '@babel/plugin-syntax-async-generators': https://registry.npmmirror.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz(@babel/core@7.22.11) + '@babel/plugin-syntax-bigint': https://registry.npmmirror.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz(@babel/core@7.22.11) + '@babel/plugin-syntax-class-properties': https://registry.npmmirror.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz(@babel/core@7.22.11) + '@babel/plugin-syntax-import-meta': https://registry.npmmirror.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz(@babel/core@7.22.11) + '@babel/plugin-syntax-json-strings': https://registry.npmmirror.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz(@babel/core@7.22.11) + '@babel/plugin-syntax-logical-assignment-operators': https://registry.npmmirror.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz(@babel/core@7.22.11) + '@babel/plugin-syntax-nullish-coalescing-operator': https://registry.npmmirror.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz(@babel/core@7.22.11) + '@babel/plugin-syntax-numeric-separator': https://registry.npmmirror.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz(@babel/core@7.22.11) + '@babel/plugin-syntax-object-rest-spread': https://registry.npmmirror.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz(@babel/core@7.22.11) + '@babel/plugin-syntax-optional-catch-binding': https://registry.npmmirror.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz(@babel/core@7.22.11) + '@babel/plugin-syntax-optional-chaining': https://registry.npmmirror.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz(@babel/core@7.22.11) + '@babel/plugin-syntax-top-level-await': https://registry.npmmirror.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz(@babel/core@7.22.11) + + babel-preset-jest@https://registry.npmmirror.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz(@babel/core@7.22.11): + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + babel-plugin-jest-hoist: https://registry.npmmirror.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz + babel-preset-current-node-syntax: https://registry.npmmirror.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz(@babel/core@7.22.11) + + balanced-match@1.0.2: {} + + balanced-match@2.0.0: {} + + balanced-match@https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz: {} + + base64-js@1.5.1: {} + + base@0.11.2: + dependencies: + cache-base: 1.0.1 + class-utils: 0.3.6 + component-emitter: 1.3.0 + define-property: 1.0.0 + isobject: 3.0.1 + mixin-deep: 1.3.2 + pascalcase: 0.1.1 + + big-integer@1.6.51: {} + + big-integer@https://registry.npmmirror.com/big-integer/-/big-integer-1.6.51.tgz: {} + + big.js@5.2.2: {} + + binary-extensions@2.2.0: {} + + binary-extensions@https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz: {} + + binary@0.3.0: + dependencies: + buffers: 0.1.1 + chainsaw: 0.1.0 + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz + readable-stream: 3.6.2 + + bluebird@3.4.7: {} + + bluebird@3.7.2: {} + + boolbase@1.0.0: {} + + bplist-parser@https://registry.npmmirror.com/bplist-parser/-/bplist-parser-0.2.0.tgz: + dependencies: + big-integer: https://registry.npmmirror.com/big-integer/-/big-integer-1.6.51.tgz + + bpmn-js-properties-panel@5.6.1(@bpmn-io/properties-panel@3.13.0)(bpmn-js@16.1.0)(camunda-bpmn-js-behaviors@1.2.2)(diagram-js@13.4.0): + dependencies: + '@bpmn-io/extract-process-variables': 0.8.0 + '@bpmn-io/properties-panel': 3.13.0(@lezer/common@1.1.2) + array-move: 3.0.1 + bpmn-js: 16.1.0 + camunda-bpmn-js-behaviors: 1.2.2(bpmn-js@16.1.0)(camunda-bpmn-moddle@7.0.1)(zeebe-bpmn-moddle@1.0.0) + diagram-js: 13.4.0 + ids: 1.0.5 + min-dash: 4.1.1 + min-dom: 4.1.0 + + bpmn-js@16.1.0: + dependencies: + bpmn-moddle: 8.0.1 + diagram-js: 13.4.0 + diagram-js-direct-editing: 2.1.1(diagram-js@13.4.0) + ids: 1.0.5 + inherits-browser: 0.1.0 + min-dash: 4.1.1 + min-dom: 4.1.0 + tiny-svg: 3.0.1 + + bpmn-moddle@8.0.1: + dependencies: + min-dash: 4.1.1 + moddle: 6.2.3 + moddle-xml: 10.1.0 + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + brace-expansion@https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz: + dependencies: + balanced-match: https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz + concat-map: 0.0.1 + + brace-expansion@https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz: + dependencies: + balanced-match: https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz + + braces@2.3.2: + dependencies: + arr-flatten: 1.1.0 + array-unique: 0.3.2 + extend-shallow: 2.0.1 + fill-range: 4.0.0 + isobject: 3.0.1 + repeat-element: 1.1.4 + snapdragon: 0.8.2 + snapdragon-node: 2.1.1 + split-string: 3.1.0 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + braces@3.0.2: + dependencies: + fill-range: 7.0.1 + + braces@https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz: + dependencies: + fill-range: https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz + + browser-process-hrtime@https://registry.npmmirror.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz: {} + + browserslist@4.21.10: + dependencies: + caniuse-lite: 1.0.30001524 + electron-to-chromium: 1.4.505 + node-releases: 2.0.13 + update-browserslist-db: 1.0.11(browserslist@4.21.10) + + browserslist@https://registry.npmmirror.com/browserslist/-/browserslist-4.21.10.tgz: + dependencies: + caniuse-lite: https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001524.tgz + electron-to-chromium: https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.505.tgz + node-releases: https://registry.npmmirror.com/node-releases/-/node-releases-2.0.13.tgz + update-browserslist-db: https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz(browserslist@4.21.10) + + bser@https://registry.npmmirror.com/bser/-/bser-2.1.1.tgz: + dependencies: + node-int64: https://registry.npmmirror.com/node-int64/-/node-int64-0.4.0.tgz + + buffer-crc32@0.2.13: {} + + buffer-from@1.1.2: {} + + buffer-from@https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz: {} + + buffer-indexof-polyfill@1.0.2: {} + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + buffers@0.1.1: {} + + builtin-modules@3.3.0: {} + + bundle-name@https://registry.npmmirror.com/bundle-name/-/bundle-name-3.0.0.tgz: + dependencies: + run-applescript: https://registry.npmmirror.com/run-applescript/-/run-applescript-5.0.0.tgz + + bundle-require@4.0.1(esbuild@0.19.2): + dependencies: + esbuild: 0.19.2 + load-tsconfig: 0.2.5 + + cac@6.7.14: {} + + cache-base@1.0.1: + dependencies: + collection-visit: 1.0.0 + component-emitter: 1.3.0 + get-value: 2.0.6 + has-value: 1.0.0 + isobject: 3.0.1 + set-value: 2.0.1 + to-object-path: 0.3.0 + union-value: 1.0.1 + unset-value: 1.0.0 + + call-bind@1.0.2: + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.2.0 + + callsites@3.1.0: {} + + callsites@https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz: {} + + camel-case@4.1.2: + dependencies: + pascal-case: 3.1.2 + tslib: https://registry.npmmirror.com/tslib/-/tslib-2.6.2.tgz + + camelcase-keys@7.0.2: + dependencies: + camelcase: 6.3.0 + map-obj: 4.3.0 + quick-lru: 5.1.1 + type-fest: 1.4.0 + + camelcase-keys@https://registry.npmmirror.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz: + dependencies: + camelcase: https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz + map-obj: https://registry.npmmirror.com/map-obj/-/map-obj-4.3.0.tgz + quick-lru: https://registry.npmmirror.com/quick-lru/-/quick-lru-4.0.1.tgz + + camelcase@5.3.1: {} + + camelcase@6.3.0: {} + + camelcase@https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz: {} + + camelcase@https://registry.npmmirror.com/camelcase/-/camelcase-6.3.0.tgz: {} + + camunda-bpmn-js-behaviors@1.2.2(bpmn-js@16.1.0)(camunda-bpmn-moddle@7.0.1)(zeebe-bpmn-moddle@1.0.0): + dependencies: + bpmn-js: 16.1.0 + camunda-bpmn-moddle: 7.0.1 + ids: 1.0.5 + min-dash: 4.1.1 + zeebe-bpmn-moddle: 1.0.0 + + camunda-bpmn-moddle@7.0.1: {} + + caniuse-lite@1.0.30001524: {} + + caniuse-lite@https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001524.tgz: {} + + cfb@1.2.2: + dependencies: + adler-32: 1.3.1 + crc-32: 1.2.2 + + chainsaw@0.1.0: + dependencies: + traverse: 0.3.9 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.3.0: {} + + chalk@https://registry.npmmirror.com/chalk/-/chalk-1.1.3.tgz: + dependencies: + ansi-styles: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-2.2.1.tgz + escape-string-regexp: 1.0.5 + has-ansi: 2.0.0 + strip-ansi: 3.0.1 + supports-color: https://registry.npmmirror.com/supports-color/-/supports-color-2.0.0.tgz + + chalk@https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz: + dependencies: + ansi-styles: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz + escape-string-regexp: 1.0.5 + supports-color: https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz + + chalk@https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz: + dependencies: + ansi-styles: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz + supports-color: https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz + + chalk@https://registry.npmmirror.com/chalk/-/chalk-5.2.0.tgz: {} + + char-regex@https://registry.npmmirror.com/char-regex/-/char-regex-1.0.2.tgz: {} + + chokidar@3.5.3: + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz: + dependencies: + anymatch: https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz + braces: https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz + glob-parent: https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz + is-binary-path: https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz + is-glob: https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz + normalize-path: https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz + readdirp: https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz + optionalDependencies: + fsevents: 2.3.3 + + ci-info@https://registry.npmmirror.com/ci-info/-/ci-info-3.8.0.tgz: {} + + citty@0.1.3: + dependencies: + consola: 3.2.3 + + cjs-module-lexer@https://registry.npmmirror.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz: {} + + class-utils@0.3.6: + dependencies: + arr-union: 3.1.0 + define-property: 0.2.5 + isobject: 3.0.1 + static-extend: 0.1.2 + + classnames@2.3.2: {} + + clean-css@5.3.2: + dependencies: + source-map: 0.6.1 + + clean-stack@https://registry.npmmirror.com/clean-stack/-/clean-stack-2.2.0.tgz: {} + + cli-cursor@https://registry.npmmirror.com/cli-cursor/-/cli-cursor-3.1.0.tgz: + dependencies: + restore-cursor: https://registry.npmmirror.com/restore-cursor/-/restore-cursor-3.1.0.tgz + + cli-truncate@https://registry.npmmirror.com/cli-truncate/-/cli-truncate-2.1.0.tgz: + dependencies: + slice-ansi: https://registry.npmmirror.com/slice-ansi/-/slice-ansi-3.0.0.tgz + string-width: https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz + + cli-truncate@https://registry.npmmirror.com/cli-truncate/-/cli-truncate-3.1.0.tgz: + dependencies: + slice-ansi: https://registry.npmmirror.com/slice-ansi/-/slice-ansi-5.0.0.tgz + string-width: https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz + + cliui@6.0.0: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + cliui@https://registry.npmmirror.com/cliui/-/cliui-7.0.4.tgz: + dependencies: + string-width: https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz + strip-ansi: https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz + wrap-ansi: https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz + + cliui@https://registry.npmmirror.com/cliui/-/cliui-8.0.1.tgz: + dependencies: + string-width: https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz + strip-ansi: https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz + wrap-ansi: https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz + + clone@2.1.2: {} + + clsx@2.0.0: {} + + co@https://registry.npmmirror.com/co/-/co-4.6.0.tgz: {} + + code-block-writer@12.0.0: {} + + codemirror@https://registry.npmmirror.com/codemirror/-/codemirror-5.65.15.tgz: {} + + codepage@1.15.0: {} + + collect-v8-coverage@https://registry.npmmirror.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz: {} + + collection-visit@1.0.0: + dependencies: + map-visit: 1.0.0 + object-visit: 1.0.1 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-convert@https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz: + dependencies: + color-name: https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz + + color-convert@https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz: + dependencies: + color-name: https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz + + color-name@1.1.4: {} + + color-name@https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz: {} + + color-name@https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz: {} + + colord@2.9.3: {} + + colorette@2.0.20: {} + + colorette@https://registry.npmmirror.com/colorette/-/colorette-2.0.20.tgz: {} + + colors@1.2.5: {} + + combined-stream@https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz: + dependencies: + delayed-stream: https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz + + commander@11.0.0: {} + + commander@7.2.0: {} + + commander@8.3.0: {} + + commander@9.5.0: {} + + commander@https://registry.npmmirror.com/commander/-/commander-10.0.1.tgz: {} + + commander@https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz: {} + + commondir@1.0.1: {} + + compare-func@https://registry.npmmirror.com/compare-func/-/compare-func-2.0.0.tgz: + dependencies: + array-ify: https://registry.npmmirror.com/array-ify/-/array-ify-1.0.0.tgz + dot-prop: https://registry.npmmirror.com/dot-prop/-/dot-prop-5.3.0.tgz + + component-emitter@1.3.0: {} + + component-event@0.2.1: {} + + compress-commons@4.1.1: + dependencies: + buffer-crc32: 0.2.13 + crc32-stream: 4.0.2 + normalize-path: https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz + readable-stream: 3.6.2 + + compute-scroll-into-view@https://registry.npmmirror.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz: {} + + concat-map@0.0.1: {} + + config-chain@https://registry.npmmirror.com/config-chain/-/config-chain-1.1.13.tgz: + dependencies: + ini: https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz + proto-list: https://registry.npmmirror.com/proto-list/-/proto-list-1.2.4.tgz + + connect-history-api-fallback@1.6.0: {} + + connect@3.7.0: + dependencies: + debug: 2.6.9 + finalhandler: 1.1.2 + parseurl: 1.3.3 + utils-merge: 1.0.1 + transitivePeerDependencies: + - supports-color + + connect@https://registry.npmmirror.com/connect/-/connect-3.7.0.tgz: + dependencies: + debug: https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz + finalhandler: https://registry.npmmirror.com/finalhandler/-/finalhandler-1.1.2.tgz + parseurl: https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz + utils-merge: https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz + transitivePeerDependencies: + - supports-color + + consola@2.15.3: {} + + consola@3.2.3: {} + + conventional-changelog-angular@https://registry.npmmirror.com/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz: + dependencies: + compare-func: https://registry.npmmirror.com/compare-func/-/compare-func-2.0.0.tgz + + conventional-changelog-conventionalcommits@https://registry.npmmirror.com/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz: + dependencies: + compare-func: https://registry.npmmirror.com/compare-func/-/compare-func-2.0.0.tgz + + conventional-commits-parser@https://registry.npmmirror.com/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz: + dependencies: + JSONStream: https://registry.npmmirror.com/JSONStream/-/JSONStream-1.3.5.tgz + is-text-path: https://registry.npmmirror.com/is-text-path/-/is-text-path-1.0.1.tgz + meow: https://registry.npmmirror.com/meow/-/meow-8.1.2.tgz + split2: https://registry.npmmirror.com/split2/-/split2-3.2.2.tgz + + convert-source-map@1.9.0: {} + + convert-source-map@https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.9.0.tgz: {} + + copy-anything@2.0.6: + dependencies: + is-what: 3.14.1 + + copy-descriptor@0.1.1: {} + + core-js@https://registry.npmmirror.com/core-js/-/core-js-3.32.1.tgz: {} + + core-util-is@1.0.3: {} + + cors@2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + cosmiconfig-typescript-loader@https://registry.npmmirror.com/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.4.0.tgz(@types/node@20.4.7)(cosmiconfig@8.2.0)(ts-node@10.9.1)(typescript@5.2.2): + dependencies: + '@types/node': https://registry.npmmirror.com/@types/node/-/node-20.4.7.tgz + cosmiconfig: https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-8.2.0.tgz + ts-node: https://registry.npmmirror.com/ts-node/-/ts-node-10.9.1.tgz(@types/node@20.4.7)(typescript@5.2.2) + typescript: https://registry.npmmirror.com/typescript/-/typescript-5.2.2.tgz + + cosmiconfig@8.2.0: + dependencies: + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + path-type: 4.0.0 + + cosmiconfig@https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-8.2.0.tgz: + dependencies: + import-fresh: https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz + js-yaml: https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.0.tgz + parse-json: https://registry.npmmirror.com/parse-json/-/parse-json-5.2.0.tgz + path-type: https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz + + crc-32@1.2.2: {} + + crc32-stream@4.0.2: + dependencies: + crc-32: 1.2.2 + readable-stream: 3.6.2 + + create-require@https://registry.npmmirror.com/create-require/-/create-require-1.1.1.tgz: {} + + crelt@1.0.6: {} + + cropperjs@https://registry.npmmirror.com/cropperjs/-/cropperjs-1.6.0.tgz: {} + + cross-env@7.0.3: + dependencies: + cross-spawn: 7.0.3 + + cross-fetch@3.1.8: + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + cross-spawn@https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz: + dependencies: + path-key: https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz + shebang-command: https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz + which: https://registry.npmmirror.com/which/-/which-2.0.2.tgz + + crypto-js@4.1.1: {} + + css-functions-list@3.2.0: {} + + css-property-sort-order-smacss@2.2.0: {} + + css-select@4.3.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 4.3.1 + domutils: 2.8.0 + nth-check: 2.1.1 + + css-tree@1.1.3: + dependencies: + mdn-data: 2.0.14 + source-map: 0.6.1 + + css-tree@2.3.1: + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.0.2 + + css-what@6.1.0: {} + + cssesc@3.0.0: {} + + csso@4.2.0: + dependencies: + css-tree: 1.1.3 + + cssom@https://registry.npmmirror.com/cssom/-/cssom-0.3.8.tgz: {} + + cssom@https://registry.npmmirror.com/cssom/-/cssom-0.4.4.tgz: {} + + cssstyle@https://registry.npmmirror.com/cssstyle/-/cssstyle-2.3.0.tgz: + dependencies: + cssom: https://registry.npmmirror.com/cssom/-/cssom-0.3.8.tgz + + csstype@2.6.21: {} + + csstype@3.1.2: {} + + csstype@https://registry.npmmirror.com/csstype/-/csstype-3.1.2.tgz: {} + + cz-git@https://registry.npmmirror.com/cz-git/-/cz-git-1.7.1.tgz: {} + + czg@https://registry.npmmirror.com/czg/-/czg-1.7.1.tgz: {} + + dargs@https://registry.npmmirror.com/dargs/-/dargs-7.0.0.tgz: {} + + data-urls@https://registry.npmmirror.com/data-urls/-/data-urls-2.0.0.tgz: + dependencies: + abab: https://registry.npmmirror.com/abab/-/abab-2.0.6.tgz + whatwg-mimetype: https://registry.npmmirror.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz + whatwg-url: https://registry.npmmirror.com/whatwg-url/-/whatwg-url-8.7.0.tgz + + dayjs@1.11.9: {} + + dayjs@https://registry.npmmirror.com/dayjs/-/dayjs-1.11.9.tgz: {} + + de-indent@https://registry.npmmirror.com/de-indent/-/de-indent-1.0.2.tgz: {} + + debug@2.6.9: + dependencies: + ms: https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz + + debug@4.3.4: + dependencies: + ms: 2.1.2 + + debug@https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz: + dependencies: + ms: https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz + + debug@https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz: + dependencies: + ms: https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz + optional: true + + debug@https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz: + dependencies: + ms: https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz + + decamelize-keys@1.1.1: + dependencies: + decamelize: 1.2.0 + map-obj: 1.0.1 + + decamelize-keys@https://registry.npmmirror.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz: + dependencies: + decamelize: https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz + map-obj: https://registry.npmmirror.com/map-obj/-/map-obj-1.0.1.tgz + + decamelize@1.2.0: {} + + decamelize@5.0.1: {} + + decamelize@https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz: {} + + decimal.js@https://registry.npmmirror.com/decimal.js/-/decimal.js-10.4.3.tgz: {} + + decode-uri-component@0.2.2: {} + + dedent@https://registry.npmmirror.com/dedent/-/dedent-0.7.0.tgz: {} + + deepmerge@4.3.1: {} + + deepmerge@https://registry.npmmirror.com/deepmerge/-/deepmerge-4.3.1.tgz: {} + + default-browser-id@https://registry.npmmirror.com/default-browser-id/-/default-browser-id-3.0.0.tgz: + dependencies: + bplist-parser: https://registry.npmmirror.com/bplist-parser/-/bplist-parser-0.2.0.tgz + untildify: https://registry.npmmirror.com/untildify/-/untildify-4.0.0.tgz + + default-browser@https://registry.npmmirror.com/default-browser/-/default-browser-4.0.0.tgz: + dependencies: + bundle-name: https://registry.npmmirror.com/bundle-name/-/bundle-name-3.0.0.tgz + default-browser-id: https://registry.npmmirror.com/default-browser-id/-/default-browser-id-3.0.0.tgz + execa: https://registry.npmmirror.com/execa/-/execa-7.2.0.tgz + titleize: https://registry.npmmirror.com/titleize/-/titleize-3.0.0.tgz + + define-lazy-prop@2.0.0: {} + + define-lazy-prop@https://registry.npmmirror.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz: {} + + define-property@0.2.5: + dependencies: + is-descriptor: 0.1.6 + + define-property@1.0.0: + dependencies: + is-descriptor: 1.0.2 + + define-property@2.0.2: + dependencies: + is-descriptor: 1.0.2 + isobject: 3.0.1 + + defu@6.1.2: {} + + delayed-stream@https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz: {} + + destr@2.0.1: {} + + detect-indent@https://registry.npmmirror.com/detect-indent/-/detect-indent-7.0.1.tgz: {} + + detect-newline@https://registry.npmmirror.com/detect-newline/-/detect-newline-3.1.0.tgz: {} + + detect-newline@https://registry.npmmirror.com/detect-newline/-/detect-newline-4.0.0.tgz: {} + + diagram-js-direct-editing@2.1.1(diagram-js@13.4.0): + dependencies: + diagram-js: 13.4.0 + min-dash: 4.1.1 + min-dom: 4.1.0 + + diagram-js-grid-bg@1.0.4: + dependencies: + min-dom: 4.1.0 + tiny-svg: 3.0.1 + + diagram-js-minimap@4.1.0: + dependencies: + hammerjs: 2.0.8 + min-dash: 4.1.1 + min-dom: 4.1.0 + tiny-svg: 3.0.1 + + diagram-js@13.4.0: + dependencies: + '@bpmn-io/diagram-js-ui': 0.2.2 + clsx: 2.0.0 + didi: 10.0.1 + hammerjs: 2.0.8 + inherits-browser: 0.1.0 + min-dash: 4.1.1 + min-dom: 4.1.0 + object-refs: 0.4.0 + path-intersection: 3.0.0 + tiny-svg: 3.0.1 + + didi@10.0.1: {} + + diff-match-patch@https://registry.npmmirror.com/diff-match-patch/-/diff-match-patch-1.0.5.tgz: {} + + diff-sequences@https://registry.npmmirror.com/diff-sequences/-/diff-sequences-27.5.1.tgz: {} + + diff@https://registry.npmmirror.com/diff/-/diff-4.0.2.tgz: {} + + dijkstrajs@1.0.3: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dir-glob@https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz: + dependencies: + path-type: https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz + + dom-align@https://registry.npmmirror.com/dom-align/-/dom-align-1.12.4.tgz: {} + + dom-scroll-into-view@https://registry.npmmirror.com/dom-scroll-into-view/-/dom-scroll-into-view-2.0.1.tgz: {} + + dom-serializer@0.2.2: + dependencies: + domelementtype: 2.3.0 + entities: 2.2.0 + + dom-serializer@1.4.1: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + entities: 2.2.0 + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + dom-zindex@https://registry.npmmirror.com/dom-zindex/-/dom-zindex-1.0.1.tgz: {} + + domelementtype@1.3.1: {} + + domelementtype@2.3.0: {} + + domexception@https://registry.npmmirror.com/domexception/-/domexception-2.0.1.tgz: + dependencies: + webidl-conversions: https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz + + domhandler@2.4.2: + dependencies: + domelementtype: 1.3.1 + + domhandler@4.3.1: + dependencies: + domelementtype: 2.3.0 + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domify@1.4.2: {} + + domutils@1.7.0: + dependencies: + dom-serializer: 0.2.2 + domelementtype: 1.3.1 + + domutils@2.8.0: + dependencies: + dom-serializer: 1.4.1 + domelementtype: 2.3.0 + domhandler: 4.3.1 + + domutils@3.1.0: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dot-case@3.0.4: + dependencies: + no-case: 3.0.4 + tslib: https://registry.npmmirror.com/tslib/-/tslib-2.6.2.tgz + + dot-prop@https://registry.npmmirror.com/dot-prop/-/dot-prop-5.3.0.tgz: + dependencies: + is-obj: https://registry.npmmirror.com/is-obj/-/is-obj-2.0.0.tgz + + dotenv-expand@8.0.3: {} + + dotenv@16.3.1: {} + + duplexer2@0.1.4: + dependencies: + readable-stream: 2.3.8 + + duplexer@0.1.2: {} + + eastasianwidth@https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz: {} + + echarts@https://registry.npmmirror.com/echarts/-/echarts-5.4.3.tgz: + dependencies: + tslib: https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz + zrender: https://registry.npmmirror.com/zrender/-/zrender-5.4.4.tgz + + editorconfig@https://registry.npmmirror.com/editorconfig/-/editorconfig-1.0.4.tgz: + dependencies: + '@one-ini/wasm': https://registry.npmmirror.com/@one-ini/wasm/-/wasm-0.1.1.tgz + commander: https://registry.npmmirror.com/commander/-/commander-10.0.1.tgz + minimatch: https://registry.npmmirror.com/minimatch/-/minimatch-9.0.1.tgz + semver: https://registry.npmmirror.com/semver/-/semver-7.5.4.tgz + + ee-first@1.1.1: {} + + ee-first@https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz: {} + + ejs@3.1.9: + dependencies: + jake: 10.8.7 + + electron-to-chromium@1.4.505: {} + + electron-to-chromium@https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.505.tgz: {} + + emittery@https://registry.npmmirror.com/emittery/-/emittery-0.8.1.tgz: {} + + emoji-regex@8.0.0: {} + + emoji-regex@https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz: {} + + emoji-regex@https://registry.npmmirror.com/emoji-regex/-/emoji-regex-9.2.2.tgz: {} + + emojis-list@3.0.0: {} + + encode-utf8@1.0.3: {} + + encodeurl@1.0.2: {} + + encodeurl@https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz: {} + + end-of-stream@1.4.4: + dependencies: + once: 1.4.0 + + entities@1.1.2: {} + + entities@2.2.0: {} + + entities@4.5.0: {} + + errno@0.1.8: + dependencies: + prr: 1.0.1 + optional: true + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + error-ex@https://registry.npmmirror.com/error-ex/-/error-ex-1.3.2.tgz: + dependencies: + is-arrayish: https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.2.1.tgz + + esbuild-android-64@0.14.54: + optional: true + + esbuild-android-arm64@0.14.54: + optional: true + + esbuild-darwin-64@0.14.54: + optional: true + + esbuild-darwin-arm64@0.14.54: + optional: true + + esbuild-freebsd-64@0.14.54: + optional: true + + esbuild-freebsd-arm64@0.14.54: + optional: true + + esbuild-linux-32@0.14.54: + optional: true + + esbuild-linux-64@0.14.54: + optional: true + + esbuild-linux-arm64@0.14.54: + optional: true + + esbuild-linux-arm@0.14.54: + optional: true + + esbuild-linux-mips64le@0.14.54: + optional: true + + esbuild-linux-ppc64le@0.14.54: + optional: true + + esbuild-linux-riscv64@0.14.54: + optional: true + + esbuild-linux-s390x@0.14.54: + optional: true + + esbuild-netbsd-64@0.14.54: + optional: true + + esbuild-openbsd-64@0.14.54: + optional: true + + esbuild-sunos-64@0.14.54: + optional: true + + esbuild-windows-32@0.14.54: + optional: true + + esbuild-windows-64@0.14.54: + optional: true + + esbuild-windows-arm64@0.14.54: + optional: true + + esbuild@0.17.19: + optionalDependencies: + '@esbuild/android-arm': 0.17.19 + '@esbuild/android-arm64': 0.17.19 + '@esbuild/android-x64': 0.17.19 + '@esbuild/darwin-arm64': 0.17.19 + '@esbuild/darwin-x64': 0.17.19 + '@esbuild/freebsd-arm64': 0.17.19 + '@esbuild/freebsd-x64': 0.17.19 + '@esbuild/linux-arm': 0.17.19 + '@esbuild/linux-arm64': 0.17.19 + '@esbuild/linux-ia32': 0.17.19 + '@esbuild/linux-loong64': 0.17.19 + '@esbuild/linux-mips64el': 0.17.19 + '@esbuild/linux-ppc64': 0.17.19 + '@esbuild/linux-riscv64': 0.17.19 + '@esbuild/linux-s390x': 0.17.19 + '@esbuild/linux-x64': 0.17.19 + '@esbuild/netbsd-x64': 0.17.19 + '@esbuild/openbsd-x64': 0.17.19 + '@esbuild/sunos-x64': 0.17.19 + '@esbuild/win32-arm64': 0.17.19 + '@esbuild/win32-ia32': 0.17.19 + '@esbuild/win32-x64': 0.17.19 + + esbuild@0.18.20: + optionalDependencies: + '@esbuild/android-arm': 0.18.20 + '@esbuild/android-arm64': 0.18.20 + '@esbuild/android-x64': 0.18.20 + '@esbuild/darwin-arm64': 0.18.20 + '@esbuild/darwin-x64': 0.18.20 + '@esbuild/freebsd-arm64': 0.18.20 + '@esbuild/freebsd-x64': 0.18.20 + '@esbuild/linux-arm': 0.18.20 + '@esbuild/linux-arm64': 0.18.20 + '@esbuild/linux-ia32': 0.18.20 + '@esbuild/linux-loong64': 0.18.20 + '@esbuild/linux-mips64el': 0.18.20 + '@esbuild/linux-ppc64': 0.18.20 + '@esbuild/linux-riscv64': 0.18.20 + '@esbuild/linux-s390x': 0.18.20 + '@esbuild/linux-x64': 0.18.20 + '@esbuild/netbsd-x64': 0.18.20 + '@esbuild/openbsd-x64': 0.18.20 + '@esbuild/sunos-x64': 0.18.20 + '@esbuild/win32-arm64': 0.18.20 + '@esbuild/win32-ia32': 0.18.20 + '@esbuild/win32-x64': 0.18.20 + + esbuild@0.19.2: + optionalDependencies: + '@esbuild/android-arm': 0.19.2 + '@esbuild/android-arm64': 0.19.2 + '@esbuild/android-x64': 0.19.2 + '@esbuild/darwin-arm64': 0.19.2 + '@esbuild/darwin-x64': 0.19.2 + '@esbuild/freebsd-arm64': 0.19.2 + '@esbuild/freebsd-x64': 0.19.2 + '@esbuild/linux-arm': 0.19.2 + '@esbuild/linux-arm64': 0.19.2 + '@esbuild/linux-ia32': 0.19.2 + '@esbuild/linux-loong64': 0.19.2 + '@esbuild/linux-mips64el': 0.19.2 + '@esbuild/linux-ppc64': 0.19.2 + '@esbuild/linux-riscv64': 0.19.2 + '@esbuild/linux-s390x': 0.19.2 + '@esbuild/linux-x64': 0.19.2 + '@esbuild/netbsd-x64': 0.19.2 + '@esbuild/openbsd-x64': 0.19.2 + '@esbuild/sunos-x64': 0.19.2 + '@esbuild/win32-arm64': 0.19.2 + '@esbuild/win32-ia32': 0.19.2 + '@esbuild/win32-x64': 0.19.2 + + esbuild@https://registry.npmmirror.com/esbuild/-/esbuild-0.14.54.tgz: + optionalDependencies: + '@esbuild/linux-loong64': 0.14.54 + esbuild-android-64: 0.14.54 + esbuild-android-arm64: 0.14.54 + esbuild-darwin-64: 0.14.54 + esbuild-darwin-arm64: 0.14.54 + esbuild-freebsd-64: 0.14.54 + esbuild-freebsd-arm64: 0.14.54 + esbuild-linux-32: 0.14.54 + esbuild-linux-64: 0.14.54 + esbuild-linux-arm: 0.14.54 + esbuild-linux-arm64: 0.14.54 + esbuild-linux-mips64le: 0.14.54 + esbuild-linux-ppc64le: 0.14.54 + esbuild-linux-riscv64: 0.14.54 + esbuild-linux-s390x: 0.14.54 + esbuild-netbsd-64: 0.14.54 + esbuild-openbsd-64: 0.14.54 + esbuild-sunos-64: 0.14.54 + esbuild-windows-32: 0.14.54 + esbuild-windows-64: 0.14.54 + esbuild-windows-arm64: 0.14.54 + + esbuild@https://registry.npmmirror.com/esbuild/-/esbuild-0.18.20.tgz: + optionalDependencies: + '@esbuild/android-arm': 0.18.20 + '@esbuild/android-arm64': 0.18.20 + '@esbuild/android-x64': 0.18.20 + '@esbuild/darwin-arm64': 0.18.20 + '@esbuild/darwin-x64': 0.18.20 + '@esbuild/freebsd-arm64': 0.18.20 + '@esbuild/freebsd-x64': 0.18.20 + '@esbuild/linux-arm': 0.18.20 + '@esbuild/linux-arm64': 0.18.20 + '@esbuild/linux-ia32': 0.18.20 + '@esbuild/linux-loong64': 0.18.20 + '@esbuild/linux-mips64el': 0.18.20 + '@esbuild/linux-ppc64': 0.18.20 + '@esbuild/linux-riscv64': 0.18.20 + '@esbuild/linux-s390x': 0.18.20 + '@esbuild/linux-x64': 0.18.20 + '@esbuild/netbsd-x64': 0.18.20 + '@esbuild/openbsd-x64': 0.18.20 + '@esbuild/sunos-x64': 0.18.20 + '@esbuild/win32-arm64': 0.18.20 + '@esbuild/win32-ia32': 0.18.20 + '@esbuild/win32-x64': 0.18.20 + + escalade@3.1.1: {} + + escalade@https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz: {} + + escape-html@1.0.3: {} + + escape-html@https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz: {} + + escodegen@https://registry.npmmirror.com/escodegen/-/escodegen-2.1.0.tgz: + dependencies: + esprima: https://registry.npmmirror.com/esprima/-/esprima-4.0.1.tgz + estraverse: https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz + esutils: https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz + optionalDependencies: + source-map: 0.6.1 + + esprima@https://registry.npmmirror.com/esprima/-/esprima-4.0.1.tgz: {} + + estraverse@https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz: {} + + estree-walker@2.0.2: {} + + estree-walker@https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz: {} + + esutils@https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz: {} + + etag@1.8.1: {} + + exceljs@4.3.0: + dependencies: + archiver: 5.3.2 + dayjs: 1.11.9 + fast-csv: 4.3.6 + jszip: 3.10.1 + readable-stream: 3.6.2 + saxes: 5.0.1 + tmp: 0.2.1 + unzipper: 0.10.14 + uuid: 8.3.2 + + execa@https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz: + dependencies: + cross-spawn: https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz + get-stream: https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz + human-signals: https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz + is-stream: https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz + merge-stream: https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz + npm-run-path: https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz + onetime: https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz + signal-exit: https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz + strip-final-newline: https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz + + execa@https://registry.npmmirror.com/execa/-/execa-7.2.0.tgz: + dependencies: + cross-spawn: https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz + get-stream: https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz + human-signals: https://registry.npmmirror.com/human-signals/-/human-signals-4.3.1.tgz + is-stream: https://registry.npmmirror.com/is-stream/-/is-stream-3.0.0.tgz + merge-stream: https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz + npm-run-path: https://registry.npmmirror.com/npm-run-path/-/npm-run-path-5.1.0.tgz + onetime: https://registry.npmmirror.com/onetime/-/onetime-6.0.0.tgz + signal-exit: https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz + strip-final-newline: https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz + + exit@https://registry.npmmirror.com/exit/-/exit-0.1.2.tgz: {} + + expand-brackets@2.1.4: + dependencies: + debug: https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz + define-property: 0.2.5 + extend-shallow: 2.0.1 + posix-character-classes: 0.1.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + expect@https://registry.npmmirror.com/expect/-/expect-27.5.1.tgz: + dependencies: + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + jest-get-type: https://registry.npmmirror.com/jest-get-type/-/jest-get-type-27.5.1.tgz + jest-matcher-utils: https://registry.npmmirror.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz + jest-message-util: https://registry.npmmirror.com/jest-message-util/-/jest-message-util-27.5.1.tgz + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend-shallow@3.0.2: + dependencies: + assign-symbols: 1.0.0 + is-extendable: 1.0.1 + + extglob@2.0.4: + dependencies: + array-unique: 0.3.2 + define-property: 1.0.0 + expand-brackets: 2.1.4 + extend-shallow: 2.0.1 + fragment-cache: 0.2.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + fast-csv@4.3.6: + dependencies: + '@fast-csv/format': 4.3.5 + '@fast-csv/parse': 4.3.6 + + fast-deep-equal@3.1.3: {} + + fast-deep-equal@https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz: {} + + fast-diff@1.2.0: {} + + fast-glob@3.3.1: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + + fast-glob@https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.1.tgz: + dependencies: + '@nodelib/fs.stat': https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz + '@nodelib/fs.walk': https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz + glob-parent: https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz + merge2: https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz + micromatch: https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz + + fast-json-stable-stringify@2.1.0: {} + + fast-json-stable-stringify@https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz: {} + + fastest-levenshtein@1.0.16: {} + + fastest-levenshtein@https://registry.npmmirror.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz: {} + + fastq@1.15.0: + dependencies: + reusify: 1.0.4 + + fastq@https://registry.npmmirror.com/fastq/-/fastq-1.15.0.tgz: + dependencies: + reusify: https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz + + fb-watchman@https://registry.npmmirror.com/fb-watchman/-/fb-watchman-2.0.2.tgz: + dependencies: + bser: https://registry.npmmirror.com/bser/-/bser-2.1.1.tgz + + feelers@1.2.0: + dependencies: + '@bpmn-io/cm-theme': 0.1.0-alpha.2 + '@bpmn-io/feel-lint': 1.1.0 + '@codemirror/autocomplete': 6.11.1(@codemirror/language@6.9.3)(@codemirror/state@6.3.3)(@codemirror/view@6.22.3)(@lezer/common@1.1.2) + '@codemirror/commands': 6.3.2 + '@codemirror/language': 6.9.3 + '@codemirror/lint': 6.4.2 + '@codemirror/state': 6.3.3 + '@codemirror/view': 6.22.3 + '@lezer/common': 1.1.2 + '@lezer/highlight': 1.2.0 + '@lezer/lr': 1.3.14 + '@lezer/markdown': 1.1.2 + feelin: 2.3.0 + lezer-feel: 1.2.3 + min-dom: 4.1.0 + + feelin@2.3.0: + dependencies: + '@lezer/lr': 1.3.14 + lezer-feel: 1.2.3 + luxon: 3.4.4 + + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.1.0 + + filelist@1.0.4: + dependencies: + minimatch: https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz + + fill-range@4.0.0: + dependencies: + extend-shallow: 2.0.1 + is-number: 3.0.0 + repeat-string: 1.6.1 + to-regex-range: 2.1.1 + + fill-range@7.0.1: + dependencies: + to-regex-range: 5.0.1 + + fill-range@https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz: + dependencies: + to-regex-range: https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz + + finalhandler@1.1.2: + dependencies: + debug: https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.3.0 + parseurl: 1.3.3 + statuses: 1.5.0 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + finalhandler@https://registry.npmmirror.com/finalhandler/-/finalhandler-1.1.2.tgz: + dependencies: + debug: https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz + encodeurl: https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz + escape-html: https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz + on-finished: https://registry.npmmirror.com/on-finished/-/on-finished-2.3.0.tgz + parseurl: https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz + statuses: https://registry.npmmirror.com/statuses/-/statuses-1.5.0.tgz + unpipe: https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz + transitivePeerDependencies: + - supports-color + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + find-up@https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz: + dependencies: + locate-path: https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz + path-exists: https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz + + find-up@https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz: + dependencies: + locate-path: https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz + path-exists: https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz + + flat-cache@3.1.0: + dependencies: + flatted: 3.2.7 + keyv: 4.5.3 + rimraf: 3.0.2 + + flatted@3.2.7: {} + + focus-trap@7.5.4: + dependencies: + tabbable: 6.2.0 + + follow-redirects@https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz(debug@4.3.4): + dependencies: + debug: https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz + + for-in@1.0.2: {} + + foreground-child@3.1.1: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + + form-data@https://registry.npmmirror.com/form-data/-/form-data-3.0.1.tgz: + dependencies: + asynckit: https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz + combined-stream: https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz + mime-types: https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz + + form-data@https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz: + dependencies: + asynckit: https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz + combined-stream: https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz + mime-types: https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz + + frac@1.1.2: {} + + fragment-cache@0.2.1: + dependencies: + map-cache: 0.2.2 + + fs-constants@1.0.0: {} + + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.0 + + fs-extra@11.1.1: + dependencies: + graceful-fs: 4.2.10 + jsonfile: 6.1.0 + universalify: 2.0.0 + + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@https://registry.npmmirror.com/fs-extra/-/fs-extra-11.1.1.tgz: + dependencies: + graceful-fs: 4.2.11 + jsonfile: https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz + universalify: https://registry.npmmirror.com/universalify/-/universalify-2.0.0.tgz + + fs.realpath@1.0.0: {} + + fs.realpath@https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz: {} + + fsevents@2.3.3: + optional: true + + fstream@1.0.12: + dependencies: + graceful-fs: 4.2.11 + inherits: https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz + mkdirp: 0.5.6 + rimraf: 2.7.1 + + function-bind@1.1.1: {} + + function-bind@https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz: {} + + gensync@1.0.0-beta.2: {} + + gensync@https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz: {} + + get-caller-file@2.0.5: {} + + get-caller-file@https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz: {} + + get-intrinsic@1.2.0: + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-symbols: 1.0.3 + + get-intrinsic@1.2.1: + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-proto: 1.0.1 + has-symbols: 1.0.3 + + get-package-type@https://registry.npmmirror.com/get-package-type/-/get-package-type-0.1.0.tgz: {} + + get-stdin@https://registry.npmmirror.com/get-stdin/-/get-stdin-9.0.0.tgz: {} + + get-stream@https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz: {} + + get-value@2.0.6: {} + + git-hooks-list@https://registry.npmmirror.com/git-hooks-list/-/git-hooks-list-3.1.0.tgz: {} + + git-raw-commits@https://registry.npmmirror.com/git-raw-commits/-/git-raw-commits-2.0.11.tgz: + dependencies: + dargs: https://registry.npmmirror.com/dargs/-/dargs-7.0.0.tgz + lodash: https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz + meow: https://registry.npmmirror.com/meow/-/meow-8.1.2.tgz + split2: https://registry.npmmirror.com/split2/-/split2-3.2.2.tgz + through2: https://registry.npmmirror.com/through2/-/through2-4.0.2.tgz + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz: + dependencies: + is-glob: https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz + + glob@10.3.3: + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.3.1 + minimatch: 9.0.3 + minipass: 7.0.3 + path-scurry: 1.10.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz + minimatch: 5.1.6 + once: 1.4.0 + + glob@https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz: + dependencies: + fs.realpath: https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz + inflight: https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz + inherits: https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz + minimatch: https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz + once: https://registry.npmmirror.com/once/-/once-1.4.0.tgz + path-is-absolute: 1.0.1 + + glob@https://registry.npmmirror.com/glob/-/glob-8.1.0.tgz: + dependencies: + fs.realpath: https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz + inflight: https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz + inherits: https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz + minimatch: https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz + once: https://registry.npmmirror.com/once/-/once-1.4.0.tgz + + global-dirs@https://registry.npmmirror.com/global-dirs/-/global-dirs-0.1.1.tgz: + dependencies: + ini: https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz + + global-modules@2.0.0: + dependencies: + global-prefix: 3.0.0 + + global-prefix@3.0.0: + dependencies: + ini: 1.3.8 + kind-of: 6.0.3 + which: 1.3.1 + + globals@11.12.0: {} + + globals@https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz: {} + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.1 + ignore: 5.2.4 + merge2: 1.4.1 + slash: 3.0.0 + + globby@13.2.2: + dependencies: + dir-glob: 3.0.1 + fast-glob: 3.3.1 + ignore: 5.2.4 + merge2: 1.4.1 + slash: 4.0.0 + + globby@https://registry.npmmirror.com/globby/-/globby-13.2.2.tgz: + dependencies: + dir-glob: https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz + fast-glob: https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.1.tgz + ignore: https://registry.npmmirror.com/ignore/-/ignore-5.2.4.tgz + merge2: https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz + slash: https://registry.npmmirror.com/slash/-/slash-4.0.0.tgz + + globjoin@0.1.4: {} + + graceful-fs@4.2.10: {} + + graceful-fs@4.2.11: {} + + gzip-size@6.0.0: + dependencies: + duplexer: 0.1.2 + + hammerjs@2.0.8: {} + + hard-rejection@2.1.0: {} + + hard-rejection@https://registry.npmmirror.com/hard-rejection/-/hard-rejection-2.1.0.tgz: {} + + has-ansi@2.0.0: + dependencies: + ansi-regex: 2.1.1 + + has-flag@1.0.0: {} + + has-flag@4.0.0: {} + + has-flag@https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz: {} + + has-flag@https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz: {} + + has-proto@1.0.1: {} + + has-symbols@1.0.3: {} + + has-value@0.3.1: + dependencies: + get-value: 2.0.6 + has-values: 0.1.4 + isobject: 2.1.0 + + has-value@1.0.0: + dependencies: + get-value: 2.0.6 + has-values: 1.0.0 + isobject: 3.0.1 + + has-values@0.1.4: {} + + has-values@1.0.0: + dependencies: + is-number: 3.0.0 + kind-of: 4.0.0 + + has@1.0.3: + dependencies: + function-bind: 1.1.1 + + has@https://registry.npmmirror.com/has/-/has-1.0.3.tgz: + dependencies: + function-bind: https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz + + he@1.2.0: {} + + he@https://registry.npmmirror.com/he/-/he-1.2.0.tgz: {} + + hookable@5.5.3: {} + + hosted-git-info@4.1.0: + dependencies: + lru-cache: https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz + + hosted-git-info@https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz: {} + + hosted-git-info@https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz: + dependencies: + lru-cache: https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz + + htm@3.1.1: {} + + html-encoding-sniffer@https://registry.npmmirror.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz: + dependencies: + whatwg-encoding: https://registry.npmmirror.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz + + html-escaper@https://registry.npmmirror.com/html-escaper/-/html-escaper-2.0.2.tgz: {} + + html-minifier-terser@6.1.0: + dependencies: + camel-case: 4.1.2 + clean-css: 5.3.2 + commander: 8.3.0 + he: 1.2.0 + param-case: 3.0.4 + relateurl: 0.2.7 + terser: 5.19.3 + + html-tags@3.3.1: {} + + htmlparser2@3.10.1: + dependencies: + domelementtype: 1.3.1 + domhandler: 2.4.2 + domutils: 1.7.0 + entities: 1.1.2 + inherits: https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz + readable-stream: 3.6.2 + + htmlparser2@8.0.2: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + entities: 4.5.0 + + http-proxy-agent@https://registry.npmmirror.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz: + dependencies: + '@tootallnate/once': https://registry.npmmirror.com/@tootallnate/once/-/once-1.1.2.tgz + agent-base: https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz + debug: https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz + transitivePeerDependencies: + - supports-color + + https-proxy-agent@https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz: + dependencies: + agent-base: https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz + debug: https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz + transitivePeerDependencies: + - supports-color + + human-signals@https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz: {} + + human-signals@https://registry.npmmirror.com/human-signals/-/human-signals-4.3.1.tgz: {} + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + optional: true + + iconv-lite@https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz: + dependencies: + safer-buffer: https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz + + ids@1.0.5: {} + + ieee754@1.2.1: {} + + ignore@5.2.4: {} + + ignore@https://registry.npmmirror.com/ignore/-/ignore-5.2.4.tgz: {} + + image-size@0.5.5: {} + + immediate@3.0.6: {} + + immutable@4.3.4: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz + + import-fresh@https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz: + dependencies: + parent-module: https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz + resolve-from: https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz + + import-lazy@4.0.0: {} + + import-local@https://registry.npmmirror.com/import-local/-/import-local-3.1.0.tgz: + dependencies: + pkg-dir: https://registry.npmmirror.com/pkg-dir/-/pkg-dir-4.2.0.tgz + resolve-cwd: https://registry.npmmirror.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz + + imurmurhash@0.1.4: {} + + imurmurhash@https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz: {} + + indent-string@5.0.0: {} + + indent-string@https://registry.npmmirror.com/indent-string/-/indent-string-4.0.0.tgz: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inflight@https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz: + dependencies: + once: https://registry.npmmirror.com/once/-/once-1.4.0.tgz + wrappy: https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz + + inherits-browser@0.1.0: {} + + inherits@https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz: {} + + ini@1.3.8: {} + + ini@https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz: {} + + intro.js@https://registry.npmmirror.com/intro.js/-/intro.js-7.2.0.tgz: {} + + is-accessor-descriptor@0.1.6: + dependencies: + kind-of: 3.2.2 + + is-accessor-descriptor@1.0.0: + dependencies: + kind-of: 6.0.3 + + is-arrayish@0.2.1: {} + + is-arrayish@https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.2.1.tgz: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.2.0 + + is-binary-path@https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz: + dependencies: + binary-extensions: https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz + + is-buffer@1.1.6: {} + + is-builtin-module@3.2.1: + dependencies: + builtin-modules: 3.3.0 + + is-core-module@2.11.0: + dependencies: + has: 1.0.3 + + is-core-module@2.13.0: + dependencies: + has: 1.0.3 + + is-core-module@https://registry.npmmirror.com/is-core-module/-/is-core-module-2.13.0.tgz: + dependencies: + has: https://registry.npmmirror.com/has/-/has-1.0.3.tgz + + is-data-descriptor@0.1.4: + dependencies: + kind-of: 3.2.2 + + is-data-descriptor@1.0.0: + dependencies: + kind-of: 6.0.3 + + is-descriptor@0.1.6: + dependencies: + is-accessor-descriptor: 0.1.6 + is-data-descriptor: 0.1.4 + kind-of: 5.1.0 + + is-descriptor@1.0.2: + dependencies: + is-accessor-descriptor: 1.0.0 + is-data-descriptor: 1.0.0 + kind-of: 6.0.3 + + is-docker@2.2.1: {} + + is-docker@https://registry.npmmirror.com/is-docker/-/is-docker-2.2.1.tgz: {} + + is-docker@https://registry.npmmirror.com/is-docker/-/is-docker-3.0.0.tgz: {} + + is-extendable@0.1.1: {} + + is-extendable@1.0.1: + dependencies: + is-plain-object: https://registry.npmmirror.com/is-plain-object/-/is-plain-object-2.0.4.tgz + + is-extglob@2.1.1: {} + + is-extglob@https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz: {} + + is-fullwidth-code-point@3.0.0: {} + + is-fullwidth-code-point@https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz: {} + + is-fullwidth-code-point@https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz: {} + + is-generator-fn@https://registry.npmmirror.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-glob@https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz: + dependencies: + is-extglob: https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz + + is-inside-container@https://registry.npmmirror.com/is-inside-container/-/is-inside-container-1.0.0.tgz: + dependencies: + is-docker: https://registry.npmmirror.com/is-docker/-/is-docker-3.0.0.tgz + + is-module@1.0.0: {} + + is-number@3.0.0: + dependencies: + kind-of: 3.2.2 + + is-number@7.0.0: {} + + is-number@https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz: {} + + is-obj@https://registry.npmmirror.com/is-obj/-/is-obj-2.0.0.tgz: {} + + is-plain-obj@1.1.0: {} + + is-plain-obj@https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz: {} + + is-plain-obj@https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz: {} + + is-plain-object@5.0.0: {} + + is-plain-object@https://registry.npmmirror.com/is-plain-object/-/is-plain-object-2.0.4.tgz: + dependencies: + isobject: 3.0.1 + + is-plain-object@https://registry.npmmirror.com/is-plain-object/-/is-plain-object-3.0.1.tgz: {} + + is-plain-object@https://registry.npmmirror.com/is-plain-object/-/is-plain-object-5.0.0.tgz: {} + + is-potential-custom-element-name@https://registry.npmmirror.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz: {} + + is-reference@1.2.1: + dependencies: + '@types/estree': 1.0.1 + + is-stream@https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz: {} + + is-stream@https://registry.npmmirror.com/is-stream/-/is-stream-3.0.0.tgz: {} + + is-text-path@https://registry.npmmirror.com/is-text-path/-/is-text-path-1.0.1.tgz: + dependencies: + text-extensions: https://registry.npmmirror.com/text-extensions/-/text-extensions-1.9.0.tgz + + is-typedarray@https://registry.npmmirror.com/is-typedarray/-/is-typedarray-1.0.0.tgz: {} + + is-what@3.14.1: {} + + is-windows@1.0.2: {} + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + is-wsl@https://registry.npmmirror.com/is-wsl/-/is-wsl-2.2.0.tgz: + dependencies: + is-docker: https://registry.npmmirror.com/is-docker/-/is-docker-2.2.1.tgz + + isarray@1.0.0: {} + + isexe@2.0.0: {} + + isexe@https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz: {} + + isobject@2.1.0: + dependencies: + isarray: 1.0.0 + + isobject@3.0.1: {} + + istanbul-lib-coverage@https://registry.npmmirror.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz: {} + + istanbul-lib-instrument@https://registry.npmmirror.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz: + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + '@babel/parser': https://registry.npmmirror.com/@babel/parser/-/parser-7.22.13.tgz + '@istanbuljs/schema': https://registry.npmmirror.com/@istanbuljs/schema/-/schema-0.1.3.tgz + istanbul-lib-coverage: https://registry.npmmirror.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz + semver: https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz + transitivePeerDependencies: + - supports-color + + istanbul-lib-report@https://registry.npmmirror.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz: + dependencies: + istanbul-lib-coverage: https://registry.npmmirror.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz + make-dir: 4.0.0 + supports-color: https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz + + istanbul-lib-source-maps@https://registry.npmmirror.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz: + dependencies: + debug: https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz + istanbul-lib-coverage: https://registry.npmmirror.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + + istanbul-reports@https://registry.npmmirror.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz: + dependencies: + html-escaper: https://registry.npmmirror.com/html-escaper/-/html-escaper-2.0.2.tgz + istanbul-lib-report: https://registry.npmmirror.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz + + jackspeak@2.3.1: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jake@10.8.7: + dependencies: + async: 3.2.4 + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + filelist: 1.0.4 + minimatch: 3.1.2 + + jest-changed-files@https://registry.npmmirror.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz: + dependencies: + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + execa: https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz + throat: https://registry.npmmirror.com/throat/-/throat-6.0.2.tgz + + jest-circus@https://registry.npmmirror.com/jest-circus/-/jest-circus-27.5.1.tgz: + dependencies: + '@jest/environment': https://registry.npmmirror.com/@jest/environment/-/environment-27.5.1.tgz + '@jest/test-result': https://registry.npmmirror.com/@jest/test-result/-/test-result-27.5.1.tgz + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + '@types/node': https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + co: https://registry.npmmirror.com/co/-/co-4.6.0.tgz + dedent: https://registry.npmmirror.com/dedent/-/dedent-0.7.0.tgz + expect: https://registry.npmmirror.com/expect/-/expect-27.5.1.tgz + is-generator-fn: https://registry.npmmirror.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz + jest-each: https://registry.npmmirror.com/jest-each/-/jest-each-27.5.1.tgz + jest-matcher-utils: https://registry.npmmirror.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz + jest-message-util: https://registry.npmmirror.com/jest-message-util/-/jest-message-util-27.5.1.tgz + jest-runtime: https://registry.npmmirror.com/jest-runtime/-/jest-runtime-27.5.1.tgz + jest-snapshot: https://registry.npmmirror.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz + jest-util: https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz + pretty-format: https://registry.npmmirror.com/pretty-format/-/pretty-format-27.5.1.tgz + slash: https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz + stack-utils: https://registry.npmmirror.com/stack-utils/-/stack-utils-2.0.6.tgz + throat: https://registry.npmmirror.com/throat/-/throat-6.0.2.tgz + transitivePeerDependencies: + - supports-color + + jest-cli@https://registry.npmmirror.com/jest-cli/-/jest-cli-27.5.1.tgz(ts-node@10.9.1): + dependencies: + '@jest/core': https://registry.npmmirror.com/@jest/core/-/core-27.5.1.tgz(ts-node@10.9.1) + '@jest/test-result': https://registry.npmmirror.com/@jest/test-result/-/test-result-27.5.1.tgz + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + exit: https://registry.npmmirror.com/exit/-/exit-0.1.2.tgz + graceful-fs: 4.2.11 + import-local: https://registry.npmmirror.com/import-local/-/import-local-3.1.0.tgz + jest-config: https://registry.npmmirror.com/jest-config/-/jest-config-27.5.1.tgz(ts-node@10.9.1) + jest-util: https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz + jest-validate: https://registry.npmmirror.com/jest-validate/-/jest-validate-27.5.1.tgz + prompts: https://registry.npmmirror.com/prompts/-/prompts-2.4.2.tgz + yargs: https://registry.npmmirror.com/yargs/-/yargs-16.2.0.tgz + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - ts-node + - utf-8-validate + + jest-config@https://registry.npmmirror.com/jest-config/-/jest-config-27.5.1.tgz(ts-node@10.9.1): + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + '@jest/test-sequencer': https://registry.npmmirror.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + babel-jest: https://registry.npmmirror.com/babel-jest/-/babel-jest-27.5.1.tgz(@babel/core@7.22.11) + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + ci-info: https://registry.npmmirror.com/ci-info/-/ci-info-3.8.0.tgz + deepmerge: https://registry.npmmirror.com/deepmerge/-/deepmerge-4.3.1.tgz + glob: https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz + graceful-fs: 4.2.11 + jest-circus: https://registry.npmmirror.com/jest-circus/-/jest-circus-27.5.1.tgz + jest-environment-jsdom: https://registry.npmmirror.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz + jest-environment-node: https://registry.npmmirror.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz + jest-get-type: https://registry.npmmirror.com/jest-get-type/-/jest-get-type-27.5.1.tgz + jest-jasmine2: https://registry.npmmirror.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz + jest-regex-util: https://registry.npmmirror.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz + jest-resolve: https://registry.npmmirror.com/jest-resolve/-/jest-resolve-27.5.1.tgz + jest-runner: https://registry.npmmirror.com/jest-runner/-/jest-runner-27.5.1.tgz + jest-util: https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz + jest-validate: https://registry.npmmirror.com/jest-validate/-/jest-validate-27.5.1.tgz + micromatch: https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz + parse-json: https://registry.npmmirror.com/parse-json/-/parse-json-5.2.0.tgz + pretty-format: https://registry.npmmirror.com/pretty-format/-/pretty-format-27.5.1.tgz + slash: https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz + strip-json-comments: https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz + ts-node: https://registry.npmmirror.com/ts-node/-/ts-node-10.9.1.tgz(@types/node@20.4.7)(typescript@5.2.2) + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + + jest-diff@https://registry.npmmirror.com/jest-diff/-/jest-diff-27.5.1.tgz: + dependencies: + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + diff-sequences: https://registry.npmmirror.com/diff-sequences/-/diff-sequences-27.5.1.tgz + jest-get-type: https://registry.npmmirror.com/jest-get-type/-/jest-get-type-27.5.1.tgz + pretty-format: https://registry.npmmirror.com/pretty-format/-/pretty-format-27.5.1.tgz + + jest-docblock@https://registry.npmmirror.com/jest-docblock/-/jest-docblock-27.5.1.tgz: + dependencies: + detect-newline: https://registry.npmmirror.com/detect-newline/-/detect-newline-3.1.0.tgz + + jest-each@https://registry.npmmirror.com/jest-each/-/jest-each-27.5.1.tgz: + dependencies: + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + jest-get-type: https://registry.npmmirror.com/jest-get-type/-/jest-get-type-27.5.1.tgz + jest-util: https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz + pretty-format: https://registry.npmmirror.com/pretty-format/-/pretty-format-27.5.1.tgz + + jest-environment-jsdom@https://registry.npmmirror.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz: + dependencies: + '@jest/environment': https://registry.npmmirror.com/@jest/environment/-/environment-27.5.1.tgz + '@jest/fake-timers': https://registry.npmmirror.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + '@types/node': https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz + jest-mock: https://registry.npmmirror.com/jest-mock/-/jest-mock-27.5.1.tgz + jest-util: https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz + jsdom: https://registry.npmmirror.com/jsdom/-/jsdom-16.7.0.tgz + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + + jest-environment-node@https://registry.npmmirror.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz: + dependencies: + '@jest/environment': https://registry.npmmirror.com/@jest/environment/-/environment-27.5.1.tgz + '@jest/fake-timers': https://registry.npmmirror.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + '@types/node': https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz + jest-mock: https://registry.npmmirror.com/jest-mock/-/jest-mock-27.5.1.tgz + jest-util: https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz + + jest-get-type@https://registry.npmmirror.com/jest-get-type/-/jest-get-type-27.5.1.tgz: {} + + jest-haste-map@https://registry.npmmirror.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz: + dependencies: + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + '@types/graceful-fs': https://registry.npmmirror.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz + '@types/node': https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz + anymatch: https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz + fb-watchman: https://registry.npmmirror.com/fb-watchman/-/fb-watchman-2.0.2.tgz + graceful-fs: 4.2.11 + jest-regex-util: https://registry.npmmirror.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz + jest-serializer: https://registry.npmmirror.com/jest-serializer/-/jest-serializer-27.5.1.tgz + jest-util: https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz + jest-worker: https://registry.npmmirror.com/jest-worker/-/jest-worker-27.5.1.tgz + micromatch: https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz + walker: https://registry.npmmirror.com/walker/-/walker-1.0.8.tgz + optionalDependencies: + fsevents: 2.3.3 + + jest-jasmine2@https://registry.npmmirror.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz: + dependencies: + '@jest/environment': https://registry.npmmirror.com/@jest/environment/-/environment-27.5.1.tgz + '@jest/source-map': https://registry.npmmirror.com/@jest/source-map/-/source-map-27.5.1.tgz + '@jest/test-result': https://registry.npmmirror.com/@jest/test-result/-/test-result-27.5.1.tgz + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + '@types/node': https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + co: https://registry.npmmirror.com/co/-/co-4.6.0.tgz + expect: https://registry.npmmirror.com/expect/-/expect-27.5.1.tgz + is-generator-fn: https://registry.npmmirror.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz + jest-each: https://registry.npmmirror.com/jest-each/-/jest-each-27.5.1.tgz + jest-matcher-utils: https://registry.npmmirror.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz + jest-message-util: https://registry.npmmirror.com/jest-message-util/-/jest-message-util-27.5.1.tgz + jest-runtime: https://registry.npmmirror.com/jest-runtime/-/jest-runtime-27.5.1.tgz + jest-snapshot: https://registry.npmmirror.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz + jest-util: https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz + pretty-format: https://registry.npmmirror.com/pretty-format/-/pretty-format-27.5.1.tgz + throat: https://registry.npmmirror.com/throat/-/throat-6.0.2.tgz + transitivePeerDependencies: + - supports-color + + jest-leak-detector@https://registry.npmmirror.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz: + dependencies: + jest-get-type: https://registry.npmmirror.com/jest-get-type/-/jest-get-type-27.5.1.tgz + pretty-format: https://registry.npmmirror.com/pretty-format/-/pretty-format-27.5.1.tgz + + jest-matcher-utils@https://registry.npmmirror.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz: + dependencies: + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + jest-diff: https://registry.npmmirror.com/jest-diff/-/jest-diff-27.5.1.tgz + jest-get-type: https://registry.npmmirror.com/jest-get-type/-/jest-get-type-27.5.1.tgz + pretty-format: https://registry.npmmirror.com/pretty-format/-/pretty-format-27.5.1.tgz + + jest-message-util@https://registry.npmmirror.com/jest-message-util/-/jest-message-util-27.5.1.tgz: + dependencies: + '@babel/code-frame': 7.22.13 + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + '@types/stack-utils': https://registry.npmmirror.com/@types/stack-utils/-/stack-utils-2.0.1.tgz + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + graceful-fs: 4.2.11 + micromatch: https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz + pretty-format: https://registry.npmmirror.com/pretty-format/-/pretty-format-27.5.1.tgz + slash: https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz + stack-utils: https://registry.npmmirror.com/stack-utils/-/stack-utils-2.0.6.tgz + + jest-mock@https://registry.npmmirror.com/jest-mock/-/jest-mock-27.5.1.tgz: + dependencies: + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + '@types/node': https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz + + jest-pnp-resolver@https://registry.npmmirror.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz(jest-resolve@27.5.1): + dependencies: + jest-resolve: https://registry.npmmirror.com/jest-resolve/-/jest-resolve-27.5.1.tgz + + jest-regex-util@https://registry.npmmirror.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz: {} + + jest-resolve-dependencies@https://registry.npmmirror.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz: + dependencies: + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + jest-regex-util: https://registry.npmmirror.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz + jest-snapshot: https://registry.npmmirror.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz + transitivePeerDependencies: + - supports-color + + jest-resolve@https://registry.npmmirror.com/jest-resolve/-/jest-resolve-27.5.1.tgz: + dependencies: + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + graceful-fs: 4.2.11 + jest-haste-map: https://registry.npmmirror.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz + jest-pnp-resolver: https://registry.npmmirror.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz(jest-resolve@27.5.1) + jest-util: https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz + jest-validate: https://registry.npmmirror.com/jest-validate/-/jest-validate-27.5.1.tgz + resolve: https://registry.npmmirror.com/resolve/-/resolve-1.22.4.tgz + resolve.exports: https://registry.npmmirror.com/resolve.exports/-/resolve.exports-1.1.1.tgz + slash: https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz + + jest-runner@https://registry.npmmirror.com/jest-runner/-/jest-runner-27.5.1.tgz: + dependencies: + '@jest/console': https://registry.npmmirror.com/@jest/console/-/console-27.5.1.tgz + '@jest/environment': https://registry.npmmirror.com/@jest/environment/-/environment-27.5.1.tgz + '@jest/test-result': https://registry.npmmirror.com/@jest/test-result/-/test-result-27.5.1.tgz + '@jest/transform': https://registry.npmmirror.com/@jest/transform/-/transform-27.5.1.tgz + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + '@types/node': https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + emittery: https://registry.npmmirror.com/emittery/-/emittery-0.8.1.tgz + graceful-fs: 4.2.11 + jest-docblock: https://registry.npmmirror.com/jest-docblock/-/jest-docblock-27.5.1.tgz + jest-environment-jsdom: https://registry.npmmirror.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz + jest-environment-node: https://registry.npmmirror.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz + jest-haste-map: https://registry.npmmirror.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz + jest-leak-detector: https://registry.npmmirror.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz + jest-message-util: https://registry.npmmirror.com/jest-message-util/-/jest-message-util-27.5.1.tgz + jest-resolve: https://registry.npmmirror.com/jest-resolve/-/jest-resolve-27.5.1.tgz + jest-runtime: https://registry.npmmirror.com/jest-runtime/-/jest-runtime-27.5.1.tgz + jest-util: https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz + jest-worker: https://registry.npmmirror.com/jest-worker/-/jest-worker-27.5.1.tgz + source-map-support: https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz + throat: https://registry.npmmirror.com/throat/-/throat-6.0.2.tgz + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + + jest-runtime@https://registry.npmmirror.com/jest-runtime/-/jest-runtime-27.5.1.tgz: + dependencies: + '@jest/environment': https://registry.npmmirror.com/@jest/environment/-/environment-27.5.1.tgz + '@jest/fake-timers': https://registry.npmmirror.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz + '@jest/globals': https://registry.npmmirror.com/@jest/globals/-/globals-27.5.1.tgz + '@jest/source-map': https://registry.npmmirror.com/@jest/source-map/-/source-map-27.5.1.tgz + '@jest/test-result': https://registry.npmmirror.com/@jest/test-result/-/test-result-27.5.1.tgz + '@jest/transform': https://registry.npmmirror.com/@jest/transform/-/transform-27.5.1.tgz + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + cjs-module-lexer: https://registry.npmmirror.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz + collect-v8-coverage: https://registry.npmmirror.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz + execa: https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz + glob: https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz + graceful-fs: 4.2.11 + jest-haste-map: https://registry.npmmirror.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz + jest-message-util: https://registry.npmmirror.com/jest-message-util/-/jest-message-util-27.5.1.tgz + jest-mock: https://registry.npmmirror.com/jest-mock/-/jest-mock-27.5.1.tgz + jest-regex-util: https://registry.npmmirror.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz + jest-resolve: https://registry.npmmirror.com/jest-resolve/-/jest-resolve-27.5.1.tgz + jest-snapshot: https://registry.npmmirror.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz + jest-util: https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz + slash: https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz + strip-bom: https://registry.npmmirror.com/strip-bom/-/strip-bom-4.0.0.tgz + transitivePeerDependencies: + - supports-color + + jest-serializer@https://registry.npmmirror.com/jest-serializer/-/jest-serializer-27.5.1.tgz: + dependencies: + '@types/node': https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz + graceful-fs: 4.2.11 + + jest-snapshot@https://registry.npmmirror.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz: + dependencies: + '@babel/core': https://registry.npmmirror.com/@babel/core/-/core-7.22.11.tgz + '@babel/generator': https://registry.npmmirror.com/@babel/generator/-/generator-7.22.10.tgz + '@babel/plugin-syntax-typescript': https://registry.npmmirror.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz(@babel/core@7.22.11) + '@babel/traverse': https://registry.npmmirror.com/@babel/traverse/-/traverse-7.22.11.tgz + '@babel/types': https://registry.npmmirror.com/@babel/types/-/types-7.22.11.tgz + '@jest/transform': https://registry.npmmirror.com/@jest/transform/-/transform-27.5.1.tgz + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + '@types/babel__traverse': https://registry.npmmirror.com/@types/babel__traverse/-/babel__traverse-7.20.1.tgz + '@types/prettier': https://registry.npmmirror.com/@types/prettier/-/prettier-2.7.3.tgz + babel-preset-current-node-syntax: https://registry.npmmirror.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz(@babel/core@7.22.11) + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + expect: https://registry.npmmirror.com/expect/-/expect-27.5.1.tgz + graceful-fs: 4.2.11 + jest-diff: https://registry.npmmirror.com/jest-diff/-/jest-diff-27.5.1.tgz + jest-get-type: https://registry.npmmirror.com/jest-get-type/-/jest-get-type-27.5.1.tgz + jest-haste-map: https://registry.npmmirror.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz + jest-matcher-utils: https://registry.npmmirror.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz + jest-message-util: https://registry.npmmirror.com/jest-message-util/-/jest-message-util-27.5.1.tgz + jest-util: https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz + natural-compare: https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz + pretty-format: https://registry.npmmirror.com/pretty-format/-/pretty-format-27.5.1.tgz + semver: https://registry.npmmirror.com/semver/-/semver-7.5.4.tgz + transitivePeerDependencies: + - supports-color + + jest-util@https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz: + dependencies: + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + '@types/node': https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + ci-info: https://registry.npmmirror.com/ci-info/-/ci-info-3.8.0.tgz + graceful-fs: 4.2.11 + picomatch: https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz + + jest-validate@https://registry.npmmirror.com/jest-validate/-/jest-validate-27.5.1.tgz: + dependencies: + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + camelcase: https://registry.npmmirror.com/camelcase/-/camelcase-6.3.0.tgz + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + jest-get-type: https://registry.npmmirror.com/jest-get-type/-/jest-get-type-27.5.1.tgz + leven: https://registry.npmmirror.com/leven/-/leven-3.1.0.tgz + pretty-format: https://registry.npmmirror.com/pretty-format/-/pretty-format-27.5.1.tgz + + jest-watcher@https://registry.npmmirror.com/jest-watcher/-/jest-watcher-27.5.1.tgz: + dependencies: + '@jest/test-result': https://registry.npmmirror.com/@jest/test-result/-/test-result-27.5.1.tgz + '@jest/types': https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz + '@types/node': https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz + ansi-escapes: https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + jest-util: https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz + string-length: https://registry.npmmirror.com/string-length/-/string-length-4.0.2.tgz + + jest-worker@https://registry.npmmirror.com/jest-worker/-/jest-worker-27.5.1.tgz: + dependencies: + '@types/node': https://registry.npmmirror.com/@types/node/-/node-18.17.12.tgz + merge-stream: https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz + supports-color: https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz + + jest@https://registry.npmmirror.com/jest/-/jest-27.5.1.tgz(ts-node@10.9.1): + dependencies: + '@jest/core': https://registry.npmmirror.com/@jest/core/-/core-27.5.1.tgz(ts-node@10.9.1) + import-local: https://registry.npmmirror.com/import-local/-/import-local-3.1.0.tgz + jest-cli: https://registry.npmmirror.com/jest-cli/-/jest-cli-27.5.1.tgz(ts-node@10.9.1) + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - ts-node + - utf-8-validate + + jiti@1.19.3: {} + + jju@1.4.0: {} + + js-base64@2.6.4: {} + + js-beautify@https://registry.npmmirror.com/js-beautify/-/js-beautify-1.14.9.tgz: + dependencies: + config-chain: https://registry.npmmirror.com/config-chain/-/config-chain-1.1.13.tgz + editorconfig: https://registry.npmmirror.com/editorconfig/-/editorconfig-1.0.4.tgz + glob: https://registry.npmmirror.com/glob/-/glob-8.1.0.tgz + nopt: https://registry.npmmirror.com/nopt/-/nopt-6.0.0.tgz + + js-tokens@8.0.1: {} + + js-tokens@https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + js-yaml@https://registry.npmmirror.com/js-yaml/-/js-yaml-3.14.1.tgz: + dependencies: + argparse: https://registry.npmmirror.com/argparse/-/argparse-1.0.10.tgz + esprima: https://registry.npmmirror.com/esprima/-/esprima-4.0.1.tgz + + js-yaml@https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.0.tgz: + dependencies: + argparse: https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz + + jsdom@https://registry.npmmirror.com/jsdom/-/jsdom-16.7.0.tgz: + dependencies: + abab: https://registry.npmmirror.com/abab/-/abab-2.0.6.tgz + acorn: https://registry.npmmirror.com/acorn/-/acorn-8.10.0.tgz + acorn-globals: https://registry.npmmirror.com/acorn-globals/-/acorn-globals-6.0.0.tgz + cssom: https://registry.npmmirror.com/cssom/-/cssom-0.4.4.tgz + cssstyle: https://registry.npmmirror.com/cssstyle/-/cssstyle-2.3.0.tgz + data-urls: https://registry.npmmirror.com/data-urls/-/data-urls-2.0.0.tgz + decimal.js: https://registry.npmmirror.com/decimal.js/-/decimal.js-10.4.3.tgz + domexception: https://registry.npmmirror.com/domexception/-/domexception-2.0.1.tgz + escodegen: https://registry.npmmirror.com/escodegen/-/escodegen-2.1.0.tgz + form-data: https://registry.npmmirror.com/form-data/-/form-data-3.0.1.tgz + html-encoding-sniffer: https://registry.npmmirror.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz + http-proxy-agent: https://registry.npmmirror.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz + https-proxy-agent: https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz + is-potential-custom-element-name: https://registry.npmmirror.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz + nwsapi: https://registry.npmmirror.com/nwsapi/-/nwsapi-2.2.7.tgz + parse5: https://registry.npmmirror.com/parse5/-/parse5-6.0.1.tgz + saxes: https://registry.npmmirror.com/saxes/-/saxes-5.0.1.tgz + symbol-tree: https://registry.npmmirror.com/symbol-tree/-/symbol-tree-3.2.4.tgz + tough-cookie: https://registry.npmmirror.com/tough-cookie/-/tough-cookie-4.1.3.tgz + w3c-hr-time: https://registry.npmmirror.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz + w3c-xmlserializer: https://registry.npmmirror.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz + webidl-conversions: https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz + whatwg-encoding: https://registry.npmmirror.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz + whatwg-mimetype: https://registry.npmmirror.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz + whatwg-url: https://registry.npmmirror.com/whatwg-url/-/whatwg-url-8.7.0.tgz + ws: https://registry.npmmirror.com/ws/-/ws-7.5.9.tgz + xml-name-validator: https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + jsesc@2.5.2: {} + + jsesc@https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz: {} + + json-buffer@3.0.1: {} + + json-parse-even-better-errors@2.3.1: {} + + json-parse-even-better-errors@https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz: {} + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json-schema-traverse@https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.7 + + json5@2.2.3: {} + + json5@https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz: {} + + jsonc-parser@3.2.0: {} + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.0 + optionalDependencies: + graceful-fs: 4.2.11 + + jsonfile@https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz: + dependencies: + universalify: https://registry.npmmirror.com/universalify/-/universalify-2.0.0.tgz + optionalDependencies: + graceful-fs: 4.2.11 + + jsonparse@https://registry.npmmirror.com/jsonparse/-/jsonparse-1.3.1.tgz: {} + + jszip@3.10.1: + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + + keyv@4.5.3: + dependencies: + json-buffer: 3.0.1 + + kind-of@3.2.2: + dependencies: + is-buffer: 1.1.6 + + kind-of@4.0.0: + dependencies: + is-buffer: 1.1.6 + + kind-of@5.1.0: {} + + kind-of@6.0.3: {} + + kind-of@https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz: {} + + kleur@https://registry.npmmirror.com/kleur/-/kleur-3.0.3.tgz: {} + + known-css-properties@0.28.0: {} + + kolorist@1.8.0: {} + + lang-feel@1.1.0: + dependencies: + '@codemirror/autocomplete': 6.11.1(@codemirror/language@6.9.3)(@codemirror/state@6.3.3)(@codemirror/view@6.22.3)(@lezer/common@1.1.2) + '@codemirror/language': 6.9.3 + '@codemirror/state': 6.3.3 + '@codemirror/view': 6.22.3 + '@lezer/common': 1.1.2 + lezer-feel: 1.2.3 + + lazystream@1.0.1: + dependencies: + readable-stream: 2.3.8 + + less@4.2.0: + dependencies: + copy-anything: 2.0.6 + parse-node-version: 1.0.1 + tslib: 2.6.2 + optionalDependencies: + errno: 0.1.8 + graceful-fs: 4.2.11 + image-size: 0.5.5 + make-dir: 2.1.0 + mime: 1.6.0 + needle: 3.2.0 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + + leven@https://registry.npmmirror.com/leven/-/leven-3.1.0.tgz: {} + + lezer-feel@1.2.3: + dependencies: + '@lezer/highlight': 1.2.0 + '@lezer/lr': 1.3.14 + + lie@3.3.0: + dependencies: + immediate: 3.0.6 + + lilconfig@https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz: {} + + lines-and-columns@1.2.4: {} + + lines-and-columns@https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz: {} + + lint-staged@https://registry.npmmirror.com/lint-staged/-/lint-staged-13.2.3.tgz: + dependencies: + chalk: https://registry.npmmirror.com/chalk/-/chalk-5.2.0.tgz + cli-truncate: https://registry.npmmirror.com/cli-truncate/-/cli-truncate-3.1.0.tgz + commander: https://registry.npmmirror.com/commander/-/commander-10.0.1.tgz + debug: https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz + execa: https://registry.npmmirror.com/execa/-/execa-7.2.0.tgz + lilconfig: https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz + listr2: https://registry.npmmirror.com/listr2/-/listr2-5.0.8.tgz + micromatch: https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz + normalize-path: https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz + object-inspect: https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.3.tgz + pidtree: https://registry.npmmirror.com/pidtree/-/pidtree-0.6.0.tgz + string-argv: https://registry.npmmirror.com/string-argv/-/string-argv-0.3.2.tgz + yaml: https://registry.npmmirror.com/yaml/-/yaml-2.3.2.tgz + transitivePeerDependencies: + - enquirer + - supports-color + + listenercount@1.0.1: {} + + listr2@https://registry.npmmirror.com/listr2/-/listr2-5.0.8.tgz: + dependencies: + cli-truncate: https://registry.npmmirror.com/cli-truncate/-/cli-truncate-2.1.0.tgz + colorette: https://registry.npmmirror.com/colorette/-/colorette-2.0.20.tgz + log-update: https://registry.npmmirror.com/log-update/-/log-update-4.0.0.tgz + p-map: https://registry.npmmirror.com/p-map/-/p-map-4.0.0.tgz + rfdc: https://registry.npmmirror.com/rfdc/-/rfdc-1.3.0.tgz + rxjs: https://registry.npmmirror.com/rxjs/-/rxjs-7.8.1.tgz + through: https://registry.npmmirror.com/through/-/through-2.3.8.tgz + wrap-ansi: https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz + + load-tsconfig@0.2.5: {} + + loader-utils@1.4.2: + dependencies: + big.js: 5.2.2 + emojis-list: 3.0.0 + json5: 1.0.2 + + local-pkg@0.4.3: {} + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + locate-path@https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz: + dependencies: + p-locate: https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz + + locate-path@https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz: + dependencies: + p-locate: https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz + + lodash-es@4.17.21: {} + + lodash-es@https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz: {} + + lodash.camelcase@https://registry.npmmirror.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz: {} + + lodash.defaults@4.2.0: {} + + lodash.difference@4.5.0: {} + + lodash.escaperegexp@4.1.2: {} + + lodash.flatten@4.4.0: {} + + lodash.get@4.4.2: {} + + lodash.groupby@4.6.0: {} + + lodash.isboolean@3.0.3: {} + + lodash.isequal@4.5.0: {} + + lodash.isfunction@https://registry.npmmirror.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz: {} + + lodash.isnil@4.0.0: {} + + lodash.isplainobject@4.0.6: {} + + lodash.isplainobject@https://registry.npmmirror.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz: {} + + lodash.isundefined@3.0.1: {} + + lodash.kebabcase@https://registry.npmmirror.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz: {} + + lodash.merge@https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz: {} + + lodash.mergewith@https://registry.npmmirror.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz: {} + + lodash.snakecase@https://registry.npmmirror.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz: {} + + lodash.startcase@https://registry.npmmirror.com/lodash.startcase/-/lodash.startcase-4.4.0.tgz: {} + + lodash.truncate@4.4.2: {} + + lodash.union@4.6.0: {} + + lodash.uniq@4.5.0: {} + + lodash.uniq@https://registry.npmmirror.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz: {} + + lodash.upperfirst@https://registry.npmmirror.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz: {} + + lodash@4.17.21: {} + + lodash@https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz: {} + + log-update@https://registry.npmmirror.com/log-update/-/log-update-4.0.0.tgz: + dependencies: + ansi-escapes: https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz + cli-cursor: https://registry.npmmirror.com/cli-cursor/-/cli-cursor-3.1.0.tgz + slice-ansi: https://registry.npmmirror.com/slice-ansi/-/slice-ansi-4.0.0.tgz + wrap-ansi: https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz + + loose-envify@https://registry.npmmirror.com/loose-envify/-/loose-envify-1.4.0.tgz: + dependencies: + js-tokens: https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz + + lower-case@2.0.2: + dependencies: + tslib: https://registry.npmmirror.com/tslib/-/tslib-2.6.2.tgz + + lru-cache@10.0.1: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + + lru-cache@https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz: + dependencies: + yallist: https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz + + lru-cache@https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz: + dependencies: + yallist: https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz + + luxon@3.4.4: {} + + magic-string-ast@0.3.0: + dependencies: + magic-string: 0.30.2 + + magic-string@0.25.9: + dependencies: + sourcemap-codec: 1.4.8 + + magic-string@0.27.0: + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + + magic-string@0.29.0: + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + + magic-string@0.30.2: + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + + magic-string@0.30.3: + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + + make-dir@2.1.0: + dependencies: + pify: 4.0.1 + semver: https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz + optional: true + + make-dir@4.0.0: + dependencies: + semver: https://registry.npmmirror.com/semver/-/semver-7.5.4.tgz + + make-error@https://registry.npmmirror.com/make-error/-/make-error-1.3.6.tgz: {} + + makeerror@https://registry.npmmirror.com/makeerror/-/makeerror-1.0.12.tgz: + dependencies: + tmpl: https://registry.npmmirror.com/tmpl/-/tmpl-1.0.5.tgz + + map-cache@0.2.2: {} + + map-obj@1.0.1: {} + + map-obj@4.3.0: {} + + map-obj@https://registry.npmmirror.com/map-obj/-/map-obj-1.0.1.tgz: {} + + map-obj@https://registry.npmmirror.com/map-obj/-/map-obj-4.3.0.tgz: {} + + map-visit@1.0.0: + dependencies: + object-visit: 1.0.1 + + mathml-tag-names@2.1.3: {} + + mdn-data@2.0.14: {} + + mdn-data@2.0.30: {} + + meow@10.1.5: + dependencies: + '@types/minimist': 1.2.2 + camelcase-keys: 7.0.2 + decamelize: 5.0.1 + decamelize-keys: 1.1.1 + hard-rejection: 2.1.0 + minimist-options: 4.1.0 + normalize-package-data: 3.0.3 + read-pkg-up: 8.0.0 + redent: 4.0.0 + trim-newlines: 4.1.1 + type-fest: 1.4.0 + yargs-parser: 20.2.9 + + meow@https://registry.npmmirror.com/meow/-/meow-8.1.2.tgz: + dependencies: + '@types/minimist': https://registry.npmmirror.com/@types/minimist/-/minimist-1.2.2.tgz + camelcase-keys: https://registry.npmmirror.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz + decamelize-keys: https://registry.npmmirror.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz + hard-rejection: https://registry.npmmirror.com/hard-rejection/-/hard-rejection-2.1.0.tgz + minimist-options: https://registry.npmmirror.com/minimist-options/-/minimist-options-4.1.0.tgz + normalize-package-data: https://registry.npmmirror.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz + read-pkg-up: https://registry.npmmirror.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz + redent: https://registry.npmmirror.com/redent/-/redent-3.0.0.tgz + trim-newlines: https://registry.npmmirror.com/trim-newlines/-/trim-newlines-3.0.1.tgz + type-fest: https://registry.npmmirror.com/type-fest/-/type-fest-0.18.1.tgz + yargs-parser: https://registry.npmmirror.com/yargs-parser/-/yargs-parser-20.2.9.tgz + + merge-options@1.0.1: + dependencies: + is-plain-obj: 1.1.0 + + merge-stream@https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz: {} + + merge2@1.4.1: {} + + merge2@https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz: {} + + micromatch@3.1.0: + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + braces: 2.3.2 + define-property: 1.0.0 + extend-shallow: 2.0.1 + extglob: 2.0.4 + fragment-cache: 0.2.1 + kind-of: 5.1.0 + nanomatch: 1.2.13 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.5: + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + + micromatch@https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz: + dependencies: + braces: https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz + picomatch: https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz + + mime-db@https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz: {} + + mime-types@https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz: + dependencies: + mime-db: https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz + + mime@1.6.0: + optional: true + + mimic-fn@https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz: {} + + mimic-fn@https://registry.npmmirror.com/mimic-fn/-/mimic-fn-4.0.0.tgz: {} + + min-dash@4.1.1: {} + + min-dom@4.1.0: + dependencies: + component-event: 0.2.1 + domify: 1.4.2 + min-dash: 4.1.1 + + min-indent@1.0.1: {} + + min-indent@https://registry.npmmirror.com/min-indent/-/min-indent-1.0.1.tgz: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.1 + + minimatch@7.4.6: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.3: + dependencies: + brace-expansion: 2.0.1 + + minimatch@https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz: + dependencies: + brace-expansion: https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz + + minimatch@https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz: + dependencies: + brace-expansion: https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz + + minimatch@https://registry.npmmirror.com/minimatch/-/minimatch-9.0.1.tgz: + dependencies: + brace-expansion: https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz + + minimatch@https://registry.npmmirror.com/minimatch/-/minimatch-9.0.3.tgz: + dependencies: + brace-expansion: https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz + + minimist-options@4.1.0: + dependencies: + arrify: 1.0.1 + is-plain-obj: 1.1.0 + kind-of: 6.0.3 + + minimist-options@https://registry.npmmirror.com/minimist-options/-/minimist-options-4.1.0.tgz: + dependencies: + arrify: https://registry.npmmirror.com/arrify/-/arrify-1.0.1.tgz + is-plain-obj: https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz + kind-of: https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz + + minimist@1.2.7: {} + + minimist@https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz: {} + + minipass@7.0.3: {} + + mixin-deep@1.3.2: + dependencies: + for-in: 1.0.2 + is-extendable: 1.0.1 + + mkdirp@0.5.6: + dependencies: + minimist: https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz + + mkdirp@2.1.6: {} + + mkdist@1.3.0(typescript@5.2.2): + dependencies: + citty: 0.1.3 + defu: 6.1.2 + esbuild: 0.18.20 + fs-extra: 11.1.1 + globby: 13.2.2 + jiti: 1.19.3 + mlly: 1.4.1 + mri: 1.2.0 + pathe: https://registry.npmmirror.com/pathe/-/pathe-1.1.1.tgz + typescript: https://registry.npmmirror.com/typescript/-/typescript-5.2.2.tgz + + mlly@1.4.1: + dependencies: + acorn: 8.10.0 + pathe: https://registry.npmmirror.com/pathe/-/pathe-1.1.1.tgz + pkg-types: 1.0.3 + ufo: 1.3.0 + + mockjs@1.1.0: + dependencies: + commander: 11.0.0 + + moddle-xml@10.1.0: + dependencies: + min-dash: 4.1.1 + moddle: 6.2.3 + saxen: 8.1.2 + + moddle@6.2.3: + dependencies: + min-dash: 4.1.1 + + mousetrap@https://registry.npmmirror.com/mousetrap/-/mousetrap-1.6.5.tgz: {} + + mri@1.2.0: {} + + mrmime@1.0.1: {} + + ms@2.1.2: {} + + ms@https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz: {} + + ms@https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz: {} + + ms@https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz: + optional: true + + muggle-string@https://registry.npmmirror.com/muggle-string/-/muggle-string-0.3.1.tgz: {} + + nanoid@3.3.6: {} + + nanoid@https://registry.npmmirror.com/nanoid/-/nanoid-3.3.6.tgz: {} + + nanomatch@1.2.13: + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + define-property: 2.0.2 + extend-shallow: 3.0.2 + fragment-cache: 0.2.1 + is-windows: 1.0.2 + kind-of: 6.0.3 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + nanopop@https://registry.npmmirror.com/nanopop/-/nanopop-2.3.0.tgz: {} + + natural-compare@https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz: {} + + needle@3.2.0: + dependencies: + debug: https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz + iconv-lite: 0.6.3 + sax: 1.2.4 + transitivePeerDependencies: + - supports-color + optional: true + + no-case@3.0.4: + dependencies: + lower-case: 2.0.2 + tslib: https://registry.npmmirror.com/tslib/-/tslib-2.6.2.tgz + + node-fetch-native@1.4.0: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-html-parser@5.4.2: + dependencies: + css-select: 4.3.0 + he: 1.2.0 + + node-int64@https://registry.npmmirror.com/node-int64/-/node-int64-0.4.0.tgz: {} + + node-releases@2.0.13: {} + + node-releases@https://registry.npmmirror.com/node-releases/-/node-releases-2.0.13.tgz: {} + + nopt@https://registry.npmmirror.com/nopt/-/nopt-6.0.0.tgz: + dependencies: + abbrev: https://registry.npmmirror.com/abbrev/-/abbrev-1.1.1.tgz + + normalize-package-data@3.0.3: + dependencies: + hosted-git-info: 4.1.0 + is-core-module: 2.11.0 + semver: https://registry.npmmirror.com/semver/-/semver-7.5.4.tgz + validate-npm-package-license: 3.0.4 + + normalize-package-data@https://registry.npmmirror.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz: + dependencies: + hosted-git-info: https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz + resolve: https://registry.npmmirror.com/resolve/-/resolve-1.22.4.tgz + semver: https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz + validate-npm-package-license: https://registry.npmmirror.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz + + normalize-package-data@https://registry.npmmirror.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz: + dependencies: + hosted-git-info: https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz + is-core-module: https://registry.npmmirror.com/is-core-module/-/is-core-module-2.13.0.tgz + semver: https://registry.npmmirror.com/semver/-/semver-7.5.4.tgz + validate-npm-package-license: https://registry.npmmirror.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz + + normalize-path@3.0.0: {} + + normalize-path@https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz: {} + + npm-run-path@https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz: + dependencies: + path-key: https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz + + npm-run-path@https://registry.npmmirror.com/npm-run-path/-/npm-run-path-5.1.0.tgz: + dependencies: + path-key: https://registry.npmmirror.com/path-key/-/path-key-4.0.0.tgz + + nprogress@0.2.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + nwsapi@https://registry.npmmirror.com/nwsapi/-/nwsapi-2.2.7.tgz: {} + + object-assign@4.1.1: {} + + object-copy@0.1.0: + dependencies: + copy-descriptor: 0.1.1 + define-property: 0.2.5 + kind-of: 3.2.2 + + object-inspect@1.12.3: {} + + object-inspect@https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.3.tgz: {} + + object-refs@0.4.0: {} + + object-visit@1.0.1: + dependencies: + isobject: 3.0.1 + + object.pick@1.3.0: + dependencies: + isobject: 3.0.1 + + ofetch@1.3.3: + dependencies: + destr: 2.0.1 + node-fetch-native: 1.4.0 + ufo: 1.3.0 + + on-finished@2.3.0: + dependencies: + ee-first: 1.1.1 + + on-finished@https://registry.npmmirror.com/on-finished/-/on-finished-2.3.0.tgz: + dependencies: + ee-first: https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + once@https://registry.npmmirror.com/once/-/once-1.4.0.tgz: + dependencies: + wrappy: https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz + + onetime@https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz: + dependencies: + mimic-fn: https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz + + onetime@https://registry.npmmirror.com/onetime/-/onetime-6.0.0.tgz: + dependencies: + mimic-fn: https://registry.npmmirror.com/mimic-fn/-/mimic-fn-4.0.0.tgz + + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + + open@https://registry.npmmirror.com/open/-/open-9.1.0.tgz: + dependencies: + default-browser: https://registry.npmmirror.com/default-browser/-/default-browser-4.0.0.tgz + define-lazy-prop: https://registry.npmmirror.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz + is-inside-container: https://registry.npmmirror.com/is-inside-container/-/is-inside-container-1.0.0.tgz + is-wsl: https://registry.npmmirror.com/is-wsl/-/is-wsl-2.2.0.tgz + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-limit@https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz: + dependencies: + p-try: https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz + + p-limit@https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz: + dependencies: + yocto-queue: https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-locate@https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz: + dependencies: + p-limit: https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz + + p-locate@https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz: + dependencies: + p-limit: https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz + + p-map@https://registry.npmmirror.com/p-map/-/p-map-4.0.0.tgz: + dependencies: + aggregate-error: https://registry.npmmirror.com/aggregate-error/-/aggregate-error-3.1.0.tgz + + p-try@2.2.0: {} + + p-try@https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz: {} + + pako@1.0.11: {} + + param-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: https://registry.npmmirror.com/tslib/-/tslib-2.6.2.tgz + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parent-module@https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz: + dependencies: + callsites: https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.21.4 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + parse-json@https://registry.npmmirror.com/parse-json/-/parse-json-5.2.0.tgz: + dependencies: + '@babel/code-frame': 7.22.13 + error-ex: https://registry.npmmirror.com/error-ex/-/error-ex-1.3.2.tgz + json-parse-even-better-errors: https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz + lines-and-columns: https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz + + parse-node-version@1.0.1: {} + + parse5@https://registry.npmmirror.com/parse5/-/parse5-6.0.1.tgz: {} + + parseurl@1.3.3: {} + + parseurl@https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz: {} + + pascal-case@3.1.2: + dependencies: + no-case: 3.0.4 + tslib: https://registry.npmmirror.com/tslib/-/tslib-2.6.2.tgz + + pascalcase@0.1.1: {} + + path-browserify@1.0.1: {} + + path-exists@4.0.0: {} + + path-exists@https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz: {} + + path-intersection@3.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-key@https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz: {} + + path-key@https://registry.npmmirror.com/path-key/-/path-key-4.0.0.tgz: {} + + path-parse@1.0.7: {} + + path-parse@https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz: {} + + path-scurry@1.10.1: + dependencies: + lru-cache: 10.0.1 + minipass: 7.0.3 + + path-to-regexp@6.2.1: {} + + path-to-regexp@https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz: {} + + path-type@4.0.0: {} + + path-type@https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz: {} + + pathe@0.2.0: {} + + pathe@1.1.1: {} + + pathe@https://registry.npmmirror.com/pathe/-/pathe-1.1.1.tgz: {} + + perfect-debounce@1.0.0: {} + + picocolors@1.0.0: {} + + picocolors@https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz: {} + + picomatch@2.3.1: {} + + picomatch@https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz: {} + + pidtree@https://registry.npmmirror.com/pidtree/-/pidtree-0.6.0.tgz: {} + + pify@4.0.1: + optional: true + + pinia@https://registry.npmmirror.com/pinia/-/pinia-2.1.4.tgz(typescript@5.2.2)(vue@3.3.4): + dependencies: + '@vue/devtools-api': https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.5.0.tgz + typescript: https://registry.npmmirror.com/typescript/-/typescript-5.2.2.tgz + vue: 3.3.4 + vue-demi: https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.6.tgz(vue@3.3.4) + + pirates@https://registry.npmmirror.com/pirates/-/pirates-4.0.6.tgz: {} + + pkg-dir@https://registry.npmmirror.com/pkg-dir/-/pkg-dir-4.2.0.tgz: + dependencies: + find-up: https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz + + pkg-types@1.0.3: + dependencies: + jsonc-parser: 3.2.0 + mlly: 1.4.1 + pathe: 1.1.1 + + pngjs@5.0.0: {} + + posix-character-classes@0.1.1: {} + + postcss-html@1.5.0: + dependencies: + htmlparser2: 8.0.2 + js-tokens: 8.0.1 + postcss: 8.4.29 + postcss-safe-parser: 6.0.0(postcss@8.4.29) + + postcss-less@6.0.0(postcss@8.4.29): + dependencies: + postcss: 8.4.29 + + postcss-media-query-parser@0.2.3: {} + + postcss-prefix-selector@1.16.0(postcss@5.2.18): + dependencies: + postcss: 5.2.18 + + postcss-resolve-nested-selector@0.1.1: {} + + postcss-safe-parser@6.0.0(postcss@8.4.29): + dependencies: + postcss: 8.4.29 + + postcss-scss@4.0.7(postcss@8.4.29): + dependencies: + postcss: 8.4.29 + + postcss-selector-parser@6.0.13: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-sorting@8.0.2(postcss@8.4.29): + dependencies: + postcss: 8.4.29 + + postcss-value-parser@4.2.0: {} + + postcss@5.2.18: + dependencies: + chalk: https://registry.npmmirror.com/chalk/-/chalk-1.1.3.tgz + js-base64: 2.6.4 + source-map: 0.5.7 + supports-color: 3.2.3 + + postcss@8.4.29: + dependencies: + nanoid: 3.3.6 + picocolors: 1.0.0 + source-map-js: 1.0.2 + + postcss@https://registry.npmmirror.com/postcss/-/postcss-8.4.29.tgz: + dependencies: + nanoid: https://registry.npmmirror.com/nanoid/-/nanoid-3.3.6.tgz + picocolors: https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz + source-map-js: https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz + + posthtml-parser@0.2.1: + dependencies: + htmlparser2: 3.10.1 + isobject: 2.1.0 + + posthtml-rename-id@1.0.12: + dependencies: + escape-string-regexp: 1.0.5 + + posthtml-render@1.4.0: {} + + posthtml-svg-mode@1.0.3: + dependencies: + merge-options: 1.0.1 + posthtml: 0.9.2 + posthtml-parser: 0.2.1 + posthtml-render: 1.4.0 + + posthtml@0.9.2: + dependencies: + posthtml-parser: 0.2.1 + posthtml-render: 1.4.0 + + preact@10.17.1: {} + + preact@https://registry.npmmirror.com/preact/-/preact-10.17.1.tgz: {} + + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.2.0 + + prettier-plugin-packagejson@https://registry.npmmirror.com/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.4.5.tgz(prettier@2.8.8): + dependencies: + prettier: https://registry.npmmirror.com/prettier/-/prettier-2.8.8.tgz + sort-package-json: https://registry.npmmirror.com/sort-package-json/-/sort-package-json-2.5.1.tgz + synckit: https://registry.npmmirror.com/synckit/-/synckit-0.8.5.tgz + + prettier@2.8.8: {} + + prettier@https://registry.npmmirror.com/prettier/-/prettier-2.8.8.tgz: {} + + pretty-bytes@6.1.1: {} + + pretty-format@https://registry.npmmirror.com/pretty-format/-/pretty-format-27.5.1.tgz: + dependencies: + ansi-regex: https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz + ansi-styles: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-5.2.0.tgz + react-is: https://registry.npmmirror.com/react-is/-/react-is-17.0.2.tgz + + print-js@1.6.0: {} + + process-nextick-args@2.0.1: {} + + prompts@https://registry.npmmirror.com/prompts/-/prompts-2.4.2.tgz: + dependencies: + kleur: https://registry.npmmirror.com/kleur/-/kleur-3.0.3.tgz + sisteransi: https://registry.npmmirror.com/sisteransi/-/sisteransi-1.0.5.tgz + + proto-list@https://registry.npmmirror.com/proto-list/-/proto-list-1.2.4.tgz: {} + + proxy-from-env@https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz: {} + + prr@1.0.1: + optional: true + + psl@https://registry.npmmirror.com/psl/-/psl-1.9.0.tgz: {} + + punycode@2.3.0: {} + + punycode@https://registry.npmmirror.com/punycode/-/punycode-2.3.0.tgz: {} + + qrcode@1.5.3: + dependencies: + dijkstrajs: 1.0.3 + encode-utf8: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 + + qs@6.11.2: + dependencies: + side-channel: 1.0.4 + + query-string@4.3.4: + dependencies: + object-assign: 4.1.1 + strict-uri-encode: 1.1.0 + + querystringify@https://registry.npmmirror.com/querystringify/-/querystringify-2.2.0.tgz: {} + + queue-microtask@1.2.3: {} + + queue-microtask@https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz: {} + + quick-lru@5.1.1: {} + + quick-lru@https://registry.npmmirror.com/quick-lru/-/quick-lru-4.0.1.tgz: {} + + react-is@https://registry.npmmirror.com/react-is/-/react-is-17.0.2.tgz: {} + + read-pkg-up@8.0.0: + dependencies: + find-up: 5.0.0 + read-pkg: 6.0.0 + type-fest: 1.4.0 + + read-pkg-up@https://registry.npmmirror.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz: + dependencies: + find-up: https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz + read-pkg: https://registry.npmmirror.com/read-pkg/-/read-pkg-5.2.0.tgz + type-fest: https://registry.npmmirror.com/type-fest/-/type-fest-0.8.1.tgz + + read-pkg@6.0.0: + dependencies: + '@types/normalize-package-data': 2.4.1 + normalize-package-data: 3.0.3 + parse-json: 5.2.0 + type-fest: 1.4.0 + + read-pkg@https://registry.npmmirror.com/read-pkg/-/read-pkg-5.2.0.tgz: + dependencies: + '@types/normalize-package-data': https://registry.npmmirror.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz + normalize-package-data: https://registry.npmmirror.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz + parse-json: https://registry.npmmirror.com/parse-json/-/parse-json-5.2.0.tgz + type-fest: https://registry.npmmirror.com/type-fest/-/type-fest-0.6.0.tgz + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readable-stream@https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz: + dependencies: + inherits: https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz + string_decoder: https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz + util-deprecate: https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz + + readdir-glob@1.1.3: + dependencies: + minimatch: 5.1.6 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + readdirp@https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz: + dependencies: + picomatch: https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz + + redent@4.0.0: + dependencies: + indent-string: 5.0.0 + strip-indent: 4.0.0 + + redent@https://registry.npmmirror.com/redent/-/redent-3.0.0.tgz: + dependencies: + indent-string: https://registry.npmmirror.com/indent-string/-/indent-string-4.0.0.tgz + strip-indent: https://registry.npmmirror.com/strip-indent/-/strip-indent-3.0.0.tgz + + regenerator-runtime@https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz: {} + + regex-not@1.0.2: + dependencies: + extend-shallow: 3.0.2 + safe-regex: 1.1.0 + + relateurl@0.2.7: {} + + repeat-element@1.1.4: {} + + repeat-string@1.6.1: {} + + require-directory@2.1.1: {} + + require-directory@https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz: {} + + require-from-string@2.0.2: {} + + require-from-string@https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz: {} + + require-main-filename@2.0.0: {} + + requires-port@https://registry.npmmirror.com/requires-port/-/requires-port-1.0.0.tgz: {} + + resize-observer-polyfill@1.5.1: {} + + resize-observer-polyfill@https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz: {} + + resolve-cwd@https://registry.npmmirror.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz: + dependencies: + resolve-from: https://registry.npmmirror.com/resolve-from/-/resolve-from-5.0.0.tgz + + resolve-from@5.0.0: {} + + resolve-from@https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz: {} + + resolve-from@https://registry.npmmirror.com/resolve-from/-/resolve-from-5.0.0.tgz: {} + + resolve-global@https://registry.npmmirror.com/resolve-global/-/resolve-global-1.0.0.tgz: + dependencies: + global-dirs: https://registry.npmmirror.com/global-dirs/-/global-dirs-0.1.1.tgz + + resolve-url@0.2.1: {} + + resolve.exports@https://registry.npmmirror.com/resolve.exports/-/resolve.exports-1.1.1.tgz: {} + + resolve@1.19.0: + dependencies: + is-core-module: 2.13.0 + path-parse: 1.0.7 + + resolve@1.22.4: + dependencies: + is-core-module: 2.13.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + resolve@https://registry.npmmirror.com/resolve/-/resolve-1.22.4.tgz: + dependencies: + is-core-module: https://registry.npmmirror.com/is-core-module/-/is-core-module-2.13.0.tgz + path-parse: https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz + supports-preserve-symlinks-flag: https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz + + restore-cursor@https://registry.npmmirror.com/restore-cursor/-/restore-cursor-3.1.0.tgz: + dependencies: + onetime: https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz + signal-exit: https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz + + ret@0.1.15: {} + + reusify@1.0.4: {} + + reusify@https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz: {} + + rfdc@https://registry.npmmirror.com/rfdc/-/rfdc-1.3.0.tgz: {} + + rimraf@2.7.1: + dependencies: + glob: https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + rimraf@5.0.1: + dependencies: + glob: 10.3.3 + + rimraf@https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz: + dependencies: + glob: https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz + + rollup-plugin-dts@5.3.1(rollup@3.28.1)(typescript@5.2.2): + dependencies: + magic-string: 0.30.3 + rollup: 3.28.1 + typescript: https://registry.npmmirror.com/typescript/-/typescript-5.2.2.tgz + optionalDependencies: + '@babel/code-frame': 7.22.13 + + rollup-plugin-purge-icons@0.9.1: + dependencies: + '@purge-icons/core': 0.9.1 + '@purge-icons/generated': 0.9.0 + transitivePeerDependencies: + - encoding + - supports-color + + rollup-plugin-visualizer@5.9.2(rollup@3.28.1): + dependencies: + open: 8.4.2 + picomatch: 2.3.1 + rollup: 3.28.1 + source-map: 0.7.4 + yargs: 17.7.2 + + rollup@3.28.1: + optionalDependencies: + fsevents: 2.3.3 + + rollup@https://registry.npmmirror.com/rollup/-/rollup-3.28.1.tgz: + optionalDependencies: + fsevents: 2.3.3 + + run-applescript@https://registry.npmmirror.com/run-applescript/-/run-applescript-5.0.0.tgz: + dependencies: + execa: https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + run-parallel@https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz: + dependencies: + queue-microtask: https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz + + rxjs@https://registry.npmmirror.com/rxjs/-/rxjs-7.8.1.tgz: + dependencies: + tslib: https://registry.npmmirror.com/tslib/-/tslib-2.6.2.tgz + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-buffer@https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz: {} + + safe-regex@1.1.0: + dependencies: + ret: 0.1.15 + + safer-buffer@2.1.2: + optional: true + + safer-buffer@https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz: {} + + sass@1.66.1: + dependencies: + chokidar: 3.5.3 + immutable: 4.3.4 + source-map-js: 1.0.2 + + sax@1.2.4: + optional: true + + saxen@8.1.2: {} + + saxes@5.0.1: + dependencies: + xmlchars: 2.2.0 + + saxes@https://registry.npmmirror.com/saxes/-/saxes-5.0.1.tgz: + dependencies: + xmlchars: https://registry.npmmirror.com/xmlchars/-/xmlchars-2.2.0.tgz + + scroll-into-view-if-needed@https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz: + dependencies: + compute-scroll-into-view: https://registry.npmmirror.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz + + scule@1.0.0: {} + + semver@6.3.1: {} + + semver@7.5.4: + dependencies: + lru-cache: 6.0.0 + + semver@https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz: {} + + semver@https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz: {} + + semver@https://registry.npmmirror.com/semver/-/semver-7.5.4.tgz: + dependencies: + lru-cache: https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz + + set-blocking@2.0.0: {} + + set-value@2.0.1: + dependencies: + extend-shallow: 2.0.1 + is-extendable: 0.1.1 + is-plain-object: https://registry.npmmirror.com/is-plain-object/-/is-plain-object-2.0.4.tgz + split-string: 3.1.0 + + setimmediate@1.0.5: {} + + shallow-equal@https://registry.npmmirror.com/shallow-equal/-/shallow-equal-1.2.1.tgz: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-command@https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz: + dependencies: + shebang-regex: https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz + + shebang-regex@3.0.0: {} + + shebang-regex@https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz: {} + + showdown@2.1.0: + dependencies: + commander: 9.5.0 + + side-channel@1.0.4: + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + object-inspect: 1.12.3 + + signal-exit@4.1.0: {} + + signal-exit@https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz: {} + + sirv@2.0.3: + dependencies: + '@polka/url': 1.0.0-next.21 + mrmime: 1.0.1 + totalist: 3.0.1 + + sisteransi@https://registry.npmmirror.com/sisteransi/-/sisteransi-1.0.5.tgz: {} + + slash@3.0.0: {} + + slash@4.0.0: {} + + slash@https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz: {} + + slash@https://registry.npmmirror.com/slash/-/slash-4.0.0.tgz: {} + + slice-ansi@4.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + + slice-ansi@https://registry.npmmirror.com/slice-ansi/-/slice-ansi-3.0.0.tgz: + dependencies: + ansi-styles: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz + astral-regex: https://registry.npmmirror.com/astral-regex/-/astral-regex-2.0.0.tgz + is-fullwidth-code-point: https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz + + slice-ansi@https://registry.npmmirror.com/slice-ansi/-/slice-ansi-4.0.0.tgz: + dependencies: + ansi-styles: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz + astral-regex: https://registry.npmmirror.com/astral-regex/-/astral-regex-2.0.0.tgz + is-fullwidth-code-point: https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz + + slice-ansi@https://registry.npmmirror.com/slice-ansi/-/slice-ansi-5.0.0.tgz: + dependencies: + ansi-styles: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.1.tgz + is-fullwidth-code-point: https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz + + snapdragon-node@2.1.1: + dependencies: + define-property: 1.0.0 + isobject: 3.0.1 + snapdragon-util: 3.0.1 + + snapdragon-util@3.0.1: + dependencies: + kind-of: 3.2.2 + + snapdragon@0.8.2: + dependencies: + base: 0.11.2 + debug: https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz + define-property: 0.2.5 + extend-shallow: 2.0.1 + map-cache: 0.2.2 + source-map: 0.5.7 + source-map-resolve: 0.5.3 + use: 3.1.1 + transitivePeerDependencies: + - supports-color + + sort-object-keys@https://registry.npmmirror.com/sort-object-keys/-/sort-object-keys-1.1.3.tgz: {} + + sort-package-json@https://registry.npmmirror.com/sort-package-json/-/sort-package-json-2.5.1.tgz: + dependencies: + detect-indent: https://registry.npmmirror.com/detect-indent/-/detect-indent-7.0.1.tgz + detect-newline: https://registry.npmmirror.com/detect-newline/-/detect-newline-4.0.0.tgz + get-stdin: https://registry.npmmirror.com/get-stdin/-/get-stdin-9.0.0.tgz + git-hooks-list: https://registry.npmmirror.com/git-hooks-list/-/git-hooks-list-3.1.0.tgz + globby: https://registry.npmmirror.com/globby/-/globby-13.2.2.tgz + is-plain-obj: https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz + sort-object-keys: https://registry.npmmirror.com/sort-object-keys/-/sort-object-keys-1.1.3.tgz + + sortablejs@1.15.0: {} + + sortablejs@https://registry.npmmirror.com/sortablejs/-/sortablejs-1.14.0.tgz: {} + + source-map-js@1.0.2: {} + + source-map-js@https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz: {} + + source-map-resolve@0.5.3: + dependencies: + atob: 2.1.2 + decode-uri-component: 0.2.2 + resolve-url: 0.2.1 + source-map-url: 0.4.1 + urix: 0.1.0 + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map-support@https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz: + dependencies: + buffer-from: https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz + source-map: 0.6.1 + + source-map-url@0.4.1: {} + + source-map@0.5.7: {} + + source-map@0.6.1: {} + + source-map@0.7.4: {} + + sourcemap-codec@1.4.8: {} + + spdx-correct@3.1.1: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.12 + + spdx-correct@https://registry.npmmirror.com/spdx-correct/-/spdx-correct-3.1.1.tgz: + dependencies: + spdx-expression-parse: https://registry.npmmirror.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz + spdx-license-ids: https://registry.npmmirror.com/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz + + spdx-exceptions@2.3.0: {} + + spdx-exceptions@https://registry.npmmirror.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.3.0 + spdx-license-ids: 3.0.12 + + spdx-expression-parse@https://registry.npmmirror.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz: + dependencies: + spdx-exceptions: https://registry.npmmirror.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz + spdx-license-ids: https://registry.npmmirror.com/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz + + spdx-license-ids@3.0.12: {} + + spdx-license-ids@https://registry.npmmirror.com/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz: {} + + split-string@3.1.0: + dependencies: + extend-shallow: 3.0.2 + + split2@https://registry.npmmirror.com/split2/-/split2-3.2.2.tgz: + dependencies: + readable-stream: https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz + + sprintf-js@1.0.3: {} + + sprintf-js@https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz: {} + + ssf@0.11.2: + dependencies: + frac: 1.1.2 + + stable@0.1.8: {} + + stack-utils@https://registry.npmmirror.com/stack-utils/-/stack-utils-2.0.6.tgz: + dependencies: + escape-string-regexp: https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz + + static-extend@0.1.2: + dependencies: + define-property: 0.2.5 + object-copy: 0.1.0 + + statuses@1.5.0: {} + + statuses@https://registry.npmmirror.com/statuses/-/statuses-1.5.0.tgz: {} + + strict-uri-encode@1.1.0: {} + + string-argv@https://registry.npmmirror.com/string-argv/-/string-argv-0.3.2.tgz: {} + + string-length@https://registry.npmmirror.com/string-length/-/string-length-4.0.2.tgz: + dependencies: + char-regex: https://registry.npmmirror.com/char-regex/-/char-regex-1.0.2.tgz + strip-ansi: https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz: + dependencies: + emoji-regex: https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz + is-fullwidth-code-point: https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz + strip-ansi: https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz + + string-width@https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz: + dependencies: + eastasianwidth: https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz + emoji-regex: https://registry.npmmirror.com/emoji-regex/-/emoji-regex-9.2.2.tgz + strip-ansi: https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.0.tgz + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + string_decoder@https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz: + dependencies: + safe-buffer: https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz + + strip-ansi@3.0.1: + dependencies: + ansi-regex: 2.1.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + + strip-ansi@https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz: + dependencies: + ansi-regex: https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz + + strip-ansi@https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.0.tgz: + dependencies: + ansi-regex: https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.0.1.tgz + + strip-bom@https://registry.npmmirror.com/strip-bom/-/strip-bom-4.0.0.tgz: {} + + strip-final-newline@https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz: {} + + strip-final-newline@https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz: {} + + strip-indent@4.0.0: + dependencies: + min-indent: 1.0.1 + + strip-indent@https://registry.npmmirror.com/strip-indent/-/strip-indent-3.0.0.tgz: + dependencies: + min-indent: https://registry.npmmirror.com/min-indent/-/min-indent-1.0.1.tgz + + strip-json-comments@3.1.1: {} + + strip-json-comments@https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz: {} + + style-mod@4.1.0: {} + + style-search@0.1.0: {} + + stylelint-config-html@1.1.0(postcss-html@1.5.0)(stylelint@15.10.3): + dependencies: + postcss-html: 1.5.0 + stylelint: 15.10.3 + + stylelint-config-property-sort-order-smacss@9.1.0(stylelint@15.10.3): + dependencies: + css-property-sort-order-smacss: 2.2.0 + stylelint: 15.10.3 + stylelint-order: 6.0.3(stylelint@15.10.3) + + stylelint-config-recommended-scss@11.0.0(postcss@8.4.29)(stylelint@15.10.3): + dependencies: + postcss: 8.4.29 + postcss-scss: 4.0.7(postcss@8.4.29) + stylelint: 15.10.3 + stylelint-config-recommended: 12.0.0(stylelint@15.10.3) + stylelint-scss: 4.7.0(stylelint@15.10.3) + + stylelint-config-recommended-vue@1.5.0(postcss-html@1.5.0)(stylelint@15.10.3): + dependencies: + postcss-html: 1.5.0 + semver: 7.5.4 + stylelint: 15.10.3 + stylelint-config-html: 1.1.0(postcss-html@1.5.0)(stylelint@15.10.3) + stylelint-config-recommended: 12.0.0(stylelint@15.10.3) + + stylelint-config-recommended@12.0.0(stylelint@15.10.3): + dependencies: + stylelint: 15.10.3 + + stylelint-config-standard-scss@9.0.0(postcss@8.4.29)(stylelint@15.10.3): + dependencies: + postcss: 8.4.29 + stylelint: 15.10.3 + stylelint-config-recommended-scss: 11.0.0(postcss@8.4.29)(stylelint@15.10.3) + stylelint-config-standard: 33.0.0(stylelint@15.10.3) + + stylelint-config-standard@33.0.0(stylelint@15.10.3): + dependencies: + stylelint: 15.10.3 + stylelint-config-recommended: 12.0.0(stylelint@15.10.3) + + stylelint-order@6.0.3(stylelint@15.10.3): + dependencies: + postcss: 8.4.29 + postcss-sorting: 8.0.2(postcss@8.4.29) + stylelint: 15.10.3 + + stylelint-prettier@3.0.0(prettier@2.8.8)(stylelint@15.10.3): + dependencies: + prettier: 2.8.8 + prettier-linter-helpers: 1.0.0 + stylelint: 15.10.3 + + stylelint-scss@4.7.0(stylelint@15.10.3): + dependencies: + postcss-media-query-parser: 0.2.3 + postcss-resolve-nested-selector: 0.1.1 + postcss-selector-parser: 6.0.13 + postcss-value-parser: 4.2.0 + stylelint: 15.10.3 + + stylelint@15.10.3: + dependencies: + '@csstools/css-parser-algorithms': 2.3.1(@csstools/css-tokenizer@2.2.0) + '@csstools/css-tokenizer': 2.2.0 + '@csstools/media-query-list-parser': 2.1.4(@csstools/css-parser-algorithms@2.3.1)(@csstools/css-tokenizer@2.2.0) + '@csstools/selector-specificity': 3.0.0(postcss-selector-parser@6.0.13) + balanced-match: 2.0.0 + colord: 2.9.3 + cosmiconfig: 8.2.0 + css-functions-list: 3.2.0 + css-tree: 2.3.1 + debug: 4.3.4 + fast-glob: 3.3.1 + fastest-levenshtein: 1.0.16 + file-entry-cache: 6.0.1 + global-modules: 2.0.0 + globby: 11.1.0 + globjoin: 0.1.4 + html-tags: 3.3.1 + ignore: 5.2.4 + import-lazy: 4.0.0 + imurmurhash: 0.1.4 + is-plain-object: 5.0.0 + known-css-properties: 0.28.0 + mathml-tag-names: 2.1.3 + meow: 10.1.5 + micromatch: 4.0.5 + normalize-path: 3.0.0 + picocolors: 1.0.0 + postcss: 8.4.29 + postcss-resolve-nested-selector: 0.1.1 + postcss-safe-parser: 6.0.0(postcss@8.4.29) + postcss-selector-parser: 6.0.13 + postcss-value-parser: 4.2.0 + resolve-from: 5.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + style-search: 0.1.0 + supports-hyperlinks: 3.0.0 + svg-tags: 1.0.0 + table: 6.8.1 + write-file-atomic: 5.0.1 + transitivePeerDependencies: + - supports-color + + stylis@https://registry.npmmirror.com/stylis/-/stylis-4.3.0.tgz: {} + + supports-color@3.2.3: + dependencies: + has-flag: 1.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@https://registry.npmmirror.com/supports-color/-/supports-color-2.0.0.tgz: {} + + supports-color@https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz: + dependencies: + has-flag: https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz + + supports-color@https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz: + dependencies: + has-flag: https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz + + supports-color@https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz: + dependencies: + has-flag: https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz + + supports-hyperlinks@3.0.0: + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + + supports-hyperlinks@https://registry.npmmirror.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz: + dependencies: + has-flag: https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz + supports-color: https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz + + supports-preserve-symlinks-flag@1.0.0: {} + + supports-preserve-symlinks-flag@https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz: {} + + svg-baker@1.7.0: + dependencies: + bluebird: 3.7.2 + clone: 2.1.2 + he: 1.2.0 + image-size: 0.5.5 + loader-utils: 1.4.2 + merge-options: 1.0.1 + micromatch: 3.1.0 + postcss: 5.2.18 + postcss-prefix-selector: 1.16.0(postcss@5.2.18) + posthtml-rename-id: 1.0.12 + posthtml-svg-mode: 1.0.3 + query-string: 4.3.4 + traverse: 0.6.7 + transitivePeerDependencies: + - supports-color + + svg-tags@1.0.0: {} + + svgo@2.8.0: + dependencies: + '@trysound/sax': 0.2.0 + commander: 7.2.0 + css-select: 4.3.0 + css-tree: 1.1.3 + csso: 4.2.0 + picocolors: 1.0.0 + stable: 0.1.8 + + symbol-tree@https://registry.npmmirror.com/symbol-tree/-/symbol-tree-3.2.4.tgz: {} + + synckit@https://registry.npmmirror.com/synckit/-/synckit-0.8.5.tgz: + dependencies: + '@pkgr/utils': https://registry.npmmirror.com/@pkgr/utils/-/utils-2.4.2.tgz + tslib: https://registry.npmmirror.com/tslib/-/tslib-2.6.2.tgz + + tabbable@6.2.0: {} + + table@6.8.1: + dependencies: + ajv: 8.12.0 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + inherits: https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz + readable-stream: 3.6.2 + + terminal-link@https://registry.npmmirror.com/terminal-link/-/terminal-link-2.1.1.tgz: + dependencies: + ansi-escapes: https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz + supports-hyperlinks: https://registry.npmmirror.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz + + terser@5.19.3: + dependencies: + '@jridgewell/source-map': 0.3.5 + acorn: 8.10.0 + commander: https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz + source-map-support: 0.5.21 + + test-exclude@https://registry.npmmirror.com/test-exclude/-/test-exclude-6.0.0.tgz: + dependencies: + '@istanbuljs/schema': https://registry.npmmirror.com/@istanbuljs/schema/-/schema-0.1.3.tgz + glob: https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz + minimatch: https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz + + text-extensions@https://registry.npmmirror.com/text-extensions/-/text-extensions-1.9.0.tgz: {} + + throat@https://registry.npmmirror.com/throat/-/throat-6.0.2.tgz: {} + + throttle-debounce@https://registry.npmmirror.com/throttle-debounce/-/throttle-debounce-5.0.0.tgz: {} + + through2@https://registry.npmmirror.com/through2/-/through2-4.0.2.tgz: + dependencies: + readable-stream: https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz + + through@https://registry.npmmirror.com/through/-/through-2.3.8.tgz: {} + + tiny-svg@3.0.1: {} + + tinymce@https://registry.npmmirror.com/tinymce/-/tinymce-5.10.7.tgz: {} + + titleize@https://registry.npmmirror.com/titleize/-/titleize-3.0.0.tgz: {} + + tmp@0.2.1: + dependencies: + rimraf: 3.0.2 + + tmpl@https://registry.npmmirror.com/tmpl/-/tmpl-1.0.5.tgz: {} + + to-fast-properties@2.0.0: {} + + to-fast-properties@https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz: {} + + to-object-path@0.3.0: + dependencies: + kind-of: 3.2.2 + + to-regex-range@2.1.1: + dependencies: + is-number: 3.0.0 + repeat-string: 1.6.1 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + to-regex-range@https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz: + dependencies: + is-number: https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz + + to-regex@3.0.2: + dependencies: + define-property: 2.0.2 + extend-shallow: 3.0.2 + regex-not: 1.0.2 + safe-regex: 1.1.0 + + totalist@3.0.1: {} + + tough-cookie@https://registry.npmmirror.com/tough-cookie/-/tough-cookie-4.1.3.tgz: + dependencies: + psl: https://registry.npmmirror.com/psl/-/psl-1.9.0.tgz + punycode: https://registry.npmmirror.com/punycode/-/punycode-2.3.0.tgz + universalify: https://registry.npmmirror.com/universalify/-/universalify-0.2.0.tgz + url-parse: https://registry.npmmirror.com/url-parse/-/url-parse-1.5.10.tgz + + tr46@0.0.3: {} + + tr46@https://registry.npmmirror.com/tr46/-/tr46-2.1.0.tgz: + dependencies: + punycode: https://registry.npmmirror.com/punycode/-/punycode-2.3.0.tgz + + traverse@0.3.9: {} + + traverse@0.6.7: {} + + trim-newlines@4.1.1: {} + + trim-newlines@https://registry.npmmirror.com/trim-newlines/-/trim-newlines-3.0.1.tgz: {} + + ts-morph@18.0.0: + dependencies: + '@ts-morph/common': 0.19.0 + code-block-writer: 12.0.0 + + ts-node@https://registry.npmmirror.com/ts-node/-/ts-node-10.9.1.tgz(@types/node@20.4.7)(typescript@5.2.2): + dependencies: + '@cspotcode/source-map-support': https://registry.npmmirror.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz + '@tsconfig/node10': https://registry.npmmirror.com/@tsconfig/node10/-/node10-1.0.9.tgz + '@tsconfig/node12': https://registry.npmmirror.com/@tsconfig/node12/-/node12-1.0.11.tgz + '@tsconfig/node14': https://registry.npmmirror.com/@tsconfig/node14/-/node14-1.0.3.tgz + '@tsconfig/node16': https://registry.npmmirror.com/@tsconfig/node16/-/node16-1.0.3.tgz + '@types/node': https://registry.npmmirror.com/@types/node/-/node-20.4.7.tgz + acorn: https://registry.npmmirror.com/acorn/-/acorn-8.10.0.tgz + acorn-walk: https://registry.npmmirror.com/acorn-walk/-/acorn-walk-8.2.0.tgz + arg: https://registry.npmmirror.com/arg/-/arg-4.1.3.tgz + create-require: https://registry.npmmirror.com/create-require/-/create-require-1.1.1.tgz + diff: https://registry.npmmirror.com/diff/-/diff-4.0.2.tgz + make-error: https://registry.npmmirror.com/make-error/-/make-error-1.3.6.tgz + typescript: https://registry.npmmirror.com/typescript/-/typescript-5.2.2.tgz + v8-compile-cache-lib: https://registry.npmmirror.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz + yn: https://registry.npmmirror.com/yn/-/yn-3.1.1.tgz + + tslib@2.6.2: {} + + tslib@https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz: {} + + tslib@https://registry.npmmirror.com/tslib/-/tslib-2.6.2.tgz: {} + + turbo-darwin-64@1.10.14: + optional: true + + turbo-darwin-arm64@1.10.14: + optional: true + + turbo-linux-64@1.10.14: + optional: true + + turbo-linux-arm64@1.10.14: + optional: true + + turbo-windows-64@1.10.14: + optional: true + + turbo-windows-arm64@1.10.14: + optional: true + + turbo@https://registry.npmmirror.com/turbo/-/turbo-1.10.14.tgz: + optionalDependencies: + turbo-darwin-64: 1.10.14 + turbo-darwin-arm64: 1.10.14 + turbo-linux-64: 1.10.14 + turbo-linux-arm64: 1.10.14 + turbo-windows-64: 1.10.14 + turbo-windows-arm64: 1.10.14 + + type-detect@https://registry.npmmirror.com/type-detect/-/type-detect-4.0.8.tgz: {} + + type-fest@1.4.0: {} + + type-fest@https://registry.npmmirror.com/type-fest/-/type-fest-0.18.1.tgz: {} + + type-fest@https://registry.npmmirror.com/type-fest/-/type-fest-0.21.3.tgz: {} + + type-fest@https://registry.npmmirror.com/type-fest/-/type-fest-0.6.0.tgz: {} + + type-fest@https://registry.npmmirror.com/type-fest/-/type-fest-0.8.1.tgz: {} + + typedarray-to-buffer@https://registry.npmmirror.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz: + dependencies: + is-typedarray: https://registry.npmmirror.com/is-typedarray/-/is-typedarray-1.0.0.tgz + + typescript@https://registry.npmmirror.com/typescript/-/typescript-5.0.4.tgz: {} + + typescript@https://registry.npmmirror.com/typescript/-/typescript-5.2.2.tgz: {} + + ufo@1.3.0: {} + + unbuild@1.2.1: + dependencies: + '@rollup/plugin-alias': 5.0.0(rollup@3.28.1) + '@rollup/plugin-commonjs': 24.1.0(rollup@3.28.1) + '@rollup/plugin-json': 6.0.0(rollup@3.28.1) + '@rollup/plugin-node-resolve': 15.2.1(rollup@3.28.1) + '@rollup/plugin-replace': 5.0.2(rollup@3.28.1) + '@rollup/pluginutils': 5.0.4(rollup@3.28.1) + chalk: 5.3.0 + consola: 3.2.3 + defu: 6.1.2 + esbuild: 0.17.19 + globby: 13.2.2 + hookable: 5.5.3 + jiti: 1.19.3 + magic-string: 0.30.3 + mkdist: 1.3.0(typescript@5.2.2) + mlly: 1.4.1 + mri: 1.2.0 + pathe: 1.1.1 + pkg-types: 1.0.3 + pretty-bytes: 6.1.1 + rollup: 3.28.1 + rollup-plugin-dts: 5.3.1(rollup@3.28.1)(typescript@5.2.2) + scule: 1.0.0 + typescript: https://registry.npmmirror.com/typescript/-/typescript-5.2.2.tgz + untyped: 1.4.0 + transitivePeerDependencies: + - sass + - supports-color + + unconfig@0.3.10: + dependencies: + '@antfu/utils': 0.7.6 + defu: 6.1.2 + jiti: 1.19.3 + mlly: 1.4.1 + + union-value@1.0.1: + dependencies: + arr-union: 3.1.0 + get-value: 2.0.6 + is-extendable: 0.1.1 + set-value: 2.0.1 + + universalify@0.1.2: {} + + universalify@2.0.0: {} + + universalify@https://registry.npmmirror.com/universalify/-/universalify-0.2.0.tgz: {} + + universalify@https://registry.npmmirror.com/universalify/-/universalify-2.0.0.tgz: {} + + unocss@0.55.3(postcss@8.4.29)(rollup@3.28.1)(vite@4.4.9): + dependencies: + '@unocss/astro': 0.55.3(rollup@3.28.1)(vite@4.4.9) + '@unocss/cli': 0.55.3(rollup@3.28.1) + '@unocss/core': 0.55.3 + '@unocss/extractor-arbitrary-variants': 0.55.3 + '@unocss/postcss': 0.55.3(postcss@8.4.29) + '@unocss/preset-attributify': 0.55.3 + '@unocss/preset-icons': 0.55.3 + '@unocss/preset-mini': 0.55.3 + '@unocss/preset-tagify': 0.55.3 + '@unocss/preset-typography': 0.55.3 + '@unocss/preset-uno': 0.55.3 + '@unocss/preset-web-fonts': 0.55.3 + '@unocss/preset-wind': 0.55.3 + '@unocss/reset': 0.55.3 + '@unocss/transformer-attributify-jsx': 0.55.3 + '@unocss/transformer-attributify-jsx-babel': 0.55.3 + '@unocss/transformer-compile-class': 0.55.3 + '@unocss/transformer-directives': 0.55.3 + '@unocss/transformer-variant-group': 0.55.3 + '@unocss/vite': 0.55.3(rollup@3.28.1)(vite@4.4.9) + vite: 4.4.9(@types/node@20.4.7)(less@4.2.0)(sass@1.66.1) + transitivePeerDependencies: + - postcss + - rollup + - supports-color + + unpipe@1.0.0: {} + + unpipe@https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz: {} + + unplugin-vue-define-options@1.3.17(rollup@3.28.1)(vue@3.3.4): + dependencies: + '@vue-macros/common': 1.7.2(rollup@3.28.1)(vue@3.3.4) + ast-walker-scope: 0.5.0(rollup@3.28.1) + unplugin: 1.4.0 + transitivePeerDependencies: + - rollup + - vue + + unplugin@1.4.0: + dependencies: + acorn: 8.10.0 + chokidar: 3.5.3 + webpack-sources: 3.2.3 + webpack-virtual-modules: 0.5.0 + + unset-value@1.0.0: + dependencies: + has-value: 0.3.1 + isobject: 3.0.1 + + untildify@https://registry.npmmirror.com/untildify/-/untildify-4.0.0.tgz: {} + + untyped@1.4.0: + dependencies: + '@babel/core': 7.22.11 + '@babel/standalone': 7.22.13 + '@babel/types': 7.22.11 + defu: 6.1.2 + jiti: 1.19.3 + mri: 1.2.0 + scule: 1.0.0 + transitivePeerDependencies: + - supports-color + + unzipper@0.10.14: + dependencies: + big-integer: 1.6.51 + binary: 0.3.0 + bluebird: 3.4.7 + buffer-indexof-polyfill: 1.0.2 + duplexer2: 0.1.4 + fstream: 1.0.12 + graceful-fs: 4.2.11 + listenercount: 1.0.1 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + + update-browserslist-db@1.0.11(browserslist@4.21.10): + dependencies: + browserslist: 4.21.10 + escalade: https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz + picocolors: 1.0.0 + + update-browserslist-db@https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz(browserslist@4.21.10): + dependencies: + browserslist: https://registry.npmmirror.com/browserslist/-/browserslist-4.21.10.tgz + escalade: https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz + picocolors: https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz + + uri-js@4.4.1: + dependencies: + punycode: 2.3.0 + + uri-js@https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz: + dependencies: + punycode: https://registry.npmmirror.com/punycode/-/punycode-2.3.0.tgz + + urix@0.1.0: {} + + url-parse@https://registry.npmmirror.com/url-parse/-/url-parse-1.5.10.tgz: + dependencies: + querystringify: https://registry.npmmirror.com/querystringify/-/querystringify-2.2.0.tgz + requires-port: https://registry.npmmirror.com/requires-port/-/requires-port-1.0.0.tgz + + use@3.1.1: {} + + util-deprecate@1.0.2: {} + + util-deprecate@https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz: {} + + utils-merge@1.0.1: {} + + utils-merge@https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz: {} + + uuid@8.3.2: {} + + v8-compile-cache-lib@https://registry.npmmirror.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz: {} + + v8-to-istanbul@https://registry.npmmirror.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz: + dependencies: + '@types/istanbul-lib-coverage': https://registry.npmmirror.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz + convert-source-map: https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.9.0.tgz + source-map: 0.7.4 + + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.1.1 + spdx-expression-parse: 3.0.1 + + validate-npm-package-license@https://registry.npmmirror.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz: + dependencies: + spdx-correct: https://registry.npmmirror.com/spdx-correct/-/spdx-correct-3.1.1.tgz + spdx-expression-parse: https://registry.npmmirror.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz + + validator@13.11.0: {} + + vary@1.1.2: {} + + vditor@https://registry.npmmirror.com/vditor/-/vditor-3.9.5.tgz: + dependencies: + diff-match-patch: https://registry.npmmirror.com/diff-match-patch/-/diff-match-patch-1.0.5.tgz + + vite-plugin-compression@0.5.1(vite@4.4.9): + dependencies: + chalk: 4.1.2 + debug: 4.3.4 + fs-extra: 10.1.0 + vite: 4.4.9(@types/node@20.4.7)(less@4.2.0)(sass@1.66.1) + transitivePeerDependencies: + - supports-color + + vite-plugin-dts@2.3.0(@types/node@20.4.7)(rollup@3.28.1)(vite@4.4.9): + dependencies: + '@babel/parser': 7.22.13 + '@microsoft/api-extractor': 7.36.4(@types/node@20.4.7) + '@rollup/pluginutils': 5.0.4(rollup@3.28.1) + '@rushstack/node-core-library': 3.59.7(@types/node@20.4.7) + debug: 4.3.4 + fast-glob: 3.3.1 + fs-extra: 10.1.0 + kolorist: 1.8.0 + magic-string: 0.29.0 + ts-morph: 18.0.0 + vite: 4.4.9(@types/node@20.4.7)(less@4.2.0)(sass@1.66.1) + transitivePeerDependencies: + - '@types/node' + - rollup + - supports-color + + vite-plugin-html@3.2.0(vite@4.4.9): + dependencies: + '@rollup/pluginutils': 4.2.1 + colorette: 2.0.20 + connect-history-api-fallback: 1.6.0 + consola: 2.15.3 + dotenv: 16.3.1 + dotenv-expand: 8.0.3 + ejs: 3.1.9 + fast-glob: 3.3.1 + fs-extra: 10.1.0 + html-minifier-terser: 6.1.0 + node-html-parser: 5.4.2 + pathe: 0.2.0 + vite: 4.4.9(@types/node@20.4.7)(less@4.2.0)(sass@1.66.1) + + vite-plugin-mock@3.0.0(esbuild@0.19.2)(mockjs@1.1.0)(vite@4.4.9): + dependencies: + '@types/mockjs': 1.0.7 + bundle-require: 4.0.1(esbuild@0.19.2) + chokidar: 3.5.3 + connect: 3.7.0 + debug: 4.3.4 + fast-glob: 3.3.1 + mockjs: 1.1.0 + path-to-regexp: 6.2.1 + picocolors: 1.0.0 + vite: 4.4.9(@types/node@20.4.7)(less@4.2.0)(sass@1.66.1) + transitivePeerDependencies: + - esbuild + - supports-color + + vite-plugin-mock@https://registry.npmmirror.com/vite-plugin-mock/-/vite-plugin-mock-2.9.8.tgz(mockjs@1.1.0)(vite@4.4.9): + dependencies: + '@types/mockjs': https://registry.npmmirror.com/@types/mockjs/-/mockjs-1.0.7.tgz + chalk: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz + chokidar: https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz + connect: https://registry.npmmirror.com/connect/-/connect-3.7.0.tgz + debug: https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz + esbuild: https://registry.npmmirror.com/esbuild/-/esbuild-0.14.54.tgz + fast-glob: https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.1.tgz + mockjs: 1.1.0 + path-to-regexp: https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz + vite: https://registry.npmmirror.com/vite/-/vite-4.4.9.tgz(@types/node@20.4.7) + transitivePeerDependencies: + - supports-color + + vite-plugin-purge-icons@0.9.2(vite@4.4.9): + dependencies: + '@purge-icons/core': 0.9.1 + '@purge-icons/generated': 0.9.0 + rollup-plugin-purge-icons: 0.9.1 + vite: 4.4.9(@types/node@20.4.7)(less@4.2.0)(sass@1.66.1) + transitivePeerDependencies: + - encoding + - supports-color + + vite-plugin-svg-icons@2.0.1(vite@4.4.9): + dependencies: + '@types/svgo': 2.6.4 + cors: 2.8.5 + debug: 4.3.4 + etag: 1.8.1 + fs-extra: 10.1.0 + pathe: 0.2.0 + svg-baker: 1.7.0 + svgo: 2.8.0 + vite: 4.4.9(@types/node@20.4.7)(less@4.2.0)(sass@1.66.1) + transitivePeerDependencies: + - supports-color + + vite@4.4.9(@types/node@18.17.12): + dependencies: + '@types/node': 18.17.12 + esbuild: 0.18.20 + postcss: 8.4.29 + rollup: 3.28.1 + optionalDependencies: + fsevents: 2.3.3 + + vite@4.4.9(@types/node@20.4.7)(less@4.2.0)(sass@1.66.1): + dependencies: + '@types/node': https://registry.npmmirror.com/@types/node/-/node-20.4.7.tgz + esbuild: 0.18.20 + less: 4.2.0 + postcss: 8.4.29 + rollup: 3.28.1 + sass: 1.66.1 + optionalDependencies: + fsevents: 2.3.3 + + vite@https://registry.npmmirror.com/vite/-/vite-4.4.9.tgz(@types/node@20.4.7): + dependencies: + '@types/node': https://registry.npmmirror.com/@types/node/-/node-20.4.7.tgz + esbuild: https://registry.npmmirror.com/esbuild/-/esbuild-0.18.20.tgz + postcss: https://registry.npmmirror.com/postcss/-/postcss-8.4.29.tgz + rollup: https://registry.npmmirror.com/rollup/-/rollup-3.28.1.tgz + optionalDependencies: + fsevents: 2.3.3 + + vue-component-type-helpers@https://registry.npmmirror.com/vue-component-type-helpers/-/vue-component-type-helpers-1.8.4.tgz: {} + + vue-demi@0.14.0(vue@3.2.47): + dependencies: + vue: 3.2.47 + + vue-demi@https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.6.tgz(vue@3.3.4): + dependencies: + vue: 3.3.4 + + vue-i18n@9.2.2(vue@3.3.4): + dependencies: + '@intlify/core-base': 9.2.2 + '@intlify/shared': 9.2.2 + '@intlify/vue-devtools': 9.2.2 + '@vue/devtools-api': 6.5.0 + vue: 3.3.4 + + vue-json-pretty@2.2.4(vue@3.3.4): + dependencies: + vue: 3.3.4 + + vue-router@https://registry.npmmirror.com/vue-router/-/vue-router-4.2.4.tgz(vue@3.3.4): + dependencies: + '@vue/devtools-api': https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.5.0.tgz + vue: 3.3.4 + + vue-template-compiler@https://registry.npmmirror.com/vue-template-compiler/-/vue-template-compiler-2.7.14.tgz: + dependencies: + de-indent: https://registry.npmmirror.com/de-indent/-/de-indent-1.0.2.tgz + he: https://registry.npmmirror.com/he/-/he-1.2.0.tgz + + vue-tsc@https://registry.npmmirror.com/vue-tsc/-/vue-tsc-1.8.8.tgz(typescript@5.2.2): + dependencies: + '@vue/language-core': https://registry.npmmirror.com/@vue/language-core/-/language-core-1.8.8.tgz(typescript@5.2.2) + '@vue/typescript': https://registry.npmmirror.com/@vue/typescript/-/typescript-1.8.8.tgz(typescript@5.2.2) + semver: https://registry.npmmirror.com/semver/-/semver-7.5.4.tgz + typescript: https://registry.npmmirror.com/typescript/-/typescript-5.2.2.tgz + + vue-types@https://registry.npmmirror.com/vue-types/-/vue-types-3.0.2.tgz(vue@3.3.4): + dependencies: + is-plain-object: https://registry.npmmirror.com/is-plain-object/-/is-plain-object-3.0.1.tgz + vue: 3.3.4 + + vue-types@https://registry.npmmirror.com/vue-types/-/vue-types-5.1.1.tgz(vue@3.3.4): + dependencies: + is-plain-object: https://registry.npmmirror.com/is-plain-object/-/is-plain-object-5.0.0.tgz + vue: 3.3.4 + + vue@3.2.47: + dependencies: + '@vue/compiler-dom': 3.2.47 + '@vue/compiler-sfc': 3.2.47 + '@vue/runtime-dom': 3.2.47 + '@vue/server-renderer': 3.2.47(vue@3.2.47) + '@vue/shared': 3.2.47 + + vue@3.3.4: + dependencies: + '@vue/compiler-dom': 3.3.4 + '@vue/compiler-sfc': 3.3.4 + '@vue/runtime-dom': 3.3.4 + '@vue/server-renderer': 3.3.4(vue@3.3.4) + '@vue/shared': 3.3.4 + + vuedraggable@https://registry.npmmirror.com/vuedraggable/-/vuedraggable-4.1.0.tgz(vue@3.3.4): + dependencies: + sortablejs: https://registry.npmmirror.com/sortablejs/-/sortablejs-1.14.0.tgz + vue: 3.3.4 + + vxe-table-plugin-export-xlsx@https://registry.npmmirror.com/vxe-table-plugin-export-xlsx/-/vxe-table-plugin-export-xlsx-3.1.0.tgz(vxe-table@4.5.14): + dependencies: + vxe-table: https://registry.npmmirror.com/vxe-table/-/vxe-table-4.5.14.tgz(vue@3.3.4)(xe-utils@3.5.12) + + vxe-table@https://registry.npmmirror.com/vxe-table/-/vxe-table-4.5.14.tgz(vue@3.3.4)(xe-utils@3.5.12): + dependencies: + dom-zindex: https://registry.npmmirror.com/dom-zindex/-/dom-zindex-1.0.1.tgz + vue: 3.3.4 + xe-utils: https://registry.npmmirror.com/xe-utils/-/xe-utils-3.5.12.tgz + + w3c-hr-time@https://registry.npmmirror.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz: + dependencies: + browser-process-hrtime: https://registry.npmmirror.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz + + w3c-keyname@2.2.8: {} + + w3c-xmlserializer@https://registry.npmmirror.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz: + dependencies: + xml-name-validator: https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz + + walker@https://registry.npmmirror.com/walker/-/walker-1.0.8.tgz: + dependencies: + makeerror: https://registry.npmmirror.com/makeerror/-/makeerror-1.0.12.tgz + + warning@https://registry.npmmirror.com/warning/-/warning-4.0.3.tgz: + dependencies: + loose-envify: https://registry.npmmirror.com/loose-envify/-/loose-envify-1.4.0.tgz + + webidl-conversions@3.0.1: {} + + webidl-conversions@https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz: {} + + webidl-conversions@https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz: {} + + webpack-sources@3.2.3: {} + + webpack-virtual-modules@0.5.0: {} + + whatwg-encoding@https://registry.npmmirror.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz: + dependencies: + iconv-lite: https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz + + whatwg-mimetype@https://registry.npmmirror.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + whatwg-url@https://registry.npmmirror.com/whatwg-url/-/whatwg-url-8.7.0.tgz: + dependencies: + lodash: https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz + tr46: https://registry.npmmirror.com/tr46/-/tr46-2.1.0.tgz + webidl-conversions: https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz + + which-module@2.0.1: {} + + which@1.3.1: + dependencies: + isexe: 2.0.0 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + which@https://registry.npmmirror.com/which/-/which-2.0.2.tgz: + dependencies: + isexe: https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz + + wmf@1.0.2: {} + + word@0.3.0: {} + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz: + dependencies: + ansi-styles: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz + string-width: https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz + strip-ansi: https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz + + wrap-ansi@https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz: + dependencies: + ansi-styles: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz + string-width: https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz + strip-ansi: https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz + + wrap-ansi@https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz: + dependencies: + ansi-styles: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.1.tgz + string-width: https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz + strip-ansi: https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.0.tgz + + wrappy@1.0.2: {} + + wrappy@https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz: {} + + write-file-atomic@5.0.1: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 4.1.0 + + write-file-atomic@https://registry.npmmirror.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz: + dependencies: + imurmurhash: https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz + is-typedarray: https://registry.npmmirror.com/is-typedarray/-/is-typedarray-1.0.0.tgz + signal-exit: https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz + typedarray-to-buffer: https://registry.npmmirror.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz + + ws@https://registry.npmmirror.com/ws/-/ws-7.5.9.tgz: {} + + xe-utils@https://registry.npmmirror.com/xe-utils/-/xe-utils-3.5.12.tgz: {} + + xlsx@0.18.5: + dependencies: + adler-32: 1.3.1 + cfb: 1.2.2 + codepage: 1.15.0 + crc-32: 1.2.2 + ssf: 0.11.2 + wmf: 1.0.2 + word: 0.3.0 + + xml-name-validator@https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz: {} + + xmlchars@2.2.0: {} + + xmlchars@https://registry.npmmirror.com/xmlchars/-/xmlchars-2.2.0.tgz: {} + + y18n@4.0.3: {} + + y18n@5.0.8: {} + + y18n@https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz: {} + + yallist@3.1.1: {} + + yallist@4.0.0: {} + + yallist@https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz: {} + + yallist@https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz: {} + + yaml@https://registry.npmmirror.com/yaml/-/yaml-2.3.2.tgz: {} + + yargs-parser@18.1.3: + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + + yargs-parser@20.2.9: {} + + yargs-parser@21.1.1: {} + + yargs-parser@https://registry.npmmirror.com/yargs-parser/-/yargs-parser-20.2.9.tgz: {} + + yargs-parser@https://registry.npmmirror.com/yargs-parser/-/yargs-parser-21.1.1.tgz: {} + + yargs@15.4.1: + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yargs@https://registry.npmmirror.com/yargs/-/yargs-16.2.0.tgz: + dependencies: + cliui: https://registry.npmmirror.com/cliui/-/cliui-7.0.4.tgz + escalade: https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz + get-caller-file: https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz + require-directory: https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz + string-width: https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz + y18n: https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz + yargs-parser: https://registry.npmmirror.com/yargs-parser/-/yargs-parser-20.2.9.tgz + + yargs@https://registry.npmmirror.com/yargs/-/yargs-17.7.2.tgz: + dependencies: + cliui: https://registry.npmmirror.com/cliui/-/cliui-8.0.1.tgz + escalade: https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz + get-caller-file: https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz + require-directory: https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz + string-width: https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz + y18n: https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz + yargs-parser: https://registry.npmmirror.com/yargs-parser/-/yargs-parser-21.1.1.tgz + + yn@https://registry.npmmirror.com/yn/-/yn-3.1.1.tgz: {} + + yocto-queue@0.1.0: {} + + yocto-queue@https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz: {} + + z-schema@5.0.5: + dependencies: + lodash.get: 4.4.2 + lodash.isequal: 4.5.0 + validator: 13.11.0 + optionalDependencies: + commander: 9.5.0 + + zeebe-bpmn-moddle@1.0.0: {} + + zip-stream@4.1.0: + dependencies: + archiver-utils: 2.1.0 + compress-commons: 4.1.1 + readable-stream: 3.6.2 + + zrender@https://registry.npmmirror.com/zrender/-/zrender-5.4.4.tgz: + dependencies: + tslib: https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..7195df0 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,4 @@ +packages: + - 'internal/*' + - 'packages/*' + - 'apps/test-server' diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c04e95efb7b01555c2c79e5cad114013a9ea5bd5 GIT binary patch literal 16025 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 literal 0 HcmV?d00001 diff --git a/public/resource/.DS_Store b/public/resource/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..0a5d89b819b1948db5f8adfaeafc2656c762bf80 GIT binary patch literal 6148 zcmeHKOHRW;47J-z6tU@&<=g<31E8S_C+G!GTT~DY=>it)<{GRx4XduY>v8%#wo1~p zED@r%tBm$3(=Vx7m_s*1=UQ&Z#Tjr0oPm>L06klzf1&8BGvEw313L!f`w*al(J(3I zPY0Gf0swn3XTe@(3CRhD(J(2(17S@CYAV}^!I}Nr2- zaN?-wt25vXG#TjX#ePalU^I3_fQduONzS` iY;r3`thC}wXcpLmY=F@)DZ&ErAAwARFV4WPGOz`E0YtF? literal 0 HcmV?d00001 diff --git a/public/resource/img/logo.png b/public/resource/img/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..c04e95efb7b01555c2c79e5cad114013a9ea5bd5 GIT binary patch literal 16025 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 literal 0 HcmV?d00001 diff --git a/public/resource/tinymce/icons/default/icons.min.js b/public/resource/tinymce/icons/default/icons.min.js new file mode 100644 index 0000000..7ed2965 --- /dev/null +++ b/public/resource/tinymce/icons/default/icons.min.js @@ -0,0 +1 @@ +tinymce.IconManager.add("default",{icons:{"accessibility-check":'',"action-next":'',"action-prev":'',addtag:'',"align-center":'',"align-justify":'',"align-left":'',"align-none":'',"align-right":'',"arrow-left":'',"arrow-right":'',bold:'',bookmark:'',"border-style":'',"border-width":'',brightness:'',browse:'',cancel:'',"cell-background-color":'',"cell-border-color":'',"change-case":'',"character-count":'',"checklist-rtl":'',checklist:'',checkmark:'',"chevron-down":'',"chevron-left":'',"chevron-right":'',"chevron-up":'',close:'',"code-sample":'',"color-levels":'',"color-picker":'',"color-swatch-remove-color":'',"color-swatch":'',"comment-add":'',comment:'',contrast:'',copy:'',crop:'',"cut-column":'',"cut-row":'',cut:'',"document-properties":'',drag:'',"duplicate-column":'',"duplicate-row":'',duplicate:'',"edit-block":'',"edit-image":'',"embed-page":'',embed:'',emoji:'',export:'',fill:'',"flip-horizontally":'',"flip-vertically":'',footnote:'',"format-painter":'',format:'',fullscreen:'',gallery:'',gamma:'',help:'',"highlight-bg-color":'',home:'',"horizontal-rule":'',"image-options":'',image:'',indent:'',info:'',"insert-character":'',"insert-time":'',invert:'',italic:'',language:'',"line-height":'',line:'',link:'',"list-bull-circle":'',"list-bull-default":'',"list-bull-square":'',"list-num-default-rtl":'',"list-num-default":'',"list-num-lower-alpha-rtl":'',"list-num-lower-alpha":'',"list-num-lower-greek-rtl":'',"list-num-lower-greek":'',"list-num-lower-roman-rtl":'',"list-num-lower-roman":'',"list-num-upper-alpha-rtl":'',"list-num-upper-alpha":'',"list-num-upper-roman-rtl":'',"list-num-upper-roman":'',lock:'',ltr:'',minus:'',"more-drawer":'',"new-document":'',"new-tab":'',"non-breaking":'',notice:'',"ordered-list-rtl":'',"ordered-list":'',orientation:'',outdent:'',"page-break":'',paragraph:'',"paste-column-after":'',"paste-column-before":'',"paste-row-after":'',"paste-row-before":'',"paste-text":'',paste:'',"anent-pen":'',plus:'',preferences:'',preview:'',print:'',quote:'',redo:'',reload:'',"remove-formatting":'',remove:'',"resize-handle":'',resize:'',"restore-draft":'',"rotate-left":'',"rotate-right":'',rtl:'',save:'',search:'',"select-all":'',selected:'',settings:'',sharpen:'',sourcecode:'',"spell-check":'',"strike-through":'',subscript:'',superscript:'',"table-caption":'',"table-cell-classes":'',"table-cell-properties":'',"table-cell-select-all":'',"table-cell-select-inner":'',"table-classes":'',"table-delete-column":'',"table-delete-row":'',"table-delete-table":'',"table-insert-column-after":'',"table-insert-column-before":'',"table-insert-row-above":'',"table-insert-row-after":'',"table-left-header":'',"table-merge-cells":'',"table-row-numbering-rtl":'',"table-row-numbering":'',"table-row-properties":'',"table-split-cells":'',"table-top-header":'',table:'',"template-add":'',template:'',"temporary-placeholder":'',"text-color":'',"text-size-decrease":'',"text-size-increase":'',toc:'',translate:'',typography:'',underline:'',undo:'',unlink:'',unlock:'',"unordered-list":'',unselected:'',upload:'',user:'',"vertical-align":'',visualblocks:'',visualchars:'',warning:'',"zoom-in":'',"zoom-out":''}}); diff --git a/public/resource/tinymce/langs/README.md b/public/resource/tinymce/langs/README.md new file mode 100644 index 0000000..a52bf03 --- /dev/null +++ b/public/resource/tinymce/langs/README.md @@ -0,0 +1,3 @@ +This is where language files should be placed. + +Please DO NOT translate these directly use this service: https://www.transifex.com/projects/p/tinymce/ diff --git a/public/resource/tinymce/langs/en.js b/public/resource/tinymce/langs/en.js new file mode 100644 index 0000000..27337c3 --- /dev/null +++ b/public/resource/tinymce/langs/en.js @@ -0,0 +1,419 @@ +tinymce.addI18n('es', { + Redo: 'Rehacer', + Undo: 'Deshacer', + Cut: 'Cortar', + Copy: 'Copiar', + Paste: 'Pegar', + 'Select all': 'Seleccionar todo', + 'New document': 'Nuevo documento', + Ok: 'Ok', + Cancel: 'Cancelar', + 'Visual aids': 'Ayudas visuales', + Bold: 'Negrita', + Italic: 'Cursiva', + Underline: 'Subrayado', + Strikethrough: 'Tachado', + Superscript: 'Super\u00edndice', + Subscript: 'Sub\u00edndice', + 'Clear formatting': 'Limpiar formato', + 'Align left': 'Alinear a la izquierda', + 'Align center': 'Alinear al centro', + 'Align right': 'Alinear a la derecha', + Justify: 'Justificar', + 'Bullet list': 'Lista de vi\u00f1etas', + 'Numbered list': 'Lista numerada', + 'Decrease indent': 'Disminuir sangr\u00eda', + 'Increase indent': 'Incrementar sangr\u00eda', + Close: 'Cerrar', + Formats: 'Formatos', + "Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": 'Su navegador no es compatible con el acceso directo al portapapeles. Use las teclas Crtl+X\/C\/V de su teclado.', + Headers: 'Encabezados', + 'Header 1': 'Encabezado 1', + 'Header 2': 'Encabezado 2', + 'Header 3': 'Encabezado 3', + 'Header 4': 'Encabezado 4', + 'Header 5': 'Encabezado 5', + 'Header 6': 'Encabezado 6', + Headings: 'Encabezados', + 'Heading 1': 'Encabezado 1', + 'Heading 2': 'Encabezado 2', + 'Heading 3': 'Encabezado 3', + 'Heading 4': 'Encabezado 4', + 'Heading 5': 'Encabezado 5', + 'Heading 6': 'Encabezado 6', + Preformatted: 'Con formato previo', + Div: 'Div', + Pre: 'Pre', + Code: 'C\u00f3digo', + Paragraph: 'P\u00e1rrafo', + Blockquote: 'Blockquote', + Inline: 'Alineado', + Blocks: 'Bloques', + 'Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.': 'Pegar est\u00e1 ahora en modo de texto plano. El contenido se pegar\u00e1 como texto plano hasta que desactive esta opci\u00f3n.', + Fonts: 'Fuentes', + 'Font Sizes': 'Tama\u00f1os de fuente', + Class: 'Clase', + 'Browse for an image': 'Buscar una imagen', + OR: 'OR', + 'Drop an image here': 'Arrastre una imagen aqu\u00ed', + Upload: 'Cargar', + Block: 'Bloque', + Align: 'Alinear', + Default: 'Por defecto', + Circle: 'C\u00edrculo', + Disc: 'Disco', + Square: 'Cuadrado', + 'Lower Alpha': 'Inferior Alfa', + 'Lower Greek': 'Inferior Griega', + 'Lower Roman': 'Inferior Romana', + 'Upper Alpha': 'Superior Alfa', + 'Upper Roman': 'Superior Romana', + 'Anchor...': 'Anclaje...', + Name: 'Nombre', + Id: 'Id', + 'Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.': 'Deber\u00eda comenzar por una letra, seguida solo de letras, n\u00fameros, guiones, puntos, dos puntos o guiones bajos.', + 'You have unsaved changes are you sure you want to navigate away?': 'Tiene cambios sin guardar. \u00bfEst\u00e1 seguro de que quiere salir?', + 'Restore last draft': 'Restaurar el \u00faltimo borrador', + 'Special character...': 'Car\u00e1cter especial...', + 'Source code': 'C\u00f3digo fuente', + 'Insert\/Edit code sample': 'Insertar\/editar c\u00f3digo de prueba', + Language: 'Idioma', + 'Code sample...': 'Ejemplo de c\u00f3digo...', + 'Color Picker': 'Selector de colores', + R: 'R', + G: 'V', + B: 'A', + 'Left to right': 'De izquierda a derecha', + 'Right to left': 'De derecha a izquierda', + 'Emoticons...': 'Emoticones...', + 'Metadata and Document Properties': 'Metadatos y propiedades del documento', + Title: 'T\u00edtulo', + Keywords: 'Palabras clave', + Description: 'Descripci\u00f3n', + Robots: 'Robots', + Author: 'Autor', + Encoding: 'Codificaci\u00f3n', + Fullscreen: 'Pantalla completa', + Action: 'Acci\u00f3n', + Shortcut: 'Atajo', + Help: 'Ayuda', + Address: 'Direcci\u00f3n', + 'Focus to menubar': 'Enfocar la barra del men\u00fa', + 'Focus to toolbar': 'Enfocar la barra de herramientas', + 'Focus to element path': 'Enfocar la ruta del elemento', + 'Focus to contextual toolbar': 'Enfocar la barra de herramientas contextual', + 'Insert link (if link plugin activated)': 'Insertar enlace (si el complemento de enlace est\u00e1 activado)', + 'Save (if save plugin activated)': 'Guardar (si el componente de salvar est\u00e1 activado)', + 'Find (if searchreplace plugin activated)': 'Buscar (si el complemento buscar-remplazar est\u00e1 activado)', + 'Plugins installed ({0}):': 'Plugins instalados ({0}):', + 'Premium plugins:': 'Complementos premium:', + 'Learn more...': 'Aprende m\u00e1s...', + 'You are using {0}': 'Estas usando {0}', + Plugins: 'Complementos', + 'Handy Shortcuts': 'Accesos directos', + 'Horizontal line': 'L\u00ednea horizontal', + 'Insert\/edit image': 'Insertar\/editar imagen', + 'Image description': 'Descripci\u00f3n de la imagen', + Source: 'Enlace', + Dimensions: 'Dimensiones', + 'Constrain proportions': 'Restringir proporciones', + General: 'General', + Advanced: 'Avanzado', + Style: 'Estilo', + 'Vertical space': 'Espacio vertical', + 'Horizontal space': 'Espacio horizontal', + Border: 'Borde', + 'Insert image': 'Insertar imagen', + 'Image...': 'Imagen...', + 'Image list': 'Lista de im\u00e1genes', + 'Rotate counterclockwise': 'Girar a la izquierda', + 'Rotate clockwise': 'Girar a la derecha', + 'Flip vertically': 'Invertir verticalmente', + 'Flip horizontally': 'Invertir horizontalmente', + 'Edit image': 'Editar imagen', + 'Image options': 'Opciones de imagen', + 'Zoom in': 'Acercar', + 'Zoom out': 'Alejar', + Crop: 'Recortar', + Resize: 'Redimensionar', + Orientation: 'Orientaci\u00f3n', + Brightness: 'Brillo', + Sharpen: 'Forma', + Contrast: 'Contraste', + 'Color levels': 'Niveles de color', + Gamma: 'Gamma', + Invert: 'Invertir', + Apply: 'Aplicar', + Back: 'Atr\u00e1s', + 'Insert date\/time': 'Insertar fecha\/hora', + 'Date\/time': 'Fecha\/hora', + 'Insert\/Edit Link': 'Insertar\/editar enlace', + 'Insert\/edit link': 'Insertar\/editar enlace', + 'Text to display': 'Texto para mostrar', + Url: 'URL', + 'Open link in...': 'Abrir enlace en...', + 'Current window': 'Ventana actual', + None: 'Ninguno', + 'New window': 'Nueva ventana', + 'Remove link': 'Quitar enlace', + Anchors: 'Anclas', + 'Link...': 'Enlace...', + 'Paste or type a link': 'Pega o introduce un enlace', + 'The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?': 'El enlace que has introducido no parece ser una direcci\u00f3n de correo electr\u00f3nico. Quieres a\u00f1adir el prefijo necesario mailto: ?', + 'The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?': 'El enlace que has introducido no parece ser una enlace externo. Quieres a\u00f1adir el prefijo necesario http:\/\/ ?', + 'Link list': 'Lista de enlaces', + 'Insert video': 'Insertar video', + 'Insert\/edit video': 'Insertar\/editar video', + 'Insert\/edit media': 'Insertar\/editar medio', + 'Alternative source': 'Enlace alternativo', + 'Alternative source URL': 'Origen de URL alternativo', + 'Media poster (Image URL)': 'P\u00f3ster de medio (URL de imagen)', + 'Paste your embed code below:': 'Pega tu c\u00f3digo embebido debajo', + Embed: 'Incrustado', + 'Media...': 'Medios...', + 'Nonbreaking space': 'Espacio fijo', + 'Page break': 'Salto de p\u00e1gina', + 'Paste as text': 'Pegar como texto', + Preview: 'Previsualizar', + 'Print...': 'Imprimir...', + Save: 'Guardar', + Find: 'Buscar', + 'Replace with': 'Reemplazar con', + Replace: 'Reemplazar', + 'Replace all': 'Reemplazar todo', + Previous: 'Anterior', + Next: 'Siguiente', + 'Find and replace...': 'Buscar y reemplazar...', + 'Could not find the specified string.': 'No se encuentra la cadena de texto especificada', + 'Match case': 'Coincidencia exacta', + 'Find whole words only': 'Solo palabras completas', + 'Spell check': 'Revisar ortograf\u00eda', + Ignore: 'Ignorar', + 'Ignore all': 'Ignorar todos', + Finish: 'Finalizar', + 'Add to Dictionary': 'A\u00f1adir al Diccionario', + 'Insert table': 'Insertar tabla', + 'Table properties': 'Propiedades de la tabla', + 'Delete table': 'Eliminar tabla', + Cell: 'Celda', + Row: 'Fila', + Column: 'Columna', + 'Cell properties': 'Propiedades de la celda', + 'Merge cells': 'Combinar celdas', + 'Split cell': 'Dividir celdas', + 'Insert row before': 'Insertar fila antes', + 'Insert row after': 'Insertar fila despu\u00e9s ', + 'Delete row': 'Eliminar fila', + 'Row properties': 'Propiedades de la fila', + 'Cut row': 'Cortar fila', + 'Copy row': 'Copiar fila', + 'Paste row before': 'Pegar la fila antes', + 'Paste row after': 'Pegar la fila despu\u00e9s', + 'Insert column before': 'Insertar columna antes', + 'Insert column after': 'Insertar columna despu\u00e9s', + 'Delete column': 'Eliminar columna', + Cols: 'Columnas', + Rows: 'Filas', + Width: 'Ancho', + Height: 'Alto', + 'Cell spacing': 'Espacio entre celdas', + 'Cell padding': 'Relleno de celda', + 'Show caption': 'Mostrar t\u00edtulo', + Left: 'Izquierda', + Center: 'Centrado', + Right: 'Derecha', + 'Cell type': 'Tipo de celda', + Scope: '\u00c1mbito', + Alignment: 'Alineaci\u00f3n', + 'H Align': 'Alineamiento Horizontal', + 'V Align': 'Alineamiento Vertical', + Top: 'Arriba', + Middle: 'Centro', + Bottom: 'Abajo', + 'Header cell': 'Celda de la cebecera', + 'Row group': 'Grupo de filas', + 'Column group': 'Grupo de columnas', + 'Row type': 'Tipo de fila', + Header: 'Cabecera', + Body: 'Cuerpo', + Footer: 'Pie de p\u00e1gina', + 'Border color': 'Color del borde', + 'Insert template...': 'Insertar plantilla...', + Templates: 'Plantillas', + Template: 'Plantilla', + 'Text color': 'Color del texto', + 'Background color': 'Color de fondo', + 'Custom...': 'Personalizar...', + 'Custom color': 'Color personalizado', + 'No color': 'Sin color', + 'Remove color': 'Quitar color', + 'Table of Contents': 'Tabla de contenidos', + 'Show blocks': 'Mostrar bloques', + 'Show invisible characters': 'Mostrar caracteres invisibles', + 'Word count': 'Contar palabras', + Count: 'Recuento', + Document: 'Documento', + Selection: 'Selecci\u00f3n', + Words: 'Palabras', + 'Words: {0}': 'Palabras: {0}', + '{0} words': '{0} palabras', + File: 'Archivo', + Edit: 'Editar', + Insert: 'Insertar', + View: 'Ver', + Format: 'Formato', + Table: 'Tabla', + Tools: 'Herramientas', + 'Powered by {0}': 'Desarrollado por {0}', + 'Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help': '\u00c1rea de texto enriquecido. Pulse ALT-F9 para el menu. Pulse ALT-F10 para la barra de herramientas. Pulse ALT-0 para ayuda', + 'Image title': 'Titulo de imagen', + 'Border width': 'Ancho de borde', + 'Border style': 'Estilo de borde', + Error: 'Error', + Warn: 'Advertencia', + Valid: 'V\u00e1lido', + 'To open the popup, press Shift+Enter': 'Para abrir el elemento emergente, pulse May\u00fas+Intro', + 'Rich Text Area. Press ALT-0 for help.': '\u00c1rea de texto enriquecido. Pulse ALT-0 para abrir la ayuda.', + 'System Font': 'Fuente de sistema', + 'Failed to upload image: {0}': 'Fallo al cargar imagen: {0}', + 'Failed to load plugin: {0} from url {1}': 'Fallo al cargar complemento: {0} desde URL {1}', + 'Failed to load plugin url: {0}': 'Fallo al cargar URL del complemento: {0}', + 'Failed to initialize plugin: {0}': 'Fallo al iniciar el complemento: {0}', + example: 'ejemplo', + Search: 'Buscar', + All: 'Todo', + Currency: 'Divisa', + Text: 'Texto', + Quotations: 'Comillas', + Mathematical: 'S\u00edmbolo matem\u00e1tico', + 'Extended Latin': 'Latino extendido A', + Symbols: 'S\u00edmbolos', + Arrows: 'Flechas', + 'User Defined': 'Definido por el usuario', + 'dollar sign': 'signo de d\u00f3lar', + 'currency sign': 'signo de divisa', + 'euro-currency sign': 'signo de euro', + 'colon sign': 'signo de dos puntos', + 'cruzeiro sign': 'signo de cruceiro', + 'french franc sign': 'signo de franco franc\u00e9s', + 'lira sign': 'signo de lira', + 'mill sign': 'signo de mill', + 'naira sign': 'signo de naira', + 'peseta sign': 'signo de peseta', + 'rupee sign': 'signo de rupia', + 'won sign': 'signo de won', + 'new sheqel sign': 'signo de nuevo s\u00e9quel', + 'dong sign': 'signo de dong', + 'kip sign': 'signo de kip', + 'tugrik sign': 'signo de tugrik', + 'drachma sign': 'signo de dracma', + 'german penny symbol': 'signo de penique alem\u00e1n', + 'peso sign': 'signo de peso', + 'guarani sign': 'signo de guaran\u00ed', + 'austral sign': 'signo de austral', + 'hryvnia sign': 'signo de grivna', + 'cedi sign': 'signo de cedi', + 'livre tournois sign': 'signo de libra tornesa', + 'spesmilo sign': 'signo de spesmilo', + 'tenge sign': 'signo de tenge', + 'indian rupee sign': 'signo de rupia india', + 'turkish lira sign': 'signo de lira turca', + 'nordic mark sign': 'signo de marco n\u00f3rdico', + 'manat sign': 'signo de manat', + 'ruble sign': 'signo de rublo', + 'yen character': 'car\u00e1cter de yen', + 'yuan character': 'car\u00e1cter de yuan', + 'yuan character, in hong kong and taiwan': 'car\u00e1cter de yuan en Hong Kong y Taiw\u00e1n', + 'yen\/yuan character variant one': 'Variante uno de car\u00e1cter de yen\/yuan', + 'Loading emoticons...': 'Cargando emoticonos...', + 'Could not load emoticons': 'No se han podido cargar los emoticonos', + People: 'Personas', + 'Animals and Nature': 'Animales y naturaleza', + 'Food and Drink': 'Comida y bebida', + Activity: 'Actividad', + 'Travel and Places': 'Viajes y lugares', + Objects: 'Objetos', + Flags: 'Banderas', + Characters: 'Caracteres', + 'Characters (no spaces)': 'Caracteres (sin espacios)', + '{0} characters': '{0} caracteres', + 'Error: Form submit field collision.': 'Error: Colisi\u00f3n de campo al enviar formulario.', + 'Error: No form element found.': 'Error: No se encuentra ning\u00fan elemento de formulario.', + Update: 'Actualizar', + 'Color swatch': 'Muestrario de colores', + Turquoise: 'Turquesa', + Green: 'Verde', + Blue: 'Azul', + Purple: 'P\u00farpura', + 'Navy Blue': 'Azul marino', + 'Dark Turquoise': 'Turquesa oscuro', + 'Dark Green': 'Verde oscuro', + 'Medium Blue': 'Azul medio', + 'Medium Purple': 'P\u00farpura medio', + 'Midnight Blue': 'Azul medio', + Yellow: 'Amarillo', + Orange: 'Naranja', + Red: 'Rojo', + 'Light Gray': 'Gris claro', + Gray: 'Gris', + 'Dark Yellow': 'Amarillo oscuro', + 'Dark Orange': 'Naranja oscuro', + 'Dark Red': 'Rojo oscuro', + 'Medium Gray': 'Gris medio', + 'Dark Gray': 'Gris oscuro', + 'Light Green': 'Verde claro', + 'Light Yellow': 'Amarillo claro', + 'Light Red': 'Rojo claro', + 'Light Purple': 'Morado claro', + 'Light Blue': 'Azul claro', + 'Dark Purple': 'Morado oscuro', + 'Dark Blue': 'Azul oscuro', + Black: 'Negro', + White: 'Blanco', + 'Switch to or from fullscreen mode': 'Activar o desactivar modo pantalla completa', + 'Open help dialog': 'Abrir di\u00e1logo de ayuda', + history: 'historial', + styles: 'estilos', + formatting: 'formato', + alignment: 'alineaci\u00f3n', + indentation: 'sangr\u00eda', + 'permanent pen': 'bol\u00edgrafo permanente', + comments: 'comentarios', + 'Format Painter': 'Copiar formato', + 'Insert\/edit iframe': 'Insertar\/editar iframe', + Capitalization: 'Uso de may\u00fasculas', + lowercase: 'min\u00fasculas', + UPPERCASE: 'MAY\u00daSCULAS', + 'Title Case': 'Tipo T\u00edtulo', + 'Permanent Pen Properties': 'Propiedades del bol\u00edgrafo permanente', + 'Permanent pen properties...': 'Propiedades del bol\u00edgrafo permanente...', + Font: 'Fuente', + Size: 'Tama\u00f1o', + 'More...': 'M\u00e1s...', + 'Spellcheck Language': 'Corrector', + 'Select...': 'Seleccionar...', + Preferences: 'Preferencias', + Yes: 'S\u00ed', + No: 'No', + 'Keyboard Navigation': 'Navegaci\u00f3n con el teclado', + Version: 'Versi\u00f3n', + Anchor: 'Ancla', + 'Special character': 'Car\u00e1cter especial', + 'Code sample': 'Ejemplo de c\u00f3digo', + Color: 'Color', + Emoticons: 'Emoticonos', + 'Document properties': 'Propiedades del documento', + Image: 'Imagen', + 'Insert link': 'Insertar enlace', + Target: 'Destino', + Link: 'Enlace', + Poster: 'Miniatura', + Media: 'Media', + Print: 'Imprimir', + Prev: 'Anterior', + 'Find and replace': 'Buscar y reemplazar', + 'Whole words': 'Palabras completas', + Spellcheck: 'Corrector ortogr\u00e1fico', + Caption: 'Subt\u00edtulo', + 'Insert template': 'Insertar plantilla' +}) diff --git a/public/resource/tinymce/langs/zh_CN.js b/public/resource/tinymce/langs/zh_CN.js new file mode 100644 index 0000000..f9d8b5c --- /dev/null +++ b/public/resource/tinymce/langs/zh_CN.js @@ -0,0 +1,389 @@ +tinymce.addI18n('zh_CN',{ +"Redo": "\u91cd\u505a", +"Undo": "\u64a4\u9500", +"Cut": "\u526a\u5207", +"Copy": "\u590d\u5236", +"Paste": "\u7c98\u8d34", +"Select all": "\u5168\u9009", +"New document": "\u65b0\u6587\u4ef6", +"Ok": "\u786e\u5b9a", +"Cancel": "\u53d6\u6d88", +"Visual aids": "\u7f51\u683c\u7ebf", +"Bold": "\u7c97\u4f53", +"Italic": "\u659c\u4f53", +"Underline": "\u4e0b\u5212\u7ebf", +"Strikethrough": "\u5220\u9664\u7ebf", +"Superscript": "\u4e0a\u6807", +"Subscript": "\u4e0b\u6807", +"Clear formatting": "\u6e05\u9664\u683c\u5f0f", +"Align left": "\u5de6\u8fb9\u5bf9\u9f50", +"Align center": "\u4e2d\u95f4\u5bf9\u9f50", +"Align right": "\u53f3\u8fb9\u5bf9\u9f50", +"Justify": "\u4e24\u7aef\u5bf9\u9f50", +"Bullet list": "\u9879\u76ee\u7b26\u53f7", +"Numbered list": "\u7f16\u53f7\u5217\u8868", +"Decrease indent": "\u51cf\u5c11\u7f29\u8fdb", +"Increase indent": "\u589e\u52a0\u7f29\u8fdb", +"Close": "\u5173\u95ed", +"Formats": "\u683c\u5f0f", +"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "\u4f60\u7684\u6d4f\u89c8\u5668\u4e0d\u652f\u6301\u6253\u5f00\u526a\u8d34\u677f\uff0c\u8bf7\u4f7f\u7528Ctrl+X\/C\/V\u7b49\u5feb\u6377\u952e\u3002", +"Headers": "\u6807\u9898", +"Header 1": "\u6807\u98981", +"Header 2": "\u6807\u98982", +"Header 3": "\u6807\u98983", +"Header 4": "\u6807\u98984", +"Header 5": "\u6807\u98985", +"Header 6": "\u6807\u98986", +"Headings": "\u6807\u9898", +"Heading 1": "\u6807\u98981", +"Heading 2": "\u6807\u98982", +"Heading 3": "\u6807\u98983", +"Heading 4": "\u6807\u98984", +"Heading 5": "\u6807\u98985", +"Heading 6": "\u6807\u98986", +"Preformatted": "\u9884\u5148\u683c\u5f0f\u5316\u7684", +"Div": "Div", +"Pre": "Pre", +"Code": "\u4ee3\u7801", +"Paragraph": "\u6bb5\u843d", +"Blockquote": "\u5f15\u6587\u533a\u5757", +"Inline": "\u6587\u672c", +"Blocks": "\u57fa\u5757", +"Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "\u5f53\u524d\u4e3a\u7eaf\u6587\u672c\u7c98\u8d34\u6a21\u5f0f\uff0c\u518d\u6b21\u70b9\u51fb\u53ef\u4ee5\u56de\u5230\u666e\u901a\u7c98\u8d34\u6a21\u5f0f\u3002", +"Fonts": "\u5b57\u4f53", +"Font Sizes": "\u5b57\u53f7", +"Class": "\u7c7b\u578b", +"Browse for an image": "\u6d4f\u89c8\u56fe\u50cf", +"OR": "\u6216", +"Drop an image here": "\u62d6\u653e\u4e00\u5f20\u56fe\u50cf\u81f3\u6b64", +"Upload": "\u4e0a\u4f20", +"Block": "\u5757", +"Align": "\u5bf9\u9f50", +"Default": "\u9ed8\u8ba4", +"Circle": "\u7a7a\u5fc3\u5706", +"Disc": "\u5b9e\u5fc3\u5706", +"Square": "\u65b9\u5757", +"Lower Alpha": "\u5c0f\u5199\u82f1\u6587\u5b57\u6bcd", +"Lower Greek": "\u5c0f\u5199\u5e0c\u814a\u5b57\u6bcd", +"Lower Roman": "\u5c0f\u5199\u7f57\u9a6c\u5b57\u6bcd", +"Upper Alpha": "\u5927\u5199\u82f1\u6587\u5b57\u6bcd", +"Upper Roman": "\u5927\u5199\u7f57\u9a6c\u5b57\u6bcd", +"Anchor...": "\u951a\u70b9...", +"Name": "\u540d\u79f0", +"Id": "\u6807\u8bc6\u7b26", +"Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "\u6807\u8bc6\u7b26\u5e94\u8be5\u4ee5\u5b57\u6bcd\u5f00\u5934\uff0c\u540e\u8ddf\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u7834\u6298\u53f7\u3001\u70b9\u3001\u5192\u53f7\u6216\u4e0b\u5212\u7ebf\u3002", +"You have unsaved changes are you sure you want to navigate away?": "\u4f60\u8fd8\u6709\u6587\u6863\u5c1a\u672a\u4fdd\u5b58\uff0c\u786e\u5b9a\u8981\u79bb\u5f00\uff1f", +"Restore last draft": "\u6062\u590d\u4e0a\u6b21\u7684\u8349\u7a3f", +"Special characters...": "\u7279\u6b8a\u5b57\u7b26...", +"Source code": "\u6e90\u4ee3\u7801", +"Insert\/Edit code sample": "\u63d2\u5165\/\u7f16\u8f91\u4ee3\u7801\u793a\u4f8b", +"Language": "\u8bed\u8a00", +"Code sample...": "\u793a\u4f8b\u4ee3\u7801...", +"Color Picker": "\u9009\u8272\u5668", +"R": "R", +"G": "G", +"B": "B", +"Left to right": "\u4ece\u5de6\u5230\u53f3", +"Right to left": "\u4ece\u53f3\u5230\u5de6", +"Emoticons...": "\u8868\u60c5\u7b26\u53f7...", +"Metadata and Document Properties": "\u5143\u6570\u636e\u548c\u6587\u6863\u5c5e\u6027", +"Title": "\u6807\u9898", +"Keywords": "\u5173\u952e\u8bcd", +"Description": "\u63cf\u8ff0", +"Robots": "\u673a\u5668\u4eba", +"Author": "\u4f5c\u8005", +"Encoding": "\u7f16\u7801", +"Fullscreen": "\u5168\u5c4f", +"Action": "\u64cd\u4f5c", +"Shortcut": "\u5feb\u6377\u952e", +"Help": "\u5e2e\u52a9", +"Address": "\u5730\u5740", +"Focus to menubar": "\u79fb\u52a8\u7126\u70b9\u5230\u83dc\u5355\u680f", +"Focus to toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u5de5\u5177\u680f", +"Focus to element path": "\u79fb\u52a8\u7126\u70b9\u5230\u5143\u7d20\u8def\u5f84", +"Focus to contextual toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u4e0a\u4e0b\u6587\u83dc\u5355", +"Insert link (if link plugin activated)": "\u63d2\u5165\u94fe\u63a5 (\u5982\u679c\u94fe\u63a5\u63d2\u4ef6\u5df2\u6fc0\u6d3b)", +"Save (if save plugin activated)": "\u4fdd\u5b58(\u5982\u679c\u4fdd\u5b58\u63d2\u4ef6\u5df2\u6fc0\u6d3b)", +"Find (if searchreplace plugin activated)": "\u67e5\u627e(\u5982\u679c\u67e5\u627e\u66ff\u6362\u63d2\u4ef6\u5df2\u6fc0\u6d3b)", +"Plugins installed ({0}):": "\u5df2\u5b89\u88c5\u63d2\u4ef6 ({0}):", +"Premium plugins:": "\u4f18\u79c0\u63d2\u4ef6\uff1a", +"Learn more...": "\u4e86\u89e3\u66f4\u591a...", +"You are using {0}": "\u4f60\u6b63\u5728\u4f7f\u7528 {0}", +"Plugins": "\u63d2\u4ef6", +"Handy Shortcuts": "\u5feb\u6377\u952e", +"Horizontal line": "\u6c34\u5e73\u5206\u5272\u7ebf", +"Insert\/edit image": "\u63d2\u5165\/\u7f16\u8f91\u56fe\u7247", +"Image description": "\u56fe\u7247\u63cf\u8ff0", +"Source": "\u5730\u5740", +"Dimensions": "\u5927\u5c0f", +"Constrain proportions": "\u4fdd\u6301\u7eb5\u6a2a\u6bd4", +"General": "\u666e\u901a", +"Advanced": "\u9ad8\u7ea7", +"Style": "\u6837\u5f0f", +"Vertical space": "\u5782\u76f4\u8fb9\u8ddd", +"Horizontal space": "\u6c34\u5e73\u8fb9\u8ddd", +"Border": "\u8fb9\u6846", +"Insert image": "\u63d2\u5165\u56fe\u7247", +"Image...": "\u56fe\u7247...", +"Image list": "\u56fe\u7247\u5217\u8868", +"Rotate counterclockwise": "\u9006\u65f6\u9488\u65cb\u8f6c", +"Rotate clockwise": "\u987a\u65f6\u9488\u65cb\u8f6c", +"Flip vertically": "\u5782\u76f4\u7ffb\u8f6c", +"Flip horizontally": "\u6c34\u5e73\u7ffb\u8f6c", +"Edit image": "\u7f16\u8f91\u56fe\u7247", +"Image options": "\u56fe\u7247\u9009\u9879", +"Zoom in": "\u653e\u5927", +"Zoom out": "\u7f29\u5c0f", +"Crop": "\u88c1\u526a", +"Resize": "\u8c03\u6574\u5927\u5c0f", +"Orientation": "\u65b9\u5411", +"Brightness": "\u4eae\u5ea6", +"Sharpen": "\u9510\u5316", +"Contrast": "\u5bf9\u6bd4\u5ea6", +"Color levels": "\u989c\u8272\u5c42\u6b21", +"Gamma": "\u4f3d\u9a6c\u503c", +"Invert": "\u53cd\u8f6c", +"Apply": "\u5e94\u7528", +"Back": "\u540e\u9000", +"Insert date\/time": "\u63d2\u5165\u65e5\u671f\/\u65f6\u95f4", +"Date\/time": "\u65e5\u671f\/\u65f6\u95f4", +"Insert\/Edit Link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5", +"Insert\/edit link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5", +"Text to display": "\u663e\u793a\u6587\u5b57", +"Url": "\u5730\u5740", +"Open link in...": "\u94fe\u63a5\u6253\u5f00\u4f4d\u7f6e...", +"Current window": "\u5f53\u524d\u7a97\u53e3", +"None": "\u65e0", +"New window": "\u5728\u65b0\u7a97\u53e3\u6253\u5f00", +"Remove link": "\u5220\u9664\u94fe\u63a5", +"Anchors": "\u951a\u70b9", +"Link...": "\u94fe\u63a5...", +"Paste or type a link": "\u7c98\u8d34\u6216\u8f93\u5165\u94fe\u63a5", +"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u4e3a\u90ae\u4ef6\u5730\u5740\uff0c\u9700\u8981\u52a0\u4e0amailto:\u524d\u7f00\u5417\uff1f", +"The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u5c5e\u4e8e\u5916\u90e8\u94fe\u63a5\uff0c\u9700\u8981\u52a0\u4e0ahttp:\/\/:\u524d\u7f00\u5417\uff1f", +"Link list": "\u94fe\u63a5\u5217\u8868", +"Insert video": "\u63d2\u5165\u89c6\u9891", +"Insert\/edit video": "\u63d2\u5165\/\u7f16\u8f91\u89c6\u9891", +"Insert\/edit media": "\u63d2\u5165\/\u7f16\u8f91\u5a92\u4f53", +"Alternative source": "\u955c\u50cf", +"Alternative source URL": "\u66ff\u4ee3\u6765\u6e90\u7f51\u5740", +"Media poster (Image URL)": "\u5c01\u9762(\u56fe\u7247\u5730\u5740)", +"Paste your embed code below:": "\u5c06\u5185\u5d4c\u4ee3\u7801\u7c98\u8d34\u5728\u4e0b\u9762:", +"Embed": "\u5185\u5d4c", +"Media...": "\u591a\u5a92\u4f53...", +"Nonbreaking space": "\u4e0d\u95f4\u65ad\u7a7a\u683c", +"Page break": "\u5206\u9875\u7b26", +"Paste as text": "\u7c98\u8d34\u4e3a\u6587\u672c", +"Preview": "\u9884\u89c8", +"Print...": "\u6253\u5370...", +"Save": "\u4fdd\u5b58", +"Find": "\u67e5\u627e", +"Replace with": "\u66ff\u6362\u4e3a", +"Replace": "\u66ff\u6362", +"Replace all": "\u5168\u90e8\u66ff\u6362", +"Previous": "\u4e0a\u4e00\u4e2a", +"Next": "\u4e0b\u4e00\u4e2a", +"Find and replace...": "\u67e5\u627e\u5e76\u66ff\u6362...", +"Could not find the specified string.": "\u672a\u627e\u5230\u641c\u7d22\u5185\u5bb9.", +"Match case": "\u533a\u5206\u5927\u5c0f\u5199", +"Find whole words only": "\u5168\u5b57\u5339\u914d", +"Spell check": "\u62fc\u5199\u68c0\u67e5", +"Ignore": "\u5ffd\u7565", +"Ignore all": "\u5168\u90e8\u5ffd\u7565", +"Finish": "\u5b8c\u6210", +"Add to Dictionary": "\u6dfb\u52a0\u5230\u5b57\u5178", +"Insert table": "\u63d2\u5165\u8868\u683c", +"Table properties": "\u8868\u683c\u5c5e\u6027", +"Delete table": "\u5220\u9664\u8868\u683c", +"Cell": "\u5355\u5143\u683c", +"Row": "\u884c", +"Column": "\u5217", +"Cell properties": "\u5355\u5143\u683c\u5c5e\u6027", +"Merge cells": "\u5408\u5e76\u5355\u5143\u683c", +"Split cell": "\u62c6\u5206\u5355\u5143\u683c", +"Insert row before": "\u5728\u4e0a\u65b9\u63d2\u5165", +"Insert row after": "\u5728\u4e0b\u65b9\u63d2\u5165", +"Delete row": "\u5220\u9664\u884c", +"Row properties": "\u884c\u5c5e\u6027", +"Cut row": "\u526a\u5207\u884c", +"Copy row": "\u590d\u5236\u884c", +"Paste row before": "\u7c98\u8d34\u5230\u4e0a\u65b9", +"Paste row after": "\u7c98\u8d34\u5230\u4e0b\u65b9", +"Insert column before": "\u5728\u5de6\u4fa7\u63d2\u5165", +"Insert column after": "\u5728\u53f3\u4fa7\u63d2\u5165", +"Delete column": "\u5220\u9664\u5217", +"Cols": "\u5217", +"Rows": "\u884c", +"Width": "\u5bbd", +"Height": "\u9ad8", +"Cell spacing": "\u5355\u5143\u683c\u5916\u95f4\u8ddd", +"Cell padding": "\u5355\u5143\u683c\u5185\u8fb9\u8ddd", +"Show caption": "\u663e\u793a\u6807\u9898", +"Left": "\u5de6\u5bf9\u9f50", +"Center": "\u5c45\u4e2d", +"Right": "\u53f3\u5bf9\u9f50", +"Cell type": "\u5355\u5143\u683c\u7c7b\u578b", +"Scope": "\u8303\u56f4", +"Alignment": "\u5bf9\u9f50\u65b9\u5f0f", +"H Align": "\u6c34\u5e73\u5bf9\u9f50", +"V Align": "\u5782\u76f4\u5bf9\u9f50", +"Top": "\u9876\u90e8\u5bf9\u9f50", +"Middle": "\u5782\u76f4\u5c45\u4e2d", +"Bottom": "\u5e95\u90e8\u5bf9\u9f50", +"Header cell": "\u8868\u5934\u5355\u5143\u683c", +"Row group": "\u884c\u7ec4", +"Column group": "\u5217\u7ec4", +"Row type": "\u884c\u7c7b\u578b", +"Header": "\u8868\u5934", +"Body": "\u8868\u4f53", +"Footer": "\u8868\u5c3e", +"Border color": "\u8fb9\u6846\u989c\u8272", +"Insert template...": "\u63d2\u5165\u6a21\u677f...", +"Templates": "\u6a21\u677f", +"Template": "\u6a21\u677f", +"Text color": "\u6587\u5b57\u989c\u8272", +"Background color": "\u80cc\u666f\u8272", +"Custom...": "\u81ea\u5b9a\u4e49...", +"Custom color": "\u81ea\u5b9a\u4e49\u989c\u8272", +"No color": "\u65e0", +"Remove color": "\u79fb\u9664\u989c\u8272", +"Table of Contents": "\u5185\u5bb9\u5217\u8868", +"Show blocks": "\u663e\u793a\u533a\u5757\u8fb9\u6846", +"Show invisible characters": "\u663e\u793a\u4e0d\u53ef\u89c1\u5b57\u7b26", +"Word count": "\u5b57\u6570", +"Words: {0}": "\u5b57\u6570\uff1a{0}", +"{0} words": "{0} \u5b57", +"File": "\u6587\u4ef6", +"Edit": "\u7f16\u8f91", +"Insert": "\u63d2\u5165", +"View": "\u89c6\u56fe", +"Format": "\u683c\u5f0f", +"Table": "\u8868\u683c", +"Tools": "\u5de5\u5177", +"Powered by {0}": "\u7531{0}\u9a71\u52a8", +"Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "\u5728\u7f16\u8f91\u533a\u6309ALT-F9\u6253\u5f00\u83dc\u5355\uff0c\u6309ALT-F10\u6253\u5f00\u5de5\u5177\u680f\uff0c\u6309ALT-0\u67e5\u770b\u5e2e\u52a9", +"Image title": "\u56fe\u7247\u6807\u9898", +"Border width": "\u8fb9\u6846\u5bbd\u5ea6", +"Border style": "\u8fb9\u6846\u6837\u5f0f", +"Error": "\u9519\u8bef", +"Warn": "\u8b66\u544a", +"Valid": "\u6709\u6548", +"To open the popup, press Shift+Enter": "\u6309Shitf+Enter\u952e\u6253\u5f00\u5bf9\u8bdd\u6846", +"Rich Text Area. Press ALT-0 for help.": "\u7f16\u8f91\u533a\u3002\u6309Alt+0\u952e\u6253\u5f00\u5e2e\u52a9\u3002", +"System Font": "\u7cfb\u7edf\u5b57\u4f53", +"Failed to upload image: {0}": "\u56fe\u7247\u4e0a\u4f20\u5931\u8d25: {0}", +"Failed to load plugin: {0} from url {1}": "\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25: {0} \u6765\u81ea\u94fe\u63a5 {1}", +"Failed to load plugin url: {0}": "\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25 \u94fe\u63a5: {0}", +"Failed to initialize plugin: {0}": "\u63d2\u4ef6\u521d\u59cb\u5316\u5931\u8d25: {0}", +"example": "\u793a\u4f8b", +"Search": "\u641c\u7d22", +"All": "\u5168\u90e8", +"Currency": "\u8d27\u5e01", +"Text": "\u6587\u5b57", +"Quotations": "\u5f15\u7528", +"Mathematical": "\u6570\u5b66", +"Extended Latin": "\u62c9\u4e01\u8bed\u6269\u5145", +"Symbols": "\u7b26\u53f7", +"Arrows": "\u7bad\u5934", +"User Defined": "\u81ea\u5b9a\u4e49", +"dollar sign": "\u7f8e\u5143\u7b26\u53f7", +"currency sign": "\u8d27\u5e01\u7b26\u53f7", +"euro-currency sign": "\u6b27\u5143\u7b26\u53f7", +"colon sign": "\u5192\u53f7", +"cruzeiro sign": "\u514b\u9c81\u8d5b\u7f57\u5e01\u7b26\u53f7", +"french franc sign": "\u6cd5\u90ce\u7b26\u53f7", +"lira sign": "\u91cc\u62c9\u7b26\u53f7", +"mill sign": "\u5bc6\u5c14\u7b26\u53f7", +"naira sign": "\u5948\u62c9\u7b26\u53f7", +"peseta sign": "\u6bd4\u585e\u5854\u7b26\u53f7", +"rupee sign": "\u5362\u6bd4\u7b26\u53f7", +"won sign": "\u97e9\u5143\u7b26\u53f7", +"new sheqel sign": "\u65b0\u8c22\u514b\u5c14\u7b26\u53f7", +"dong sign": "\u8d8a\u5357\u76fe\u7b26\u53f7", +"kip sign": "\u8001\u631d\u57fa\u666e\u7b26\u53f7", +"tugrik sign": "\u56fe\u683c\u91cc\u514b\u7b26\u53f7", +"drachma sign": "\u5fb7\u62c9\u514b\u9a6c\u7b26\u53f7", +"german penny symbol": "\u5fb7\u56fd\u4fbf\u58eb\u7b26\u53f7", +"peso sign": "\u6bd4\u7d22\u7b26\u53f7", +"guarani sign": "\u74dc\u62c9\u5c3c\u7b26\u53f7", +"austral sign": "\u6fb3\u5143\u7b26\u53f7", +"hryvnia sign": "\u683c\u91cc\u592b\u5c3c\u4e9a\u7b26\u53f7", +"cedi sign": "\u585e\u5730\u7b26\u53f7", +"livre tournois sign": "\u91cc\u5f17\u5f17\u5c14\u7b26\u53f7", +"spesmilo sign": "spesmilo\u7b26\u53f7", +"tenge sign": "\u575a\u6208\u7b26\u53f7", +"indian rupee sign": "\u5370\u5ea6\u5362\u6bd4", +"turkish lira sign": "\u571f\u8033\u5176\u91cc\u62c9", +"nordic mark sign": "\u5317\u6b27\u9a6c\u514b", +"manat sign": "\u9a6c\u7eb3\u7279\u7b26\u53f7", +"ruble sign": "\u5362\u5e03\u7b26\u53f7", +"yen character": "\u65e5\u5143\u5b57\u6837", +"yuan character": "\u4eba\u6c11\u5e01\u5143\u5b57\u6837", +"yuan character, in hong kong and taiwan": "\u5143\u5b57\u6837\uff08\u6e2f\u53f0\u5730\u533a\uff09", +"yen\/yuan character variant one": "\u5143\u5b57\u6837\uff08\u5927\u5199\uff09", +"Loading emoticons...": "\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7...", +"Could not load emoticons": "\u4e0d\u80fd\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7", +"People": "\u4eba\u7c7b", +"Animals and Nature": "\u52a8\u7269\u548c\u81ea\u7136", +"Food and Drink": "\u98df\u7269\u548c\u996e\u54c1", +"Activity": "\u6d3b\u52a8", +"Travel and Places": "\u65c5\u6e38\u548c\u5730\u70b9", +"Objects": "\u7269\u4ef6", +"Flags": "\u65d7\u5e1c", +"Characters": "\u5b57\u7b26", +"Characters (no spaces)": "\u5b57\u7b26(\u65e0\u7a7a\u683c)", +"Error: Form submit field collision.": "\u9519\u8bef: \u8868\u5355\u63d0\u4ea4\u5b57\u6bb5\u51b2\u7a81\u3002", +"Error: No form element found.": "\u9519\u8bef: \u6ca1\u6709\u8868\u5355\u63a7\u4ef6\u3002", +"Update": "\u66f4\u65b0", +"Color swatch": "\u989c\u8272\u6837\u672c", +"Turquoise": "\u9752\u7eff\u8272", +"Green": "\u7eff\u8272", +"Blue": "\u84dd\u8272", +"Purple": "\u7d2b\u8272", +"Navy Blue": "\u6d77\u519b\u84dd", +"Dark Turquoise": "\u6df1\u84dd\u7eff\u8272", +"Dark Green": "\u6df1\u7eff\u8272", +"Medium Blue": "\u4e2d\u84dd\u8272", +"Medium Purple": "\u4e2d\u7d2b\u8272", +"Midnight Blue": "\u6df1\u84dd\u8272", +"Yellow": "\u9ec4\u8272", +"Orange": "\u6a59\u8272", +"Red": "\u7ea2\u8272", +"Light Gray": "\u6d45\u7070\u8272", +"Gray": "\u7070\u8272", +"Dark Yellow": "\u6697\u9ec4\u8272", +"Dark Orange": "\u6df1\u6a59\u8272", +"Dark Red": "\u6df1\u7ea2\u8272", +"Medium Gray": "\u4e2d\u7070\u8272", +"Dark Gray": "\u6df1\u7070\u8272", +"Black": "\u9ed1\u8272", +"White": "\u767d\u8272", +"Switch to or from fullscreen mode": "\u5207\u6362\u5168\u5c4f\u6a21\u5f0f", +"Open help dialog": "\u6253\u5f00\u5e2e\u52a9\u5bf9\u8bdd\u6846", +"history": "\u5386\u53f2", +"styles": "\u6837\u5f0f", +"formatting": "\u683c\u5f0f\u5316", +"alignment": "\u5bf9\u9f50", +"indentation": "\u7f29\u8fdb", +"permanent pen": "\u8bb0\u53f7\u7b14", +"comments": "\u5907\u6ce8", +"Anchor": "\u951a\u70b9", +"Special character": "\u7279\u6b8a\u7b26\u53f7", +"Code sample": "\u4ee3\u7801\u793a\u4f8b", +"Color": "\u989c\u8272", +"Emoticons": "\u8868\u60c5", +"Document properties": "\u6587\u6863\u5c5e\u6027", +"Image": "\u56fe\u7247", +"Insert link": "\u63d2\u5165\u94fe\u63a5", +"Target": "\u6253\u5f00\u65b9\u5f0f", +"Link": "\u94fe\u63a5", +"Poster": "\u5c01\u9762", +"Media": "\u5a92\u4f53", +"Print": "\u6253\u5370", +"Prev": "\u4e0a\u4e00\u4e2a", +"Find and replace": "\u67e5\u627e\u548c\u66ff\u6362", +"Whole words": "\u5168\u5b57\u5339\u914d", +"Spellcheck": "\u62fc\u5199\u68c0\u67e5", +"Caption": "\u6807\u9898", +"Insert template": "\u63d2\u5165\u6a21\u677f" +}); \ No newline at end of file diff --git a/public/resource/tinymce/license.txt b/public/resource/tinymce/license.txt new file mode 100644 index 0000000..3a49f66 --- /dev/null +++ b/public/resource/tinymce/license.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Ephox Corporation DBA Tiny Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/public/resource/tinymce/models/dom/model.min.js b/public/resource/tinymce/models/dom/model.min.js new file mode 100644 index 0000000..323b2c5 --- /dev/null +++ b/public/resource/tinymce/models/dom/model.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.4.2 (2023-04-26) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.ModelManager");const t=e=>t=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(o=n=e,(r=String).prototype.isPrototypeOf(o)||(null===(s=n.constructor)||void 0===s?void 0:s.name)===r.name)?"string":t;var o,n,r,s})(t)===e,o=e=>t=>typeof t===e,n=e=>t=>e===t,r=t("string"),s=t("object"),l=t("array"),a=n(null),c=o("boolean"),i=n(void 0),m=e=>!(e=>null==e)(e),d=o("function"),u=o("number"),f=()=>{},g=e=>()=>e,h=e=>e,p=(e,t)=>e===t;function w(e,...t){return(...o)=>{const n=t.concat(o);return e.apply(null,n)}}const b=e=>t=>!e(t),v=e=>e(),y=g(!1),x=g(!0);class C{constructor(e,t){this.tag=e,this.value=t}static some(e){return new C(!0,e)}static none(){return C.singletonNone}fold(e,t){return this.tag?t(this.value):e()}isSome(){return this.tag}isNone(){return!this.tag}map(e){return this.tag?C.some(e(this.value)):C.none()}bind(e){return this.tag?e(this.value):C.none()}exists(e){return this.tag&&e(this.value)}forall(e){return!this.tag||e(this.value)}filter(e){return!this.tag||e(this.value)?this:C.none()}getOr(e){return this.tag?this.value:e}or(e){return this.tag?this:e}getOrThunk(e){return this.tag?this.value:e()}orThunk(e){return this.tag?this:e()}getOrDie(e){if(this.tag)return this.value;throw new Error(null!=e?e:"Called getOrDie on None")}static from(e){return m(e)?C.some(e):C.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(e){this.tag&&e(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}C.singletonNone=new C(!1);const S=Array.prototype.slice,T=Array.prototype.indexOf,R=Array.prototype.push,D=(e,t)=>{return o=e,n=t,T.call(o,n)>-1;var o,n},O=(e,t)=>{for(let o=0,n=e.length;o{const o=[];for(let n=0;n{const o=e.length,n=new Array(o);for(let r=0;r{for(let o=0,n=e.length;o{const o=[],n=[];for(let r=0,s=e.length;r{const o=[];for(let n=0,r=e.length;n(((e,t)=>{for(let o=e.length-1;o>=0;o--)t(e[o],o)})(e,((e,n)=>{o=t(o,e,n)})),o),L=(e,t,o)=>(N(e,((e,n)=>{o=t(o,e,n)})),o),W=(e,t)=>((e,t,o)=>{for(let n=0,r=e.length;n{for(let o=0,n=e.length;o{const t=[];for(let o=0,n=e.length;o_(E(e,t)),P=(e,t)=>{for(let o=0,n=e.length;o{const o={};for(let n=0,r=e.length;nt>=0&&tF(e,0),q=e=>F(e,e.length-1),V=(e,t)=>{for(let o=0;o{const o=$(e);for(let n=0,r=o.length;nY(e,((e,o)=>({k:o,v:t(e,o)}))),Y=(e,t)=>{const o={};return G(e,((e,n)=>{const r=t(e,n);o[r.k]=r.v})),o},J=(e,t)=>{const o=[];return G(e,((e,n)=>{o.push(t(e,n))})),o},Q=e=>J(e,h),X=(e,t)=>U.call(e,t),Z="undefined"!=typeof window?window:Function("return this;")(),ee=(e,t)=>((e,t)=>{let o=null!=t?t:Z;for(let t=0;t{const t=ee("ownerDocument.defaultView",e);return s(e)&&((e=>((e,t)=>{const o=((e,t)=>ee(e,t))(e,t);if(null==o)throw new Error(e+" not available on this browser");return o})("HTMLElement",e))(t).prototype.isPrototypeOf(e)||/^HTML\w*Element$/.test(te(e).constructor.name))},ne=e=>e.dom.nodeName.toLowerCase(),re=e=>e.dom.nodeType,se=e=>t=>re(t)===e,le=e=>8===re(e)||"#comment"===ne(e),ae=e=>ce(e)&&oe(e.dom),ce=se(1),ie=se(3),me=se(9),de=se(11),ue=e=>t=>ce(t)&&ne(t)===e,fe=(e,t,o)=>{if(!(r(o)||c(o)||u(o)))throw console.error("Invalid call to Attribute.set. Key ",t,":: Value ",o,":: Element ",e),new Error("Attribute value was not simple");e.setAttribute(t,o+"")},ge=(e,t,o)=>{fe(e.dom,t,o)},he=(e,t)=>{const o=e.dom;G(t,((e,t)=>{fe(o,t,e)}))},pe=(e,t)=>{const o=e.dom.getAttribute(t);return null===o?void 0:o},we=(e,t)=>C.from(pe(e,t)),be=(e,t)=>{e.dom.removeAttribute(t)},ve=e=>L(e.dom.attributes,((e,t)=>(e[t.name]=t.value,e)),{}),ye=e=>{if(null==e)throw new Error("Node cannot be null or undefined");return{dom:e}},xe={fromHtml:(e,t)=>{const o=(t||document).createElement("div");if(o.innerHTML=e,!o.hasChildNodes()||o.childNodes.length>1){const t="HTML does not have a single root node";throw console.error(t,e),new Error(t)}return ye(o.childNodes[0])},fromTag:(e,t)=>{const o=(t||document).createElement(e);return ye(o)},fromText:(e,t)=>{const o=(t||document).createTextNode(e);return ye(o)},fromDom:ye,fromPoint:(e,t,o)=>C.from(e.dom.elementFromPoint(t,o)).map(ye)},Ce=(e,t)=>{const o=e.dom;if(1!==o.nodeType)return!1;{const e=o;if(void 0!==e.matches)return e.matches(t);if(void 0!==e.msMatchesSelector)return e.msMatchesSelector(t);if(void 0!==e.webkitMatchesSelector)return e.webkitMatchesSelector(t);if(void 0!==e.mozMatchesSelector)return e.mozMatchesSelector(t);throw new Error("Browser lacks native selectors")}},Se=e=>1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType||0===e.childElementCount,Te=(e,t)=>{const o=void 0===t?document:t.dom;return Se(o)?C.none():C.from(o.querySelector(e)).map(xe.fromDom)},Re=(e,t)=>e.dom===t.dom,De=(e,t)=>{const o=e.dom,n=t.dom;return o!==n&&o.contains(n)},Oe=Ce,ke=e=>xe.fromDom(e.dom.ownerDocument),Ee=e=>me(e)?e:ke(e),Ne=e=>C.from(e.dom.parentNode).map(xe.fromDom),Be=e=>C.from(e.dom.parentElement).map(xe.fromDom),ze=(e,t)=>{const o=d(t)?t:y;let n=e.dom;const r=[];for(;null!==n.parentNode&&void 0!==n.parentNode;){const e=n.parentNode,t=xe.fromDom(e);if(r.push(t),!0===o(t))break;n=e}return r},Ae=e=>C.from(e.dom.previousSibling).map(xe.fromDom),Le=e=>C.from(e.dom.nextSibling).map(xe.fromDom),We=e=>E(e.dom.childNodes,xe.fromDom),Me=(e,t)=>{const o=e.dom.childNodes;return C.from(o[t]).map(xe.fromDom)},_e=(e,t)=>{Ne(e).each((o=>{o.dom.insertBefore(t.dom,e.dom)}))},je=(e,t)=>{Le(e).fold((()=>{Ne(e).each((e=>{Ie(e,t)}))}),(e=>{_e(e,t)}))},Pe=(e,t)=>{const o=(e=>Me(e,0))(e);o.fold((()=>{Ie(e,t)}),(o=>{e.dom.insertBefore(t.dom,o.dom)}))},Ie=(e,t)=>{e.dom.appendChild(t.dom)},Fe=(e,t)=>{_e(e,t),Ie(t,e)},He=(e,t)=>{N(t,((o,n)=>{const r=0===n?e:t[n-1];je(r,o)}))},qe=(e,t)=>{N(t,(t=>{Ie(e,t)}))},Ve=e=>{e.dom.textContent="",N(We(e),(e=>{$e(e)}))},$e=e=>{const t=e.dom;null!==t.parentNode&&t.parentNode.removeChild(t)},Ue=e=>{const t=We(e);t.length>0&&He(e,t),$e(e)},Ge=(e,t)=>xe.fromDom(e.dom.cloneNode(t)),Ke=e=>Ge(e,!1),Ye=e=>Ge(e,!0),Je=(e,t)=>{const o=xe.fromTag(t),n=ve(e);return he(o,n),o},Qe=["tfoot","thead","tbody","colgroup"],Xe=(e,t,o)=>({element:e,rowspan:t,colspan:o}),Ze=(e,t,o)=>({element:e,cells:t,section:o}),et=(e,t,o)=>({element:e,isNew:t,isLocked:o}),tt=(e,t,o,n)=>({element:e,cells:t,section:o,isNew:n}),ot=d(Element.prototype.attachShadow)&&d(Node.prototype.getRootNode),nt=g(ot),rt=ot?e=>xe.fromDom(e.dom.getRootNode()):Ee,st=e=>xe.fromDom(e.dom.host),lt=e=>{const t=ie(e)?e.dom.parentNode:e.dom;if(null==t||null===t.ownerDocument)return!1;const o=t.ownerDocument;return(e=>{const t=rt(e);return de(o=t)&&m(o.dom.host)?C.some(t):C.none();var o})(xe.fromDom(t)).fold((()=>o.body.contains(t)),(n=lt,r=st,e=>n(r(e))));var n,r},at=e=>{const t=e.dom.body;if(null==t)throw new Error("Body is not available yet");return xe.fromDom(t)},ct=(e,t)=>{let o=[];return N(We(e),(e=>{t(e)&&(o=o.concat([e])),o=o.concat(ct(e,t))})),o},it=(e,t,o)=>((e,o,n)=>z(ze(e,n),(e=>Ce(e,t))))(e,0,o),mt=(e,t)=>((e,o)=>z(We(e),(e=>Ce(e,t))))(e),dt=(e,t)=>((e,t)=>{const o=void 0===t?document:t.dom;return Se(o)?[]:E(o.querySelectorAll(e),xe.fromDom)})(t,e);var ut=(e,t,o,n,r)=>e(o,n)?C.some(o):d(r)&&r(o)?C.none():t(o,n,r);const ft=(e,t,o)=>{let n=e.dom;const r=d(o)?o:y;for(;n.parentNode;){n=n.parentNode;const e=xe.fromDom(n);if(t(e))return C.some(e);if(r(e))break}return C.none()},gt=(e,t,o)=>ut(((e,t)=>t(e)),ft,e,t,o),ht=(e,t,o)=>ft(e,(e=>Ce(e,t)),o),pt=(e,t)=>((e,o)=>W(e.dom.childNodes,(e=>{return o=xe.fromDom(e),Ce(o,t);var o})).map(xe.fromDom))(e),wt=(e,t)=>Te(t,e),bt=(e,t,o)=>ut(((e,t)=>Ce(e,t)),ht,e,t,o),vt=(e,t,o=p)=>e.exists((e=>o(e,t))),yt=e=>{const t=[],o=e=>{t.push(e)};for(let t=0;te?C.some(t):C.none(),Ct=(e,t,o)=>""===t||e.length>=t.length&&e.substr(o,o+t.length)===t,St=(e,t,o=0,n)=>{const r=e.indexOf(t,o);return-1!==r&&(!!i(n)||r+t.length<=n)},Tt=(e,t)=>Ct(e,t,0),Rt=(e,t)=>Ct(e,t,e.length-t.length),Dt=(e=>t=>t.replace(e,""))(/^\s+|\s+$/g),Ot=e=>e.length>0,kt=e=>void 0!==e.style&&d(e.style.getPropertyValue),Et=(e,t,o)=>{if(!r(o))throw console.error("Invalid call to CSS.set. Property ",t,":: Value ",o,":: Element ",e),new Error("CSS value must be a string: "+o);kt(e)&&e.style.setProperty(t,o)},Nt=(e,t,o)=>{const n=e.dom;Et(n,t,o)},Bt=(e,t)=>{const o=e.dom;G(t,((e,t)=>{Et(o,t,e)}))},zt=(e,t)=>{const o=e.dom,n=window.getComputedStyle(o).getPropertyValue(t);return""!==n||lt(e)?n:At(o,t)},At=(e,t)=>kt(e)?e.style.getPropertyValue(t):"",Lt=(e,t)=>{const o=e.dom,n=At(o,t);return C.from(n).filter((e=>e.length>0))},Wt=(e,t)=>{((e,t)=>{kt(e)&&e.style.removeProperty(t)})(e.dom,t),vt(we(e,"style").map(Dt),"")&&be(e,"style")},Mt=(e,t,o=0)=>we(e,t).map((e=>parseInt(e,10))).getOr(o),_t=(e,t)=>Mt(e,t,1),jt=e=>ue("col")(e)?Mt(e,"span",1)>1:_t(e,"colspan")>1,Pt=e=>_t(e,"rowspan")>1,It=(e,t)=>parseInt(zt(e,t),10),Ft=g(10),Ht=g(10),qt=(e,t)=>Vt(e,t,x),Vt=(e,t,o)=>j(We(e),(e=>Ce(e,t)?o(e)?[e]:[]:Vt(e,t,o))),$t=(e,t)=>((e,t,o=y)=>o(t)?C.none():D(e,ne(t))?C.some(t):ht(t,e.join(","),(e=>Ce(e,"table")||o(e))))(["td","th"],e,t),Ut=e=>qt(e,"th,td"),Gt=e=>Ce(e,"colgroup")?mt(e,"col"):j(Jt(e),(e=>mt(e,"col"))),Kt=(e,t)=>bt(e,"table",t),Yt=e=>qt(e,"tr"),Jt=e=>Kt(e).fold(g([]),(e=>mt(e,"colgroup"))),Qt=(e,t)=>E(e,(e=>{if("colgroup"===ne(e)){const t=E(Gt(e),(e=>{const t=Mt(e,"span",1);return Xe(e,1,t)}));return Ze(e,t,"colgroup")}{const o=E(Ut(e),(e=>{const t=Mt(e,"rowspan",1),o=Mt(e,"colspan",1);return Xe(e,t,o)}));return Ze(e,o,t(e))}})),Xt=e=>Ne(e).map((e=>{const t=ne(e);return(e=>D(Qe,e))(t)?t:"tbody"})).getOr("tbody"),Zt=e=>{const t=Yt(e),o=[...Jt(e),...t];return Qt(o,Xt)},eo=e=>{let t,o=!1;return(...n)=>(o||(o=!0,t=e.apply(null,n)),t)},to=()=>oo(0,0),oo=(e,t)=>({major:e,minor:t}),no={nu:oo,detect:(e,t)=>{const o=String(t).toLowerCase();return 0===e.length?to():((e,t)=>{const o=((e,t)=>{for(let o=0;oNumber(t.replace(o,"$"+e));return oo(n(1),n(2))})(e,o)},unknown:to},ro=(e,t)=>{const o=String(t).toLowerCase();return W(e,(e=>e.search(o)))},so=/.*?version\/\ ?([0-9]+)\.([0-9]+).*/,lo=e=>t=>St(t,e),ao=[{name:"Edge",versionRegexes:[/.*?edge\/ ?([0-9]+)\.([0-9]+)$/],search:e=>St(e,"edge/")&&St(e,"chrome")&&St(e,"safari")&&St(e,"applewebkit")},{name:"Chromium",brand:"Chromium",versionRegexes:[/.*?chrome\/([0-9]+)\.([0-9]+).*/,so],search:e=>St(e,"chrome")&&!St(e,"chromeframe")},{name:"IE",versionRegexes:[/.*?msie\ ?([0-9]+)\.([0-9]+).*/,/.*?rv:([0-9]+)\.([0-9]+).*/],search:e=>St(e,"msie")||St(e,"trident")},{name:"Opera",versionRegexes:[so,/.*?opera\/([0-9]+)\.([0-9]+).*/],search:lo("opera")},{name:"Firefox",versionRegexes:[/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/],search:lo("firefox")},{name:"Safari",versionRegexes:[so,/.*?cpu os ([0-9]+)_([0-9]+).*/],search:e=>(St(e,"safari")||St(e,"mobile/"))&&St(e,"applewebkit")}],co=[{name:"Windows",search:lo("win"),versionRegexes:[/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/]},{name:"iOS",search:e=>St(e,"iphone")||St(e,"ipad"),versionRegexes:[/.*?version\/\ ?([0-9]+)\.([0-9]+).*/,/.*cpu os ([0-9]+)_([0-9]+).*/,/.*cpu iphone os ([0-9]+)_([0-9]+).*/]},{name:"Android",search:lo("android"),versionRegexes:[/.*?android\ ?([0-9]+)\.([0-9]+).*/]},{name:"macOS",search:lo("mac os x"),versionRegexes:[/.*?mac\ os\ x\ ?([0-9]+)_([0-9]+).*/]},{name:"Linux",search:lo("linux"),versionRegexes:[]},{name:"Solaris",search:lo("sunos"),versionRegexes:[]},{name:"FreeBSD",search:lo("freebsd"),versionRegexes:[]},{name:"ChromeOS",search:lo("cros"),versionRegexes:[/.*?chrome\/([0-9]+)\.([0-9]+).*/]}],io={browsers:g(ao),oses:g(co)},mo="Edge",uo="Chromium",fo="Opera",go="Firefox",ho="Safari",po=e=>{const t=e.current,o=e.version,n=e=>()=>t===e;return{current:t,version:o,isEdge:n(mo),isChromium:n(uo),isIE:n("IE"),isOpera:n(fo),isFirefox:n(go),isSafari:n(ho)}},wo=()=>po({current:void 0,version:no.unknown()}),bo=po,vo=(g(mo),g(uo),g("IE"),g(fo),g(go),g(ho),"Windows"),yo="Android",xo="Linux",Co="macOS",So="Solaris",To="FreeBSD",Ro="ChromeOS",Do=e=>{const t=e.current,o=e.version,n=e=>()=>t===e;return{current:t,version:o,isWindows:n(vo),isiOS:n("iOS"),isAndroid:n(yo),isMacOS:n(Co),isLinux:n(xo),isSolaris:n(So),isFreeBSD:n(To),isChromeOS:n(Ro)}},Oo=()=>Do({current:void 0,version:no.unknown()}),ko=Do,Eo=(g(vo),g("iOS"),g(yo),g(xo),g(Co),g(So),g(To),g(Ro),e=>window.matchMedia(e).matches);let No=eo((()=>((e,t,o)=>{const n=io.browsers(),r=io.oses(),s=t.bind((e=>((e,t)=>V(t.brands,(t=>{const o=t.brand.toLowerCase();return W(e,(e=>{var t;return o===(null===(t=e.brand)||void 0===t?void 0:t.toLowerCase())})).map((e=>({current:e.name,version:no.nu(parseInt(t.version,10),0)})))})))(n,e))).orThunk((()=>((e,t)=>ro(e,t).map((e=>{const o=no.detect(e.versionRegexes,t);return{current:e.name,version:o}})))(n,e))).fold(wo,bo),l=((e,t)=>ro(e,t).map((e=>{const o=no.detect(e.versionRegexes,t);return{current:e.name,version:o}})))(r,e).fold(Oo,ko),a=((e,t,o,n)=>{const r=e.isiOS()&&!0===/ipad/i.test(o),s=e.isiOS()&&!r,l=e.isiOS()||e.isAndroid(),a=l||n("(pointer:coarse)"),c=r||!s&&l&&n("(min-device-width:768px)"),i=s||l&&!c,m=t.isSafari()&&e.isiOS()&&!1===/safari/i.test(o),d=!i&&!c&&!m;return{isiPad:g(r),isiPhone:g(s),isTablet:g(c),isPhone:g(i),isTouch:g(a),isAndroid:e.isAndroid,isiOS:e.isiOS,isWebView:g(m),isDesktop:g(d)}})(l,s,e,o);return{browser:s,os:l,deviceType:a}})(navigator.userAgent,C.from(navigator.userAgentData),Eo)));const Bo=()=>No(),zo=(e,t)=>{const o=o=>{const n=t(o);if(n<=0||null===n){const t=zt(o,e);return parseFloat(t)||0}return n},n=(e,t)=>L(t,((t,o)=>{const n=zt(e,o),r=void 0===n?0:parseInt(n,10);return isNaN(r)?t:t+r}),0);return{set:(t,o)=>{if(!u(o)&&!o.match(/^[0-9]+$/))throw new Error(e+".set accepts only positive integer values. Value was "+o);const n=t.dom;kt(n)&&(n.style[e]=o+"px")},get:o,getOuter:o,aggregate:n,max:(e,t,o)=>{const r=n(e,o);return t>r?t-r:0}}},Ao=(e,t,o)=>((e,t)=>(e=>{const t=parseFloat(e);return isNaN(t)?C.none():C.some(t)})(e).getOr(t))(zt(e,t),o),Lo=zo("width",(e=>e.dom.offsetWidth)),Wo=e=>Lo.get(e),Mo=e=>Lo.getOuter(e),_o=e=>((e,t)=>{const o=e.dom,n=o.getBoundingClientRect().width||o.offsetWidth;return"border-box"===t?n:((e,t,o,n)=>t-Ao(e,"padding-left",0)-Ao(e,"padding-right",0)-Ao(e,"border-left-width",0)-Ao(e,"border-right-width",0))(e,n)})(e,"content-box"),jo=(e,t,o)=>{const n=e.cells,r=n.slice(0,t),s=n.slice(t),l=r.concat(o).concat(s);return Fo(e,l)},Po=(e,t,o)=>jo(e,t,[o]),Io=(e,t,o)=>{e.cells[t]=o},Fo=(e,t)=>tt(e.element,t,e.section,e.isNew),Ho=(e,t)=>e.cells[t],qo=(e,t)=>Ho(e,t).element,Vo=e=>e.cells.length,$o=e=>{const t=B(e,(e=>"colgroup"===e.section));return{rows:t.fail,cols:t.pass}},Uo=(e,t,o)=>{const n=E(e.cells,o);return tt(t(e.element),n,e.section,!0)},Go="data-snooker-locked-cols",Ko=e=>we(e,Go).bind((e=>C.from(e.match(/\d+/g)))).map((e=>I(e,x))),Yo=e=>{const t=L($o(e).rows,((e,t)=>(N(t.cells,((t,o)=>{t.isLocked&&(e[o]=!0)})),e)),{}),o=J(t,((e,t)=>parseInt(t,10)));return((e,t)=>{const o=S.call(e,0);return o.sort(void 0),o})(o)},Jo=(e,t)=>e+","+t,Qo=(e,t)=>{const o=j(e.all,(e=>e.cells));return z(o,t)},Xo=e=>{const t={},o=[],n=H(e).map((e=>e.element)).bind(Kt).bind(Ko).getOr({});let r=0,s=0,l=0;const{pass:a,fail:c}=B(e,(e=>"colgroup"===e.section));N(c,(e=>{const a=[];N(e.cells,(e=>{let o=0;for(;void 0!==t[Jo(l,o)];)o++;const r=((e,t)=>X(e,t)&&void 0!==e[t]&&null!==e[t])(n,o.toString()),c=((e,t,o,n,r,s)=>({element:e,rowspan:t,colspan:o,row:n,column:r,isLocked:s}))(e.element,e.rowspan,e.colspan,l,o,r);for(let n=0;n{const t=(e=>{const t={};let o=0;return N(e.cells,(e=>{const n=e.colspan;k(n,(r=>{const s=o+r;t[s]=((e,t,o)=>({element:e,colspan:t,column:o}))(e.element,n,s)})),o+=n})),t})(e),o=((e,t)=>({element:e,columns:t}))(e.element,Q(t));return{colgroups:[o],columns:t}})).getOrThunk((()=>({colgroups:[],columns:{}}))),d=((e,t)=>({rows:e,columns:t}))(r,s);return{grid:d,access:t,all:o,columns:i,colgroups:m}},Zo=e=>{const t=Zt(e);return Xo(t)},en=Xo,tn=(e,t,o)=>C.from(e.access[Jo(t,o)]),on=(e,t,o)=>{const n=Qo(e,(e=>o(t,e.element)));return n.length>0?C.some(n[0]):C.none()},nn=Qo,rn=e=>j(e.all,(e=>e.cells)),sn=e=>Q(e.columns),ln=e=>$(e.columns).length>0,an=(e,t)=>C.from(e.columns[t]),cn=(e,t=x)=>{const o=e.grid,n=k(o.columns,h),r=k(o.rows,h);return E(n,(o=>mn((()=>j(r,(t=>tn(e,t,o).filter((e=>e.column===o)).toArray()))),(e=>1===e.colspan&&t(e.element)),(()=>tn(e,0,o)))))},mn=(e,t,o)=>{const n=e();return W(n,t).orThunk((()=>C.from(n[0]).orThunk(o))).map((e=>e.element))},dn=e=>{const t=e.grid,o=k(t.rows,h),n=k(t.columns,h);return E(o,(t=>mn((()=>j(n,(o=>tn(e,t,o).filter((e=>e.row===t)).fold(g([]),(e=>[e]))))),(e=>1===e.rowspan),(()=>tn(e,t,0)))))},un=(e,t)=>o=>"rtl"===fn(o)?t:e,fn=e=>"rtl"===zt(e,"direction")?"rtl":"ltr",gn=zo("height",(e=>{const t=e.dom;return lt(e)?t.getBoundingClientRect().height:t.offsetHeight})),hn=e=>gn.get(e),pn=e=>gn.getOuter(e),wn=(e,t)=>({left:e,top:t,translate:(o,n)=>wn(e+o,t+n)}),bn=wn,vn=(e,t)=>void 0!==e?e:void 0!==t?t:0,yn=e=>{const t=e.dom.ownerDocument,o=t.body,n=t.defaultView,r=t.documentElement;if(o===e.dom)return bn(o.offsetLeft,o.offsetTop);const s=vn(null==n?void 0:n.pageYOffset,r.scrollTop),l=vn(null==n?void 0:n.pageXOffset,r.scrollLeft),a=vn(r.clientTop,o.clientTop),c=vn(r.clientLeft,o.clientLeft);return xn(e).translate(l-c,s-a)},xn=e=>{const t=e.dom,o=t.ownerDocument.body;return o===t?bn(o.offsetLeft,o.offsetTop):lt(e)?(e=>{const t=e.getBoundingClientRect();return bn(t.left,t.top)})(t):bn(0,0)},Cn=(e,t)=>({row:e,y:t}),Sn=(e,t)=>({col:e,x:t}),Tn=e=>yn(e).left+Mo(e),Rn=e=>yn(e).left,Dn=(e,t)=>Sn(e,Rn(t)),On=(e,t)=>Sn(e,Tn(t)),kn=e=>yn(e).top,En=(e,t)=>Cn(e,kn(t)),Nn=(e,t)=>Cn(e,kn(t)+pn(t)),Bn=(e,t,o)=>{if(0===o.length)return[];const n=E(o.slice(1),((t,o)=>t.map((t=>e(o,t))))),r=o[o.length-1].map((e=>t(o.length-1,e)));return n.concat([r])},zn={delta:h,positions:e=>Bn(En,Nn,e),edge:kn},An=un({delta:h,edge:Rn,positions:e=>Bn(Dn,On,e)},{delta:e=>-e,edge:Tn,positions:e=>Bn(On,Dn,e)}),Ln={delta:(e,t)=>An(t).delta(e,t),positions:(e,t)=>An(t).positions(e,t),edge:e=>An(e).edge(e)},Wn={unsupportedLength:["em","ex","cap","ch","ic","rem","lh","rlh","vw","vh","vi","vb","vmin","vmax","cm","mm","Q","in","pc","pt","px"],fixed:["px","pt"],relative:["%"],empty:[""]},Mn=(()=>{const e="[0-9]+",t="[eE][+-]?[0-9]+",o=e=>`(?:${e})?`,n=["Infinity","[0-9]+\\."+o(e)+o(t),"\\.[0-9]+"+o(t),e+o(t)].join("|");return new RegExp(`^([+-]?(?:${n}))(.*)$`)})(),_n=/(\d+(\.\d+)?)%/,jn=/(\d+(\.\d+)?)px|em/,Pn=ue("col"),In=(e,t,o)=>{const n=Be(e).getOrThunk((()=>at(ke(e))));return t(e)/o(n)*100},Fn=(e,t)=>{Nt(e,"width",t+"px")},Hn=(e,t)=>{Nt(e,"width",t+"%")},qn=(e,t)=>{Nt(e,"height",t+"px")},Vn=e=>{const t=(e=>{return Ao(t=e,"height",t.dom.offsetHeight)+"px";var t})(e);return t?((e,t,o,n)=>{const r=parseFloat(e);return Rt(e,"%")&&"table"!==ne(t)?((e,t,o,n)=>{const r=Kt(e).map((e=>{const n=o(e);return Math.floor(t/100*n)})).getOr(t);return n(e,r),r})(t,r,o,n):r})(t,e,hn,qn):hn(e)},$n=(e,t)=>Lt(e,t).orThunk((()=>we(e,t).map((e=>e+"px")))),Un=e=>$n(e,"width"),Gn=e=>In(e,Wo,_o),Kn=e=>{return Pn(e)?Wo(e):Ao(t=e,"width",t.dom.offsetWidth);var t},Yn=e=>((e,t,o)=>o(e)/_t(e,"rowspan"))(e,0,Vn),Jn=(e,t,o)=>{Nt(e,"width",t+o)},Qn=e=>In(e,Wo,_o)+"%",Xn=g(_n),Zn=ue("col"),er=e=>Un(e).getOrThunk((()=>Kn(e)+"px")),tr=e=>{return(t=e,$n(t,"height")).getOrThunk((()=>Yn(e)+"px"));var t},or=(e,t,o,n,r,s)=>e.filter(n).fold((()=>s(((e,t)=>{if(t<0||t>=e.length-1)return C.none();const o=e[t].fold((()=>{const o=(e=>{const t=S.call(e,0);return t.reverse(),t})(e.slice(0,t));return V(o,((e,t)=>e.map((e=>({value:e,delta:t+1})))))}),(e=>C.some({value:e,delta:0}))),n=e[t+1].fold((()=>{const o=e.slice(t+1);return V(o,((e,t)=>e.map((e=>({value:e,delta:t+1})))))}),(e=>C.some({value:e,delta:1})));return o.bind((e=>n.map((t=>{const o=t.delta+e.delta;return Math.abs(t.value-e.value)/o}))))})(o,t))),(e=>r(e))),nr=(e,t,o,n)=>{const r=cn(e),s=ln(e)?(e=>E(sn(e),(e=>C.from(e.element))))(e):r,l=[C.some(Ln.edge(t))].concat(E(Ln.positions(r,t),(e=>e.map((e=>e.x))))),a=b(jt);return E(s,((e,t)=>or(e,t,l,a,(e=>{if((e=>{const t=Bo().browser,o=t.isChromium()||t.isFirefox();return!Zn(e)||o})(e))return o(e);{const e=null!=(s=r[t])?h(s):C.none();return or(e,t,l,a,(e=>n(C.some(Wo(e)))),n)}var s}),n)))},rr=e=>e.map((e=>e+"px")).getOr(""),sr=(e,t,o)=>nr(e,t,Kn,(e=>e.getOrThunk(o.minCellWidth))),lr=(e,t,o,n,r)=>{const s=dn(e),l=[C.some(o.edge(t))].concat(E(o.positions(s,t),(e=>e.map((e=>e.y)))));return E(s,((e,t)=>or(e,t,l,b(Pt),n,r)))},ar=(e,t)=>()=>lt(e)?t(e):parseFloat(Lt(e,"width").getOr("0")),cr=e=>{const t=ar(e,(e=>parseFloat(Qn(e)))),o=ar(e,Wo);return{width:t,pixelWidth:o,getWidths:(t,o)=>((e,t,o)=>nr(e,t,Gn,(e=>e.fold((()=>o.minCellWidth()),(e=>e/o.pixelWidth()*100)))))(t,e,o),getCellDelta:e=>e/o()*100,singleColumnWidth:(e,t)=>[100-e],minCellWidth:()=>Ft()/o()*100,setElementWidth:Hn,adjustTableWidth:o=>{const n=t();Hn(e,n+o/100*n)},isRelative:!0,label:"percent"}},ir=e=>{const t=ar(e,Wo);return{width:t,pixelWidth:t,getWidths:(t,o)=>sr(t,e,o),getCellDelta:h,singleColumnWidth:(e,t)=>[Math.max(Ft(),e+t)-e],minCellWidth:Ft,setElementWidth:Fn,adjustTableWidth:o=>{const n=t()+o;Fn(e,n)},isRelative:!1,label:"pixel"}},mr=e=>Un(e).fold((()=>(e=>{const t=ar(e,Wo),o=g(0);return{width:t,pixelWidth:t,getWidths:(t,o)=>sr(t,e,o),getCellDelta:o,singleColumnWidth:g([0]),minCellWidth:o,setElementWidth:f,adjustTableWidth:f,isRelative:!0,label:"none"}})(e)),(t=>((e,t)=>null!==Xn().exec(t)?cr(e):ir(e))(e,t))),dr=ir,ur=cr,fr=(e,t,o)=>{const n=e[o].element,r=xe.fromTag("td");Ie(r,xe.fromTag("br")),(t?Ie:Pe)(n,r)},gr=((e,t)=>{const o=t=>e(t)?C.from(t.dom.nodeValue):C.none();return{get:t=>{if(!e(t))throw new Error("Can only get text value of a text node");return o(t).getOr("")},getOption:o,set:(t,o)=>{if(!e(t))throw new Error("Can only set raw text value of a text node");t.dom.nodeValue=o}}})(ie),hr=e=>gr.get(e),pr=e=>gr.getOption(e),wr=(e,t)=>gr.set(e,t),br=e=>"img"===ne(e)?1:pr(e).fold((()=>We(e).length),(e=>e.length)),vr=["img","br"],yr=e=>pr(e).filter((e=>0!==e.trim().length||e.indexOf("\xa0")>-1)).isSome()||D(vr,ne(e))||(e=>ae(e)&&"false"===pe(e,"contenteditable"))(e),xr=e=>((e,t)=>{const o=e=>{for(let n=0;nSr(e,yr),Sr=(e,t)=>{const o=e=>{const n=We(e);for(let e=n.length-1;e>=0;e--){const r=n[e];if(t(r))return C.some(r);const s=o(r);if(s.isSome())return s}return C.none()};return o(e)},Tr={scope:["row","col"]},Rr=e=>()=>{const t=xe.fromTag("td",e.dom);return Ie(t,xe.fromTag("br",e.dom)),t},Dr=e=>()=>xe.fromTag("col",e.dom),Or=e=>()=>xe.fromTag("colgroup",e.dom),kr=e=>()=>xe.fromTag("tr",e.dom),Er=(e,t,o)=>{const n=((e,t)=>{const o=Je(e,t),n=We(Ye(e));return qe(o,n),o})(e,t);return G(o,((e,t)=>{null===e?be(n,t):ge(n,t,e)})),n},Nr=e=>e,Br=(e,t,o)=>{const n=(e,t)=>{((e,t)=>{const o=e.dom,n=t.dom;kt(o)&&kt(n)&&(n.style.cssText=o.style.cssText)})(e.element,t),Wt(t,"height"),1!==e.colspan&&Wt(t,"width")};return{col:o=>{const r=xe.fromTag(ne(o.element),t.dom);return n(o,r),e(o.element,r),r},colgroup:Or(t),row:kr(t),cell:r=>{const s=xe.fromTag(ne(r.element),t.dom),l=o.getOr(["strong","em","b","i","span","font","h1","h2","h3","h4","h5","h6","p","div"]),a=l.length>0?((e,t,o)=>xr(e).map((n=>{const r=o.join(","),s=it(n,r,(t=>Re(t,e)));return A(s,((e,t)=>{const o=Ke(t);return Ie(e,o),o}),t)})).getOr(t))(r.element,s,l):s;return Ie(a,xe.fromTag("br")),n(r,s),((e,t)=>{G(Tr,((o,n)=>we(e,n).filter((e=>D(o,e))).each((e=>ge(t,n,e)))))})(r.element,s),e(r.element,s),s},replace:Er,colGap:Dr(t),gap:Rr(t)}},zr=e=>({col:Dr(e),colgroup:Or(e),row:kr(e),cell:Rr(e),replace:Nr,colGap:Dr(e),gap:Rr(e)}),Ar=e=>bt(e,"[contenteditable]"),Lr=(e,t=!1)=>lt(e)?e.dom.isContentEditable:Ar(e).fold(g(t),(e=>"true"===Wr(e))),Wr=e=>e.dom.contentEditable,Mr=e=>xe.fromDom(e.getBody()),_r=e=>t=>Re(t,Mr(e)),jr=e=>{be(e,"data-mce-style");const t=e=>be(e,"data-mce-style");N(Ut(e),t),N(Gt(e),t),N(Yt(e),t)},Pr=e=>xe.fromDom(e.selection.getStart()),Ir=e=>e.getBoundingClientRect().width,Fr=e=>e.getBoundingClientRect().height,Hr=e=>gt(e,ue("table")).exists(Lr),qr=(e,t)=>{const o=t.column,n=t.column+t.colspan-1,r=t.row,s=t.row+t.rowspan-1;return o<=e.finishCol&&n>=e.startCol&&r<=e.finishRow&&s>=e.startRow},Vr=(e,t)=>t.column>=e.startCol&&t.column+t.colspan-1<=e.finishCol&&t.row>=e.startRow&&t.row+t.rowspan-1<=e.finishRow,$r=(e,t,o)=>{const n=on(e,t,Re),r=on(e,o,Re);return n.bind((e=>r.map((t=>{return o=e,n=t,{startRow:Math.min(o.row,n.row),startCol:Math.min(o.column,n.column),finishRow:Math.max(o.row+o.rowspan-1,n.row+n.rowspan-1),finishCol:Math.max(o.column+o.colspan-1,n.column+n.colspan-1)};var o,n}))))},Ur=(e,t,o)=>$r(e,t,o).map((t=>{const o=nn(e,w(qr,t));return E(o,(e=>e.element))})),Gr=(e,t)=>on(e,t,((e,t)=>De(t,e))).map((e=>e.element)),Kr=(e,t,o)=>{const n=Jr(e);return Ur(n,t,o)},Yr=(e,t,o,n,r)=>{const s=Jr(e),l=Re(e,o)?C.some(t):Gr(s,t),a=Re(e,r)?C.some(n):Gr(s,n);return l.bind((e=>a.bind((t=>Ur(s,e,t)))))},Jr=Zo;var Qr=["body","p","div","article","aside","figcaption","figure","footer","header","nav","section","ol","ul","li","table","thead","tbody","tfoot","caption","tr","td","th","h1","h2","h3","h4","h5","h6","blockquote","pre","address"],Xr=()=>({up:g({selector:ht,closest:bt,predicate:ft,all:ze}),down:g({selector:dt,predicate:ct}),styles:g({get:zt,getRaw:Lt,set:Nt,remove:Wt}),attrs:g({get:pe,set:ge,remove:be,copyTo:(e,t)=>{const o=ve(e);he(t,o)}}),insert:g({before:_e,after:je,afterAll:He,append:Ie,appendAll:qe,prepend:Pe,wrap:Fe}),remove:g({unwrap:Ue,remove:$e}),create:g({nu:xe.fromTag,clone:e=>xe.fromDom(e.dom.cloneNode(!1)),text:xe.fromText}),query:g({comparePosition:(e,t)=>e.dom.compareDocumentPosition(t.dom),prevSibling:Ae,nextSibling:Le}),property:g({children:We,name:ne,parent:Ne,document:e=>Ee(e).dom,isText:ie,isComment:le,isElement:ce,isSpecial:e=>{const t=ne(e);return D(["script","noscript","iframe","noframes","noembed","title","style","textarea","xmp"],t)},getLanguage:e=>ce(e)?we(e,"lang"):C.none(),getText:hr,setText:wr,isBoundary:e=>!!ce(e)&&("body"===ne(e)||D(Qr,ne(e))),isEmptyTag:e=>!!ce(e)&&D(["br","img","hr","input"],ne(e)),isNonEditable:e=>ce(e)&&"false"===pe(e,"contenteditable")}),eq:Re,is:Oe});const Zr=(e,t,o,n)=>{const r=t(e,o);return A(n,((o,n)=>{const r=t(e,n);return es(e,o,r)}),r)},es=(e,t,o)=>t.bind((t=>o.filter(w(e.eq,t)))),ts=Xr(),os=(e,t)=>((e,t,o)=>o.length>0?((e,t,o,n)=>n(e,t,o[0],o.slice(1)))(e,t,o,Zr):C.none())(ts,((t,o)=>e(o)),t),ns=e=>ht(e,"table"),rs=(e,t,o)=>{const n=e=>t=>void 0!==o&&o(t)||Re(t,e);return Re(e,t)?C.some({boxes:C.some([e]),start:e,finish:t}):ns(e).bind((r=>ns(t).bind((s=>{if(Re(r,s))return C.some({boxes:Kr(r,e,t),start:e,finish:t});if(De(r,s)){const o=it(t,"td,th",n(r)),l=o.length>0?o[o.length-1]:t;return C.some({boxes:Yr(r,e,r,t,s),start:e,finish:l})}if(De(s,r)){const o=it(e,"td,th",n(s)),l=o.length>0?o[o.length-1]:e;return C.some({boxes:Yr(s,e,r,t,s),start:e,finish:l})}return((e,t,o)=>((e,t,o,n=y)=>{const r=[t].concat(e.up().all(t)),s=[o].concat(e.up().all(o)),l=e=>M(e,n).fold((()=>e),(t=>e.slice(0,t+1))),a=l(r),c=l(s),i=W(a,(t=>O(c,((e,t)=>w(e.eq,t))(e,t))));return{firstpath:a,secondpath:c,shared:i}})(ts,e,t,void 0))(e,t).shared.bind((l=>bt(l,"table",o).bind((o=>{const l=it(t,"td,th",n(o)),a=l.length>0?l[l.length-1]:t,c=it(e,"td,th",n(o)),i=c.length>0?c[c.length-1]:e;return C.some({boxes:Yr(o,e,r,t,s),start:i,finish:a})}))))}))))},ss=(e,t)=>{const o=dt(e,t);return o.length>0?C.some(o):C.none()},ls=(e,t,o)=>wt(e,t).bind((t=>wt(e,o).bind((e=>os(ns,[t,e]).map((o=>({first:t,last:e,table:o}))))))),as=(e,t,o,n,r)=>((e,t)=>W(e,(e=>Ce(e,t))))(e,r).bind((e=>((e,t,o)=>Kt(e).bind((n=>((e,t,o,n)=>on(e,t,Re).bind((t=>{const r=o>0?t.row+t.rowspan-1:t.row,s=n>0?t.column+t.colspan-1:t.column;return tn(e,r+o,s+n).map((e=>e.element))})))(Jr(n),e,t,o))))(e,t,o).bind((e=>((e,t)=>ht(e,"table").bind((o=>wt(o,t).bind((t=>rs(t,e).bind((e=>e.boxes.map((t=>({boxes:t,start:e.start,finish:e.finish}))))))))))(e,n))))),cs=(e,t)=>ss(e,t),is=(e,t,o)=>ls(e,t,o).bind((t=>{const o=t=>Re(e,t),n="thead,tfoot,tbody,table",r=ht(t.first,n,o),s=ht(t.last,n,o);return r.bind((e=>s.bind((o=>Re(e,o)?((e,t,o)=>((e,t,o)=>$r(e,t,o).bind((t=>((e,t)=>{let o=!0;const n=w(Vr,t);for(let r=t.startRow;r<=t.finishRow;r++)for(let s=t.startCol;s<=t.finishCol;s++)o=o&&tn(e,r,s).exists(n);return o?C.some(t):C.none()})(e,t))))(Jr(e),t,o))(t.table,t.first,t.last):C.none()))))})),ms=h,ds=e=>{const t=(e,t)=>we(e,t).exists((e=>parseInt(e,10)>1));return e.length>0&&P(e,(e=>t(e,"rowspan")||t(e,"colspan")))?C.some(e):C.none()},us=(e,t,o)=>t.length<=1?C.none():is(e,o.firstSelectedSelector,o.lastSelectedSelector).map((e=>({bounds:e,cells:t}))),fs={selected:"data-mce-selected",selectedSelector:"td[data-mce-selected],th[data-mce-selected]",firstSelected:"data-mce-first-selected",firstSelectedSelector:"td[data-mce-first-selected],th[data-mce-first-selected]",lastSelected:"data-mce-last-selected",lastSelectedSelector:"td[data-mce-last-selected],th[data-mce-last-selected]"},gs=(e,t,o)=>({element:o,mergable:us(t,e,fs),unmergable:ds(e),selection:ms(e)}),hs=e=>(t,o)=>{const n=ne(t),r="col"===n||"colgroup"===n?Kt(s=t).bind((e=>cs(e,fs.firstSelectedSelector))).fold(g(s),(e=>e[0])):t;var s;return bt(r,e,o)},ps=hs("th,td,caption"),ws=hs("th,td"),bs=e=>{return t=e.model.table.getSelectedCells(),E(t,xe.fromDom);var t},vs=(e,t)=>{e.on("BeforeGetContent",(t=>{const o=o=>{t.preventDefault(),(e=>Kt(e[0]).map((e=>{const t=((e,t)=>{const o=e=>Ce(e.element,t),n=Ye(e),r=Zt(n),s=mr(e),l=en(r),a=((e,t)=>{const o=e.grid.columns;let n=e.grid.rows,r=o,s=0,l=0;const a=[],c=[];return G(e.access,(e=>{if(a.push(e),t(e)){c.push(e);const t=e.row,o=t+e.rowspan-1,a=e.column,i=a+e.colspan-1;ts&&(s=o),al&&(l=i)}})),((e,t,o,n,r,s)=>({minRow:e,minCol:t,maxRow:o,maxCol:n,allCells:r,selectedCells:s}))(n,r,s,l,a,c)})(l,o),c="th:not("+t+"),td:not("+t+")",i=Vt(n,"th,td",(e=>Ce(e,c)));N(i,$e),((e,t,o,n)=>{const r=z(e,(e=>"colgroup"!==e.section)),s=t.grid.columns,l=t.grid.rows;for(let e=0;eo.maxRow||ao.maxCol||(tn(t,e,a).filter(n).isNone()?fr(r,l,e):l=!0)}})(r,l,a,o);const m=((e,t,o,n)=>{if(0===n.minCol&&t.grid.columns===n.maxCol+1)return 0;const r=sr(t,e,o),s=L(r,((e,t)=>e+t),0),l=L(r.slice(n.minCol,n.maxCol+1),((e,t)=>e+t),0),a=l/s*o.pixelWidth()-o.pixelWidth();return o.getCellDelta(a)})(e,Zo(e),s,a);return((e,t,o,n)=>{G(o.columns,(e=>{(e.columnt.maxCol)&&$e(e.element)}));const r=z(qt(e,"tr"),(e=>0===e.dom.childElementCount));N(r,$e),t.minCol!==t.maxCol&&t.minRow!==t.maxRow||N(qt(e,"th,td"),(e=>{be(e,"rowspan"),be(e,"colspan")})),be(e,Go),be(e,"data-snooker-col-series"),mr(e).adjustTableWidth(n)})(n,a,l,m),n})(e,"[data-mce-selected]");return jr(t),[t]})))(o).each((o=>{t.content="text"===t.format?(e=>E(e,(e=>e.dom.innerText)).join(""))(o):((e,t)=>E(t,(t=>e.selection.serializer.serialize(t.dom,{}))).join(""))(e,o)}))};if(!0===t.selection){const t=(e=>z(bs(e),(e=>Ce(e,fs.selectedSelector))))(e);t.length>=1&&o(t)}})),e.on("BeforeSetContent",(o=>{if(!0===o.selection&&!0===o.paste){const n=bs(e);H(n).each((n=>{Kt(n).each((r=>{const s=z(((e,t)=>{const o=document.createElement("div");return o.innerHTML=e,We(xe.fromDom(o))})(o.content),(e=>"meta"!==ne(e))),l=ue("table");if(1===s.length&&l(s[0])){o.preventDefault();const l=xe.fromDom(e.getDoc()),a=zr(l),c=((e,t,o)=>({element:e,clipboard:t,generators:o}))(n,s[0],a);t.pasteCells(r,c).each((()=>{e.focus()}))}}))}))}}))},ys=(e,t)=>({element:e,offset:t}),xs=(e,t,o)=>e.property().isText(t)&&0===e.property().getText(t).trim().length||e.property().isComment(t)?o(t).bind((t=>xs(e,t,o).orThunk((()=>C.some(t))))):C.none(),Cs=(e,t)=>e.property().isText(t)?e.property().getText(t).length:e.property().children(t).length,Ss=(e,t)=>{const o=xs(e,t,e.query().prevSibling).getOr(t);if(e.property().isText(o))return ys(o,Cs(e,o));const n=e.property().children(o);return n.length>0?Ss(e,n[n.length-1]):ys(o,Cs(e,o))},Ts=Ss,Rs=Xr(),Ds=(e,t)=>{if(!jt(e)){const o=(e=>Un(e).bind((e=>{return t=e,o=["fixed","relative","empty"],C.from(Mn.exec(t)).bind((e=>{const t=Number(e[1]),n=e[2];return((e,t)=>O(t,(t=>O(Wn[t],(t=>e===t)))))(n,o)?C.some({value:t,unit:n}):C.none()}));var t,o})))(e);o.each((o=>{const n=o.value/2;Jn(e,n,o.unit),Jn(t,n,o.unit)}))}},Os=e=>E(e,g(0)),ks=(e,t,o,n,r)=>r(e.slice(0,t)).concat(n).concat(r(e.slice(o))),Es=e=>(t,o,n,r)=>{if(e(n)){const e=Math.max(r,t[o]-Math.abs(n)),s=Math.abs(e-t[o]);return n>=0?s:-s}return n},Ns=Es((e=>e<0)),Bs=Es(x),zs=()=>{const e=(e,t,o,n)=>{const r=(100+o)/100,s=Math.max(n,(e[t]+o)/r);return E(e,((e,o)=>(o===t?s:e/r)-e))},t=(t,o,n,r,s,l)=>l?e(t,o,r,s):((e,t,o,n,r)=>{const s=Ns(e,t,n,r);return ks(e,t,o+1,[s,0],Os)})(t,o,n,r,s);return{resizeTable:(e,t)=>e(t),clampTableDelta:Ns,calcLeftEdgeDeltas:t,calcMiddleDeltas:(e,o,n,r,s,l,a)=>t(e,n,r,s,l,a),calcRightEdgeDeltas:(t,o,n,r,s,l)=>{if(l)return e(t,n,r,s);{const e=Ns(t,n,r,s);return Os(t.slice(0,n)).concat([e])}},calcRedestributedWidths:(e,t,o,n)=>{if(n){const n=(t+o)/t,r=E(e,(e=>e/n));return{delta:100*n-100,newSizes:r}}return{delta:o,newSizes:e}}}},As=()=>{const e=(e,t,o,n,r)=>{const s=Bs(e,n>=0?o:t,n,r);return ks(e,t,o+1,[s,-s],Os)};return{resizeTable:(e,t,o)=>{o&&e(t)},clampTableDelta:(e,t,o,n,r)=>{if(r){if(o>=0)return o;{const t=L(e,((e,t)=>e+t-n),0);return Math.max(-t,o)}}return Ns(e,t,o,n)},calcLeftEdgeDeltas:e,calcMiddleDeltas:(t,o,n,r,s,l)=>e(t,n,r,s,l),calcRightEdgeDeltas:(e,t,o,n,r,s)=>{if(s)return Os(e);{const t=n/e.length;return E(e,g(t))}},calcRedestributedWidths:(e,t,o,n)=>({delta:0,newSizes:e})}},Ls=e=>Zo(e).grid,Ws=ue("th"),Ms=e=>P(e,(e=>Ws(e.element))),_s=(e,t)=>e&&t?"sectionCells":e?"section":"cells",js=e=>{const t="thead"===e.section,o=vt(Ps(e.cells),"th");return"tfoot"===e.section?{type:"footer"}:t||o?{type:"header",subType:_s(t,o)}:{type:"body"}},Ps=e=>{const t=z(e,(e=>Ws(e.element)));return 0===t.length?C.some("td"):t.length===e.length?C.some("th"):C.none()},Is=(e,t,o)=>et(o(e.element,t),!0,e.isLocked),Fs=(e,t)=>e.section!==t?tt(e.element,e.cells,t,e.isNew):e,Hs=()=>({transformRow:Fs,transformCell:(e,t,o)=>{const n=o(e.element,t),r="td"!==ne(n)?((e,t)=>{const o=Je(e,"td");je(e,o);const n=We(e);return qe(o,n),$e(e),o})(n):n;return et(r,e.isNew,e.isLocked)}}),qs=()=>({transformRow:Fs,transformCell:Is}),Vs=()=>({transformRow:(e,t)=>Fs(e,"thead"===t?"tbody":t),transformCell:Is}),$s=Hs,Us=qs,Gs=Vs,Ks=()=>({transformRow:h,transformCell:Is}),Ys=(e,t,o,n)=>{o===n?be(e,t):ge(e,t,o)},Js=(e,t,o)=>{q(mt(e,t)).fold((()=>Pe(e,o)),(e=>je(e,o)))},Qs=(e,t)=>{const o=[],n=[],r=e=>E(e,(e=>{e.isNew&&o.push(e.element);const t=e.element;return Ve(t),N(e.cells,(e=>{e.isNew&&n.push(e.element),Ys(e.element,"colspan",e.colspan,1),Ys(e.element,"rowspan",e.rowspan,1),Ie(t,e.element)})),t})),s=e=>j(e,(e=>E(e.cells,(e=>(Ys(e.element,"span",e.colspan,1),e.element))))),l=(t,o)=>{const n=((e,t)=>{const o=pt(e,t).getOrThunk((()=>{const o=xe.fromTag(t,ke(e).dom);return"thead"===t?Js(e,"caption,colgroup",o):"colgroup"===t?Js(e,"caption",o):Ie(e,o),o}));return Ve(o),o})(e,o),l=("colgroup"===o?s:r)(t);qe(n,l)},a=(t,o)=>{t.length>0?l(t,o):(t=>{pt(e,t).each($e)})(o)},c=[],i=[],m=[],d=[];return N(t,(e=>{switch(e.section){case"thead":c.push(e);break;case"tbody":i.push(e);break;case"tfoot":m.push(e);break;case"colgroup":d.push(e)}})),a(d,"colgroup"),a(c,"thead"),a(i,"tbody"),a(m,"tfoot"),{newRows:o,newCells:n}},Xs=(e,t)=>{if(0===e.length)return 0;const o=e[0];return M(e,(e=>!t(o.element,e.element))).getOr(e.length)},Zs=(e,t)=>{const o=E(e,(e=>E(e.cells,y)));return E(e,((n,r)=>{const s=j(n.cells,((n,s)=>{if(!1===o[r][s]){const m=((e,t,o,n)=>{const r=((e,t)=>e[t])(e,t),s="colgroup"===r.section,l=Xs(r.cells.slice(o),n),a=s?1:Xs(((e,t)=>E(e,(e=>Ho(e,t))))(e.slice(t),o),n);return{colspan:l,rowspan:a}})(e,r,s,t);return((e,t,n,r)=>{for(let s=e;s({element:e,cells:t,section:o,isNew:n}))(n.element,s,n.section,n.isNew)}))},el=(e,t,o)=>{const n=[];N(e.colgroups,(r=>{const s=[];for(let n=0;net(e.element,o,!1))).getOrThunk((()=>et(t.colGap(),!0,!1)));s.push(r)}n.push(tt(r.element,s,"colgroup",o))}));for(let r=0;ret(e.element,o,e.isLocked))).getOrThunk((()=>et(t.gap(),!0,!1)));s.push(l)}const l=e.all[r],a=tt(l.element,s,l.section,o);n.push(a)}return n},tl=e=>Zs(e,Re),ol=(e,t)=>V(e.all,(e=>W(e.cells,(e=>Re(t,e.element))))),nl=(e,t,o)=>{const n=E(t.selection,(t=>$t(t).bind((t=>ol(e,t))).filter(o))),r=yt(n);return xt(r.length>0,r)},rl=(e,t,o,n,r)=>(s,l,a,c)=>{const i=Zo(s),m=C.from(null==c?void 0:c.section).getOrThunk(Ks);return t(i,l).map((t=>{const o=((e,t)=>el(e,t,!1))(i,a),n=e(o,t,Re,r(a),m),s=Yo(n.grid);return{info:t,grid:tl(n.grid),cursor:n.cursor,lockedColumns:s}})).bind((e=>{const t=Qs(s,e.grid),r=C.from(null==c?void 0:c.sizing).getOrThunk((()=>mr(s))),l=C.from(null==c?void 0:c.resize).getOrThunk(As);return o(s,e.grid,e.info,{sizing:r,resize:l,section:m}),n(s),be(s,Go),e.lockedColumns.length>0&&ge(s,Go,e.lockedColumns.join(",")),C.some({cursor:e.cursor,newRows:t.newRows,newCells:t.newCells})}))},sl=(e,t)=>nl(e,t,x).map((e=>({cells:e,generators:t.generators,clipboard:t.clipboard}))),ll=(e,t)=>nl(e,t,x),al=(e,t)=>nl(e,t,(e=>!e.isLocked)),cl=(e,t)=>P(t,(t=>((e,t)=>ol(e,t).exists((e=>!e.isLocked)))(e,t))),il=(e,t,o,n)=>{const r=$o(e).rows;let s=!0;for(let e=0;e{const t=t=>t(e),o=g(e),n=()=>r,r={tag:!0,inner:e,fold:(t,o)=>o(e),isValue:x,isError:y,map:t=>ul.value(t(e)),mapError:n,bind:t,exists:t,forall:t,getOr:o,or:n,getOrThunk:o,orThunk:n,getOrDie:o,each:t=>{t(e)},toOptional:()=>C.some(e)};return r},dl=e=>{const t=()=>o,o={tag:!1,inner:e,fold:(t,o)=>t(e),isValue:y,isError:x,map:t,mapError:t=>ul.error(t(e)),bind:t,exists:y,forall:x,getOr:h,or:h,getOrThunk:v,orThunk:v,getOrDie:(n=String(e),()=>{throw new Error(n)}),each:f,toOptional:C.none};var n;return o},ul={value:ml,error:dl,fromOption:(e,t)=>e.fold((()=>dl(t)),ml)},fl=(e,t)=>({rowDelta:0,colDelta:Vo(e[0])-Vo(t[0])}),gl=(e,t)=>({rowDelta:e.length-t.length,colDelta:0}),hl=(e,t,o,n)=>{const r="colgroup"===t.section?o.col:o.cell;return k(e,(e=>et(r(),!0,n(e))))},pl=(e,t,o,n)=>{const r=e[e.length-1];return e.concat(k(t,(()=>{const e="colgroup"===r.section?o.colgroup:o.row,t=Uo(r,e,h),s=hl(t.cells.length,t,o,(e=>X(n,e.toString())));return Fo(t,s)})))},wl=(e,t,o,n)=>E(e,(e=>{const r=hl(t,e,o,y);return jo(e,n,r)})),bl=(e,t,o)=>{const n=t.colDelta<0?wl:h,r=t.rowDelta<0?pl:h,s=Yo(e),l=Vo(e[0]),a=O(s,(e=>e===l-1)),c=n(e,Math.abs(t.colDelta),o,a?l-1:l),i=Yo(c);return r(c,Math.abs(t.rowDelta),o,I(i,x))},vl=(e,t,o,n)=>{const r=w(n,Ho(e[t],o).element),s=e[t];return e.length>1&&Vo(s)>1&&(o>0&&r(qo(s,o-1))||o0&&r(qo(e[t-1],o))||tz(o,(o=>o>=e.column&&o<=Vo(t[0])+e.column)),xl=(e,t,o,n,r)=>{((e,t,o,n)=>{t>0&&t{const r=e.cells[t-1];let s=0;const l=n();for(;e.cells.length>t+s&&o(r.element,e.cells[t+s].element);)Io(e,t+s,et(l,!0,e.cells[t+s].isLocked)),s++}))})(t,e,r,n.cell);const s=gl(o,t),l=bl(o,s,n),a=gl(t,l),c=bl(t,a,n);return E(c,((t,o)=>jo(t,e,l[o].cells)))},Cl=(e,t,o,n,r)=>{((e,t,o,n)=>{const r=$o(e).rows;if(t>0&&tL(e,((e,o)=>O(e,(e=>t(e.element,o.element)))?e:e.concat([o])),[]))(r[t-1].cells,o);N(e,(e=>{let s=C.none();for(let l=t;l{Io(a,t,et(e,!0,c.isLocked))})))}}))}})(t,e,r,n.cell);const s=Yo(t),l=fl(t,o),a={...l,colDelta:l.colDelta-s.length},c=bl(t,a,n),{cols:i,rows:m}=$o(c),d=Yo(c),u=fl(o,t),f={...u,colDelta:u.colDelta+d.length},g=(p=n,w=d,E(o,(e=>L(w,((t,o)=>{const n=hl(1,e,p,x)[0];return Po(t,o,n)}),e)))),h=bl(g,f,n);var p,w;return[...i,...m.slice(0,e),...h,...m.slice(e,m.length)]},Sl=(e,t,o,n,r)=>{const{rows:s,cols:l}=$o(e),a=s.slice(0,t),c=s.slice(t);return[...l,...a,((e,t,o,n)=>Uo(e,(e=>n(e,o)),t))(s[o],((e,o)=>t>0&&tE(e,(e=>{const s=t>0&&t{if("colgroup"!==o&&n)return Ho(e,t);{const t=Ho(e,r);return et(l(t.element,s),!0,!1)}})(e,t,e.section,s,o,n,r);return Po(e,t,l)})),Rl=(e,t,o,n)=>((e,t,o,n)=>void 0!==qo(e[t],o)&&t>0&&n(qo(e[t-1],o),qo(e[t],o)))(e,t,o,n)||((e,t,o)=>t>0&&o(qo(e,t-1),qo(e,t)))(e[t],o,n),Dl=(e,t,o,n)=>{const r=e=>(e=>"row"===e?Pt(t):jt(t))(e)?`${e}group`:e;return e?Ws(t)?r(o):null:n&&Ws(t)?r("row"===o?"col":"row"):null},Ol=(e,t,o)=>et(o(e.element,t),!0,e.isLocked),kl=(e,t,o,n,r,s,l)=>E(e,((e,a)=>((e,c)=>{const i=e.cells,m=E(i,((e,c)=>{if((e=>O(t,(t=>o(e.element,t.element))))(e)){const t=l(e,a,c)?r(e,o,n):e;return s(t,a,c).each((e=>{var o,n;o=t.element,n={scope:C.from(e)},G(n,((e,t)=>{e.fold((()=>{be(o,t)}),(e=>{fe(o.dom,t,e)}))}))})),t}return e}));return tt(e.element,m,e.section,e.isNew)})(e))),El=(e,t,o)=>j(e,((n,r)=>Rl(e,r,t,o)?[]:[Ho(n,t)])),Nl=(e,t,o,n,r)=>{const s=$o(e).rows,l=j(t,(e=>El(s,e,n))),a=E(s,(e=>Ms(e.cells))),c=((e,t)=>P(t,h)&&Ms(e)?x:(e,o,n)=>!("th"===ne(e.element)&&t[o]))(l,a),i=((e,t)=>(o,n)=>C.some(Dl(e,o.element,"row",t[n])))(o,a);return kl(e,l,n,r,Ol,i,c)},Bl=(e,t,o,n)=>{const r=$o(e).rows,s=E(t,(e=>Ho(r[e.row],e.column)));return kl(e,s,o,n,Ol,C.none,x)},zl=e=>{if(!l(e))throw new Error("cases must be an array");if(0===e.length)throw new Error("there must be at least one case");const t=[],o={};return N(e,((n,r)=>{const s=$(n);if(1!==s.length)throw new Error("one and only one name per case");const a=s[0],c=n[a];if(void 0!==o[a])throw new Error("duplicate key detected:"+a);if("cata"===a)throw new Error("cannot have a case named cata (sorry)");if(!l(c))throw new Error("case arguments must be an array");t.push(a),o[a]=(...o)=>{const n=o.length;if(n!==c.length)throw new Error("Wrong number of arguments to case "+a+". Expected "+c.length+" ("+c+"), got "+n);return{fold:(...t)=>{if(t.length!==e.length)throw new Error("Wrong number of arguments to fold. Expected "+e.length+", got "+t.length);return t[r].apply(null,o)},match:e=>{const n=$(e);if(t.length!==n.length)throw new Error("Wrong number of arguments to match. Expected: "+t.join(",")+"\nActual: "+n.join(","));if(!P(t,(e=>D(n,e))))throw new Error("Not all branches were specified when using match. Specified: "+n.join(", ")+"\nRequired: "+t.join(", "));return e[a].apply(null,o)},log:e=>{console.log(e,{constructors:t,constructor:a,params:o})}}}})),o},Al={...zl([{none:[]},{only:["index"]},{left:["index","next"]},{middle:["prev","index","next"]},{right:["prev","index"]}])},Ll=(e,t,o)=>{let n=0;for(let r=e;r{const o=rn(e);return E(o,(e=>{const o=Ll(e.row,e.row+e.rowspan,t);return{element:e.element,height:o,rowspan:e.rowspan}}))},Ml=(e,t,o)=>{const n=((e,t)=>ln(e)?((e,t)=>{const o=sn(e);return E(o,((e,o)=>({element:e.element,width:t[o],colspan:e.colspan})))})(e,t):((e,t)=>{const o=rn(e);return E(o,(e=>{const o=Ll(e.column,e.column+e.colspan,t);return{element:e.element,width:o,colspan:e.colspan}}))})(e,t))(e,t);N(n,(e=>{o.setElementWidth(e.element,e.width)}))},_l=(e,t,o,n,r)=>{const s=Zo(e),l=r.getCellDelta(t),a=r.getWidths(s,r),c=o===s.grid.columns-1,i=n.clampTableDelta(a,o,l,r.minCellWidth(),c),m=((e,t,o,n,r)=>{const s=e.slice(0),l=((e,t)=>0===e.length?Al.none():1===e.length?Al.only(0):0===t?Al.left(0,1):t===e.length-1?Al.right(t-1,t):t>0&&tn.singleColumnWidth(s[e],o)),((e,t)=>r.calcLeftEdgeDeltas(s,e,t,o,n.minCellWidth(),n.isRelative)),((e,t,l)=>r.calcMiddleDeltas(s,e,t,l,o,n.minCellWidth(),n.isRelative)),((e,t)=>r.calcRightEdgeDeltas(s,e,t,o,n.minCellWidth(),n.isRelative)))})(a,o,i,r,n),d=E(m,((e,t)=>e+a[t]));Ml(s,d,r),n.resizeTable(r.adjustTableWidth,i,c)},jl=e=>L(e,((e,t)=>O(e,(e=>e.column===t.column))?e:e.concat([t])),[]).sort(((e,t)=>e.column-t.column)),Pl=ue("col"),Il=ue("colgroup"),Fl=e=>"tr"===ne(e)||Il(e),Hl=e=>({element:e,colspan:Mt(e,"colspan",1),rowspan:Mt(e,"rowspan",1)}),ql=e=>we(e,"scope").map((e=>e.substr(0,3))),Vl=(e,t=Hl)=>{const o=o=>{if(Fl(o))return Il((r={element:o}).element)?e.colgroup(r):e.row(r);{const r=o,s=(t=>Pl(t.element)?e.col(t):e.cell(t))(t(r));return n=C.some({item:r,replacement:s}),s}var r};let n=C.none();return{getOrInit:(e,t)=>n.fold((()=>o(e)),(n=>t(e,n.item)?n.replacement:o(e)))}},$l=e=>t=>{const o=[],n=n=>{const r="td"===e?{scope:null}:{},s=t.replace(n,e,r);return o.push({item:n,sub:s}),s};return{replaceOrInit:(e,t)=>{if(Fl(e)||Pl(e))return e;{const r=e;return((e,t)=>W(o,(o=>t(o.item,e))))(r,t).fold((()=>n(r)),(o=>t(e,o.item)?o.sub:n(r)))}}}},Ul=e=>({unmerge:t=>{const o=ql(t);return o.each((e=>ge(t,"scope",e))),()=>{const n=e.cell({element:t,colspan:1,rowspan:1});return Wt(n,"width"),Wt(t,"width"),o.each((e=>ge(n,"scope",e))),n}},merge:e=>(Wt(e[0],"width"),(()=>{const t=yt(E(e,ql));if(0===t.length)return C.none();{const e=t[0],o=["row","col"];return O(t,(t=>t!==e&&D(o,t)))?C.none():C.from(e)}})().fold((()=>be(e[0],"scope")),(t=>ge(e[0],"scope",t+"group"))),g(e[0]))}),Gl=["body","p","div","article","aside","figcaption","figure","footer","header","nav","section","ol","ul","table","thead","tfoot","tbody","caption","tr","td","th","h1","h2","h3","h4","h5","h6","blockquote","pre","address"],Kl=Xr(),Yl=e=>((e,t)=>{const o=e.property().name(t);return D(Gl,o)})(Kl,e),Jl=e=>((e,t)=>{const o=e.property().name(t);return D(["ol","ul"],o)})(Kl,e),Ql=e=>{const t=ue("br"),o=e=>Cr(e).bind((o=>{const n=Le(o).map((e=>!!Yl(e)||!!((e,t)=>D(["br","img","hr","input"],e.property().name(t)))(Kl,e)&&"img"!==ne(e))).getOr(!1);return Ne(o).map((r=>{return!0===n||("li"===ne(s=r)||ft(s,Jl).isSome())||t(o)||Yl(r)&&!Re(e,r)?[]:[xe.fromTag("br")];var s}))})).getOr([]),n=(()=>{const n=j(e,(e=>{const n=We(e);return(e=>P(e,(e=>t(e)||ie(e)&&0===hr(e).trim().length)))(n)?[]:n.concat(o(e))}));return 0===n.length?[xe.fromTag("br")]:n})();Ve(e[0]),qe(e[0],n)},Xl=e=>Lr(e,!0),Zl=e=>{0===Ut(e).length&&$e(e)},ea=(e,t)=>({grid:e,cursor:t}),ta=(e,t,o)=>{const n=((e,t,o)=>{var n,r;const s=$o(e).rows;return C.from(null===(r=null===(n=s[t])||void 0===n?void 0:n.cells[o])||void 0===r?void 0:r.element).filter(Xl).orThunk((()=>(e=>V(e,(e=>V(e.cells,(e=>{const t=e.element;return xt(Xl(t),t)})))))(s)))})(e,t,o);return ea(e,n)},oa=e=>L(e,((e,t)=>O(e,(e=>e.row===t.row))?e:e.concat([t])),[]).sort(((e,t)=>e.row-t.row)),na=(e,t)=>(o,n,r,s,l)=>{const a=oa(n),c=E(a,(e=>e.row)),i=((e,t,o,n,r,s,l)=>{const{cols:a,rows:c}=$o(e),i=c[t[0]],m=j(t,(e=>((e,t,o)=>{const n=e[t];return j(n.cells,((n,r)=>Rl(e,t,r,o)?[]:[n]))})(c,e,r))),d=E(i.cells,((e,t)=>Ms(El(c,t,r)))),u=[...c];N(t,(e=>{u[e]=l.transformRow(c[e],o)}));const f=[...a,...u],g=((e,t)=>P(t,h)&&Ms(e.cells)?x:(e,o,n)=>!("th"===ne(e.element)&&t[n]))(i,d),p=((e,t)=>(o,n,r)=>C.some(Dl(e,o.element,"col",t[r])))(n,d);return kl(f,m,r,s,l.transformCell,p,g)})(o,c,e,t,r,s.replaceOrInit,l);return ta(i,n[0].row,n[0].column)},ra=na("thead",!0),sa=na("tbody",!1),la=na("tfoot",!1),aa=(e,t,o)=>{const n=((e,t)=>Qt(e,(()=>t)))(e,o.section),r=en(n);return el(r,t,!0)},ca=(e,t,o,n)=>((e,t,o,n)=>{const r=en(t),s=n.getWidths(r,n);Ml(r,s,n)})(0,t,0,n.sizing),ia=(e,t,o,n)=>((e,t,o,n,r)=>{const s=en(t),l=n.getWidths(s,n),a=n.pixelWidth(),{newSizes:c,delta:i}=r.calcRedestributedWidths(l,a,o.pixelDelta,n.isRelative);Ml(s,c,n),n.adjustTableWidth(i)})(0,t,o,n.sizing,n.resize),ma=(e,t)=>O(t,(e=>0===e.column&&e.isLocked)),da=(e,t)=>O(t,(t=>t.column+t.colspan>=e.grid.columns&&t.isLocked)),ua=(e,t)=>{const o=cn(e),n=jl(t);return L(n,((e,t)=>e+o[t.column].map(Mo).getOr(0)),0)},fa=e=>(t,o)=>ll(t,o).filter((o=>!(e?ma:da)(t,o))).map((e=>({details:e,pixelDelta:ua(t,e)}))),ga=e=>(t,o)=>sl(t,o).filter((o=>!(e?ma:da)(t,o.cells))),ha=$l("th"),pa=$l("td"),wa=rl(((e,t,o,n)=>{const r=t[0].row,s=oa(t),l=A(s,((e,t)=>({grid:Sl(e.grid,r,t.row+e.delta,o,n.getOrInit),delta:e.delta+1})),{grid:e,delta:0}).grid;return ta(l,r,t[0].column)}),ll,f,f,Vl),ba=rl(((e,t,o,n)=>{const r=oa(t),s=r[r.length-1],l=s.row+s.rowspan,a=A(r,((e,t)=>Sl(e,l,t.row,o,n.getOrInit)),e);return ta(a,l,t[0].column)}),ll,f,f,Vl),va=rl(((e,t,o,n)=>{const r=t.details,s=jl(r),l=s[0].column,a=A(s,((e,t)=>({grid:Tl(e.grid,l,t.column+e.delta,o,n.getOrInit),delta:e.delta+1})),{grid:e,delta:0}).grid;return ta(a,r[0].row,l)}),fa(!0),ia,f,Vl),ya=rl(((e,t,o,n)=>{const r=t.details,s=r[r.length-1],l=s.column+s.colspan,a=jl(r),c=A(a,((e,t)=>Tl(e,l,t.column,o,n.getOrInit)),e);return ta(c,r[0].row,l)}),fa(!1),ia,f,Vl),xa=rl(((e,t,o,n)=>{const r=jl(t.details),s=((e,t)=>j(e,(e=>{const o=e.cells,n=A(t,((e,t)=>t>=0&&t0?[tt(e.element,n,e.section,e.isNew)]:[]})))(e,E(r,(e=>e.column))),l=s.length>0?s[0].cells.length-1:0;return ta(s,r[0].row,Math.min(r[0].column,l))}),((e,t)=>al(e,t).map((t=>({details:t,pixelDelta:-ua(e,t)})))),ia,Zl,Vl),Ca=rl(((e,t,o,n)=>{const r=oa(t),s=((e,t,o)=>{const{rows:n,cols:r}=$o(e);return[...r,...n.slice(0,t),...n.slice(o+1)]})(e,r[0].row,r[r.length-1].row),l=s.length>0?s.length-1:0;return ta(s,Math.min(t[0].row,l),t[0].column)}),ll,f,Zl,Vl),Sa=rl(((e,t,o,n)=>{const r=jl(t),s=E(r,(e=>e.column)),l=Nl(e,s,!0,o,n.replaceOrInit);return ta(l,t[0].row,t[0].column)}),al,f,f,ha),Ta=rl(((e,t,o,n)=>{const r=jl(t),s=E(r,(e=>e.column)),l=Nl(e,s,!1,o,n.replaceOrInit);return ta(l,t[0].row,t[0].column)}),al,f,f,pa),Ra=rl(ra,al,f,f,ha),Da=rl(sa,al,f,f,pa),Oa=rl(la,al,f,f,pa),ka=rl(((e,t,o,n)=>{const r=Bl(e,t,o,n.replaceOrInit);return ta(r,t[0].row,t[0].column)}),al,f,f,ha),Ea=rl(((e,t,o,n)=>{const r=Bl(e,t,o,n.replaceOrInit);return ta(r,t[0].row,t[0].column)}),al,f,f,pa),Na=rl(((e,t,o,n)=>{const r=t.cells;Ql(r);const s=((e,t,o,n)=>{const r=$o(e).rows;if(0===r.length)return e;for(let e=t.startRow;e<=t.finishRow;e++)for(let o=t.startCol;o<=t.finishCol;o++){const t=r[e],s=Ho(t,o).isLocked;Io(t,o,et(n(),!1,s))}return e})(e,t.bounds,0,n.merge(r));return ea(s,C.from(r[0]))}),((e,t)=>((e,t)=>t.mergable)(0,t).filter((t=>cl(e,t.cells)))),ca,f,Ul),Ba=rl(((e,t,o,n)=>{const r=A(t,((e,t)=>il(e,t,o,n.unmerge(t))),e);return ea(r,C.from(t[0]))}),((e,t)=>((e,t)=>t.unmergable)(0,t).filter((t=>cl(e,t)))),ca,f,Ul),za=rl(((e,t,o,n)=>{const r=((e,t)=>{const o=Zo(e);return el(o,t,!0)})(t.clipboard,t.generators);var s,l;return((e,t,o,n,r)=>{const s=Yo(t),l=((e,t,o)=>{const n=Vo(t[0]),r=$o(t).cols.length+e.row,s=k(n-e.column,(t=>t+e.column));return{row:r,column:W(s,(e=>P(o,(t=>t!==e)))).getOr(n-1)}})(e,t,s),a=$o(o).rows,c=yl(l,a,s),i=((e,t,o)=>{if(e.row>=t.length||e.column>Vo(t[0]))return ul.error("invalid start address out of table bounds, row: "+e.row+", column: "+e.column);const n=t.slice(e.row),r=n[0].cells.slice(e.column),s=Vo(o[0]),l=o.length;return ul.value({rowDelta:n.length-l,colDelta:r.length-s})})(l,t,a);return i.map((e=>{const o={...e,colDelta:e.colDelta-c.length},s=bl(t,o,n),i=Yo(s),m=yl(l,a,i);return((e,t,o,n,r,s)=>{const l=e.row,a=e.column,c=l+o.length,i=a+Vo(o[0])+s.length,m=I(s,x);for(let e=l;eea(e,C.some(t.element))),(e=>ta(e,t.row,t.column)))}),((e,t)=>$t(t.element).bind((o=>ol(e,o).map((e=>({...e,generators:t.generators,clipboard:t.clipboard})))))),ca,f,Vl),Aa=rl(((e,t,o,n)=>{const r=$o(e).rows,s=t.cells[0].column,l=r[t.cells[0].row],a=aa(t.clipboard,t.generators,l),c=xl(s,e,a,t.generators,o);return ta(c,t.cells[0].row,t.cells[0].column)}),ga(!0),f,f,Vl),La=rl(((e,t,o,n)=>{const r=$o(e).rows,s=t.cells[t.cells.length-1].column+t.cells[t.cells.length-1].colspan,l=r[t.cells[0].row],a=aa(t.clipboard,t.generators,l),c=xl(s,e,a,t.generators,o);return ta(c,t.cells[0].row,t.cells[0].column)}),ga(!1),f,f,Vl),Wa=rl(((e,t,o,n)=>{const r=$o(e).rows,s=t.cells[0].row,l=r[s],a=aa(t.clipboard,t.generators,l),c=Cl(s,e,a,t.generators,o);return ta(c,t.cells[0].row,t.cells[0].column)}),sl,f,f,Vl),Ma=rl(((e,t,o,n)=>{const r=$o(e).rows,s=t.cells[t.cells.length-1].row+t.cells[t.cells.length-1].rowspan,l=r[t.cells[0].row],a=aa(t.clipboard,t.generators,l),c=Cl(s,e,a,t.generators,o);return ta(c,t.cells[0].row,t.cells[0].column)}),sl,f,f,Vl),_a=(e,t)=>{const o=Zo(e);return ll(o,t).bind((e=>{const t=e[e.length-1],n=e[0].column,r=t.column+t.colspan,s=_(E(o.all,(e=>z(e.cells,(e=>e.column>=n&&e.column{const o=Zo(e);return ll(o,t).bind(Ps).getOr("")},Pa=(e,t)=>{const o=Zo(e);return ll(o,t).bind((e=>{const t=e[e.length-1],n=e[0].row,r=t.row+t.rowspan;return(e=>{const t=E(e,(e=>js(e).type)),o=D(t,"header"),n=D(t,"footer");if(o||n){const e=D(t,"body");return!o||e||n?o||e||!n?C.none():C.some("footer"):C.some("header")}return C.some("body")})(o.all.slice(n,r))})).getOr("")},Ia=(e,t)=>e.dispatch("NewRow",{node:t}),Fa=(e,t)=>e.dispatch("NewCell",{node:t}),Ha=(e,t,o)=>{e.dispatch("TableModified",{...o,table:t})},qa={structure:!1,style:!0},Va={structure:!0,style:!1},$a={structure:!0,style:!0},Ua=e=>t=>t.options.get(e),Ga="100%",Ka=e=>{var t;const o=e.dom,n=null!==(t=o.getParent(e.selection.getStart(),o.isBlock))&&void 0!==t?t:e.getBody();return _o(xe.fromDom(n))+"px"},Ya=e=>C.from(e.options.get("table_clone_elements")),Ja=Ua("table_header_type"),Qa=Ua("table_column_resizing"),Xa=e=>"preservetable"===Qa(e),Za=e=>"resizetable"===Qa(e),ec=Ua("table_sizing_mode"),tc=e=>"relative"===ec(e),oc=e=>"fixed"===ec(e),nc=e=>"responsive"===ec(e),rc=Ua("table_resize_bars"),sc=Ua("table_style_by_css"),lc=e=>{const t=e.options,o=t.get("table_default_attributes");return t.isSet("table_default_attributes")?o:((e,t)=>nc(e)||sc(e)?t:oc(e)?{...t,width:Ka(e)}:{...t,width:Ga})(e,o)},ac=Ua("table_use_colgroups"),cc=(e,t)=>tc(e)?ur(t):oc(e)?dr(t):mr(t),ic=(e,t,o)=>{const n=e=>"table"===ne(Mr(e)),r=Ya(e),s=Za(e)?f:Ds,l=t=>{switch(Ja(e)){case"section":return $s();case"sectionCells":return Us();case"cells":return Gs();default:return((e,t)=>{var o;switch((o=Zo(e),V(o.all,(e=>{const t=js(e);return"header"===t.type?C.from(t.subType):C.none()}))).getOr(t)){case"section":return Hs();case"sectionCells":return qs();case"cells":return Vs()}})(t,"section")}},a=(n,s,a,c)=>(i,m,d=!1)=>{jr(i);const u=xe.fromDom(e.getDoc()),f=Br(a,u,r),g={sizing:cc(e,i),resize:Za(e)?zs():As(),section:l(i)};return s(i)?n(i,m,f,g).bind((n=>{t.refresh(i.dom),N(n.newRows,(t=>{Ia(e,t.dom)})),N(n.newCells,(t=>{Fa(e,t.dom)}));const r=((t,n)=>n.cursor.fold((()=>{const n=Ut(t);return H(n).filter(lt).map((n=>{o.clearSelectedCells(t.dom);const r=e.dom.createRng();return r.selectNode(n.dom),e.selection.setRng(r),ge(n,"data-mce-selected","1"),r}))}),(n=>{const r=Ts(Rs,n),s=e.dom.createRng();return s.setStart(r.element.dom,r.offset),s.setEnd(r.element.dom,r.offset),e.selection.setRng(s),o.clearSelectedCells(t.dom),C.some(s)})))(i,n);return lt(i)&&(jr(i),d||Ha(e,i.dom,c)),r.map((e=>({rng:e,effect:c})))})):C.none()},c=a(Ca,(t=>!n(e)||Ls(t).rows>1),f,Va),i=a(xa,(t=>!n(e)||Ls(t).columns>1),f,Va);return{deleteRow:c,deleteColumn:i,insertRowsBefore:a(wa,x,f,Va),insertRowsAfter:a(ba,x,f,Va),insertColumnsBefore:a(va,x,s,Va),insertColumnsAfter:a(ya,x,s,Va),mergeCells:a(Na,x,f,Va),unmergeCells:a(Ba,x,f,Va),pasteColsBefore:a(Aa,x,f,Va),pasteColsAfter:a(La,x,f,Va),pasteRowsBefore:a(Wa,x,f,Va),pasteRowsAfter:a(Ma,x,f,Va),pasteCells:a(za,x,f,$a),makeCellsHeader:a(ka,x,f,Va),unmakeCellsHeader:a(Ea,x,f,Va),makeColumnsHeader:a(Sa,x,f,Va),unmakeColumnsHeader:a(Ta,x,f,Va),makeRowsHeader:a(Ra,x,f,Va),makeRowsBody:a(Da,x,f,Va),makeRowsFooter:a(Oa,x,f,Va),getTableRowType:Pa,getTableCellType:ja,getTableColType:_a}},mc=(e,t,o)=>{const n=Mt(e,t,1);1===o||n<=1?be(e,t):ge(e,t,Math.min(o,n))},dc=(e,t)=>o=>{const n=o.column+o.colspan-1,r=o.column;return n>=e&&r{const n=o.substring(0,o.length-e.length),r=parseFloat(n);return n===r.toString()?t(r):uc.invalid(o)},gc={...uc,from:e=>Rt(e,"%")?fc("%",uc.percent,e):Rt(e,"px")?fc("px",uc.pixels,e):uc.invalid(e)},hc=(e,t,o)=>{const n=gc.from(o),r=P(e,(e=>"0px"===e))?((e,t)=>{const o=e.fold((()=>g("")),(e=>g(e/t+"px")),(()=>g(100/t+"%")));return k(t,o)})(n,e.length):((e,t,o)=>e.fold((()=>t),(e=>((e,t,o)=>{const n=o/t;return E(e,(e=>gc.from(e).fold((()=>e),(e=>e*n+"px"),(e=>e/100*o+"px"))))})(t,o,e)),(e=>((e,t)=>E(e,(e=>gc.from(e).fold((()=>e),(e=>e/t*100+"%"),(e=>e+"%")))))(t,o))))(n,e,t);return bc(r)},pc=(e,t)=>0===e.length?t:A(e,((e,t)=>gc.from(t).fold(g(0),h,h)+e),0),wc=(e,t)=>gc.from(e).fold(g(e),(e=>e+t+"px"),(e=>e+t+"%")),bc=e=>{if(0===e.length)return e;const t=A(e,((e,t)=>{const o=gc.from(t).fold((()=>({value:t,remainder:0})),(e=>((e,t)=>{const o=Math.floor(e);return{value:o+"px",remainder:e-o}})(e)),(e=>({value:e+"%",remainder:0})));return{output:[o.value].concat(e.output),remainder:e.remainder+o.remainder}}),{output:[],remainder:0}),o=t.output;return o.slice(0,o.length-1).concat([wc(o[o.length-1],Math.round(t.remainder))])},vc=gc.from,yc=e=>vc(e).fold(g("px"),g("px"),g("%")),xc=(e,t,o)=>{const n=Zo(e),r=n.all,s=rn(n),l=sn(n);t.each((t=>{const o=yc(t),r=Wo(e),a=((e,t)=>nr(e,t,er,rr))(n,e),c=hc(a,r,t);ln(n)?((e,t,o)=>{N(t,((t,n)=>{const r=pc([e[n]],Ft());Nt(t.element,"width",r+o)}))})(c,l,o):((e,t,o)=>{N(t,(t=>{const n=e.slice(t.column,t.colspan+t.column),r=pc(n,Ft());Nt(t.element,"width",r+o)}))})(c,s,o),Nt(e,"width",t)})),o.each((t=>{const o=yc(t),l=hn(e),a=((e,t,o)=>lr(e,t,o,tr,rr))(n,e,zn);((e,t,o,n)=>{N(o,(t=>{const o=e.slice(t.row,t.rowspan+t.row),r=pc(o,Ht());Nt(t.element,"height",r+n)})),N(t,((t,o)=>{Nt(t.element,"height",e[o])}))})(hc(a,l,t),r,s,o),Nt(e,"height",t)}))},Cc=e=>Un(e).exists((e=>_n.test(e))),Sc=e=>Un(e).exists((e=>jn.test(e))),Tc=e=>Un(e).isNone(),Rc=e=>{be(e,"width")},Dc=e=>{const t=Qn(e);xc(e,C.some(t),C.none()),Rc(e)},Oc=e=>{const t=(e=>Wo(e)+"px")(e);xc(e,C.some(t),C.none()),Rc(e)},kc=e=>{Wt(e,"width");const t=Gt(e),o=t.length>0?t:Ut(e);N(o,(e=>{Wt(e,"width"),Rc(e)})),Rc(e)},Ec={styles:{"border-collapse":"collapse",width:"100%"},attributes:{border:"1"},colGroups:!1},Nc=(e,t,o,n)=>k(e,(e=>((e,t,o,n)=>{const r=xe.fromTag("tr");for(let s=0;s{e.selection.select(t.dom,!0),e.selection.collapse(!0)},zc=(e,t,o,n,s)=>{const l=(e=>{const t=e.options,o=t.get("table_default_styles");return t.isSet("table_default_styles")?o:((e,t)=>nc(e)||!sc(e)?t:oc(e)?{...t,width:Ka(e)}:{...t,width:Ga})(e,o)})(e),a={styles:l,attributes:lc(e),colGroups:ac(e)};return e.undoManager.ignore((()=>{const r=((e,t,o,n,r,s=Ec)=>{const l=xe.fromTag("table"),a="cells"!==r;Bt(l,s.styles),he(l,s.attributes),s.colGroups&&Ie(l,(e=>{const t=xe.fromTag("colgroup");return k(e,(()=>Ie(t,xe.fromTag("col")))),t})(t));const c=Math.min(e,o);if(a&&o>0){const e=xe.fromTag("thead");Ie(l,e);const s=Nc(o,t,"sectionCells"===r?c:0,n);qe(e,s)}const i=xe.fromTag("tbody");Ie(l,i);const m=Nc(a?e-c:e,t,a?0:o,n);return qe(i,m),l})(o,t,s,n,Ja(e),a);ge(r,"data-mce-id","__mce");const l=(e=>{const t=xe.fromTag("div"),o=xe.fromDom(e.dom.cloneNode(!0));return Ie(t,o),(e=>e.dom.innerHTML)(t)})(r);e.insertContent(l),e.addVisual()})),wt(Mr(e),'table[data-mce-id="__mce"]').map((t=>(oc(e)?Oc(t):nc(e)?kc(t):(tc(e)||(e=>r(e)&&-1!==e.indexOf("%"))(l.width))&&Dc(t),jr(t),be(t,"data-mce-id"),((e,t)=>{N(dt(t,"tr"),(t=>{Ia(e,t.dom),N(dt(t,"th,td"),(t=>{Fa(e,t.dom)}))}))})(e,t),((e,t)=>{wt(t,"td,th").each(w(Bc,e))})(e,t),t.dom))).getOrNull()};var Ac=tinymce.util.Tools.resolve("tinymce.FakeClipboard");const Lc="x-tinymce/dom-table-",Wc=Lc+"rows",Mc=Lc+"columns",_c=e=>{const t=Ac.FakeClipboardItem(e);Ac.write([t])},jc=e=>{var t;const o=null!==(t=Ac.read())&&void 0!==t?t:[];return V(o,(t=>C.from(t.getType(e))))},Pc=e=>{jc(e).isSome()&&Ac.clear()},Ic=e=>{e.fold(Hc,(e=>_c({[Wc]:e})))},Fc=()=>jc(Wc),Hc=()=>Pc(Wc),qc=e=>{e.fold($c,(e=>_c({[Mc]:e})))},Vc=()=>jc(Mc),$c=()=>Pc(Mc),Uc=e=>ps(Pr(e),_r(e)).filter(Hr),Gc=(e,t)=>{const o=_r(e),n=e=>Kt(e,o),l=t=>(e=>ws(Pr(e),_r(e)).filter(Hr))(e).bind((e=>n(e).map((o=>t(o,e))))),a=t=>{e.focus()},c=(t,o=!1)=>l(((n,r)=>{const s=gs(bs(e),n,r);t(n,s,o).each(a)})),i=()=>l(((t,o)=>((e,t,o)=>{const n=Zo(e);return ll(n,t).bind((e=>{const t=el(n,o,!1),r=$o(t).rows.slice(e[0].row,e[e.length-1].row+e[e.length-1].rowspan),s=j(r,(e=>{const t=z(e.cells,(e=>!e.isLocked));return t.length>0?[{...e,cells:t}]:[]})),l=tl(s);return xt(l.length>0,l)})).map((e=>E(e,(e=>{const t=Ke(e.element);return N(e.cells,(e=>{const o=Ye(e.element);Ys(o,"colspan",e.colspan,1),Ys(o,"rowspan",e.rowspan,1),Ie(t,o)})),t}))))})(t,gs(bs(e),t,o),Br(f,xe.fromDom(e.getDoc()),C.none())))),m=()=>l(((t,o)=>((e,t)=>{const o=Zo(e);return al(o,t).map((e=>{const t=e[e.length-1],n=e[0].column,r=t.column+t.colspan,s=((e,t,o)=>{if(ln(e)){const n=z(sn(e),dc(t,o)),r=E(n,(e=>{const n=Ye(e.element);return mc(n,"span",o-t),n})),s=xe.fromTag("colgroup");return qe(s,r),[s]}return[]})(o,n,r),l=((e,t,o)=>E(e.all,(e=>{const n=z(e.cells,dc(t,o)),r=E(n,(e=>{const n=Ye(e.element);return mc(n,"colspan",o-t),n})),s=xe.fromTag("tr");return qe(s,r),s})))(o,n,r);return[...s,...l]}))})(t,gs(bs(e),t,o)))),d=(t,o)=>o().each((o=>{const n=E(o,(e=>Ye(e)));l(((o,r)=>{const s=zr(xe.fromDom(e.getDoc())),l=((e,t,o,n)=>({selection:ms(e),clipboard:o,generators:n}))(bs(e),0,n,s);t(o,l).each(a)}))})),g=e=>(t,o)=>((e,t)=>X(e,t)?C.from(e.type):C.none())(o,"type").each((t=>{c(e(t),o.no_events)}));G({mceTableSplitCells:()=>c(t.unmergeCells),mceTableMergeCells:()=>c(t.mergeCells),mceTableInsertRowBefore:()=>c(t.insertRowsBefore),mceTableInsertRowAfter:()=>c(t.insertRowsAfter),mceTableInsertColBefore:()=>c(t.insertColumnsBefore),mceTableInsertColAfter:()=>c(t.insertColumnsAfter),mceTableDeleteCol:()=>c(t.deleteColumn),mceTableDeleteRow:()=>c(t.deleteRow),mceTableCutCol:()=>m().each((e=>{qc(e),c(t.deleteColumn)})),mceTableCutRow:()=>i().each((e=>{Ic(e),c(t.deleteRow)})),mceTableCopyCol:()=>m().each((e=>qc(e))),mceTableCopyRow:()=>i().each((e=>Ic(e))),mceTablePasteColBefore:()=>d(t.pasteColsBefore,Vc),mceTablePasteColAfter:()=>d(t.pasteColsAfter,Vc),mceTablePasteRowBefore:()=>d(t.pasteRowsBefore,Fc),mceTablePasteRowAfter:()=>d(t.pasteRowsAfter,Fc),mceTableDelete:()=>Uc(e).each((t=>{Kt(t,o).filter(b(o)).each((t=>{const o=xe.fromText("");if(je(t,o),$e(t),e.dom.isEmpty(e.getBody()))e.setContent(""),e.selection.setCursorLocation();else{const t=e.dom.createRng();t.setStart(o.dom,0),t.setEnd(o.dom,0),e.selection.setRng(t),e.nodeChanged()}}))})),mceTableCellToggleClass:(t,o)=>{l((t=>{const n=bs(e),r=P(n,(t=>e.formatter.match("tablecellclass",{value:o},t.dom))),s=r?e.formatter.remove:e.formatter.apply;N(n,(e=>s("tablecellclass",{value:o},e.dom))),Ha(e,t.dom,qa)}))},mceTableToggleClass:(t,o)=>{l((t=>{e.formatter.toggle("tableclass",{value:o},t.dom),Ha(e,t.dom,qa)}))},mceTableToggleCaption:()=>{Uc(e).each((t=>{Kt(t,o).each((o=>{pt(o,"caption").fold((()=>{const t=xe.fromTag("caption");Ie(t,xe.fromText("Caption")),((e,t,o)=>{Me(e,0).fold((()=>{Ie(e,t)}),(e=>{_e(e,t)}))})(o,t),e.selection.setCursorLocation(t.dom,0)}),(n=>{ue("caption")(t)&&Te("td",o).each((t=>e.selection.setCursorLocation(t.dom,0))),$e(n)})),Ha(e,o.dom,Va)}))}))},mceTableSizingMode:(t,n)=>(t=>Uc(e).each((n=>{nc(e)||oc(e)||tc(e)||Kt(n,o).each((o=>{"relative"!==t||Cc(o)?"fixed"!==t||Sc(o)?"responsive"!==t||Tc(o)||kc(o):Oc(o):Dc(o),jr(o),Ha(e,o.dom,Va)}))})))(n),mceTableCellType:g((e=>"th"===e?t.makeCellsHeader:t.unmakeCellsHeader)),mceTableColType:g((e=>"th"===e?t.makeColumnsHeader:t.unmakeColumnsHeader)),mceTableRowType:g((e=>{switch(e){case"header":return t.makeRowsHeader;case"footer":return t.makeRowsFooter;default:return t.makeRowsBody}}))},((t,o)=>e.addCommand(o,t))),e.addCommand("mceInsertTable",((t,o)=>{((e,t,o,n={})=>{const r=e=>u(e)&&e>0;if(r(t)&&r(o)){const r=n.headerRows||0,s=n.headerColumns||0;return zc(e,o,t,s,r)}console.error("Invalid values for mceInsertTable - rows and columns values are required to insert a table.")})(e,o.rows,o.columns,o.options)})),e.addCommand("mceTableApplyCellStyle",((t,o)=>{const l=e=>"tablecell"+e.toLowerCase().replace("-","");if(!s(o))return;const a=z(bs(e),Hr);if(0===a.length)return;const c=((e,t)=>{const o={};return((e,t,o,n)=>{G(e,((e,r)=>{(t(e,r)?o:n)(e,r)}))})(e,t,(e=>(t,o)=>{e[o]=t})(o),f),o})(o,((t,o)=>e.formatter.has(l(o))&&r(t)));(e=>{for(const t in e)if(U.call(e,t))return!1;return!0})(c)||(G(c,((t,o)=>{const n=l(o);N(a,(o=>{""===t?e.formatter.remove(n,{value:null},o.dom,!0):e.formatter.apply(n,{value:t},o.dom)}))})),n(a[0]).each((t=>Ha(e,t.dom,qa))))}))},Kc=zl([{before:["element"]},{on:["element","offset"]},{after:["element"]}]),Yc={before:Kc.before,on:Kc.on,after:Kc.after,cata:(e,t,o,n)=>e.fold(t,o,n),getStart:e=>e.fold(h,h,h)},Jc=(e,t)=>({selection:e,kill:t}),Qc=(e,t)=>{const o=e.document.createRange();return o.selectNode(t.dom),o},Xc=(e,t)=>{const o=e.document.createRange();return Zc(o,t),o},Zc=(e,t)=>e.selectNodeContents(t.dom),ei=(e,t,o)=>{const n=e.document.createRange();var r;return r=n,t.fold((e=>{r.setStartBefore(e.dom)}),((e,t)=>{r.setStart(e.dom,t)}),(e=>{r.setStartAfter(e.dom)})),((e,t)=>{t.fold((t=>{e.setEndBefore(t.dom)}),((t,o)=>{e.setEnd(t.dom,o)}),(t=>{e.setEndAfter(t.dom)}))})(n,o),n},ti=(e,t,o,n,r)=>{const s=e.document.createRange();return s.setStart(t.dom,o),s.setEnd(n.dom,r),s},oi=e=>({left:e.left,top:e.top,right:e.right,bottom:e.bottom,width:e.width,height:e.height}),ni=zl([{ltr:["start","soffset","finish","foffset"]},{rtl:["start","soffset","finish","foffset"]}]),ri=(e,t,o)=>t(xe.fromDom(o.startContainer),o.startOffset,xe.fromDom(o.endContainer),o.endOffset),si=(e,t)=>{const o=((e,t)=>t.match({domRange:e=>({ltr:g(e),rtl:C.none}),relative:(t,o)=>({ltr:eo((()=>ei(e,t,o))),rtl:eo((()=>C.some(ei(e,o,t))))}),exact:(t,o,n,r)=>({ltr:eo((()=>ti(e,t,o,n,r))),rtl:eo((()=>C.some(ti(e,n,r,t,o))))})}))(e,t);return((e,t)=>{const o=t.ltr();return o.collapsed?t.rtl().filter((e=>!1===e.collapsed)).map((e=>ni.rtl(xe.fromDom(e.endContainer),e.endOffset,xe.fromDom(e.startContainer),e.startOffset))).getOrThunk((()=>ri(0,ni.ltr,o))):ri(0,ni.ltr,o)})(0,o)},li=(e,t)=>si(e,t).match({ltr:(t,o,n,r)=>{const s=e.document.createRange();return s.setStart(t.dom,o),s.setEnd(n.dom,r),s},rtl:(t,o,n,r)=>{const s=e.document.createRange();return s.setStart(n.dom,r),s.setEnd(t.dom,o),s}});ni.ltr,ni.rtl;const ai=(e,t,o,n)=>({start:e,soffset:t,finish:o,foffset:n}),ci=(e,t,o,n)=>({start:Yc.on(e,t),finish:Yc.on(o,n)}),ii=(e,t)=>{const o=li(e,t);return ai(xe.fromDom(o.startContainer),o.startOffset,xe.fromDom(o.endContainer),o.endOffset)},mi=ci,di=(e,t,o,n,r)=>Re(o,n)?C.none():rs(o,n,t).bind((t=>{const n=t.boxes.getOr([]);return n.length>1?(r(e,n,t.start,t.finish),C.some(Jc(C.some(mi(o,0,o,br(o))),!0))):C.none()})),ui=(e,t)=>({item:e,mode:t}),fi=(e,t,o,n=gi)=>e.property().parent(t).map((e=>ui(e,n))),gi=(e,t,o,n=hi)=>o.sibling(e,t).map((e=>ui(e,n))),hi=(e,t,o,n=hi)=>{const r=e.property().children(t);return o.first(r).map((e=>ui(e,n)))},pi=[{current:fi,next:gi,fallback:C.none()},{current:gi,next:hi,fallback:C.some(fi)},{current:hi,next:hi,fallback:C.some(gi)}],wi=(e,t,o,n,r=pi)=>W(r,(e=>e.current===o)).bind((o=>o.current(e,t,n,o.next).orThunk((()=>o.fallback.bind((o=>wi(e,t,o,n))))))),bi=(e,t,o,n,r,s)=>wi(e,t,n,r).bind((t=>s(t.item)?C.none():o(t.item)?C.some(t.item):bi(e,t.item,o,t.mode,r,s))),vi=e=>t=>0===e.property().children(t).length,yi=(e,t,o,n)=>bi(e,t,o,gi,{sibling:(e,t)=>e.query().prevSibling(t),first:e=>e.length>0?C.some(e[e.length-1]):C.none()},n),xi=(e,t,o,n)=>bi(e,t,o,gi,{sibling:(e,t)=>e.query().nextSibling(t),first:e=>e.length>0?C.some(e[0]):C.none()},n),Ci=Xr(),Si=(e,t)=>((e,t,o)=>yi(e,t,vi(e),o))(Ci,e,t),Ti=(e,t)=>((e,t,o)=>xi(e,t,vi(e),o))(Ci,e,t),Ri=zl([{none:["message"]},{success:[]},{failedUp:["cell"]},{failedDown:["cell"]}]),Di=e=>bt(e,"tr"),Oi={...Ri,verify:(e,t,o,n,r,s,l)=>bt(n,"td,th",l).bind((o=>bt(t,"td,th",l).map((t=>Re(o,t)?Re(n,o)&&br(o)===r?s(t):Ri.none("in same cell"):os(Di,[o,t]).fold((()=>((e,t,o)=>{const n=e.getRect(t),r=e.getRect(o);return r.right>n.left&&r.lefts(t))))))).getOr(Ri.none("default")),cata:(e,t,o,n,r)=>e.fold(t,o,n,r)},ki=ue("br"),Ei=(e,t,o)=>t(e,o).bind((e=>ie(e)&&0===hr(e).trim().length?Ei(e,t,o):C.some(e))),Ni=(e,t,o,n)=>((e,t)=>Me(e,t).filter(ki).orThunk((()=>Me(e,t-1).filter(ki))))(t,o).bind((t=>n.traverse(t).fold((()=>Ei(t,n.gather,e).map(n.relative)),(e=>(e=>Ne(e).bind((t=>{const o=We(t);return((e,t)=>M(e,w(Re,t)))(o,e).map((n=>((e,t,o,n)=>({parent:e,children:t,element:o,index:n}))(t,o,e,n)))})))(e).map((e=>Yc.on(e.parent,e.index))))))),Bi=(e,t)=>({left:e.left,top:e.top+t,right:e.right,bottom:e.bottom+t}),zi=(e,t)=>({left:e.left,top:e.top-t,right:e.right,bottom:e.bottom-t}),Ai=(e,t,o)=>({left:e.left+t,top:e.top+o,right:e.right+t,bottom:e.bottom+o}),Li=e=>({left:e.left,top:e.top,right:e.right,bottom:e.bottom}),Wi=(e,t)=>C.some(e.getRect(t)),Mi=(e,t,o)=>ce(t)?Wi(e,t).map(Li):ie(t)?((e,t,o)=>o>=0&&o0?e.getRangedRect(t,o-1,t,o):C.none())(e,t,o).map(Li):C.none(),_i=(e,t)=>ce(t)?Wi(e,t).map(Li):ie(t)?e.getRangedRect(t,0,t,br(t)).map(Li):C.none(),ji=zl([{none:[]},{retry:["caret"]}]),Pi=(e,t,o)=>gt(t,Yl).fold(y,(t=>_i(e,t).exists((e=>((e,t)=>e.leftt.right)(o,e))))),Ii={point:e=>e.bottom,adjuster:(e,t,o,n,r)=>{const s=Bi(r,5);return Math.abs(o.bottom-n.bottom)<1||o.top>r.bottom?ji.retry(s):o.top===r.bottom?ji.retry(Bi(r,1)):Pi(e,t,r)?ji.retry(Ai(s,5,0)):ji.none()},move:Bi,gather:Ti},Fi=(e,t,o,n,r)=>0===r?C.some(n):((e,t,o)=>e.elementFromPoint(t,o).filter((e=>"table"===ne(e))).isSome())(e,n.left,t.point(n))?((e,t,o,n,r)=>Fi(e,t,o,t.move(n,5),r))(e,t,o,n,r-1):e.situsFromPoint(n.left,t.point(n)).bind((s=>s.start.fold(C.none,(s=>_i(e,s).bind((l=>t.adjuster(e,s,l,o,n).fold(C.none,(n=>Fi(e,t,o,n,r-1))))).orThunk((()=>C.some(n)))),C.none))),Hi=(e,t,o)=>{const n=e.move(o,5),r=Fi(t,e,o,n,100).getOr(n);return((e,t,o)=>e.point(t)>o.getInnerHeight()?C.some(e.point(t)-o.getInnerHeight()):e.point(t)<0?C.some(-e.point(t)):C.none())(e,r,t).fold((()=>t.situsFromPoint(r.left,e.point(r))),(o=>(t.scrollBy(0,o),t.situsFromPoint(r.left,e.point(r)-o))))},qi={tryUp:w(Hi,{point:e=>e.top,adjuster:(e,t,o,n,r)=>{const s=zi(r,5);return Math.abs(o.top-n.top)<1||o.bottome.getSelection().bind((n=>((e,t,o,n)=>{const r=ki(t)?((e,t,o)=>o.traverse(t).orThunk((()=>Ei(t,o.gather,e))).map(o.relative))(e,t,n):Ni(e,t,o,n);return r.map((e=>({start:e,finish:e})))})(t,n.finish,n.foffset,o).fold((()=>C.some(ys(n.finish,n.foffset))),(r=>{const s=e.fromSitus(r);return l=Oi.verify(e,n.finish,n.foffset,s.finish,s.foffset,o.failure,t),Oi.cata(l,(e=>C.none()),(()=>C.none()),(e=>C.some(ys(e,0))),(e=>C.some(ys(e,br(e)))));var l})))),$i=(e,t,o,n,r,s)=>0===s?C.none():Ki(e,t,o,n,r).bind((l=>{const a=e.fromSitus(l),c=Oi.verify(e,o,n,a.finish,a.foffset,r.failure,t);return Oi.cata(c,(()=>C.none()),(()=>C.some(l)),(l=>Re(o,l)&&0===n?Ui(e,o,n,zi,r):$i(e,t,l,0,r,s-1)),(l=>Re(o,l)&&n===br(l)?Ui(e,o,n,Bi,r):$i(e,t,l,br(l),r,s-1)))})),Ui=(e,t,o,n,r)=>Mi(e,t,o).bind((t=>Gi(e,r,n(t,qi.getJumpSize())))),Gi=(e,t,o)=>{const n=Bo().browser;return n.isChromium()||n.isSafari()||n.isFirefox()?t.retry(e,o):C.none()},Ki=(e,t,o,n,r)=>Mi(e,o,n).bind((t=>Gi(e,r,t))),Yi=(e,t,o,n,r)=>bt(n,"td,th",t).bind((n=>bt(n,"table",t).bind((s=>((e,t)=>ft(e,(e=>Ne(e).exists((e=>Re(e,t)))),void 0).isSome())(r,s)?((e,t,o)=>Vi(e,t,o).bind((n=>$i(e,t,n.element,n.offset,o,20).map(e.fromSitus))))(e,t,o).bind((e=>bt(e.finish,"td,th",t).map((t=>({start:n,finish:t,range:e}))))):C.none())))),Ji=(e,t,o,n,r,s)=>s(n,t).orThunk((()=>Yi(e,t,o,n,r).map((e=>{const t=e.range;return Jc(C.some(mi(t.start,t.soffset,t.finish,t.foffset)),!0)})))),Qi=(e,t)=>bt(e,"tr",t).bind((e=>bt(e,"table",t).bind((o=>{const n=dt(o,"tr");return Re(e,n[0])?((e,t,o)=>yi(Ci,e,(e=>Cr(e).isSome()),o))(o,0,t).map((e=>{const t=br(e);return Jc(C.some(mi(e,t,e,t)),!0)})):C.none()})))),Xi=(e,t)=>bt(e,"tr",t).bind((e=>bt(e,"table",t).bind((o=>{const n=dt(o,"tr");return Re(e,n[n.length-1])?((e,t,o)=>xi(Ci,e,(e=>xr(e).isSome()),o))(o,0,t).map((e=>Jc(C.some(mi(e,0,e,0)),!0))):C.none()})))),Zi=(e,t,o,n,r,s,l)=>Yi(e,o,n,r,s).bind((e=>di(t,o,e.start,e.finish,l))),em=e=>{let t=e;return{get:()=>t,set:e=>{t=e}}},tm=()=>{const e=(e=>{const t=em(C.none()),o=()=>t.get().each(e);return{clear:()=>{o(),t.set(C.none())},isSet:()=>t.get().isSome(),get:()=>t.get(),set:e=>{o(),t.set(C.some(e))}}})(f);return{...e,on:t=>e.get().each(t)}},om=(e,t)=>bt(e,"td,th",t),nm=e=>Be(e).exists(Lr),rm={traverse:Le,gather:Ti,relative:Yc.before,retry:qi.tryDown,failure:Oi.failedDown},sm={traverse:Ae,gather:Si,relative:Yc.before,retry:qi.tryUp,failure:Oi.failedUp},lm=e=>t=>t===e,am=lm(38),cm=lm(40),im=e=>e>=37&&e<=40,mm={isBackward:lm(37),isForward:lm(39)},dm={isBackward:lm(39),isForward:lm(37)},um=zl([{domRange:["rng"]},{relative:["startSitu","finishSitu"]},{exact:["start","soffset","finish","foffset"]}]),fm={domRange:um.domRange,relative:um.relative,exact:um.exact,exactFromRange:e=>um.exact(e.start,e.soffset,e.finish,e.foffset),getWin:e=>{const t=(e=>e.match({domRange:e=>xe.fromDom(e.startContainer),relative:(e,t)=>Yc.getStart(e),exact:(e,t,o,n)=>e}))(e);return xe.fromDom(Ee(t).dom.defaultView)},range:ai},gm=document.caretPositionFromPoint?(e,t,o)=>{var n,r;return C.from(null===(r=(n=e.dom).caretPositionFromPoint)||void 0===r?void 0:r.call(n,t,o)).bind((t=>{if(null===t.offsetNode)return C.none();const o=e.dom.createRange();return o.setStart(t.offsetNode,t.offset),o.collapse(),C.some(o)}))}:document.caretRangeFromPoint?(e,t,o)=>{var n,r;return C.from(null===(r=(n=e.dom).caretRangeFromPoint)||void 0===r?void 0:r.call(n,t,o))}:C.none,hm=(e,t)=>{const o=ne(e);return"input"===o?Yc.after(e):D(["br","img"],o)?0===t?Yc.before(e):Yc.after(e):Yc.on(e,t)},pm=e=>C.from(e.getSelection()),wm=(e,t)=>{pm(e).each((e=>{e.removeAllRanges(),e.addRange(t)}))},bm=(e,t,o,n,r)=>{const s=ti(e,t,o,n,r);wm(e,s)},vm=(e,t)=>si(e,t).match({ltr:(t,o,n,r)=>{bm(e,t,o,n,r)},rtl:(t,o,n,r)=>{pm(e).each((s=>{if(s.setBaseAndExtent)s.setBaseAndExtent(t.dom,o,n.dom,r);else if(s.extend)try{((e,t,o,n,r,s)=>{t.collapse(o.dom,n),t.extend(r.dom,s)})(0,s,t,o,n,r)}catch(s){bm(e,n,r,t,o)}else bm(e,n,r,t,o)}))}}),ym=(e,t,o,n,r)=>{const s=((e,t,o,n)=>{const r=hm(e,t),s=hm(o,n);return fm.relative(r,s)})(t,o,n,r);vm(e,s)},xm=(e,t,o)=>{const n=((e,t)=>{const o=e.fold(Yc.before,hm,Yc.after),n=t.fold(Yc.before,hm,Yc.after);return fm.relative(o,n)})(t,o);vm(e,n)},Cm=e=>{if(e.rangeCount>0){const t=e.getRangeAt(0),o=e.getRangeAt(e.rangeCount-1);return C.some(ai(xe.fromDom(t.startContainer),t.startOffset,xe.fromDom(o.endContainer),o.endOffset))}return C.none()},Sm=e=>{if(null===e.anchorNode||null===e.focusNode)return Cm(e);{const t=xe.fromDom(e.anchorNode),o=xe.fromDom(e.focusNode);return((e,t,o,n)=>{const r=((e,t,o,n)=>{const r=ke(e).dom.createRange();return r.setStart(e.dom,t),r.setEnd(o.dom,n),r})(e,t,o,n),s=Re(e,o)&&t===n;return r.collapsed&&!s})(t,e.anchorOffset,o,e.focusOffset)?C.some(ai(t,e.anchorOffset,o,e.focusOffset)):Cm(e)}},Tm=(e,t,o=!0)=>{const n=(o?Xc:Qc)(e,t);wm(e,n)},Rm=e=>(e=>pm(e).filter((e=>e.rangeCount>0)).bind(Sm))(e).map((e=>fm.exact(e.start,e.soffset,e.finish,e.foffset))),Dm=e=>({elementFromPoint:(t,o)=>xe.fromPoint(xe.fromDom(e.document),t,o),getRect:e=>e.dom.getBoundingClientRect(),getRangedRect:(t,o,n,r)=>{const s=fm.exact(t,o,n,r);return((e,t)=>(e=>{const t=e.getClientRects(),o=t.length>0?t[0]:e.getBoundingClientRect();return o.width>0||o.height>0?C.some(o).map(oi):C.none()})(li(e,t)))(e,s)},getSelection:()=>Rm(e).map((t=>ii(e,t))),fromSitus:t=>{const o=fm.relative(t.start,t.finish);return ii(e,o)},situsFromPoint:(t,o)=>((e,t,o)=>((e,t,o)=>{const n=xe.fromDom(e.document);return gm(n,t,o).map((e=>ai(xe.fromDom(e.startContainer),e.startOffset,xe.fromDom(e.endContainer),e.endOffset)))})(e,t,o))(e,t,o).map((e=>ci(e.start,e.soffset,e.finish,e.foffset))),clearSelection:()=>{(e=>{pm(e).each((e=>e.removeAllRanges()))})(e)},collapseSelection:(t=!1)=>{Rm(e).each((o=>o.fold((e=>e.collapse(t)),((o,n)=>{const r=t?o:n;xm(e,r,r)}),((o,n,r,s)=>{const l=t?o:r,a=t?n:s;ym(e,l,a,l,a)}))))},setSelection:t=>{ym(e,t.start,t.soffset,t.finish,t.foffset)},setRelativeSelection:(t,o)=>{xm(e,t,o)},selectNode:t=>{Tm(e,t,!1)},selectContents:t=>{Tm(e,t)},getInnerHeight:()=>e.innerHeight,getScrollY:()=>(e=>{const t=void 0!==e?e.dom:document,o=t.body.scrollLeft||t.documentElement.scrollLeft,n=t.body.scrollTop||t.documentElement.scrollTop;return bn(o,n)})(xe.fromDom(e.document)).top,scrollBy:(t,o)=>{((e,t,o)=>{const n=(void 0!==o?o.dom:document).defaultView;n&&n.scrollBy(e,t)})(t,o,xe.fromDom(e.document))}}),Om=(e,t)=>({rows:e,cols:t}),km=e=>gt(e,ae).exists(Lr),Em=(e,t)=>km(e)||km(t),Nm=e=>void 0!==e.dom.classList,Bm=(e,t)=>((e,t,o)=>{const n=((e,t)=>{const o=pe(e,t);return void 0===o||""===o?[]:o.split(" ")})(e,t).concat([o]);return ge(e,t,n.join(" ")),!0})(e,"class",t),zm=(e,t)=>{Nm(e)?e.dom.classList.add(t):Bm(e,t)},Am=(e,t)=>Nm(e)&&e.dom.classList.contains(t),Lm=()=>({tag:"none"}),Wm=e=>({tag:"multiple",elements:e}),Mm=e=>({tag:"single",element:e}),_m=e=>{const t=xe.fromDom((e=>{if(nt()&&m(e.target)){const t=xe.fromDom(e.target);if(ce(t)&&m(t.dom.shadowRoot)&&e.composed&&e.composedPath){const t=e.composedPath();if(t)return H(t)}}return C.from(e.target)})(e).getOr(e.target)),o=()=>e.stopPropagation(),n=()=>e.preventDefault(),r=(s=n,l=o,(...e)=>s(l.apply(null,e)));var s,l;return((e,t,o,n,r,s,l)=>({target:e,x:t,y:o,stop:n,prevent:r,kill:s,raw:l}))(t,e.clientX,e.clientY,o,n,r,e)},jm=(e,t,o,n)=>{e.dom.removeEventListener(t,o,n)},Pm=x,Im=(e,t,o)=>((e,t,o,n)=>((e,t,o,n,r)=>{const s=((e,t)=>o=>{e(o)&&t(_m(o))})(o,n);return e.dom.addEventListener(t,s,r),{unbind:w(jm,e,t,s,r)}})(e,t,o,n,!1))(e,t,Pm,o),Fm=_m,Hm=e=>!Am(xe.fromDom(e.target),"ephox-snooker-resizer-bar"),qm=(e,t)=>{const o=(r=fs.selectedSelector,{get:()=>cs(xe.fromDom(e.getBody()),r).fold((()=>ws(Pr(e),_r(e)).fold(Lm,Mm)),Wm)}),n=((e,t,o)=>{const n=t=>{be(t,e.selected),be(t,e.firstSelected),be(t,e.lastSelected)},r=t=>{ge(t,e.selected,"1")},s=e=>{l(e),o()},l=t=>{const o=dt(t,`${e.selectedSelector},${e.firstSelectedSelector},${e.lastSelectedSelector}`);N(o,n)};return{clearBeforeUpdate:l,clear:s,selectRange:(o,n,l,a)=>{s(o),N(n,r),ge(l,e.firstSelected,"1"),ge(a,e.lastSelected,"1"),t(n,l,a)},selectedSelector:e.selectedSelector,firstSelectedSelector:e.firstSelectedSelector,lastSelectedSelector:e.lastSelectedSelector}})(fs,((t,o,n)=>{Kt(o).each((r=>{const s=Ya(e),l=Br(f,xe.fromDom(e.getDoc()),s),a=((e,t,o)=>{const n=Zo(e);return ll(n,t).map((e=>{const t=el(n,o,!1),{rows:r}=$o(t),s=((e,t)=>{const o=e.slice(0,t[t.length-1].row+1),n=tl(o);return j(n,(e=>{const o=e.cells.slice(0,t[t.length-1].column+1);return E(o,(e=>e.element))}))})(r,e),l=((e,t)=>{const o=e.slice(t[0].row+t[0].rowspan-1,e.length),n=tl(o);return j(n,(e=>{const o=e.cells.slice(t[0].column+t[0].colspan-1,e.cells.length);return E(o,(e=>e.element))}))})(r,e);return{upOrLeftCells:s,downOrRightCells:l}}))})(r,{selection:bs(e)},l);((e,t,o,n,r)=>{e.dispatch("TableSelectionChange",{cells:t,start:o,finish:n,otherCells:r})})(e,t,o,n,a)}))}),(()=>(e=>{e.dispatch("TableSelectionClear")})(e)));var r;return e.on("init",(o=>{const r=e.getWin(),s=Mr(e),l=_r(e),a=((e,t,o,n)=>{const r=((e,t,o,n)=>{const r=tm(),s=r.clear,l=s=>{r.on((r=>{n.clearBeforeUpdate(t),om(s.target,o).each((l=>{rs(r,l,o).each((o=>{const r=o.boxes.getOr([]);if(1===r.length){const o=r[0],l="false"===Wr(o),a=vt(Ar(s.target),o,Re);l&&a&&(n.selectRange(t,r,o,o),e.selectContents(o))}else r.length>1&&(n.selectRange(t,r,o.start,o.finish),e.selectContents(l))}))}))}))};return{clearstate:s,mousedown:e=>{n.clear(t),om(e.target,o).filter(nm).each(r.set)},mouseover:e=>{l(e)},mouseup:e=>{l(e),s()}}})(Dm(e),t,o,n);return{clearstate:r.clearstate,mousedown:r.mousedown,mouseover:r.mouseover,mouseup:r.mouseup}})(r,s,l,n),c=((e,t,o,n)=>{const r=Dm(e),s=()=>(n.clear(t),C.none());return{keydown:(e,l,a,c,i,m)=>{const d=e.raw,u=d.which,f=!0===d.shiftKey,g=ss(t,n.selectedSelector).fold((()=>(im(u)&&!f&&n.clearBeforeUpdate(t),im(u)&&f&&!Em(l,c)?C.none:cm(u)&&f?w(Zi,r,t,o,rm,c,l,n.selectRange):am(u)&&f?w(Zi,r,t,o,sm,c,l,n.selectRange):cm(u)?w(Ji,r,o,rm,c,l,Xi):am(u)?w(Ji,r,o,sm,c,l,Qi):C.none)),(e=>{const o=o=>()=>{const s=V(o,(o=>((e,t,o,n,r)=>as(n,e,t,r.firstSelectedSelector,r.lastSelectedSelector).map((e=>(r.clearBeforeUpdate(o),r.selectRange(o,e.boxes,e.start,e.finish),e.boxes))))(o.rows,o.cols,t,e,n)));return s.fold((()=>ls(t,n.firstSelectedSelector,n.lastSelectedSelector).map((e=>{const o=cm(u)||m.isForward(u)?Yc.after:Yc.before;return r.setRelativeSelection(Yc.on(e.first,0),o(e.table)),n.clear(t),Jc(C.none(),!0)}))),(e=>C.some(Jc(C.none(),!0))))};return im(u)&&f&&!Em(l,c)?C.none:cm(u)&&f?o([Om(1,0)]):am(u)&&f?o([Om(-1,0)]):m.isBackward(u)&&f?o([Om(0,-1),Om(-1,0)]):m.isForward(u)&&f?o([Om(0,1),Om(1,0)]):im(u)&&!f?s:C.none}));return g()},keyup:(e,r,s,l,a)=>ss(t,n.selectedSelector).fold((()=>{const c=e.raw,i=c.which;return!0===c.shiftKey&&im(i)&&Em(r,l)?((e,t,o,n,r,s,l)=>Re(o,r)&&n===s?C.none():bt(o,"td,th",t).bind((o=>bt(r,"td,th",t).bind((n=>di(e,t,o,n,l))))))(t,o,r,s,l,a,n.selectRange):C.none()}),C.none)}})(r,s,l,n),i=((e,t,o,n)=>{const r=Dm(e);return(e,s)=>{n.clearBeforeUpdate(t),rs(e,s,o).each((e=>{const o=e.boxes.getOr([]);n.selectRange(t,o,e.start,e.finish),r.selectContents(s),r.collapseSelection()}))}})(r,s,l,n);e.on("TableSelectorChange",(e=>i(e.start,e.finish)));const m=(t,o)=>{(e=>!0===e.raw.shiftKey)(t)&&(o.kill&&t.kill(),o.selection.each((t=>{const o=fm.relative(t.start,t.finish),n=li(r,o);e.selection.setRng(n)})))},d=e=>0===e.button,u=(()=>{const e=em(xe.fromDom(s)),t=em(0);return{touchEnd:o=>{const n=xe.fromDom(o.target);if(ue("td")(n)||ue("th")(n)){const r=e.get(),s=t.get();Re(r,n)&&o.timeStamp-s<300&&(o.preventDefault(),i(n,n))}e.set(n),t.set(o.timeStamp)}}})();e.on("dragstart",(e=>{a.clearstate()})),e.on("mousedown",(e=>{d(e)&&Hm(e)&&a.mousedown(Fm(e))})),e.on("mouseover",(e=>{var t;void 0!==(t=e).buttons&&0==(1&t.buttons)||!Hm(e)||a.mouseover(Fm(e))})),e.on("mouseup",(e=>{d(e)&&Hm(e)&&a.mouseup(Fm(e))})),e.on("touchend",u.touchEnd),e.on("keyup",(t=>{const o=Fm(t);if(o.raw.shiftKey&&im(o.raw.which)){const t=e.selection.getRng(),n=xe.fromDom(t.startContainer),r=xe.fromDom(t.endContainer);c.keyup(o,n,t.startOffset,r,t.endOffset).each((e=>{m(o,e)}))}})),e.on("keydown",(o=>{const n=Fm(o);t.hide();const r=e.selection.getRng(),s=xe.fromDom(r.startContainer),l=xe.fromDom(r.endContainer),a=un(mm,dm)(xe.fromDom(e.selection.getStart()));c.keydown(n,s,r.startOffset,l,r.endOffset,a).each((e=>{m(n,e)})),t.show()})),e.on("NodeChange",(()=>{const t=e.selection,o=xe.fromDom(t.getStart()),r=xe.fromDom(t.getEnd());os(Kt,[o,r]).fold((()=>n.clear(s)),f)}))})),e.on("PreInit",(()=>{e.serializer.addTempAttr(fs.firstSelected),e.serializer.addTempAttr(fs.lastSelected)})),{getSelectedCells:()=>((e,t,o,n)=>{switch(e.tag){case"none":return t();case"single":return(e=>[e.dom])(e.element);case"multiple":return(e=>E(e,(e=>e.dom)))(e.elements)}})(o.get(),g([])),clearSelectedCells:e=>n.clear(xe.fromDom(e))}},Vm=e=>{let t=[];return{bind:e=>{if(void 0===e)throw new Error("Event bind error: undefined handler");t.push(e)},unbind:e=>{t=z(t,(t=>t!==e))},trigger:(...o)=>{const n={};N(e,((e,t)=>{n[e]=o[t]})),N(t,(e=>{e(n)}))}}},$m=e=>({registry:K(e,(e=>({bind:e.bind,unbind:e.unbind}))),trigger:K(e,(e=>e.trigger))}),Um=e=>e.slice(0).sort(),Gm=(e,t)=>{const o=z(t,(t=>!D(e,t)));o.length>0&&(e=>{throw new Error("Unsupported keys for object: "+Um(e).join(", "))})(o)},Km=e=>((e,t)=>((e,t,o)=>{if(0===t.length)throw new Error("You must specify at least one required field.");return((e,t)=>{if(!l(t))throw new Error("The required fields must be an array. Was: "+t+".");N(t,(t=>{if(!r(t))throw new Error("The value "+t+" in the "+e+" fields was not a string.")}))})("required",t),(e=>{const t=Um(e);W(t,((e,o)=>o{throw new Error("The field: "+e+" occurs more than once in the combined fields: ["+t.join(", ")+"].")}))})(t),n=>{const r=$(n);P(t,(e=>D(r,e)))||((e,t)=>{throw new Error("All required keys ("+Um(e).join(", ")+") were not specified. Specified keys were: "+Um(t).join(", ")+".")})(t,r),e(t,r);const s=z(t,(e=>!o.validate(n[e],e)));return s.length>0&&((e,t)=>{throw new Error("All values need to be of type: "+t+". Keys ("+Um(e).join(", ")+") were not.")})(s,o.label),n}})(e,t,{validate:d,label:"function"}))(Gm,e),Ym=Km(["compare","extract","mutate","sink"]),Jm=Km(["element","start","stop","destroy"]),Qm=Km(["forceDrop","drop","move","delayDrop"]),Xm=()=>{const e=(()=>{const e=$m({move:Vm(["info"])});return{onEvent:f,reset:f,events:e.registry}})(),t=(()=>{let e=C.none();const t=$m({move:Vm(["info"])});return{onEvent:(o,n)=>{n.extract(o).each((o=>{const r=((t,o)=>{const n=e.map((e=>t.compare(e,o)));return e=C.some(o),n})(n,o);r.each((e=>{t.trigger.move(e)}))}))},reset:()=>{e=C.none()},events:t.registry}})();let o=e;return{on:()=>{o.reset(),o=t},off:()=>{o.reset(),o=e},isOn:()=>o===t,onEvent:(e,t)=>{o.onEvent(e,t)},events:t.events}},Zm=e=>{const t=e.replace(/\./g,"-");return{resolve:e=>t+"-"+e}},ed=Zm("ephox-dragster").resolve;var td=Ym({compare:(e,t)=>bn(t.left-e.left,t.top-e.top),extract:e=>C.some(bn(e.x,e.y)),sink:(e,t)=>{const o=(e=>{const t={layerClass:ed("blocker"),...e},o=xe.fromTag("div");return ge(o,"role","presentation"),Bt(o,{position:"fixed",left:"0px",top:"0px",width:"100%",height:"100%"}),zm(o,ed("blocker")),zm(o,t.layerClass),{element:g(o),destroy:()=>{$e(o)}}})(t),n=Im(o.element(),"mousedown",e.forceDrop),r=Im(o.element(),"mouseup",e.drop),s=Im(o.element(),"mousemove",e.move),l=Im(o.element(),"mouseout",e.delayDrop);return Jm({element:o.element,start:e=>{Ie(e,o.element())},stop:()=>{$e(o.element())},destroy:()=>{o.destroy(),r.unbind(),s.unbind(),l.unbind(),n.unbind()}})},mutate:(e,t)=>{e.mutate(t.left,t.top)}});const od=Zm("ephox-snooker").resolve,nd=od("resizer-bar"),rd=od("resizer-rows"),sd=od("resizer-cols"),ld=e=>{const t=dt(e.parent(),"."+nd);N(t,$e)},ad=(e,t,o)=>{const n=e.origin();N(t,(t=>{t.each((t=>{const r=o(n,t);zm(r,nd),Ie(e.parent(),r)}))}))},cd=(e,t,o,n,r)=>{const s=yn(o),l=t.isResizable,a=n.length>0?zn.positions(n,o):[],c=a.length>0?((e,t)=>j(e.all,((e,o)=>t(e.element)?[o]:[])))(e,l):[];((e,t,o,n)=>{ad(e,t,((e,t)=>{const r=((e,t,o,n,r)=>{const s=xe.fromTag("div");return Bt(s,{position:"absolute",left:t+"px",top:o-3.5+"px",height:"7px",width:n+"px"}),he(s,{"data-row":e,role:"presentation"}),s})(t.row,o.left-e.left,t.y-e.top,n);return zm(r,rd),r}))})(t,z(a,((e,t)=>O(c,(e=>t===e)))),s,Mo(o));const i=r.length>0?Ln.positions(r,o):[],m=i.length>0?((e,t)=>{const o=[];return k(e.grid.columns,(n=>{an(e,n).map((e=>e.element)).forall(t)&&o.push(n)})),z(o,(o=>{const n=nn(e,(e=>e.column===o));return P(n,(e=>t(e.element)))}))})(e,l):[];((e,t,o,n)=>{ad(e,t,((e,t)=>{const r=((e,t,o,n,r)=>{const s=xe.fromTag("div");return Bt(s,{position:"absolute",left:t-3.5+"px",top:o+"px",height:r+"px",width:"7px"}),he(s,{"data-column":e,role:"presentation"}),s})(t.col,t.x-e.left,o.top-e.top,0,n);return zm(r,sd),r}))})(t,z(i,((e,t)=>O(m,(e=>t===e)))),s,pn(o))},id=(e,t)=>{if(ld(e),e.isResizable(t)){const o=Zo(t),n=dn(o),r=cn(o);cd(o,e,t,n,r)}},md=(e,t)=>{const o=dt(e.parent(),"."+nd);N(o,t)},dd=e=>{md(e,(e=>{Nt(e,"display","none")}))},ud=e=>{md(e,(e=>{Nt(e,"display","block")}))},fd=od("resizer-bar-dragging"),gd=e=>{const t=(()=>{const e=$m({drag:Vm(["xDelta","yDelta","target"])});let t=C.none();const o=(()=>{const e=$m({drag:Vm(["xDelta","yDelta"])});return{mutate:(t,o)=>{e.trigger.drag(t,o)},events:e.registry}})();return o.events.drag.bind((o=>{t.each((t=>{e.trigger.drag(o.xDelta,o.yDelta,t)}))})),{assign:e=>{t=C.some(e)},get:()=>t,mutate:o.mutate,events:e.registry}})(),o=((e,t={})=>{var o;return((e,t,o)=>{let n=!1;const r=$m({start:Vm([]),stop:Vm([])}),s=Xm(),l=()=>{m.stop(),s.isOn()&&(s.off(),r.trigger.stop())},c=((e,t)=>{let o=null;const n=()=>{a(o)||(clearTimeout(o),o=null)};return{cancel:n,throttle:(...t)=>{n(),o=setTimeout((()=>{o=null,e.apply(null,t)}),200)}}})(l);s.events.move.bind((o=>{t.mutate(e,o.info)}));const i=e=>(...t)=>{n&&e.apply(null,t)},m=t.sink(Qm({forceDrop:l,drop:i(l),move:i((e=>{c.cancel(),s.onEvent(e,t)})),delayDrop:i(c.throttle)}),o);return{element:m.element,go:e=>{m.start(e),s.on(),r.trigger.start()},on:()=>{n=!0},off:()=>{n=!1},isActive:()=>n,destroy:()=>{m.destroy()},events:r.registry}})(e,null!==(o=t.mode)&&void 0!==o?o:td,t)})(t,{});let n=C.none();const r=(e,t)=>C.from(pe(e,t));t.events.drag.bind((e=>{r(e.target,"data-row").each((t=>{const o=It(e.target,"top");Nt(e.target,"top",o+e.yDelta+"px")})),r(e.target,"data-column").each((t=>{const o=It(e.target,"left");Nt(e.target,"left",o+e.xDelta+"px")}))}));const s=(e,t)=>It(e,t)-Mt(e,"data-initial-"+t,0);o.events.stop.bind((()=>{t.get().each((t=>{n.each((o=>{r(t,"data-row").each((e=>{const n=s(t,"top");be(t,"data-initial-top"),d.trigger.adjustHeight(o,n,parseInt(e,10))})),r(t,"data-column").each((e=>{const n=s(t,"left");be(t,"data-initial-left"),d.trigger.adjustWidth(o,n,parseInt(e,10))})),id(e,o)}))}))}));const l=(n,r)=>{d.trigger.startAdjust(),t.assign(n),ge(n,"data-initial-"+r,It(n,r)),zm(n,fd),Nt(n,"opacity","0.2"),o.go(e.parent())},c=Im(e.parent(),"mousedown",(e=>{var t;t=e.target,Am(t,rd)&&l(e.target,"top"),(e=>Am(e,sd))(e.target)&&l(e.target,"left")})),i=t=>Re(t,e.view()),m=Im(e.view(),"mouseover",(t=>{var r;(r=t.target,bt(r,"table",i).filter(Lr)).fold((()=>{lt(t.target)&&ld(e)}),(t=>{o.isActive()&&(n=C.some(t),id(e,t))}))})),d=$m({adjustHeight:Vm(["table","delta","row"]),adjustWidth:Vm(["table","delta","column"]),startAdjust:Vm([])});return{destroy:()=>{c.unbind(),m.unbind(),o.destroy(),ld(e)},refresh:t=>{id(e,t)},on:o.on,off:o.off,hideBars:w(dd,e),showBars:w(ud,e),events:d.registry}},hd=(e,t,o)=>{const n=zn,r=Ln,s=gd(e),l=$m({beforeResize:Vm(["table","type"]),afterResize:Vm(["table","type"]),startDrag:Vm([])});return s.events.adjustHeight.bind((e=>{const t=e.table;l.trigger.beforeResize(t,"row");((e,t,o,n)=>{const r=Zo(e),s=((e,t,o)=>lr(e,t,o,Yn,(e=>e.getOrThunk(Ht))))(r,e,n),l=E(s,((e,n)=>o===n?Math.max(t+e,Ht()):e)),a=Wl(r,l),c=((e,t)=>E(e.all,((e,o)=>({element:e.element,height:t[o]}))))(r,l);N(c,(e=>{qn(e.element,e.height)})),N(a,(e=>{qn(e.element,e.height)}));const i=A(l,((e,t)=>e+t),0);qn(e,i)})(t,n.delta(e.delta,t),e.row,n),l.trigger.afterResize(t,"row")})),s.events.startAdjust.bind((e=>{l.trigger.startDrag()})),s.events.adjustWidth.bind((e=>{const n=e.table;l.trigger.beforeResize(n,"col");const s=r.delta(e.delta,n),a=o(n);_l(n,s,e.column,t,a),l.trigger.afterResize(n,"col")})),{on:s.on,off:s.off,refreshBars:s.refresh,hideBars:s.hideBars,showBars:s.showBars,destroy:s.destroy,events:l.registry}},pd=e=>m(e)&&"TABLE"===e.nodeName,wd="bar-",bd=e=>"false"!==pe(e,"data-mce-resize"),vd=e=>{const t=tm(),o=tm(),n=tm();let r,s;const l=t=>cc(e,t),a=()=>Xa(e)?As():zs();return e.on("init",(()=>{const r=((e,t)=>e.inline?((e,t,o)=>({parent:g(t),view:g(e),origin:g(bn(0,0)),isResizable:o}))(xe.fromDom(e.getBody()),(()=>{const e=xe.fromTag("div");return Bt(e,{position:"static",height:"0",width:"0",padding:"0",margin:"0",border:"0"}),Ie(at(xe.fromDom(document)),e),e})(),t):((e,t)=>{const o=me(e)?(e=>xe.fromDom(Ee(e).dom.documentElement))(e):e;return{parent:g(o),view:g(e),origin:g(bn(0,0)),isResizable:t}})(xe.fromDom(e.getDoc()),t))(e,bd);if(n.set(r),(e=>{const t=e.options.get("object_resizing");return D(t.split(","),"table")})(e)&&rc(e)){const n=a(),s=hd(r,n,l);s.on(),s.events.startDrag.bind((o=>{t.set(e.selection.getRng())})),s.events.beforeResize.bind((t=>{const o=t.table.dom;((e,t,o,n,r)=>{e.dispatch("ObjectResizeStart",{target:t,width:o,height:n,origin:r})})(e,o,Ir(o),Fr(o),wd+t.type)})),s.events.afterResize.bind((o=>{const n=o.table,r=n.dom;jr(n),t.on((t=>{e.selection.setRng(t),e.focus()})),((e,t,o,n,r)=>{e.dispatch("ObjectResized",{target:t,width:o,height:n,origin:r})})(e,r,Ir(r),Fr(r),wd+o.type),e.undoManager.add()})),o.set(s)}})),e.on("ObjectResizeStart",(t=>{const o=t.target;if(pd(o)){const n=xe.fromDom(o);N(e.dom.select(".mce-clonedresizable"),(t=>{e.dom.addClass(t,"mce-"+Qa(e)+"-columns")})),!Sc(n)&&oc(e)?Oc(n):!Cc(n)&&tc(e)&&Dc(n),Tc(n)&&Tt(t.origin,wd)&&Dc(n),r=t.width,s=nc(e)?"":((e,t)=>{const o=e.dom.getStyle(t,"width")||e.dom.getAttrib(t,"width");return C.from(o).filter(Ot)})(e,o).getOr("")}})),e.on("ObjectResized",(t=>{const o=t.target;if(pd(o)){const n=xe.fromDom(o),c=t.origin;Tt(c,"corner-")&&((t,o,n)=>{const c=Rt(o,"e");if(""===s&&Dc(t),n!==r&&""!==s){Nt(t,"width",s);const o=a(),i=l(t),m=Xa(e)||c?(e=>Ls(e).columns)(t)-1:0;_l(t,n-r,m,o,i)}else if((e=>/^(\d+(\.\d+)?)%$/.test(e))(s)){const e=parseFloat(s.replace("%",""));Nt(t,"width",n*e/r+"%")}(e=>/^(\d+(\.\d+)?)px$/.test(e))(s)&&(e=>{const t=Zo(e);ln(t)||N(Ut(e),(e=>{const t=zt(e,"width");Nt(e,"width",t),be(e,"width")}))})(t)})(n,c,t.width),jr(n),Ha(e,n.dom,qa)}})),e.on("SwitchMode",(()=>{o.on((t=>{e.mode.isReadOnly()?t.hideBars():t.showBars()}))})),e.on("dragstart dragend",(e=>{o.on((t=>{"dragstart"===e.type?(t.hideBars(),t.off()):(t.on(),t.showBars())}))})),e.on("remove",(()=>{o.on((e=>{e.destroy()})),n.on((t=>{((e,t)=>{e.inline&&$e(t.parent())})(e,t)}))})),{refresh:e=>{o.on((t=>t.refreshBars(xe.fromDom(e))))},hide:()=>{o.on((e=>e.hideBars()))},show:()=>{o.on((e=>e.showBars()))}}},yd=e=>{(e=>{const t=e.options.register;t("table_clone_elements",{processor:"string[]"}),t("table_use_colgroups",{processor:"boolean",default:!0}),t("table_header_type",{processor:e=>{const t=D(["section","cells","sectionCells","auto"],e);return t?{value:e,valid:t}:{valid:!1,message:"Must be one of: section, cells, sectionCells or auto."}},default:"section"}),t("table_sizing_mode",{processor:"string",default:"auto"}),t("table_default_attributes",{processor:"object",default:{border:"1"}}),t("table_default_styles",{processor:"object",default:{"border-collapse":"collapse"}}),t("table_column_resizing",{processor:e=>{const t=D(["preservetable","resizetable"],e);return t?{value:e,valid:t}:{valid:!1,message:"Must be preservetable, or resizetable."}},default:"preservetable"}),t("table_resize_bars",{processor:"boolean",default:!0}),t("table_style_by_css",{processor:"boolean",default:!0})})(e);const t=vd(e),o=qm(e,t),n=ic(e,t,o);return Gc(e,n),((e,t)=>{const o=_r(e),n=t=>ws(Pr(e)).bind((n=>Kt(n,o).map((o=>{const r=gs(bs(e),o,n);return t(o,r)})))).getOr("");G({mceTableRowType:()=>n(t.getTableRowType),mceTableCellType:()=>n(t.getTableCellType),mceTableColType:()=>n(t.getTableColType)},((t,o)=>e.addQueryValueHandler(o,t)))})(e,n),vs(e,n),{getSelectedCells:o.getSelectedCells,clearSelectedCells:o.clearSelectedCells}};e.add("dom",(e=>({table:yd(e)})))}(); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/advlist/plugin.min.js b/public/resource/tinymce/plugins/advlist/plugin.min.js new file mode 100644 index 0000000..9916936 --- /dev/null +++ b/public/resource/tinymce/plugins/advlist/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.4.2 (2023-04-26) + */ +!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=(t,e,s)=>{const r="UL"===e?"InsertUnorderedList":"InsertOrderedList";t.execCommand(r,!1,!1===s?null:{"list-style-type":s})},s=t=>e=>e.options.get(t),r=s("advlist_number_styles"),n=s("advlist_bullet_styles"),l=t=>null==t,i=t=>!l(t);var o=tinymce.util.Tools.resolve("tinymce.util.Tools");class a{constructor(t,e){this.tag=t,this.value=e}static some(t){return new a(!0,t)}static none(){return a.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?a.some(t(this.value)):a.none()}bind(t){return this.tag?t(this.value):a.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:a.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return i(t)?a.some(t):a.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}a.singletonNone=new a(!1);const u=t=>e=>i(e)&&t.test(e.nodeName),d=u(/^(OL|UL|DL)$/),g=u(/^(TH|TD)$/),c=t=>l(t)||"default"===t?"":t,h=(t,e)=>s=>((t,e)=>{const s=t.selection.getNode();return e({parents:t.dom.getParents(s),element:s}),t.on("NodeChange",e),()=>t.off("NodeChange",e)})(t,(r=>((t,r)=>{const n=t.selection.getStart(!0);s.setActive(((t,e,s)=>((t,e,s)=>{for(let e=0,n=t.length;ee.nodeName===s&&((t,e)=>t.dom.isChildOf(e,t.getBody()))(t,e))))(t,r,e)),s.setEnabled(!((t,e)=>{const s=t.dom.getParent(e,"ol,ul,dl");return((t,e)=>null!==e&&!t.dom.isEditable(e))(t,s)})(t,n))})(t,r.parents))),m=(t,s,r,n,l,i)=>{i.length>1?((t,s,r,n,l,i)=>{t.ui.registry.addSplitButton(s,{tooltip:r,icon:"OL"===l?"ordered-list":"unordered-list",presets:"listpreview",columns:3,fetch:t=>{t(o.map(i,(t=>{const e="OL"===l?"num":"bull",s="disc"===t||"decimal"===t?"default":t,r=c(t),n=(t=>t.replace(/\-/g," ").replace(/\b\w/g,(t=>t.toUpperCase())))(t);return{type:"choiceitem",value:r,icon:"list-"+e+"-"+s,text:n}})))},onAction:()=>t.execCommand(n),onItemAction:(s,r)=>{e(t,l,r)},select:e=>{const s=(t=>{const e=t.dom.getParent(t.selection.getNode(),"ol,ul"),s=t.dom.getStyle(e,"listStyleType");return a.from(s)})(t);return s.map((t=>e===t)).getOr(!1)},onSetup:h(t,l)})})(t,s,r,n,l,i):((t,s,r,n,l,i)=>{t.ui.registry.addToggleButton(s,{active:!1,tooltip:r,icon:"OL"===l?"ordered-list":"unordered-list",onSetup:h(t,l),onAction:()=>t.queryCommandState(n)||""===i?t.execCommand(n):e(t,l,i)})})(t,s,r,n,l,c(i[0]))};t.add("advlist",(t=>{t.hasPlugin("lists")?((t=>{const e=t.options.register;e("advlist_number_styles",{processor:"string[]",default:"default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman".split(",")}),e("advlist_bullet_styles",{processor:"string[]",default:"default,circle,square".split(",")})})(t),(t=>{m(t,"numlist","Numbered list","InsertOrderedList","OL",r(t)),m(t,"bullist","Bullet list","InsertUnorderedList","UL",n(t))})(t),(t=>{t.addCommand("ApplyUnorderedListStyle",((s,r)=>{e(t,"UL",r["list-style-type"])})),t.addCommand("ApplyOrderedListStyle",((s,r)=>{e(t,"OL",r["list-style-type"])}))})(t)):console.error("Please use the Lists plugin together with the Advanced List plugin.")}))}(); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/anchor/plugin.min.js b/public/resource/tinymce/plugins/anchor/plugin.min.js new file mode 100644 index 0000000..e54d62f --- /dev/null +++ b/public/resource/tinymce/plugins/anchor/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.4.2 (2023-04-26) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.dom.RangeUtils"),o=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=("allow_html_in_named_anchor",e=>e.options.get("allow_html_in_named_anchor"));const a="a:not([href])",r=e=>!e,i=e=>e.getAttribute("id")||e.getAttribute("name")||"",l=e=>(e=>"a"===e.nodeName.toLowerCase())(e)&&!e.getAttribute("href")&&""!==i(e),s=e=>e.dom.getParent(e.selection.getStart(),a),d=(e,a)=>{const r=s(e);r?((e,t,o)=>{o.removeAttribute("name"),o.id=t,e.addVisual(),e.undoManager.add()})(e,a,r):((e,a)=>{e.undoManager.transact((()=>{n(e)||e.selection.collapse(!0),e.selection.isCollapsed()?e.insertContent(e.dom.createHTML("a",{id:a})):((e=>{const n=e.dom;t(n).walk(e.selection.getRng(),(e=>{o.each(e,(e=>{var t;l(t=e)&&!t.firstChild&&n.remove(e,!1)}))}))})(e),e.formatter.remove("namedAnchor",void 0,void 0,!0),e.formatter.apply("namedAnchor",{value:a}),e.addVisual())}))})(e,a),e.focus()},c=e=>(e=>r(e.attr("href"))&&!r(e.attr("id")||e.attr("name")))(e)&&!e.firstChild,m=e=>t=>{for(let o=0;o{(e=>{(0,e.options.register)("allow_html_in_named_anchor",{processor:"boolean",default:!1})})(e),(e=>{e.on("PreInit",(()=>{e.parser.addNodeFilter("a",m("false")),e.serializer.addNodeFilter("a",m(null))}))})(e),(e=>{e.addCommand("mceAnchor",(()=>{(e=>{const t=(e=>{const t=s(e);return t?i(t):""})(e);e.windowManager.open({title:"Anchor",size:"normal",body:{type:"panel",items:[{name:"id",type:"input",label:"ID",placeholder:"example"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{id:t},onSubmit:t=>{((e,t)=>/^[A-Za-z][A-Za-z0-9\-:._]*$/.test(t)?(d(e,t),!0):(e.windowManager.alert("ID should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores."),!1))(e,t.getData().id)&&t.close()}})})(e)}))})(e),(e=>{const t=()=>e.execCommand("mceAnchor");e.ui.registry.addToggleButton("anchor",{icon:"bookmark",tooltip:"Anchor",onAction:t,onSetup:t=>e.selection.selectorChangedWithUnbind("a:not([href])",t.setActive).unbind}),e.ui.registry.addMenuItem("anchor",{icon:"bookmark",text:"Anchor...",onAction:t})})(e),e.on("PreInit",(()=>{(e=>{e.formatter.register("namedAnchor",{inline:"a",selector:a,remove:"all",split:!0,deep:!0,attributes:{id:"%value"},onmatch:(e,t,o)=>l(e)})})(e)}))}))}(); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/autolink/plugin.min.js b/public/resource/tinymce/plugins/autolink/plugin.min.js new file mode 100644 index 0000000..672f45d --- /dev/null +++ b/public/resource/tinymce/plugins/autolink/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.4.2 (2023-04-26) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>t.options.get(e),n=t("autolink_pattern"),o=t("link_default_target"),r=t("link_default_protocol"),a=t("allow_unsafe_link_target"),s=("string",e=>"string"===(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(n=o=e,(r=String).prototype.isPrototypeOf(n)||(null===(a=o.constructor)||void 0===a?void 0:a.name)===r.name)?"string":t;var n,o,r,a})(e));const l=(void 0,e=>undefined===e);const i=e=>!(e=>null==e)(e),c=Object.hasOwnProperty,d=e=>"\ufeff"===e;var u=tinymce.util.Tools.resolve("tinymce.dom.TextSeeker");const f=e=>/^[(\[{ \u00a0]$/.test(e),g=(e,t,n)=>{for(let o=t-1;o>=0;o--){const t=e.charAt(o);if(!d(t)&&n(t))return o}return-1},m=(e,t)=>{var o;const a=e.schema.getVoidElements(),s=n(e),{dom:i,selection:d}=e;if(null!==i.getParent(d.getNode(),"a[href]"))return null;const m=d.getRng(),k=u(i,(e=>{return i.isBlock(e)||(t=a,n=e.nodeName.toLowerCase(),c.call(t,n))||"false"===i.getContentEditable(e);var t,n})),{container:p,offset:y}=((e,t)=>{let n=e,o=t;for(;1===n.nodeType&&n.childNodes[o];)n=n.childNodes[o],o=3===n.nodeType?n.data.length:n.childNodes.length;return{container:n,offset:o}})(m.endContainer,m.endOffset),h=null!==(o=i.getParent(p,i.isBlock))&&void 0!==o?o:i.getRoot(),w=k.backwards(p,y+t,((e,t)=>{const n=e.data,o=g(n,t,(r=f,e=>!r(e)));var r,a;return-1===o||(a=n[o],/[?!,.;:]/.test(a))?o:o+1}),h);if(!w)return null;let v=w.container;const _=k.backwards(w.container,w.offset,((e,t)=>{v=e;const n=g(e.data,t,f);return-1===n?n:n+1}),h),A=i.createRng();_?A.setStart(_.container,_.offset):A.setStart(v,0),A.setEnd(w.container,w.offset);const C=A.toString().replace(/\uFEFF/g,"").match(s);if(C){let t=C[0];return $="www.",(b=t).length>=$.length&&b.substr(0,0+$.length)===$?t=r(e)+"://"+t:((e,t,n=0,o)=>{const r=e.indexOf(t,n);return-1!==r&&(!!l(o)||r+t.length<=o)})(t,"@")&&!(e=>/^([A-Za-z][A-Za-z\d.+-]*:\/\/)|mailto:/.test(e))(t)&&(t="mailto:"+t),{rng:A,url:t}}var b,$;return null},k=(e,t)=>{const{dom:n,selection:r}=e,{rng:l,url:i}=t,c=r.getBookmark();r.setRng(l);const d="createlink",u={command:d,ui:!1,value:i};if(!e.dispatch("BeforeExecCommand",u).isDefaultPrevented()){e.getDoc().execCommand(d,!1,i),e.dispatch("ExecCommand",u);const t=o(e);if(s(t)){const o=r.getNode();n.setAttrib(o,"target",t),"_blank"!==t||a(e)||n.setAttrib(o,"rel","noopener")}}r.moveToBookmark(c),e.nodeChanged()},p=e=>{const t=m(e,-1);i(t)&&k(e,t)},y=p;e.add("autolink",(e=>{(e=>{const t=e.options.register;t("autolink_pattern",{processor:"regexp",default:new RegExp("^"+/(?:[A-Za-z][A-Za-z\d.+-]{0,14}:\/\/(?:[-.~*+=!&;:'%@?^${}(),\w]+@)?|www\.|[-;:&=+$,.\w]+@)[A-Za-z\d-]+(?:\.[A-Za-z\d-]+)*(?::\d+)?(?:\/(?:[-.~*+=!;:'%@$(),\/\w]*[-~*+=%@$()\/\w])?)?(?:\?(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?(?:#(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?/g.source+"$","i")}),t("link_default_target",{processor:"string"}),t("link_default_protocol",{processor:"string",default:"https"})})(e),(e=>{e.on("keydown",(t=>{13!==t.keyCode||t.isDefaultPrevented()||(e=>{const t=m(e,0);i(t)&&k(e,t)})(e)})),e.on("keyup",(t=>{32===t.keyCode?p(e):(48===t.keyCode&&t.shiftKey||221===t.keyCode)&&y(e)}))})(e)}))}(); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/autoresize/plugin.min.js b/public/resource/tinymce/plugins/autoresize/plugin.min.js new file mode 100644 index 0000000..8f7a19c --- /dev/null +++ b/public/resource/tinymce/plugins/autoresize/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.4.2 (2023-04-26) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.Env");const o=e=>t=>t.options.get(e),s=o("min_height"),i=o("max_height"),n=o("autoresize_overflow_padding"),r=o("autoresize_bottom_margin"),l=(e,t)=>{const o=e.getBody();o&&(o.style.overflowY=t?"":"hidden",t||(o.scrollTop=0))},g=(e,t,o,s)=>{var i;const n=parseInt(null!==(i=e.getStyle(t,o,s))&&void 0!==i?i:"",10);return isNaN(n)?0:n},a=(e,o,r,c)=>{var d;const f=e.dom,u=e.getDoc();if(!u)return;if((e=>e.plugins.fullscreen&&e.plugins.fullscreen.isFullscreen())(e))return void l(e,!0);const m=u.documentElement,h=c?c():n(e),p=null!==(d=s(e))&&void 0!==d?d:e.getElement().offsetHeight;let y=p;const S=g(f,m,"margin-top",!0),v=g(f,m,"margin-bottom",!0);let C=m.offsetHeight+S+v+h;C<0&&(C=0);const b=e.getContainer().offsetHeight-e.getContentAreaContainer().offsetHeight;C+b>p&&(y=C+b);const w=i(e);if(w&&y>w?(y=w,l(e,!0)):l(e,!1),y!==o.get()){const s=y-o.get();if(f.setStyle(e.getContainer(),"height",y+"px"),o.set(y),(e=>{e.dispatch("ResizeEditor")})(e),t.browser.isSafari()&&(t.os.isMacOS()||t.os.isiOS())){const t=e.getWin();t.scrollTo(t.pageXOffset,t.pageYOffset)}e.hasFocus()&&(e=>{if("setcontent"===(null==e?void 0:e.type.toLowerCase())){const t=e;return!0===t.selection||!0===t.paste}return!1})(r)&&e.selection.scrollIntoView(),(t.browser.isSafari()||t.browser.isChromium())&&s<0&&a(e,o,r,c)}};e.add("autoresize",(e=>{if((e=>{const t=e.options.register;t("autoresize_overflow_padding",{processor:"number",default:1}),t("autoresize_bottom_margin",{processor:"number",default:50})})(e),e.options.isSet("resize")||e.options.set("resize",!1),!e.inline){const o=(e=>{let t=0;return{get:()=>t,set:e=>{t=e}}})();((e,t)=>{e.addCommand("mceAutoResize",(()=>{a(e,t)}))})(e,o),((e,o)=>{let s,i,l=()=>r(e);e.on("init",(i=>{s=0;const r=n(e),g=e.dom;g.setStyles(e.getDoc().documentElement,{height:"auto"}),t.browser.isEdge()||t.browser.isIE()?g.setStyles(e.getBody(),{paddingLeft:r,paddingRight:r,"min-height":0}):g.setStyles(e.getBody(),{paddingLeft:r,paddingRight:r}),a(e,o,i,l),s+=1})),e.on("NodeChange SetContent keyup FullscreenStateChanged ResizeContent",(t=>{if(1===s)i=e.getContainer().offsetHeight,a(e,o,t,l),s+=1;else if(2===s){const t=i0):l,s+=1}else a(e,o,t,l)}))})(e,o)}}))}(); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/autosave/plugin.min.js b/public/resource/tinymce/plugins/autosave/plugin.min.js new file mode 100644 index 0000000..74dbd66 --- /dev/null +++ b/public/resource/tinymce/plugins/autosave/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.4.2 (2023-04-26) + */ +!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=("string",t=>"string"===(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(r=o=t,(a=String).prototype.isPrototypeOf(r)||(null===(s=o.constructor)||void 0===s?void 0:s.name)===a.name)?"string":e;var r,o,a,s})(t));const r=(void 0,t=>undefined===t);var o=tinymce.util.Tools.resolve("tinymce.util.Delay"),a=tinymce.util.Tools.resolve("tinymce.util.LocalStorage"),s=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=t=>{const e=/^(\d+)([ms]?)$/.exec(t);return(e&&e[2]?{s:1e3,m:6e4}[e[2]]:1)*parseInt(t,10)},i=t=>e=>e.options.get(t),u=i("autosave_ask_before_unload"),l=i("autosave_restore_when_empty"),c=i("autosave_interval"),d=i("autosave_retention"),m=t=>{const e=document.location;return t.options.get("autosave_prefix").replace(/{path}/g,e.pathname).replace(/{query}/g,e.search).replace(/{hash}/g,e.hash).replace(/{id}/g,t.id)},v=(t,e)=>{if(r(e))return t.dom.isEmpty(t.getBody());{const r=s.trim(e);if(""===r)return!0;{const e=(new DOMParser).parseFromString(r,"text/html");return t.dom.isEmpty(e)}}},f=t=>{var e;const r=parseInt(null!==(e=a.getItem(m(t)+"time"))&&void 0!==e?e:"0",10)||0;return!((new Date).getTime()-r>d(t)&&(p(t,!1),1))},p=(t,e)=>{const r=m(t);a.removeItem(r+"draft"),a.removeItem(r+"time"),!1!==e&&(t=>{t.dispatch("RemoveDraft")})(t)},g=t=>{const e=m(t);!v(t)&&t.isDirty()&&(a.setItem(e+"draft",t.getContent({format:"raw",no_events:!0})),a.setItem(e+"time",(new Date).getTime().toString()),(t=>{t.dispatch("StoreDraft")})(t))},y=t=>{var e;const r=m(t);f(t)&&(t.setContent(null!==(e=a.getItem(r+"draft"))&&void 0!==e?e:"",{format:"raw"}),(t=>{t.dispatch("RestoreDraft")})(t))};var D=tinymce.util.Tools.resolve("tinymce.EditorManager");const h=t=>e=>{e.setEnabled(f(t));const r=()=>e.setEnabled(f(t));return t.on("StoreDraft RestoreDraft RemoveDraft",r),()=>t.off("StoreDraft RestoreDraft RemoveDraft",r)};t.add("autosave",(t=>((t=>{const r=t.options.register,o=t=>{const r=e(t);return r?{value:n(t),valid:r}:{valid:!1,message:"Must be a string."}};r("autosave_ask_before_unload",{processor:"boolean",default:!0}),r("autosave_prefix",{processor:"string",default:"tinymce-autosave-{path}{query}{hash}-{id}-"}),r("autosave_restore_when_empty",{processor:"boolean",default:!1}),r("autosave_interval",{processor:o,default:"30s"}),r("autosave_retention",{processor:o,default:"20m"})})(t),(t=>{t.editorManager.on("BeforeUnload",(t=>{let e;s.each(D.get(),(t=>{t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&u(t)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))})),e&&(t.preventDefault(),t.returnValue=e)}))})(t),(t=>{(t=>{const e=c(t);o.setEditorInterval(t,(()=>{g(t)}),e)})(t);const e=()=>{(t=>{t.undoManager.transact((()=>{y(t),p(t)})),t.focus()})(t)};t.ui.registry.addButton("restoredraft",{tooltip:"Restore last draft",icon:"restore-draft",onAction:e,onSetup:h(t)}),t.ui.registry.addMenuItem("restoredraft",{text:"Restore last draft",icon:"restore-draft",onAction:e,onSetup:h(t)})})(t),t.on("init",(()=>{l(t)&&t.dom.isEmpty(t.getBody())&&y(t)})),(t=>({hasDraft:()=>f(t),storeDraft:()=>g(t),restoreDraft:()=>y(t),removeDraft:e=>p(t,e),isEmpty:e=>v(t,e)}))(t))))}(); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/charmap/plugin.min.js b/public/resource/tinymce/plugins/charmap/plugin.min.js new file mode 100644 index 0000000..50a48fa --- /dev/null +++ b/public/resource/tinymce/plugins/charmap/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.4.2 (2023-04-26) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=(e,t)=>{const r=((e,t)=>e.dispatch("insertCustomChar",{chr:t}))(e,t).chr;e.execCommand("mceInsertContent",!1,r)},r=e=>t=>e===t,a=("array",e=>"array"===(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(r=a=e,(n=String).prototype.isPrototypeOf(r)||(null===(i=a.constructor)||void 0===i?void 0:i.name)===n.name)?"string":t;var r,a,n,i})(e));const n=r(null),i=r(void 0),o=e=>"function"==typeof e,s=(!1,()=>false);class l{constructor(e,t){this.tag=e,this.value=t}static some(e){return new l(!0,e)}static none(){return l.singletonNone}fold(e,t){return this.tag?t(this.value):e()}isSome(){return this.tag}isNone(){return!this.tag}map(e){return this.tag?l.some(e(this.value)):l.none()}bind(e){return this.tag?e(this.value):l.none()}exists(e){return this.tag&&e(this.value)}forall(e){return!this.tag||e(this.value)}filter(e){return!this.tag||e(this.value)?this:l.none()}getOr(e){return this.tag?this.value:e}or(e){return this.tag?this:e}getOrThunk(e){return this.tag?this.value:e()}orThunk(e){return this.tag?this:e()}getOrDie(e){if(this.tag)return this.value;throw new Error(null!=e?e:"Called getOrDie on None")}static from(e){return null==e?l.none():l.some(e)}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(e){this.tag&&e(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}l.singletonNone=new l(!1);const c=Array.prototype.push,u=(e,t)=>{const r=e.length,a=new Array(r);for(let n=0;nt=>t.options.get(e),m=h("charmap"),p=h("charmap_append"),d=g.isArray,f="User Defined",y=e=>{return d(e)?(t=e,g.grep(t,(e=>d(e)&&2===e.length))):"function"==typeof e?e():[];var t},w=e=>{const t=((e,t)=>{const r=m(e);r&&(t=[{name:f,characters:y(r)}]);const a=p(e);if(a){const e=g.grep(t,(e=>e.name===f));return e.length?(e[0].characters=[...e[0].characters,...y(a)],t):t.concat({name:f,characters:y(a)})}return t})(e,[{name:"Currency",characters:[[36,"dollar sign"],[162,"cent sign"],[8364,"euro sign"],[163,"pound sign"],[165,"yen sign"],[164,"currency sign"],[8352,"euro-currency sign"],[8353,"colon sign"],[8354,"cruzeiro sign"],[8355,"french franc sign"],[8356,"lira sign"],[8357,"mill sign"],[8358,"naira sign"],[8359,"peseta sign"],[8360,"rupee sign"],[8361,"won sign"],[8362,"new sheqel sign"],[8363,"dong sign"],[8365,"kip sign"],[8366,"tugrik sign"],[8367,"drachma sign"],[8368,"german penny symbol"],[8369,"peso sign"],[8370,"guarani sign"],[8371,"austral sign"],[8372,"hryvnia sign"],[8373,"cedi sign"],[8374,"livre tournois sign"],[8375,"spesmilo sign"],[8376,"tenge sign"],[8377,"indian rupee sign"],[8378,"turkish lira sign"],[8379,"nordic mark sign"],[8380,"manat sign"],[8381,"ruble sign"],[20870,"yen character"],[20803,"yuan character"],[22291,"yuan character, in hong kong and taiwan"],[22278,"yen/yuan character variant one"]]},{name:"Text",characters:[[169,"copyright sign"],[174,"registered sign"],[8482,"trade mark sign"],[8240,"per mille sign"],[181,"micro sign"],[183,"middle dot"],[8226,"bullet"],[8230,"three dot leader"],[8242,"minutes / feet"],[8243,"seconds / inches"],[167,"section sign"],[182,"paragraph sign"],[223,"sharp s / ess-zed"]]},{name:"Quotations",characters:[[8249,"single left-pointing angle quotation mark"],[8250,"single right-pointing angle quotation mark"],[171,"left pointing guillemet"],[187,"right pointing guillemet"],[8216,"left single quotation mark"],[8217,"right single quotation mark"],[8220,"left double quotation mark"],[8221,"right double quotation mark"],[8218,"single low-9 quotation mark"],[8222,"double low-9 quotation mark"],[60,"less-than sign"],[62,"greater-than sign"],[8804,"less-than or equal to"],[8805,"greater-than or equal to"],[8211,"en dash"],[8212,"em dash"],[175,"macron"],[8254,"overline"],[164,"currency sign"],[166,"broken bar"],[168,"diaeresis"],[161,"inverted exclamation mark"],[191,"turned question mark"],[710,"circumflex accent"],[732,"small tilde"],[176,"degree sign"],[8722,"minus sign"],[177,"plus-minus sign"],[247,"division sign"],[8260,"fraction slash"],[215,"multiplication sign"],[185,"superscript one"],[178,"superscript two"],[179,"superscript three"],[188,"fraction one quarter"],[189,"fraction one half"],[190,"fraction three quarters"]]},{name:"Mathematical",characters:[[402,"function / florin"],[8747,"integral"],[8721,"n-ary sumation"],[8734,"infinity"],[8730,"square root"],[8764,"similar to"],[8773,"approximately equal to"],[8776,"almost equal to"],[8800,"not equal to"],[8801,"identical to"],[8712,"element of"],[8713,"not an element of"],[8715,"contains as member"],[8719,"n-ary product"],[8743,"logical and"],[8744,"logical or"],[172,"not sign"],[8745,"intersection"],[8746,"union"],[8706,"partial differential"],[8704,"for all"],[8707,"there exists"],[8709,"diameter"],[8711,"backward difference"],[8727,"asterisk operator"],[8733,"proportional to"],[8736,"angle"]]},{name:"Extended Latin",characters:[[192,"A - grave"],[193,"A - acute"],[194,"A - circumflex"],[195,"A - tilde"],[196,"A - diaeresis"],[197,"A - ring above"],[256,"A - macron"],[198,"ligature AE"],[199,"C - cedilla"],[200,"E - grave"],[201,"E - acute"],[202,"E - circumflex"],[203,"E - diaeresis"],[274,"E - macron"],[204,"I - grave"],[205,"I - acute"],[206,"I - circumflex"],[207,"I - diaeresis"],[298,"I - macron"],[208,"ETH"],[209,"N - tilde"],[210,"O - grave"],[211,"O - acute"],[212,"O - circumflex"],[213,"O - tilde"],[214,"O - diaeresis"],[216,"O - slash"],[332,"O - macron"],[338,"ligature OE"],[352,"S - caron"],[217,"U - grave"],[218,"U - acute"],[219,"U - circumflex"],[220,"U - diaeresis"],[362,"U - macron"],[221,"Y - acute"],[376,"Y - diaeresis"],[562,"Y - macron"],[222,"THORN"],[224,"a - grave"],[225,"a - acute"],[226,"a - circumflex"],[227,"a - tilde"],[228,"a - diaeresis"],[229,"a - ring above"],[257,"a - macron"],[230,"ligature ae"],[231,"c - cedilla"],[232,"e - grave"],[233,"e - acute"],[234,"e - circumflex"],[235,"e - diaeresis"],[275,"e - macron"],[236,"i - grave"],[237,"i - acute"],[238,"i - circumflex"],[239,"i - diaeresis"],[299,"i - macron"],[240,"eth"],[241,"n - tilde"],[242,"o - grave"],[243,"o - acute"],[244,"o - circumflex"],[245,"o - tilde"],[246,"o - diaeresis"],[248,"o slash"],[333,"o macron"],[339,"ligature oe"],[353,"s - caron"],[249,"u - grave"],[250,"u - acute"],[251,"u - circumflex"],[252,"u - diaeresis"],[363,"u - macron"],[253,"y - acute"],[254,"thorn"],[255,"y - diaeresis"],[563,"y - macron"],[913,"Alpha"],[914,"Beta"],[915,"Gamma"],[916,"Delta"],[917,"Epsilon"],[918,"Zeta"],[919,"Eta"],[920,"Theta"],[921,"Iota"],[922,"Kappa"],[923,"Lambda"],[924,"Mu"],[925,"Nu"],[926,"Xi"],[927,"Omicron"],[928,"Pi"],[929,"Rho"],[931,"Sigma"],[932,"Tau"],[933,"Upsilon"],[934,"Phi"],[935,"Chi"],[936,"Psi"],[937,"Omega"],[945,"alpha"],[946,"beta"],[947,"gamma"],[948,"delta"],[949,"epsilon"],[950,"zeta"],[951,"eta"],[952,"theta"],[953,"iota"],[954,"kappa"],[955,"lambda"],[956,"mu"],[957,"nu"],[958,"xi"],[959,"omicron"],[960,"pi"],[961,"rho"],[962,"final sigma"],[963,"sigma"],[964,"tau"],[965,"upsilon"],[966,"phi"],[967,"chi"],[968,"psi"],[969,"omega"]]},{name:"Symbols",characters:[[8501,"alef symbol"],[982,"pi symbol"],[8476,"real part symbol"],[978,"upsilon - hook symbol"],[8472,"Weierstrass p"],[8465,"imaginary part"]]},{name:"Arrows",characters:[[8592,"leftwards arrow"],[8593,"upwards arrow"],[8594,"rightwards arrow"],[8595,"downwards arrow"],[8596,"left right arrow"],[8629,"carriage return"],[8656,"leftwards double arrow"],[8657,"upwards double arrow"],[8658,"rightwards double arrow"],[8659,"downwards double arrow"],[8660,"left right double arrow"],[8756,"therefore"],[8834,"subset of"],[8835,"superset of"],[8836,"not a subset of"],[8838,"subset of or equal to"],[8839,"superset of or equal to"],[8853,"circled plus"],[8855,"circled times"],[8869,"perpendicular"],[8901,"dot operator"],[8968,"left ceiling"],[8969,"right ceiling"],[8970,"left floor"],[8971,"right floor"],[9001,"left-pointing angle bracket"],[9002,"right-pointing angle bracket"],[9674,"lozenge"],[9824,"black spade suit"],[9827,"black club suit"],[9829,"black heart suit"],[9830,"black diamond suit"],[8194,"en space"],[8195,"em space"],[8201,"thin space"],[8204,"zero width non-joiner"],[8205,"zero width joiner"],[8206,"left-to-right mark"],[8207,"right-to-left mark"]]}]);return t.length>1?[{name:"All",characters:(r=t,n=e=>e.characters,(e=>{const t=[];for(let r=0,n=e.length;r{let t=e;return{get:()=>t,set:e=>{t=e}}},b=(e,t,r=0,a)=>{const n=e.indexOf(t,r);return-1!==n&&(!!i(a)||n+t.length<=a)},k=String.fromCodePoint,C=(e,t)=>{const r=[],a=t.toLowerCase();return((e,t)=>{for(let t=0,i=e.length;t!!b(k(e).toLowerCase(),r)||b(t.toLowerCase(),r)||b(t.toLowerCase().replace(/\s+/g,""),r))((n=e[t])[0],n[1],a)&&r.push(n);var n})(e.characters),u(r,(e=>({text:e[1],value:k(e[0]),icon:k(e[0])})))},x="pattern",A=(e,r)=>{const a=()=>[{label:"Search",type:"input",name:x},{type:"collection",name:"results"}],i=1===r.length?v(f):v("All"),o=((e,t)=>{let r=null;const a=()=>{n(r)||(clearTimeout(r),r=null)};return{cancel:a,throttle:(...t)=>{a(),r=setTimeout((()=>{r=null,e.apply(null,t)}),40)}}})((e=>{const t=e.getData().pattern;((e,t)=>{var a,n;(a=r,n=e=>e.name===i.get(),((e,t,r)=>{for(let a=0,n=e.length;a{const a=C(r,t);e.setData({results:a})}))})(e,t)})),c={title:"Special Character",size:"normal",body:1===r.length?{type:"panel",items:a()}:{type:"tabpanel",tabs:u(r,(e=>({title:e.name,name:e.name,items:a()})))},buttons:[{type:"cancel",name:"close",text:"Close",primary:!0}],initialData:{pattern:"",results:C(r[0],"")},onAction:(r,a)=>{"results"===a.name&&(t(e,a.value),r.close())},onTabChange:(e,t)=>{i.set(t.newTabName),o.throttle(e)},onChange:(e,t)=>{t.name===x&&o.throttle(e)}};e.windowManager.open(c).focus(x)};e.add("charmap",(e=>{(e=>{const t=e.options.register,r=e=>o(e)||a(e);t("charmap",{processor:r}),t("charmap_append",{processor:r})})(e);const r=w(e);return((e,t)=>{e.addCommand("mceShowCharmap",(()=>{A(e,t)}))})(e,r),(e=>{const t=()=>e.execCommand("mceShowCharmap");e.ui.registry.addButton("charmap",{icon:"insert-character",tooltip:"Special character",onAction:t}),e.ui.registry.addMenuItem("charmap",{icon:"insert-character",text:"Special character...",onAction:t})})(e),((e,t)=>{e.ui.registry.addAutocompleter("charmap",{trigger:":",columns:"auto",minChars:2,fetch:(e,r)=>new Promise(((r,a)=>{r(C(t,e))})),onAction:(t,r,a)=>{e.selection.setRng(r),e.insertContent(a),t.hide()}})})(e,r[0]),(e=>({getCharMap:()=>w(e),insertChar:r=>{t(e,r)}}))(e)}))}(); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/code/plugin.min.js b/public/resource/tinymce/plugins/code/plugin.min.js new file mode 100644 index 0000000..34e553b --- /dev/null +++ b/public/resource/tinymce/plugins/code/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.4.2 (2023-04-26) + */ +!function(){"use strict";tinymce.util.Tools.resolve("tinymce.PluginManager").add("code",(e=>((e=>{e.addCommand("mceCodeEditor",(()=>{(e=>{const o=(e=>e.getContent({source_view:!0}))(e);e.windowManager.open({title:"Source Code",size:"large",body:{type:"panel",items:[{type:"textarea",name:"code"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{code:o},onSubmit:o=>{((e,o)=>{e.focus(),e.undoManager.transact((()=>{e.setContent(o)})),e.selection.setCursorLocation(),e.nodeChanged()})(e,o.getData().code),o.close()}})})(e)}))})(e),(e=>{const o=()=>e.execCommand("mceCodeEditor");e.ui.registry.addButton("code",{icon:"sourcecode",tooltip:"Source code",onAction:o}),e.ui.registry.addMenuItem("code",{icon:"sourcecode",text:"Source code",onAction:o})})(e),{})))}(); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/codesample/plugin.min.js b/public/resource/tinymce/plugins/codesample/plugin.min.js new file mode 100644 index 0000000..4329d5e --- /dev/null +++ b/public/resource/tinymce/plugins/codesample/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.4.2 (2023-04-26) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>!(e=>null==e)(e);class n{constructor(e,t){this.tag=e,this.value=t}static some(e){return new n(!0,e)}static none(){return n.singletonNone}fold(e,t){return this.tag?t(this.value):e()}isSome(){return this.tag}isNone(){return!this.tag}map(e){return this.tag?n.some(e(this.value)):n.none()}bind(e){return this.tag?e(this.value):n.none()}exists(e){return this.tag&&e(this.value)}forall(e){return!this.tag||e(this.value)}filter(e){return!this.tag||e(this.value)?this:n.none()}getOr(e){return this.tag?this.value:e}or(e){return this.tag?this:e}getOrThunk(e){return this.tag?this.value:e()}orThunk(e){return this.tag?this:e()}getOrDie(e){if(this.tag)return this.value;throw new Error(null!=e?e:"Called getOrDie on None")}static from(e){return t(e)?n.some(e):n.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(e){this.tag&&e(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}n.singletonNone=new n(!1);var a=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils");const s="undefined"!=typeof window?window:Function("return this;")(),r=function(e,t,n){const a=window.Prism;window.Prism={manual:!0};var s=function(e){var t=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,n=0,a={},s={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(t){return t instanceof r?new r(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=d.reach);x+=_.value.length,_=_.next){var F=_.value;if(t.length>e.length)return;if(!(F instanceof r)){var A,S=1;if(y){if(!(A=i(v,x,e,m))||A.index>=e.length)break;var $=A.index,z=A.index+A[0].length,E=x;for(E+=_.value.length;$>=E;)E+=(_=_.next).value.length;if(x=E-=_.value.length,_.value instanceof r)continue;for(var C=_;C!==t.tail&&(Ed.reach&&(d.reach=O);var P=_.prev;if(B&&(P=u(t,P,B),x+=B.length),c(t,P,S),_=u(t,P,new r(g,f?s.tokenize(j,f):j,w,j)),T&&u(t,_,T),S>1){var N={cause:g+","+b,reach:O};o(e,t,n,_.prev,x,N),d&&N.reach>d.reach&&(d.reach=N.reach)}}}}}}function l(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function u(e,t,n){var a=t.next,s={value:n,prev:t,next:a};return t.next=s,a.prev=s,e.length++,s}function c(e,t,n){for(var a=t.next,s=0;s"+r.content+""},!e.document)return e.addEventListener?(s.disableWorkerMessageHandler||e.addEventListener("message",(function(t){var n=JSON.parse(t.data),a=n.language,r=n.code,i=n.immediateClose;e.postMessage(s.highlight(r,s.languages[a],a)),i&&e.close()}),!1),s):s;var d=s.util.currentScript();function g(){s.manual||s.highlightAll()}if(d&&(s.filename=d.src,d.hasAttribute("data-manual")&&(s.manual=!0)),!s.manual){var p=document.readyState;"loading"===p||"interactive"===p&&d&&d.defer?document.addEventListener("DOMContentLoaded",g):window.requestAnimationFrame?window.requestAnimationFrame(g):window.setTimeout(g,16)}return s}("undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{});return s.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,a,s,r){if(n.language===a){var i=n.tokenStack=[];n.code=n.code.replace(s,(function(e){if("function"==typeof r&&!r(e))return e;for(var s,o=i.length;-1!==n.code.indexOf(s=t(a,o));)++o;return i[o]=e,s})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,a){if(n.language===a&&n.tokenStack){n.grammar=e.languages[a];var s=0,r=Object.keys(n.tokenStack);!function i(o){for(var l=0;l=r.length);l++){var u=o[l];if("string"==typeof u||u.content&&"string"==typeof u.content){var c=r[s],d=n.tokenStack[c],g="string"==typeof u?u:u.content,p=t(a,c),b=g.indexOf(p);if(b>-1){++s;var h=g.substring(0,b),f=new e.Token(a,e.tokenize(d,n.grammar),"language-"+a,d),m=g.substring(b+p.length),y=[];h&&y.push.apply(y,i([h])),y.push(f),m&&y.push.apply(y,i([m])),"string"==typeof u?o.splice.apply(o,[l,1].concat(y)):u.content=y}}else u.content&&i(u.content)}return o}(n.tokens)}}}})}(s),s.languages.c=s.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),s.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),s.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},s.languages.c.string],char:s.languages.c.char,comment:s.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:s.languages.c}}}}),s.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete s.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(s),function(e){function t(e,t){return e.replace(/<<(\d+)>>/g,(function(e,n){return"(?:"+t[+n]+")"}))}function n(e,n,a){return RegExp(t(e,n),a||"")}function a(e,t){for(var n=0;n>/g,(function(){return"(?:"+e+")"}));return e.replace(/<>/g,"[^\\s\\S]")}var s="bool byte char decimal double dynamic float int long object sbyte short string uint ulong ushort var void",r="class enum interface record struct",i="add alias and ascending async await by descending from(?=\\s*(?:\\w|$)) get global group into init(?=\\s*;) join let nameof not notnull on or orderby partial remove select set unmanaged value when where with(?=\\s*{)",o="abstract as base break case catch checked const continue default delegate do else event explicit extern finally fixed for foreach goto if implicit in internal is lock namespace new null operator out override params private protected public readonly ref return sealed sizeof stackalloc static switch this throw try typeof unchecked unsafe using virtual volatile while yield";function l(e){return"\\b(?:"+e.trim().replace(/ /g,"|")+")\\b"}var u=l(r),c=RegExp(l(s+" "+r+" "+i+" "+o)),d=l(r+" "+i+" "+o),g=l(s+" "+r+" "+o),p=a(/<(?:[^<>;=+\-*/%&|^]|<>)*>/.source,2),b=a(/\((?:[^()]|<>)*\)/.source,2),h=/@?\b[A-Za-z_]\w*\b/.source,f=t(/<<0>>(?:\s*<<1>>)?/.source,[h,p]),m=t(/(?!<<0>>)<<1>>(?:\s*\.\s*<<1>>)*/.source,[d,f]),y=/\[\s*(?:,\s*)*\]/.source,w=t(/<<0>>(?:\s*(?:\?\s*)?<<1>>)*(?:\s*\?)?/.source,[m,y]),k=t(/[^,()<>[\];=+\-*/%&|^]|<<0>>|<<1>>|<<2>>/.source,[p,b,y]),v=t(/\(<<0>>+(?:,<<0>>+)+\)/.source,[k]),_=t(/(?:<<0>>|<<1>>)(?:\s*(?:\?\s*)?<<2>>)*(?:\s*\?)?/.source,[v,m,y]),x={keyword:c,punctuation:/[<>()?,.:[\]]/},F=/'(?:[^\r\n'\\]|\\.|\\[Uux][\da-fA-F]{1,8})'/.source,A=/"(?:\\.|[^\\"\r\n])*"/.source,S=/@"(?:""|\\[\s\S]|[^\\"])*"(?!")/.source;e.languages.csharp=e.languages.extend("clike",{string:[{pattern:n(/(^|[^$\\])<<0>>/.source,[S]),lookbehind:!0,greedy:!0},{pattern:n(/(^|[^@$\\])<<0>>/.source,[A]),lookbehind:!0,greedy:!0}],"class-name":[{pattern:n(/(\busing\s+static\s+)<<0>>(?=\s*;)/.source,[m]),lookbehind:!0,inside:x},{pattern:n(/(\busing\s+<<0>>\s*=\s*)<<1>>(?=\s*;)/.source,[h,_]),lookbehind:!0,inside:x},{pattern:n(/(\busing\s+)<<0>>(?=\s*=)/.source,[h]),lookbehind:!0},{pattern:n(/(\b<<0>>\s+)<<1>>/.source,[u,f]),lookbehind:!0,inside:x},{pattern:n(/(\bcatch\s*\(\s*)<<0>>/.source,[m]),lookbehind:!0,inside:x},{pattern:n(/(\bwhere\s+)<<0>>/.source,[h]),lookbehind:!0},{pattern:n(/(\b(?:is(?:\s+not)?|as)\s+)<<0>>/.source,[w]),lookbehind:!0,inside:x},{pattern:n(/\b<<0>>(?=\s+(?!<<1>>|with\s*\{)<<2>>(?:\s*[=,;:{)\]]|\s+(?:in|when)\b))/.source,[_,g,h]),inside:x}],keyword:c,number:/(?:\b0(?:x[\da-f_]*[\da-f]|b[01_]*[01])|(?:\B\.\d+(?:_+\d+)*|\b\d+(?:_+\d+)*(?:\.\d+(?:_+\d+)*)?)(?:e[-+]?\d+(?:_+\d+)*)?)(?:[dflmu]|lu|ul)?\b/i,operator:/>>=?|<<=?|[-=]>|([-+&|])\1|~|\?\?=?|[-+*/%&|^!=<>]=?/,punctuation:/\?\.?|::|[{}[\];(),.:]/}),e.languages.insertBefore("csharp","number",{range:{pattern:/\.\./,alias:"operator"}}),e.languages.insertBefore("csharp","punctuation",{"named-parameter":{pattern:n(/([(,]\s*)<<0>>(?=\s*:)/.source,[h]),lookbehind:!0,alias:"punctuation"}}),e.languages.insertBefore("csharp","class-name",{namespace:{pattern:n(/(\b(?:namespace|using)\s+)<<0>>(?:\s*\.\s*<<0>>)*(?=\s*[;{])/.source,[h]),lookbehind:!0,inside:{punctuation:/\./}},"type-expression":{pattern:n(/(\b(?:default|sizeof|typeof)\s*\(\s*(?!\s))(?:[^()\s]|\s(?!\s)|<<0>>)*(?=\s*\))/.source,[b]),lookbehind:!0,alias:"class-name",inside:x},"return-type":{pattern:n(/<<0>>(?=\s+(?:<<1>>\s*(?:=>|[({]|\.\s*this\s*\[)|this\s*\[))/.source,[_,m]),inside:x,alias:"class-name"},"constructor-invocation":{pattern:n(/(\bnew\s+)<<0>>(?=\s*[[({])/.source,[_]),lookbehind:!0,inside:x,alias:"class-name"},"generic-method":{pattern:n(/<<0>>\s*<<1>>(?=\s*\()/.source,[h,p]),inside:{function:n(/^<<0>>/.source,[h]),generic:{pattern:RegExp(p),alias:"class-name",inside:x}}},"type-list":{pattern:n(/\b((?:<<0>>\s+<<1>>|record\s+<<1>>\s*<<5>>|where\s+<<2>>)\s*:\s*)(?:<<3>>|<<4>>|<<1>>\s*<<5>>|<<6>>)(?:\s*,\s*(?:<<3>>|<<4>>|<<6>>))*(?=\s*(?:where|[{;]|=>|$))/.source,[u,f,h,_,c.source,b,/\bnew\s*\(\s*\)/.source]),lookbehind:!0,inside:{"record-arguments":{pattern:n(/(^(?!new\s*\()<<0>>\s*)<<1>>/.source,[f,b]),lookbehind:!0,greedy:!0,inside:e.languages.csharp},keyword:c,"class-name":{pattern:RegExp(_),greedy:!0,inside:x},punctuation:/[,()]/}},preprocessor:{pattern:/(^[\t ]*)#.*/m,lookbehind:!0,alias:"property",inside:{directive:{pattern:/(#)\b(?:define|elif|else|endif|endregion|error|if|line|nullable|pragma|region|undef|warning)\b/,lookbehind:!0,alias:"keyword"}}}});var $=A+"|"+F,z=t(/\/(?![*/])|\/\/[^\r\n]*[\r\n]|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>/.source,[$]),E=a(t(/[^"'/()]|<<0>>|\(<>*\)/.source,[z]),2),C=/\b(?:assembly|event|field|method|module|param|property|return|type)\b/.source,j=t(/<<0>>(?:\s*\(<<1>>*\))?/.source,[m,E]);e.languages.insertBefore("csharp","class-name",{attribute:{pattern:n(/((?:^|[^\s\w>)?])\s*\[\s*)(?:<<0>>\s*:\s*)?<<1>>(?:\s*,\s*<<1>>)*(?=\s*\])/.source,[C,j]),lookbehind:!0,greedy:!0,inside:{target:{pattern:n(/^<<0>>(?=\s*:)/.source,[C]),alias:"keyword"},"attribute-arguments":{pattern:n(/\(<<0>>*\)/.source,[E]),inside:e.languages.csharp},"class-name":{pattern:RegExp(m),inside:{punctuation:/\./}},punctuation:/[:,]/}}});var B=/:[^}\r\n]+/.source,T=a(t(/[^"'/()]|<<0>>|\(<>*\)/.source,[z]),2),O=t(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source,[T,B]),P=a(t(/[^"'/()]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>|\(<>*\)/.source,[$]),2),N=t(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source,[P,B]);function R(t,a){return{interpolation:{pattern:n(/((?:^|[^{])(?:\{\{)*)<<0>>/.source,[t]),lookbehind:!0,inside:{"format-string":{pattern:n(/(^\{(?:(?![}:])<<0>>)*)<<1>>(?=\}$)/.source,[a,B]),lookbehind:!0,inside:{punctuation:/^:/}},punctuation:/^\{|\}$/,expression:{pattern:/[\s\S]+/,alias:"language-csharp",inside:e.languages.csharp}}},string:/[\s\S]+/}}e.languages.insertBefore("csharp","string",{"interpolation-string":[{pattern:n(/(^|[^\\])(?:\$@|@\$)"(?:""|\\[\s\S]|\{\{|<<0>>|[^\\{"])*"/.source,[O]),lookbehind:!0,greedy:!0,inside:R(O,T)},{pattern:n(/(^|[^@\\])\$"(?:\\.|\{\{|<<0>>|[^\\"{])*"/.source,[N]),lookbehind:!0,greedy:!0,inside:R(N,P)}],char:{pattern:RegExp(F),greedy:!0}}),e.languages.dotnet=e.languages.cs=e.languages.csharp}(s),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(s),function(e){var t=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,n=/(?:[a-z]\w*\s*\.\s*)*(?:[A-Z]\w*\s*\.\s*)*/.source,a={pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z](?:[\d_A-Z]*[a-z]\w*)?\b/.source),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[a,{pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z]\w*(?=\s+\w+\s*[;,=()]|\s*(?:\[[\s,]*\]\s*)?::\s*new\b)/.source),lookbehind:!0,inside:a.inside},{pattern:RegExp(/(\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\s+)/.source+n+/[A-Z]\w*\b/.source),lookbehind:!0,inside:a.inside}],keyword:t,function:[e.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0}}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":a,keyword:t,punctuation:/[<>(),.:]/,operator:/[?&|]/}},import:[{pattern:RegExp(/(\bimport\s+)/.source+n+/(?:[A-Z]\w*|\*)(?=\s*;)/.source),lookbehind:!0,inside:{namespace:a.inside.namespace,punctuation:/\./,operator:/\*/,"class-name":/\w+/}},{pattern:RegExp(/(\bimport\s+static\s+)/.source+n+/(?:\w+|\*)(?=\s*;)/.source),lookbehind:!0,alias:"static",inside:{namespace:a.inside.namespace,static:/\b\w+$/,punctuation:/\./,operator:/\*/,"class-name":/\w+/}}],namespace:{pattern:RegExp(/(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!)[a-z]\w*(?:\.[a-z]\w*)*\.?/.source.replace(//g,(function(){return t.source}))),lookbehind:!0,inside:{punctuation:/\./}}})}(s),s.languages.javascript=s.languages.extend("clike",{"class-name":[s.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),s.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,s.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:s.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:s.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:s.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:s.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:s.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),s.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:s.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),s.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),s.languages.markup&&(s.languages.markup.tag.addInlined("script","javascript"),s.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),s.languages.js=s.languages.javascript,s.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},s.languages.markup.tag.inside["attr-value"].inside.entity=s.languages.markup.entity,s.languages.markup.doctype.inside["internal-subset"].inside=s.languages.markup,s.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(s.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:s.languages[t]},n.cdata=/^$/i;var a={"included-cdata":{pattern://i,inside:n}};a["language-"+t]={pattern:/[\s\S]+/,inside:s.languages[t]};var r={};r[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:a},s.languages.insertBefore("markup","cdata",r)}}),Object.defineProperty(s.languages.markup.tag,"addAttribute",{value:function(e,t){s.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:s.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),s.languages.html=s.languages.markup,s.languages.mathml=s.languages.markup,s.languages.svg=s.languages.markup,s.languages.xml=s.languages.extend("markup",{}),s.languages.ssml=s.languages.xml,s.languages.atom=s.languages.xml,s.languages.rss=s.languages.xml,function(e){var t=/\/\*[\s\S]*?\*\/|\/\/.*|#(?!\[).*/,n=[{pattern:/\b(?:false|true)\b/i,alias:"boolean"},{pattern:/(::\s*)\b[a-z_]\w*\b(?!\s*\()/i,greedy:!0,lookbehind:!0},{pattern:/(\b(?:case|const)\s+)\b[a-z_]\w*(?=\s*[;=])/i,greedy:!0,lookbehind:!0},/\b(?:null)\b/i,/\b[A-Z_][A-Z0-9_]*\b(?!\s*\()/],a=/\b0b[01]+(?:_[01]+)*\b|\b0o[0-7]+(?:_[0-7]+)*\b|\b0x[\da-f]+(?:_[\da-f]+)*\b|(?:\b\d+(?:_\d+)*\.?(?:\d+(?:_\d+)*)?|\B\.\d+)(?:e[+-]?\d+)?/i,s=/|\?\?=?|\.{3}|\??->|[!=]=?=?|::|\*\*=?|--|\+\+|&&|\|\||<<|>>|[?~]|[/^|%*&<>.+-]=?/,r=/[{}\[\](),:;]/;e.languages.php={delimiter:{pattern:/\?>$|^<\?(?:php(?=\s)|=)?/i,alias:"important"},comment:t,variable:/\$+(?:\w+\b|(?=\{))/,package:{pattern:/(namespace\s+|use\s+(?:function\s+)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,lookbehind:!0,inside:{punctuation:/\\/}},"class-name-definition":{pattern:/(\b(?:class|enum|interface|trait)\s+)\b[a-z_]\w*(?!\\)\b/i,lookbehind:!0,alias:"class-name"},"function-definition":{pattern:/(\bfunction\s+)[a-z_]\w*(?=\s*\()/i,lookbehind:!0,alias:"function"},keyword:[{pattern:/(\(\s*)\b(?:array|bool|boolean|float|int|integer|object|string)\b(?=\s*\))/i,alias:"type-casting",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|object|self|static|string)\b(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|never|object|self|static|string|void)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/\b(?:array(?!\s*\()|bool|float|int|iterable|mixed|object|string|void)\b/i,alias:"type-declaration",greedy:!0},{pattern:/(\|\s*)(?:false|null)\b|\b(?:false|null)(?=\s*\|)/i,alias:"type-declaration",greedy:!0,lookbehind:!0},{pattern:/\b(?:parent|self|static)(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(\byield\s+)from\b/i,lookbehind:!0},/\bclass\b/i,{pattern:/((?:^|[^\s>:]|(?:^|[^-])>|(?:^|[^:]):)\s*)\b(?:abstract|and|array|as|break|callable|case|catch|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|enum|eval|exit|extends|final|finally|fn|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|match|namespace|never|new|or|parent|print|private|protected|public|readonly|require|require_once|return|self|static|switch|throw|trait|try|unset|use|var|while|xor|yield|__halt_compiler)\b/i,lookbehind:!0}],"argument-name":{pattern:/([(,]\s*)\b[a-z_]\w*(?=\s*:(?!:))/i,lookbehind:!0},"class-name":[{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self|\s+static))\s+|\bcatch\s*\()\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/(\|\s*)\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/\b[a-z_]\w*(?!\\)\b(?=\s*\|)/i,greedy:!0},{pattern:/(\|\s*)(?:\\?\b[a-z_]\w*)+\b/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(?:\\?\b[a-z_]\w*)+\b(?=\s*\|)/i,alias:"class-name-fully-qualified",greedy:!0,inside:{punctuation:/\\/}},{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self\b|\s+static\b))\s+|\bcatch\s*\()(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*\$)/i,alias:"type-declaration",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-declaration"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*::)/i,alias:["class-name-fully-qualified","static-context"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/([(,?]\s*)[a-z_]\w*(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-hint"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b[a-z_]\w*(?!\\)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:["class-name-fully-qualified","return-type"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:n,function:{pattern:/(^|[^\\\w])\\?[a-z_](?:[\w\\]*\w)?(?=\s*\()/i,lookbehind:!0,inside:{punctuation:/\\/}},property:{pattern:/(->\s*)\w+/,lookbehind:!0},number:a,operator:s,punctuation:r};var i={pattern:/\{\$(?:\{(?:\{[^{}]+\}|[^{}]+)\}|[^{}])+\}|(^|[^\\{])\$+(?:\w+(?:\[[^\r\n\[\]]+\]|->\w+)?)/,lookbehind:!0,inside:e.languages.php},o=[{pattern:/<<<'([^']+)'[\r\n](?:.*[\r\n])*?\1;/,alias:"nowdoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<'[^']+'|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<'?|[';]$/}}}},{pattern:/<<<(?:"([^"]+)"[\r\n](?:.*[\r\n])*?\1;|([a-z_]\w*)[\r\n](?:.*[\r\n])*?\2;)/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<"?|[";]$/}},interpolation:i}},{pattern:/`(?:\\[\s\S]|[^\\`])*`/,alias:"backtick-quoted-string",greedy:!0},{pattern:/'(?:\\[\s\S]|[^\\'])*'/,alias:"single-quoted-string",greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,alias:"double-quoted-string",greedy:!0,inside:{interpolation:i}}];e.languages.insertBefore("php","variable",{string:o,attribute:{pattern:/#\[(?:[^"'\/#]|\/(?![*/])|\/\/.*$|#(?!\[).*$|\/\*(?:[^*]|\*(?!\/))*\*\/|"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*')+\](?=\s*[a-z$#])/im,greedy:!0,inside:{"attribute-content":{pattern:/^(#\[)[\s\S]+(?=\]$)/,lookbehind:!0,inside:{comment:t,string:o,"attribute-class-name":[{pattern:/([^:]|^)\b[a-z_]\w*(?!\\)\b/i,alias:"class-name",greedy:!0,lookbehind:!0},{pattern:/([^:]|^)(?:\\?\b[a-z_]\w*)+/i,alias:["class-name","class-name-fully-qualified"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:n,number:a,operator:s,punctuation:r}},delimiter:{pattern:/^#\[|\]$/,alias:"punctuation"}}}}),e.hooks.add("before-tokenize",(function(t){/<\?/.test(t.code)&&e.languages["markup-templating"].buildPlaceholders(t,"php",/<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#(?!\[))(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|#\[|\/\*(?:[^*]|\*(?!\/))*(?:\*\/|$))*?(?:\?>|$)/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"php")}))}(s),s.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},s.languages.python["string-interpolation"].inside.interpolation.inside.rest=s.languages.python,s.languages.py=s.languages.python,function(e){e.languages.ruby=e.languages.extend("clike",{comment:{pattern:/#.*|^=begin\s[\s\S]*?^=end/m,greedy:!0},"class-name":{pattern:/(\b(?:class|module)\s+|\bcatch\s+\()[\w.\\]+|\b[A-Z_]\w*(?=\s*\.\s*new\b)/,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:BEGIN|END|alias|and|begin|break|case|class|def|define_method|defined|do|each|else|elsif|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|private|protected|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/,operator:/\.{2,3}|&\.|===||[!=]?~|(?:&&|\|\||<<|>>|\*\*|[+\-*/%<>!^&|=])=?|[?:]/,punctuation:/[(){}[\].,;]/}),e.languages.insertBefore("ruby","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}});var t={pattern:/((?:^|[^\\])(?:\\{2})*)#\{(?:[^{}]|\{[^{}]*\})*\}/,lookbehind:!0,inside:{content:{pattern:/^(#\{)[\s\S]+(?=\}$)/,lookbehind:!0,inside:e.languages.ruby},delimiter:{pattern:/^#\{|\}$/,alias:"punctuation"}}};delete e.languages.ruby.function;var n="(?:"+[/([^a-zA-Z0-9\s{(\[<=])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,/\((?:[^()\\]|\\[\s\S]|\((?:[^()\\]|\\[\s\S])*\))*\)/.source,/\{(?:[^{}\\]|\\[\s\S]|\{(?:[^{}\\]|\\[\s\S])*\})*\}/.source,/\[(?:[^\[\]\\]|\\[\s\S]|\[(?:[^\[\]\\]|\\[\s\S])*\])*\]/.source,/<(?:[^<>\\]|\\[\s\S]|<(?:[^<>\\]|\\[\s\S])*>)*>/.source].join("|")+")",a=/(?:"(?:\\.|[^"\\\r\n])*"|(?:\b[a-zA-Z_]\w*|[^\s\0-\x7F]+)[?!]?|\$.)/.source;e.languages.insertBefore("ruby","keyword",{"regex-literal":[{pattern:RegExp(/%r/.source+n+/[egimnosux]{0,6}/.source),greedy:!0,inside:{interpolation:t,regex:/[\s\S]+/}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,lookbehind:!0,greedy:!0,inside:{interpolation:t,regex:/[\s\S]+/}}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:[{pattern:RegExp(/(^|[^:]):/.source+a),lookbehind:!0,greedy:!0},{pattern:RegExp(/([\r\n{(,][ \t]*)/.source+a+/(?=:(?!:))/.source),lookbehind:!0,greedy:!0}],"method-definition":{pattern:/(\bdef\s+)\w+(?:\s*\.\s*\w+)?/,lookbehind:!0,inside:{function:/\b\w+$/,keyword:/^self\b/,"class-name":/^\w+/,punctuation:/\./}}}),e.languages.insertBefore("ruby","string",{"string-literal":[{pattern:RegExp(/%[qQiIwWs]?/.source+n),greedy:!0,inside:{interpolation:t,string:/[\s\S]+/}},{pattern:/("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,greedy:!0,inside:{interpolation:t,string:/[\s\S]+/}},{pattern:/<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?[a-z_]\w*|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?/}},interpolation:t,string:/[\s\S]+/}},{pattern:/<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?'[a-z_]\w*'|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?'|'$/}},string:/[\s\S]+/}}],"command-literal":[{pattern:RegExp(/%x/.source+n),greedy:!0,inside:{interpolation:t,command:{pattern:/[\s\S]+/,alias:"string"}}},{pattern:/`(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|[^\\`#\r\n])*`/,greedy:!0,inside:{interpolation:t,command:{pattern:/[\s\S]+/,alias:"string"}}}]}),delete e.languages.ruby.string,e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Fixnum|Float|Hash|IO|Integer|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|Stat|String|Struct|Symbol|TMS|Thread|ThreadGroup|Time|TrueClass)\b/,constant:/\b[A-Z][A-Z0-9_]*(?:[?!]|\b)/}),e.languages.rb=e.languages.ruby}(s),window.Prism=a,s}(),i=e=>t=>t.options.get(e),o=i("codesample_languages"),l=i("codesample_global_prismjs"),u=e=>s.Prism&&l(e)?s.Prism:r,c=e=>t(e)&&"PRE"===e.nodeName&&-1!==e.className.indexOf("language-"),d=e=>{const t=e.selection?e.selection.getNode():null;return c(t)?n.some(t):n.none()},g=e=>{const t=(e=>o(e)||[{text:"HTML/XML",value:"markup"},{text:"JavaScript",value:"javascript"},{text:"CSS",value:"css"},{text:"PHP",value:"php"},{text:"Ruby",value:"ruby"},{text:"Python",value:"python"},{text:"Java",value:"java"},{text:"C",value:"c"},{text:"C#",value:"csharp"},{text:"C++",value:"cpp"}])(e),s=(r=t,((e,t)=>0""),(e=>e.value));var r;const i=((e,t)=>d(e).fold((()=>t),(e=>{const n=e.className.match(/language-(\w+)/);return n?n[1]:t})))(e,s),l=(e=>d(e).bind((e=>n.from(e.textContent))).getOr(""))(e);e.windowManager.open({title:"Insert/Edit Code Sample",size:"large",body:{type:"panel",items:[{type:"selectbox",name:"language",label:"Language",items:t},{type:"textarea",name:"code",label:"Code view"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{language:i,code:l},onSubmit:t=>{const n=t.getData();((e,t,n)=>{const s=e.dom;e.undoManager.transact((()=>{const r=d(e);return n=a.DOM.encode(n),r.fold((()=>{e.insertContent('
    '+n+"
    ");const a=s.select("#__new")[0];s.setAttrib(a,"id",null),e.selection.select(a)}),(a=>{s.setAttrib(a,"class","language-"+t),a.innerHTML=n,u(e).highlightElement(a),e.selection.select(a)}))}))})(e,n.language,n.code),t.close()}})},p=(b=/^\s+|\s+$/g,e=>e.replace(b,""));var b,h=tinymce.util.Tools.resolve("tinymce.util.Tools");e.add("codesample",(e=>{(e=>{const t=e.options.register;t("codesample_languages",{processor:"object[]"}),t("codesample_global_prismjs",{processor:"boolean",default:!1})})(e),(e=>{e.on("PreProcess",(t=>{const n=e.dom,a=n.select("pre[contenteditable=false]",t.node);h.each(h.grep(a,c),(e=>{const t=e.textContent;let a;for(n.setAttrib(e,"class",p(n.getAttrib(e,"class"))),n.setAttrib(e,"contentEditable",null),n.setAttrib(e,"data-mce-highlighted",null);a=e.firstChild;)e.removeChild(a);n.add(e,"code").textContent=t}))})),e.on("SetContent",(()=>{const t=e.dom,n=h.grep(t.select("pre"),(e=>c(e)&&"true"!==t.getAttrib(e,"data-mce-highlighted")));n.length&&e.undoManager.transact((()=>{h.each(n,(n=>{var a;h.each(t.select("br",n),(n=>{t.replace(e.getDoc().createTextNode("\n"),n)})),n.innerHTML=t.encode(null!==(a=n.textContent)&&void 0!==a?a:""),u(e).highlightElement(n),t.setAttrib(n,"data-mce-highlighted",!0),n.className=p(n.className)}))}))})),e.on("PreInit",(()=>{e.parser.addNodeFilter("pre",(e=>{var t;for(let n=0,a=e.length;n{const t=()=>e.execCommand("codesample");e.ui.registry.addToggleButton("codesample",{icon:"code-sample",tooltip:"Insert/edit code sample",onAction:t,onSetup:t=>{const n=()=>{t.setActive((e=>{const t=e.selection.getStart();return e.dom.is(t,'pre[class*="language-"]')})(e))};return e.on("NodeChange",n),()=>e.off("NodeChange",n)}}),e.ui.registry.addMenuItem("codesample",{text:"Code sample...",icon:"code-sample",onAction:t})})(e),(e=>{e.addCommand("codesample",(()=>{const t=e.selection.getNode();e.selection.isCollapsed()||c(t)?g(e):e.formatter.toggle("code")}))})(e),e.on("dblclick",(t=>{c(t.target)&&g(e)}))}))}(); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/directionality/plugin.min.js b/public/resource/tinymce/plugins/directionality/plugin.min.js new file mode 100644 index 0000000..ee3a450 --- /dev/null +++ b/public/resource/tinymce/plugins/directionality/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.4.2 (2023-04-26) + */ +!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=t=>e=>typeof e===t,o=t=>"string"===(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(o=r=t,(n=String).prototype.isPrototypeOf(o)||(null===(i=r.constructor)||void 0===i?void 0:i.name)===n.name)?"string":e;var o,r,n,i})(t),r=e("boolean"),n=t=>!(t=>null==t)(t),i=e("function"),s=e("number"),l=(!1,()=>false);class a{constructor(t,e){this.tag=t,this.value=e}static some(t){return new a(!0,t)}static none(){return a.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?a.some(t(this.value)):a.none()}bind(t){return this.tag?t(this.value):a.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:a.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return n(t)?a.some(t):a.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}a.singletonNone=new a(!1);const u=(t,e)=>{for(let o=0,r=t.length;o{if(null==t)throw new Error("Node cannot be null or undefined");return{dom:t}},d=c,h=(t,e)=>{const o=t.dom;if(1!==o.nodeType)return!1;{const t=o;if(void 0!==t.matches)return t.matches(e);if(void 0!==t.msMatchesSelector)return t.msMatchesSelector(e);if(void 0!==t.webkitMatchesSelector)return t.webkitMatchesSelector(e);if(void 0!==t.mozMatchesSelector)return t.mozMatchesSelector(e);throw new Error("Browser lacks native selectors")}};"undefined"!=typeof window?window:Function("return this;")();const m=t=>e=>(t=>t.dom.nodeType)(e)===t,g=m(1),f=m(3),v=m(9),p=m(11),y=(t,e)=>{t.dom.removeAttribute(e)},w=i(Element.prototype.attachShadow)&&i(Node.prototype.getRootNode)?t=>d(t.dom.getRootNode()):t=>v(t)?t:d(t.dom.ownerDocument),N=t=>d(t.dom.host),b=t=>{const e=f(t)?t.dom.parentNode:t.dom;if(null==e||null===e.ownerDocument)return!1;const o=e.ownerDocument;return(t=>{const e=w(t);return p(o=e)&&n(o.dom.host)?a.some(e):a.none();var o})(d(e)).fold((()=>o.body.contains(e)),(r=b,i=N,t=>r(i(t))));var r,i},S=t=>"rtl"===((t,e)=>{const o=t.dom,r=window.getComputedStyle(o).getPropertyValue(e);return""!==r||b(t)?r:((t,e)=>(t=>void 0!==t.style&&i(t.style.getPropertyValue))(t)?t.style.getPropertyValue(e):"")(o,e)})(t,"direction")?"rtl":"ltr",A=(t,e)=>((t,o)=>((t,e)=>{const o=[];for(let r=0,n=t.length;r{const o=t.length,r=new Array(o);for(let n=0;nh(t,e))))(t),T=("li",t=>g(t)&&"li"===t.dom.nodeName.toLowerCase());const C=(t,e)=>{const n=t.selection.getSelectedBlocks();n.length>0&&(u(n,(t=>{const n=d(t),c=T(n),m=((t,e)=>{return(e?(o=t,r="ol,ul",((t,e,o)=>{let n=t.dom;const s=i(o)?o:l;for(;n.parentNode;){n=n.parentNode;const t=d(n);if(h(t,r))return a.some(t);if(s(t))break}return a.none()})(o,0,n)):a.some(t)).getOr(t);var o,r,n})(n,c);var f;(f=m,(t=>a.from(t.dom.parentNode).map(d))(f).filter(g)).each((t=>{if(S(t)!==e?((t,e,n)=>{((t,e,n)=>{if(!(o(n)||r(n)||s(n)))throw console.error("Invalid call to Attribute.set. Key ",e,":: Value ",n,":: Element ",t),new Error("Attribute value was not simple");t.setAttribute(e,n+"")})(t.dom,e,n)})(m,"dir",e):S(m)!==e&&y(m,"dir"),c){const t=A(m,"li[dir]");u(t,(t=>y(t,"dir")))}}))})),t.nodeChanged())},D=(t,e)=>o=>{const r=t=>{const r=d(t.element);o.setActive(S(r)===e)};return t.on("NodeChange",r),()=>t.off("NodeChange",r)};t.add("directionality",(t=>{(t=>{t.addCommand("mceDirectionLTR",(()=>{C(t,"ltr")})),t.addCommand("mceDirectionRTL",(()=>{C(t,"rtl")}))})(t),(t=>{t.ui.registry.addToggleButton("ltr",{tooltip:"Left to right",icon:"ltr",onAction:()=>t.execCommand("mceDirectionLTR"),onSetup:D(t,"ltr")}),t.ui.registry.addToggleButton("rtl",{tooltip:"Right to left",icon:"rtl",onAction:()=>t.execCommand("mceDirectionRTL"),onSetup:D(t,"rtl")})})(t)}))}(); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/emoticons/js/emojiimages.js b/public/resource/tinymce/plugins/emoticons/js/emojiimages.js new file mode 100644 index 0000000..6fcec71 --- /dev/null +++ b/public/resource/tinymce/plugins/emoticons/js/emojiimages.js @@ -0,0 +1 @@ +window.tinymce.Resource.add("tinymce.plugins.emoticons",{100:{keywords:["score","perfect","numbers","century","exam","quiz","test","pass","hundred"],char:'💯',fitzpatrick_scale:false,category:"symbols"},1234:{keywords:["numbers","blue-square"],char:'🔢',fitzpatrick_scale:false,category:"symbols"},grinning:{keywords:["face","smile","happy","joy",":D","grin"],char:'😀',fitzpatrick_scale:false,category:"people"},grimacing:{keywords:["face","grimace","teeth"],char:'😬',fitzpatrick_scale:false,category:"people"},grin:{keywords:["face","happy","smile","joy","kawaii"],char:'😁',fitzpatrick_scale:false,category:"people"},joy:{keywords:["face","cry","tears","weep","happy","happytears","haha"],char:'😂',fitzpatrick_scale:false,category:"people"},rofl:{keywords:["face","rolling","floor","laughing","lol","haha"],char:'🤣',fitzpatrick_scale:false,category:"people"},partying:{keywords:["face","celebration","woohoo"],char:'🥳',fitzpatrick_scale:false,category:"people"},smiley:{keywords:["face","happy","joy","haha",":D",":)","smile","funny"],char:'😃',fitzpatrick_scale:false,category:"people"},smile:{keywords:["face","happy","joy","funny","haha","laugh","like",":D",":)"],char:'😄',fitzpatrick_scale:false,category:"people"},sweat_smile:{keywords:["face","hot","happy","laugh","sweat","smile","relief"],char:'😅',fitzpatrick_scale:false,category:"people"},laughing:{keywords:["happy","joy","lol","satisfied","haha","face","glad","XD","laugh"],char:'😆',fitzpatrick_scale:false,category:"people"},innocent:{keywords:["face","angel","heaven","halo"],char:'😇',fitzpatrick_scale:false,category:"people"},wink:{keywords:["face","happy","mischievous","secret",";)","smile","eye"],char:'😉',fitzpatrick_scale:false,category:"people"},blush:{keywords:["face","smile","happy","flushed","crush","embarrassed","shy","joy"],char:'😊',fitzpatrick_scale:false,category:"people"},slightly_smiling_face:{keywords:["face","smile"],char:'🙂',fitzpatrick_scale:false,category:"people"},upside_down_face:{keywords:["face","flipped","silly","smile"],char:'🙃',fitzpatrick_scale:false,category:"people"},relaxed:{keywords:["face","blush","massage","happiness"],char:'☺️',fitzpatrick_scale:false,category:"people"},yum:{keywords:["happy","joy","tongue","smile","face","silly","yummy","nom","delicious","savouring"],char:'😋',fitzpatrick_scale:false,category:"people"},relieved:{keywords:["face","relaxed","phew","massage","happiness"],char:'😌',fitzpatrick_scale:false,category:"people"},heart_eyes:{keywords:["face","love","like","affection","valentines","infatuation","crush","heart"],char:'😍',fitzpatrick_scale:false,category:"people"},smiling_face_with_three_hearts:{keywords:["face","love","like","affection","valentines","infatuation","crush","hearts","adore"],char:'🥰',fitzpatrick_scale:false,category:"people"},kissing_heart:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:'😘',fitzpatrick_scale:false,category:"people"},kissing:{keywords:["love","like","face","3","valentines","infatuation","kiss"],char:'😗',fitzpatrick_scale:false,category:"people"},kissing_smiling_eyes:{keywords:["face","affection","valentines","infatuation","kiss"],char:'😙',fitzpatrick_scale:false,category:"people"},kissing_closed_eyes:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:'😚',fitzpatrick_scale:false,category:"people"},stuck_out_tongue_winking_eye:{keywords:["face","prank","childish","playful","mischievous","smile","wink","tongue"],char:'😜',fitzpatrick_scale:false,category:"people"},zany:{keywords:["face","goofy","crazy"],char:'🤪',fitzpatrick_scale:false,category:"people"},raised_eyebrow:{keywords:["face","distrust","scepticism","disapproval","disbelief","surprise"],char:'🤨',fitzpatrick_scale:false,category:"people"},monocle:{keywords:["face","stuffy","wealthy"],char:'🧐',fitzpatrick_scale:false,category:"people"},stuck_out_tongue_closed_eyes:{keywords:["face","prank","playful","mischievous","smile","tongue"],char:'😝',fitzpatrick_scale:false,category:"people"},stuck_out_tongue:{keywords:["face","prank","childish","playful","mischievous","smile","tongue"],char:'😛',fitzpatrick_scale:false,category:"people"},money_mouth_face:{keywords:["face","rich","dollar","money"],char:'🤑',fitzpatrick_scale:false,category:"people"},nerd_face:{keywords:["face","nerdy","geek","dork"],char:'🤓',fitzpatrick_scale:false,category:"people"},sunglasses:{keywords:["face","cool","smile","summer","beach","sunglass"],char:'😎',fitzpatrick_scale:false,category:"people"},star_struck:{keywords:["face","smile","starry","eyes","grinning"],char:'🤩',fitzpatrick_scale:false,category:"people"},clown_face:{keywords:["face"],char:'🤡',fitzpatrick_scale:false,category:"people"},cowboy_hat_face:{keywords:["face","cowgirl","hat"],char:'🤠',fitzpatrick_scale:false,category:"people"},hugs:{keywords:["face","smile","hug"],char:'🤗',fitzpatrick_scale:false,category:"people"},smirk:{keywords:["face","smile","mean","prank","smug","sarcasm"],char:'😏',fitzpatrick_scale:false,category:"people"},no_mouth:{keywords:["face","hellokitty"],char:'😶',fitzpatrick_scale:false,category:"people"},neutral_face:{keywords:["indifference","meh",":|","neutral"],char:'😐',fitzpatrick_scale:false,category:"people"},expressionless:{keywords:["face","indifferent","-_-","meh","deadpan"],char:'😑',fitzpatrick_scale:false,category:"people"},unamused:{keywords:["indifference","bored","straight face","serious","sarcasm","unimpressed","skeptical","dubious","side_eye"],char:'😒',fitzpatrick_scale:false,category:"people"},roll_eyes:{keywords:["face","eyeroll","frustrated"],char:'🙄',fitzpatrick_scale:false,category:"people"},thinking:{keywords:["face","hmmm","think","consider"],char:'🤔',fitzpatrick_scale:false,category:"people"},lying_face:{keywords:["face","lie","pinocchio"],char:'🤥',fitzpatrick_scale:false,category:"people"},hand_over_mouth:{keywords:["face","whoops","shock","surprise"],char:'🤭',fitzpatrick_scale:false,category:"people"},shushing:{keywords:["face","quiet","shhh"],char:'🤫',fitzpatrick_scale:false,category:"people"},symbols_over_mouth:{keywords:["face","swearing","cursing","cussing","profanity","expletive"],char:'🤬',fitzpatrick_scale:false,category:"people"},exploding_head:{keywords:["face","shocked","mind","blown"],char:'🤯',fitzpatrick_scale:false,category:"people"},flushed:{keywords:["face","blush","shy","flattered"],char:'😳',fitzpatrick_scale:false,category:"people"},disappointed:{keywords:["face","sad","upset","depressed",":("],char:'😞',fitzpatrick_scale:false,category:"people"},worried:{keywords:["face","concern","nervous",":("],char:'😟',fitzpatrick_scale:false,category:"people"},angry:{keywords:["mad","face","annoyed","frustrated"],char:'😠',fitzpatrick_scale:false,category:"people"},rage:{keywords:["angry","mad","hate","despise"],char:'😡',fitzpatrick_scale:false,category:"people"},pensive:{keywords:["face","sad","depressed","upset"],char:'😔',fitzpatrick_scale:false,category:"people"},confused:{keywords:["face","indifference","huh","weird","hmmm",":/"],char:'😕',fitzpatrick_scale:false,category:"people"},slightly_frowning_face:{keywords:["face","frowning","disappointed","sad","upset"],char:'🙁',fitzpatrick_scale:false,category:"people"},frowning_face:{keywords:["face","sad","upset","frown"],char:'☹',fitzpatrick_scale:false,category:"people"},persevere:{keywords:["face","sick","no","upset","oops"],char:'😣',fitzpatrick_scale:false,category:"people"},confounded:{keywords:["face","confused","sick","unwell","oops",":S"],char:'😖',fitzpatrick_scale:false,category:"people"},tired_face:{keywords:["sick","whine","upset","frustrated"],char:'😫',fitzpatrick_scale:false,category:"people"},weary:{keywords:["face","tired","sleepy","sad","frustrated","upset"],char:'😩',fitzpatrick_scale:false,category:"people"},pleading:{keywords:["face","begging","mercy"],char:'🥺',fitzpatrick_scale:false,category:"people"},triumph:{keywords:["face","gas","phew","proud","pride"],char:'😤',fitzpatrick_scale:false,category:"people"},open_mouth:{keywords:["face","surprise","impressed","wow","whoa",":O"],char:'😮',fitzpatrick_scale:false,category:"people"},scream:{keywords:["face","munch","scared","omg"],char:'😱',fitzpatrick_scale:false,category:"people"},fearful:{keywords:["face","scared","terrified","nervous","oops","huh"],char:'😨',fitzpatrick_scale:false,category:"people"},cold_sweat:{keywords:["face","nervous","sweat"],char:'😰',fitzpatrick_scale:false,category:"people"},hushed:{keywords:["face","woo","shh"],char:'😯',fitzpatrick_scale:false,category:"people"},frowning:{keywords:["face","aw","what"],char:'😦',fitzpatrick_scale:false,category:"people"},anguished:{keywords:["face","stunned","nervous"],char:'😧',fitzpatrick_scale:false,category:"people"},cry:{keywords:["face","tears","sad","depressed","upset",":'("],char:'😢',fitzpatrick_scale:false,category:"people"},disappointed_relieved:{keywords:["face","phew","sweat","nervous"],char:'😥',fitzpatrick_scale:false,category:"people"},drooling_face:{keywords:["face"],char:'🤤',fitzpatrick_scale:false,category:"people"},sleepy:{keywords:["face","tired","rest","nap"],char:'😪',fitzpatrick_scale:false,category:"people"},sweat:{keywords:["face","hot","sad","tired","exercise"],char:'😓',fitzpatrick_scale:false,category:"people"},hot:{keywords:["face","feverish","heat","red","sweating"],char:'🥵',fitzpatrick_scale:false,category:"people"},cold:{keywords:["face","blue","freezing","frozen","frostbite","icicles"],char:'🥶',fitzpatrick_scale:false,category:"people"},sob:{keywords:["face","cry","tears","sad","upset","depressed"],char:'😭',fitzpatrick_scale:false,category:"people"},dizzy_face:{keywords:["spent","unconscious","xox","dizzy"],char:'😵',fitzpatrick_scale:false,category:"people"},astonished:{keywords:["face","xox","surprised","poisoned"],char:'😲',fitzpatrick_scale:false,category:"people"},zipper_mouth_face:{keywords:["face","sealed","zipper","secret"],char:'🤐',fitzpatrick_scale:false,category:"people"},nauseated_face:{keywords:["face","vomit","gross","green","sick","throw up","ill"],char:'🤢',fitzpatrick_scale:false,category:"people"},sneezing_face:{keywords:["face","gesundheit","sneeze","sick","allergy"],char:'🤧',fitzpatrick_scale:false,category:"people"},vomiting:{keywords:["face","sick"],char:'🤮',fitzpatrick_scale:false,category:"people"},mask:{keywords:["face","sick","ill","disease"],char:'😷',fitzpatrick_scale:false,category:"people"},face_with_thermometer:{keywords:["sick","temperature","thermometer","cold","fever"],char:'🤒',fitzpatrick_scale:false,category:"people"},face_with_head_bandage:{keywords:["injured","clumsy","bandage","hurt"],char:'🤕',fitzpatrick_scale:false,category:"people"},woozy:{keywords:["face","dizzy","intoxicated","tipsy","wavy"],char:'🥴',fitzpatrick_scale:false,category:"people"},sleeping:{keywords:["face","tired","sleepy","night","zzz"],char:'😴',fitzpatrick_scale:false,category:"people"},zzz:{keywords:["sleepy","tired","dream"],char:'💤',fitzpatrick_scale:false,category:"people"},poop:{keywords:["hankey","shitface","fail","turd","shit"],char:'💩',fitzpatrick_scale:false,category:"people"},smiling_imp:{keywords:["devil","horns"],char:'😈',fitzpatrick_scale:false,category:"people"},imp:{keywords:["devil","angry","horns"],char:'👿',fitzpatrick_scale:false,category:"people"},japanese_ogre:{keywords:["monster","red","mask","halloween","scary","creepy","devil","demon","japanese","ogre"],char:'👹',fitzpatrick_scale:false,category:"people"},japanese_goblin:{keywords:["red","evil","mask","monster","scary","creepy","japanese","goblin"],char:'👺',fitzpatrick_scale:false,category:"people"},skull:{keywords:["dead","skeleton","creepy","death"],char:'💀',fitzpatrick_scale:false,category:"people"},ghost:{keywords:["halloween","spooky","scary"],char:'👻',fitzpatrick_scale:false,category:"people"},alien:{keywords:["UFO","paul","weird","outer_space"],char:'👽',fitzpatrick_scale:false,category:"people"},robot:{keywords:["computer","machine","bot"],char:'🤖',fitzpatrick_scale:false,category:"people"},smiley_cat:{keywords:["animal","cats","happy","smile"],char:'😺',fitzpatrick_scale:false,category:"people"},smile_cat:{keywords:["animal","cats","smile"],char:'😸',fitzpatrick_scale:false,category:"people"},joy_cat:{keywords:["animal","cats","haha","happy","tears"],char:'😹',fitzpatrick_scale:false,category:"people"},heart_eyes_cat:{keywords:["animal","love","like","affection","cats","valentines","heart"],char:'😻',fitzpatrick_scale:false,category:"people"},smirk_cat:{keywords:["animal","cats","smirk"],char:'😼',fitzpatrick_scale:false,category:"people"},kissing_cat:{keywords:["animal","cats","kiss"],char:'😽',fitzpatrick_scale:false,category:"people"},scream_cat:{keywords:["animal","cats","munch","scared","scream"],char:'🙀',fitzpatrick_scale:false,category:"people"},crying_cat_face:{keywords:["animal","tears","weep","sad","cats","upset","cry"],char:'😿',fitzpatrick_scale:false,category:"people"},pouting_cat:{keywords:["animal","cats"],char:'😾',fitzpatrick_scale:false,category:"people"},palms_up:{keywords:["hands","gesture","cupped","prayer"],char:'🤲',fitzpatrick_scale:true,category:"people"},raised_hands:{keywords:["gesture","hooray","yea","celebration","hands"],char:'🙌',fitzpatrick_scale:true,category:"people"},clap:{keywords:["hands","praise","applause","congrats","yay"],char:'👏',fitzpatrick_scale:true,category:"people"},wave:{keywords:["hands","gesture","goodbye","solong","farewell","hello","hi","palm"],char:'👋',fitzpatrick_scale:true,category:"people"},call_me_hand:{keywords:["hands","gesture"],char:'🤙',fitzpatrick_scale:true,category:"people"},"+1":{keywords:["thumbsup","yes","awesome","good","agree","accept","cool","hand","like"],char:'👍',fitzpatrick_scale:true,category:"people"},"-1":{keywords:["thumbsdown","no","dislike","hand"],char:'👎',fitzpatrick_scale:true,category:"people"},facepunch:{keywords:["angry","violence","fist","hit","attack","hand"],char:'👊',fitzpatrick_scale:true,category:"people"},fist:{keywords:["fingers","hand","grasp"],char:'✊',fitzpatrick_scale:true,category:"people"},fist_left:{keywords:["hand","fistbump"],char:'🤛',fitzpatrick_scale:true,category:"people"},fist_right:{keywords:["hand","fistbump"],char:'🤜',fitzpatrick_scale:true,category:"people"},v:{keywords:["fingers","ohyeah","hand","peace","victory","two"],char:'✌',fitzpatrick_scale:true,category:"people"},ok_hand:{keywords:["fingers","limbs","perfect","ok","okay"],char:'👌',fitzpatrick_scale:true,category:"people"},raised_hand:{keywords:["fingers","stop","highfive","palm","ban"],char:'✋',fitzpatrick_scale:true,category:"people"},raised_back_of_hand:{keywords:["fingers","raised","backhand"],char:'🤚',fitzpatrick_scale:true,category:"people"},open_hands:{keywords:["fingers","butterfly","hands","open"],char:'👐',fitzpatrick_scale:true,category:"people"},muscle:{keywords:["arm","flex","hand","summer","strong","biceps"],char:'💪',fitzpatrick_scale:true,category:"people"},pray:{keywords:["please","hope","wish","namaste","highfive"],char:'🙏',fitzpatrick_scale:true,category:"people"},foot:{keywords:["kick","stomp"],char:'🦶',fitzpatrick_scale:true,category:"people"},leg:{keywords:["kick","limb"],char:'🦵',fitzpatrick_scale:true,category:"people"},handshake:{keywords:["agreement","shake"],char:'🤝',fitzpatrick_scale:false,category:"people"},point_up:{keywords:["hand","fingers","direction","up"],char:'☝',fitzpatrick_scale:true,category:"people"},point_up_2:{keywords:["fingers","hand","direction","up"],char:'👆',fitzpatrick_scale:true,category:"people"},point_down:{keywords:["fingers","hand","direction","down"],char:'👇',fitzpatrick_scale:true,category:"people"},point_left:{keywords:["direction","fingers","hand","left"],char:'👈',fitzpatrick_scale:true,category:"people"},point_right:{keywords:["fingers","hand","direction","right"],char:'👉',fitzpatrick_scale:true,category:"people"},fu:{keywords:["hand","fingers","rude","middle","flipping"],char:'🖕',fitzpatrick_scale:true,category:"people"},raised_hand_with_fingers_splayed:{keywords:["hand","fingers","palm"],char:'🖐',fitzpatrick_scale:true,category:"people"},love_you:{keywords:["hand","fingers","gesture"],char:'🤟',fitzpatrick_scale:true,category:"people"},metal:{keywords:["hand","fingers","evil_eye","sign_of_horns","rock_on"],char:'🤘',fitzpatrick_scale:true,category:"people"},crossed_fingers:{keywords:["good","lucky"],char:'🤞',fitzpatrick_scale:true,category:"people"},vulcan_salute:{keywords:["hand","fingers","spock","star trek"],char:'🖖',fitzpatrick_scale:true,category:"people"},writing_hand:{keywords:["lower_left_ballpoint_pen","stationery","write","compose"],char:'✍',fitzpatrick_scale:true,category:"people"},selfie:{keywords:["camera","phone"],char:'🤳',fitzpatrick_scale:true,category:"people"},nail_care:{keywords:["beauty","manicure","finger","fashion","nail"],char:'💅',fitzpatrick_scale:true,category:"people"},lips:{keywords:["mouth","kiss"],char:'👄',fitzpatrick_scale:false,category:"people"},tooth:{keywords:["teeth","dentist"],char:'🦷',fitzpatrick_scale:false,category:"people"},tongue:{keywords:["mouth","playful"],char:'👅',fitzpatrick_scale:false,category:"people"},ear:{keywords:["face","hear","sound","listen"],char:'👂',fitzpatrick_scale:true,category:"people"},nose:{keywords:["smell","sniff"],char:'👃',fitzpatrick_scale:true,category:"people"},eye:{keywords:["face","look","see","watch","stare"],char:'👁',fitzpatrick_scale:false,category:"people"},eyes:{keywords:["look","watch","stalk","peek","see"],char:'👀',fitzpatrick_scale:false,category:"people"},brain:{keywords:["smart","intelligent"],char:'🧠',fitzpatrick_scale:false,category:"people"},bust_in_silhouette:{keywords:["user","person","human"],char:'👤',fitzpatrick_scale:false,category:"people"},busts_in_silhouette:{keywords:["user","person","human","group","team"],char:'👥',fitzpatrick_scale:false,category:"people"},speaking_head:{keywords:["user","person","human","sing","say","talk"],char:'🗣',fitzpatrick_scale:false,category:"people"},baby:{keywords:["child","boy","girl","toddler"],char:'👶',fitzpatrick_scale:true,category:"people"},child:{keywords:["gender-neutral","young"],char:'🧒',fitzpatrick_scale:true,category:"people"},boy:{keywords:["man","male","guy","teenager"],char:'👦',fitzpatrick_scale:true,category:"people"},girl:{keywords:["female","woman","teenager"],char:'👧',fitzpatrick_scale:true,category:"people"},adult:{keywords:["gender-neutral","person"],char:'🧑',fitzpatrick_scale:true,category:"people"},man:{keywords:["mustache","father","dad","guy","classy","sir","moustache"],char:'👨',fitzpatrick_scale:true,category:"people"},woman:{keywords:["female","girls","lady"],char:'👩',fitzpatrick_scale:true,category:"people"},blonde_woman:{keywords:["woman","female","girl","blonde","person"],char:'👱‍♀️',fitzpatrick_scale:true,category:"people"},blonde_man:{keywords:["man","male","boy","blonde","guy","person"],char:'👱',fitzpatrick_scale:true,category:"people"},bearded_person:{keywords:["person","bewhiskered"],char:'🧔',fitzpatrick_scale:true,category:"people"},older_adult:{keywords:["human","elder","senior","gender-neutral"],char:'🧓',fitzpatrick_scale:true,category:"people"},older_man:{keywords:["human","male","men","old","elder","senior"],char:'👴',fitzpatrick_scale:true,category:"people"},older_woman:{keywords:["human","female","women","lady","old","elder","senior"],char:'👵',fitzpatrick_scale:true,category:"people"},man_with_gua_pi_mao:{keywords:["male","boy","chinese"],char:'👲',fitzpatrick_scale:true,category:"people"},woman_with_headscarf:{keywords:["female","hijab","mantilla","tichel"],char:'🧕',fitzpatrick_scale:true,category:"people"},woman_with_turban:{keywords:["female","indian","hinduism","arabs","woman"],char:'👳‍♀️',fitzpatrick_scale:true,category:"people"},man_with_turban:{keywords:["male","indian","hinduism","arabs"],char:'👳',fitzpatrick_scale:true,category:"people"},policewoman:{keywords:["woman","police","law","legal","enforcement","arrest","911","female"],char:'👮‍♀️',fitzpatrick_scale:true,category:"people"},policeman:{keywords:["man","police","law","legal","enforcement","arrest","911"],char:'👮',fitzpatrick_scale:true,category:"people"},construction_worker_woman:{keywords:["female","human","wip","build","construction","worker","labor","woman"],char:'👷‍♀️',fitzpatrick_scale:true,category:"people"},construction_worker_man:{keywords:["male","human","wip","guy","build","construction","worker","labor"],char:'👷',fitzpatrick_scale:true,category:"people"},guardswoman:{keywords:["uk","gb","british","female","royal","woman"],char:'💂‍♀️',fitzpatrick_scale:true,category:"people"},guardsman:{keywords:["uk","gb","british","male","guy","royal"],char:'💂',fitzpatrick_scale:true,category:"people"},female_detective:{keywords:["human","spy","detective","female","woman"],char:'🕵️‍♀️',fitzpatrick_scale:true,category:"people"},male_detective:{keywords:["human","spy","detective"],char:'🕵',fitzpatrick_scale:true,category:"people"},woman_health_worker:{keywords:["doctor","nurse","therapist","healthcare","woman","human"],char:'👩‍⚕️',fitzpatrick_scale:true,category:"people"},man_health_worker:{keywords:["doctor","nurse","therapist","healthcare","man","human"],char:'👨‍⚕️',fitzpatrick_scale:true,category:"people"},woman_farmer:{keywords:["rancher","gardener","woman","human"],char:'👩‍🌾',fitzpatrick_scale:true,category:"people"},man_farmer:{keywords:["rancher","gardener","man","human"],char:'👨‍🌾',fitzpatrick_scale:true,category:"people"},woman_cook:{keywords:["chef","woman","human"],char:'👩‍🍳',fitzpatrick_scale:true,category:"people"},man_cook:{keywords:["chef","man","human"],char:'👨‍🍳',fitzpatrick_scale:true,category:"people"},woman_student:{keywords:["graduate","woman","human"],char:'👩‍🎓',fitzpatrick_scale:true,category:"people"},man_student:{keywords:["graduate","man","human"],char:'👨‍🎓',fitzpatrick_scale:true,category:"people"},woman_singer:{keywords:["rockstar","entertainer","woman","human"],char:'👩‍🎤',fitzpatrick_scale:true,category:"people"},man_singer:{keywords:["rockstar","entertainer","man","human"],char:'👨‍🎤',fitzpatrick_scale:true,category:"people"},woman_teacher:{keywords:["instructor","professor","woman","human"],char:'👩‍🏫',fitzpatrick_scale:true,category:"people"},man_teacher:{keywords:["instructor","professor","man","human"],char:'👨‍🏫',fitzpatrick_scale:true,category:"people"},woman_factory_worker:{keywords:["assembly","industrial","woman","human"],char:'👩‍🏭',fitzpatrick_scale:true,category:"people"},man_factory_worker:{keywords:["assembly","industrial","man","human"],char:'👨‍🏭',fitzpatrick_scale:true,category:"people"},woman_technologist:{keywords:["coder","developer","engineer","programmer","software","woman","human","laptop","computer"],char:'👩‍💻',fitzpatrick_scale:true,category:"people"},man_technologist:{keywords:["coder","developer","engineer","programmer","software","man","human","laptop","computer"],char:'👨‍💻',fitzpatrick_scale:true,category:"people"},woman_office_worker:{keywords:["business","manager","woman","human"],char:'👩‍💼',fitzpatrick_scale:true,category:"people"},man_office_worker:{keywords:["business","manager","man","human"],char:'👨‍💼',fitzpatrick_scale:true,category:"people"},woman_mechanic:{keywords:["plumber","woman","human","wrench"],char:'👩‍🔧',fitzpatrick_scale:true,category:"people"},man_mechanic:{keywords:["plumber","man","human","wrench"],char:'👨‍🔧',fitzpatrick_scale:true,category:"people"},woman_scientist:{keywords:["biologist","chemist","engineer","physicist","woman","human"],char:'👩‍🔬',fitzpatrick_scale:true,category:"people"},man_scientist:{keywords:["biologist","chemist","engineer","physicist","man","human"],char:'👨‍🔬',fitzpatrick_scale:true,category:"people"},woman_artist:{keywords:["painter","woman","human"],char:'👩‍🎨',fitzpatrick_scale:true,category:"people"},man_artist:{keywords:["painter","man","human"],char:'👨‍🎨',fitzpatrick_scale:true,category:"people"},woman_firefighter:{keywords:["fireman","woman","human"],char:'👩‍🚒',fitzpatrick_scale:true,category:"people"},man_firefighter:{keywords:["fireman","man","human"],char:'👨‍🚒',fitzpatrick_scale:true,category:"people"},woman_pilot:{keywords:["aviator","plane","woman","human"],char:'👩‍✈️',fitzpatrick_scale:true,category:"people"},man_pilot:{keywords:["aviator","plane","man","human"],char:'👨‍✈️',fitzpatrick_scale:true,category:"people"},woman_astronaut:{keywords:["space","rocket","woman","human"],char:'👩‍🚀',fitzpatrick_scale:true,category:"people"},man_astronaut:{keywords:["space","rocket","man","human"],char:'👨‍🚀',fitzpatrick_scale:true,category:"people"},woman_judge:{keywords:["justice","court","woman","human"],char:'👩‍⚖️',fitzpatrick_scale:true,category:"people"},man_judge:{keywords:["justice","court","man","human"],char:'👨‍⚖️',fitzpatrick_scale:true,category:"people"},woman_superhero:{keywords:["woman","female","good","heroine","superpowers"],char:'🦸‍♀️',fitzpatrick_scale:true,category:"people"},man_superhero:{keywords:["man","male","good","hero","superpowers"],char:'🦸‍♂️',fitzpatrick_scale:true,category:"people"},woman_supervillain:{keywords:["woman","female","evil","bad","criminal","heroine","superpowers"],char:'🦹‍♀️',fitzpatrick_scale:true,category:"people"},man_supervillain:{keywords:["man","male","evil","bad","criminal","hero","superpowers"],char:'🦹‍♂️',fitzpatrick_scale:true,category:"people"},mrs_claus:{keywords:["woman","female","xmas","mother christmas"],char:'🤶',fitzpatrick_scale:true,category:"people"},santa:{keywords:["festival","man","male","xmas","father christmas"],char:'🎅',fitzpatrick_scale:true,category:"people"},sorceress:{keywords:["woman","female","mage","witch"],char:'🧙‍♀️',fitzpatrick_scale:true,category:"people"},wizard:{keywords:["man","male","mage","sorcerer"],char:'🧙‍♂️',fitzpatrick_scale:true,category:"people"},woman_elf:{keywords:["woman","female"],char:'🧝‍♀️',fitzpatrick_scale:true,category:"people"},man_elf:{keywords:["man","male"],char:'🧝‍♂️',fitzpatrick_scale:true,category:"people"},woman_vampire:{keywords:["woman","female"],char:'🧛‍♀️',fitzpatrick_scale:true,category:"people"},man_vampire:{keywords:["man","male","dracula"],char:'🧛‍♂️',fitzpatrick_scale:true,category:"people"},woman_zombie:{keywords:["woman","female","undead","walking dead"],char:'🧟‍♀️',fitzpatrick_scale:false,category:"people"},man_zombie:{keywords:["man","male","dracula","undead","walking dead"],char:'🧟‍♂️',fitzpatrick_scale:false,category:"people"},woman_genie:{keywords:["woman","female"],char:'🧞‍♀️',fitzpatrick_scale:false,category:"people"},man_genie:{keywords:["man","male"],char:'🧞‍♂️',fitzpatrick_scale:false,category:"people"},mermaid:{keywords:["woman","female","merwoman","ariel"],char:'🧜‍♀️',fitzpatrick_scale:true,category:"people"},merman:{keywords:["man","male","triton"],char:'🧜‍♂️',fitzpatrick_scale:true,category:"people"},woman_fairy:{keywords:["woman","female"],char:'🧚‍♀️',fitzpatrick_scale:true,category:"people"},man_fairy:{keywords:["man","male"],char:'🧚‍♂️',fitzpatrick_scale:true,category:"people"},angel:{keywords:["heaven","wings","halo"],char:'👼',fitzpatrick_scale:true,category:"people"},pregnant_woman:{keywords:["baby"],char:'🤰',fitzpatrick_scale:true,category:"people"},breastfeeding:{keywords:["nursing","baby"],char:'🤱',fitzpatrick_scale:true,category:"people"},princess:{keywords:["girl","woman","female","blond","crown","royal","queen"],char:'👸',fitzpatrick_scale:true,category:"people"},prince:{keywords:["boy","man","male","crown","royal","king"],char:'🤴',fitzpatrick_scale:true,category:"people"},bride_with_veil:{keywords:["couple","marriage","wedding","woman","bride"],char:'👰',fitzpatrick_scale:true,category:"people"},man_in_tuxedo:{keywords:["couple","marriage","wedding","groom"],char:'🤵',fitzpatrick_scale:true,category:"people"},running_woman:{keywords:["woman","walking","exercise","race","running","female"],char:'🏃‍♀️',fitzpatrick_scale:true,category:"people"},running_man:{keywords:["man","walking","exercise","race","running"],char:'🏃',fitzpatrick_scale:true,category:"people"},walking_woman:{keywords:["human","feet","steps","woman","female"],char:'🚶‍♀️',fitzpatrick_scale:true,category:"people"},walking_man:{keywords:["human","feet","steps"],char:'🚶',fitzpatrick_scale:true,category:"people"},dancer:{keywords:["female","girl","woman","fun"],char:'💃',fitzpatrick_scale:true,category:"people"},man_dancing:{keywords:["male","boy","fun","dancer"],char:'🕺',fitzpatrick_scale:true,category:"people"},dancing_women:{keywords:["female","bunny","women","girls"],char:'👯',fitzpatrick_scale:false,category:"people"},dancing_men:{keywords:["male","bunny","men","boys"],char:'👯‍♂️',fitzpatrick_scale:false,category:"people"},couple:{keywords:["pair","people","human","love","date","dating","like","affection","valentines","marriage"],char:'👫',fitzpatrick_scale:false,category:"people"},two_men_holding_hands:{keywords:["pair","couple","love","like","bromance","friendship","people","human"],char:'👬',fitzpatrick_scale:false,category:"people"},two_women_holding_hands:{keywords:["pair","friendship","couple","love","like","female","people","human"],char:'👭',fitzpatrick_scale:false,category:"people"},bowing_woman:{keywords:["woman","female","girl"],char:'🙇‍♀️',fitzpatrick_scale:true,category:"people"},bowing_man:{keywords:["man","male","boy"],char:'🙇',fitzpatrick_scale:true,category:"people"},man_facepalming:{keywords:["man","male","boy","disbelief"],char:'🤦‍♂️',fitzpatrick_scale:true,category:"people"},woman_facepalming:{keywords:["woman","female","girl","disbelief"],char:'🤦‍♀️',fitzpatrick_scale:true,category:"people"},woman_shrugging:{keywords:["woman","female","girl","confused","indifferent","doubt"],char:'🤷',fitzpatrick_scale:true,category:"people"},man_shrugging:{keywords:["man","male","boy","confused","indifferent","doubt"],char:'🤷‍♂️',fitzpatrick_scale:true,category:"people"},tipping_hand_woman:{keywords:["female","girl","woman","human","information"],char:'💁',fitzpatrick_scale:true,category:"people"},tipping_hand_man:{keywords:["male","boy","man","human","information"],char:'💁‍♂️',fitzpatrick_scale:true,category:"people"},no_good_woman:{keywords:["female","girl","woman","nope"],char:'🙅',fitzpatrick_scale:true,category:"people"},no_good_man:{keywords:["male","boy","man","nope"],char:'🙅‍♂️',fitzpatrick_scale:true,category:"people"},ok_woman:{keywords:["women","girl","female","pink","human","woman"],char:'🙆',fitzpatrick_scale:true,category:"people"},ok_man:{keywords:["men","boy","male","blue","human","man"],char:'🙆‍♂️',fitzpatrick_scale:true,category:"people"},raising_hand_woman:{keywords:["female","girl","woman"],char:'🙋',fitzpatrick_scale:true,category:"people"},raising_hand_man:{keywords:["male","boy","man"],char:'🙋‍♂️',fitzpatrick_scale:true,category:"people"},pouting_woman:{keywords:["female","girl","woman"],char:'🙎',fitzpatrick_scale:true,category:"people"},pouting_man:{keywords:["male","boy","man"],char:'🙎‍♂️',fitzpatrick_scale:true,category:"people"},frowning_woman:{keywords:["female","girl","woman","sad","depressed","discouraged","unhappy"],char:'🙍',fitzpatrick_scale:true,category:"people"},frowning_man:{keywords:["male","boy","man","sad","depressed","discouraged","unhappy"],char:'🙍‍♂️',fitzpatrick_scale:true,category:"people"},haircut_woman:{keywords:["female","girl","woman"],char:'💇',fitzpatrick_scale:true,category:"people"},haircut_man:{keywords:["male","boy","man"],char:'💇‍♂️',fitzpatrick_scale:true,category:"people"},massage_woman:{keywords:["female","girl","woman","head"],char:'💆',fitzpatrick_scale:true,category:"people"},massage_man:{keywords:["male","boy","man","head"],char:'💆‍♂️',fitzpatrick_scale:true,category:"people"},woman_in_steamy_room:{keywords:["female","woman","spa","steamroom","sauna"],char:'🧖‍♀️',fitzpatrick_scale:true,category:"people"},man_in_steamy_room:{keywords:["male","man","spa","steamroom","sauna"],char:'🧖‍♂️',fitzpatrick_scale:true,category:"people"},couple_with_heart_woman_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:'💑',fitzpatrick_scale:false,category:"people"},couple_with_heart_woman_woman:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:'👩‍❤️‍👩',fitzpatrick_scale:false,category:"people"},couple_with_heart_man_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:'👨‍❤️‍👨',fitzpatrick_scale:false,category:"people"},couplekiss_man_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:'💏',fitzpatrick_scale:false,category:"people"},couplekiss_woman_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:'👩‍❤️‍💋‍👩',fitzpatrick_scale:false,category:"people"},couplekiss_man_man:{keywords:["pair","valentines","love","like","dating","marriage"],char:'👨‍❤️‍💋‍👨',fitzpatrick_scale:false,category:"people"},family_man_woman_boy:{keywords:["home","parents","child","mom","dad","father","mother","people","human"],char:'👪',fitzpatrick_scale:false,category:"people"},family_man_woman_girl:{keywords:["home","parents","people","human","child"],char:'👨‍👩‍👧',fitzpatrick_scale:false,category:"people"},family_man_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:'👨‍👩‍👧‍👦',fitzpatrick_scale:false,category:"people"},family_man_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:'👨‍👩‍👦‍👦',fitzpatrick_scale:false,category:"people"},family_man_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:'👨‍👩‍👧‍👧',fitzpatrick_scale:false,category:"people"},family_woman_woman_boy:{keywords:["home","parents","people","human","children"],char:'👩‍👩‍👦',fitzpatrick_scale:false,category:"people"},family_woman_woman_girl:{keywords:["home","parents","people","human","children"],char:'👩‍👩‍👧',fitzpatrick_scale:false,category:"people"},family_woman_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:'👩‍👩‍👧‍👦',fitzpatrick_scale:false,category:"people"},family_woman_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:'👩‍👩‍👦‍👦',fitzpatrick_scale:false,category:"people"},family_woman_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:'👩‍👩‍👧‍👧',fitzpatrick_scale:false,category:"people"},family_man_man_boy:{keywords:["home","parents","people","human","children"],char:'👨‍👨‍👦',fitzpatrick_scale:false,category:"people"},family_man_man_girl:{keywords:["home","parents","people","human","children"],char:'👨‍👨‍👧',fitzpatrick_scale:false,category:"people"},family_man_man_girl_boy:{keywords:["home","parents","people","human","children"],char:'👨‍👨‍👧‍👦',fitzpatrick_scale:false,category:"people"},family_man_man_boy_boy:{keywords:["home","parents","people","human","children"],char:'👨‍👨‍👦‍👦',fitzpatrick_scale:false,category:"people"},family_man_man_girl_girl:{keywords:["home","parents","people","human","children"],char:'👨‍👨‍👧‍👧',fitzpatrick_scale:false,category:"people"},family_woman_boy:{keywords:["home","parent","people","human","child"],char:'👩‍👦',fitzpatrick_scale:false,category:"people"},family_woman_girl:{keywords:["home","parent","people","human","child"],char:'👩‍👧',fitzpatrick_scale:false,category:"people"},family_woman_girl_boy:{keywords:["home","parent","people","human","children"],char:'👩‍👧‍👦',fitzpatrick_scale:false,category:"people"},family_woman_boy_boy:{keywords:["home","parent","people","human","children"],char:'👩‍👦‍👦',fitzpatrick_scale:false,category:"people"},family_woman_girl_girl:{keywords:["home","parent","people","human","children"],char:'👩‍👧‍👧',fitzpatrick_scale:false,category:"people"},family_man_boy:{keywords:["home","parent","people","human","child"],char:'👨‍👦',fitzpatrick_scale:false,category:"people"},family_man_girl:{keywords:["home","parent","people","human","child"],char:'👨‍👧',fitzpatrick_scale:false,category:"people"},family_man_girl_boy:{keywords:["home","parent","people","human","children"],char:'👨‍👧‍👦',fitzpatrick_scale:false,category:"people"},family_man_boy_boy:{keywords:["home","parent","people","human","children"],char:'👨‍👦‍👦',fitzpatrick_scale:false,category:"people"},family_man_girl_girl:{keywords:["home","parent","people","human","children"],char:'👨‍👧‍👧',fitzpatrick_scale:false,category:"people"},yarn:{keywords:["ball","crochet","knit"],char:'🧶',fitzpatrick_scale:false,category:"people"},thread:{keywords:["needle","sewing","spool","string"],char:'🧵',fitzpatrick_scale:false,category:"people"},coat:{keywords:["jacket"],char:'🧥',fitzpatrick_scale:false,category:"people"},labcoat:{keywords:["doctor","experiment","scientist","chemist"],char:'🥼',fitzpatrick_scale:false,category:"people"},womans_clothes:{keywords:["fashion","shopping_bags","female"],char:'👚',fitzpatrick_scale:false,category:"people"},tshirt:{keywords:["fashion","cloth","casual","shirt","tee"],char:'👕',fitzpatrick_scale:false,category:"people"},jeans:{keywords:["fashion","shopping"],char:'👖',fitzpatrick_scale:false,category:"people"},necktie:{keywords:["shirt","suitup","formal","fashion","cloth","business"],char:'👔',fitzpatrick_scale:false,category:"people"},dress:{keywords:["clothes","fashion","shopping"],char:'👗',fitzpatrick_scale:false,category:"people"},bikini:{keywords:["swimming","female","woman","girl","fashion","beach","summer"],char:'👙',fitzpatrick_scale:false,category:"people"},kimono:{keywords:["dress","fashion","women","female","japanese"],char:'👘',fitzpatrick_scale:false,category:"people"},lipstick:{keywords:["female","girl","fashion","woman"],char:'💄',fitzpatrick_scale:false,category:"people"},kiss:{keywords:["face","lips","love","like","affection","valentines"],char:'💋',fitzpatrick_scale:false,category:"people"},footprints:{keywords:["feet","tracking","walking","beach"],char:'👣',fitzpatrick_scale:false,category:"people"},flat_shoe:{keywords:["ballet","slip-on","slipper"],char:'🥿',fitzpatrick_scale:false,category:"people"},high_heel:{keywords:["fashion","shoes","female","pumps","stiletto"],char:'👠',fitzpatrick_scale:false,category:"people"},sandal:{keywords:["shoes","fashion","flip flops"],char:'👡',fitzpatrick_scale:false,category:"people"},boot:{keywords:["shoes","fashion"],char:'👢',fitzpatrick_scale:false,category:"people"},mans_shoe:{keywords:["fashion","male"],char:'👞',fitzpatrick_scale:false,category:"people"},athletic_shoe:{keywords:["shoes","sports","sneakers"],char:'👟',fitzpatrick_scale:false,category:"people"},hiking_boot:{keywords:["backpacking","camping","hiking"],char:'🥾',fitzpatrick_scale:false,category:"people"},socks:{keywords:["stockings","clothes"],char:'🧦',fitzpatrick_scale:false,category:"people"},gloves:{keywords:["hands","winter","clothes"],char:'🧤',fitzpatrick_scale:false,category:"people"},scarf:{keywords:["neck","winter","clothes"],char:'🧣',fitzpatrick_scale:false,category:"people"},womans_hat:{keywords:["fashion","accessories","female","lady","spring"],char:'👒',fitzpatrick_scale:false,category:"people"},tophat:{keywords:["magic","gentleman","classy","circus"],char:'🎩',fitzpatrick_scale:false,category:"people"},billed_hat:{keywords:["cap","baseball"],char:'🧢',fitzpatrick_scale:false,category:"people"},rescue_worker_helmet:{keywords:["construction","build"],char:'⛑',fitzpatrick_scale:false,category:"people"},mortar_board:{keywords:["school","college","degree","university","graduation","cap","hat","legal","learn","education"],char:'🎓',fitzpatrick_scale:false,category:"people"},crown:{keywords:["king","kod","leader","royalty","lord"],char:'👑',fitzpatrick_scale:false,category:"people"},school_satchel:{keywords:["student","education","bag","backpack"],char:'🎒',fitzpatrick_scale:false,category:"people"},luggage:{keywords:["packing","travel"],char:'🧳',fitzpatrick_scale:false,category:"people"},pouch:{keywords:["bag","accessories","shopping"],char:'👝',fitzpatrick_scale:false,category:"people"},purse:{keywords:["fashion","accessories","money","sales","shopping"],char:'👛',fitzpatrick_scale:false,category:"people"},handbag:{keywords:["fashion","accessory","accessories","shopping"],char:'👜',fitzpatrick_scale:false,category:"people"},briefcase:{keywords:["business","documents","work","law","legal","job","career"],char:'💼',fitzpatrick_scale:false,category:"people"},eyeglasses:{keywords:["fashion","accessories","eyesight","nerdy","dork","geek"],char:'👓',fitzpatrick_scale:false,category:"people"},dark_sunglasses:{keywords:["face","cool","accessories"],char:'🕶',fitzpatrick_scale:false,category:"people"},goggles:{keywords:["eyes","protection","safety"],char:'🥽',fitzpatrick_scale:false,category:"people"},ring:{keywords:["wedding","propose","marriage","valentines","diamond","fashion","jewelry","gem","engagement"],char:'💍',fitzpatrick_scale:false,category:"people"},closed_umbrella:{keywords:["weather","rain","drizzle"],char:'🌂',fitzpatrick_scale:false,category:"people"},dog:{keywords:["animal","friend","nature","woof","puppy","pet","faithful"],char:'🐶',fitzpatrick_scale:false,category:"animals_and_nature"},cat:{keywords:["animal","meow","nature","pet","kitten"],char:'🐱',fitzpatrick_scale:false,category:"animals_and_nature"},mouse:{keywords:["animal","nature","cheese_wedge","rodent"],char:'🐭',fitzpatrick_scale:false,category:"animals_and_nature"},hamster:{keywords:["animal","nature"],char:'🐹',fitzpatrick_scale:false,category:"animals_and_nature"},rabbit:{keywords:["animal","nature","pet","spring","magic","bunny"],char:'🐰',fitzpatrick_scale:false,category:"animals_and_nature"},fox_face:{keywords:["animal","nature","face"],char:'🦊',fitzpatrick_scale:false,category:"animals_and_nature"},bear:{keywords:["animal","nature","wild"],char:'🐻',fitzpatrick_scale:false,category:"animals_and_nature"},panda_face:{keywords:["animal","nature","panda"],char:'🐼',fitzpatrick_scale:false,category:"animals_and_nature"},koala:{keywords:["animal","nature"],char:'🐨',fitzpatrick_scale:false,category:"animals_and_nature"},tiger:{keywords:["animal","cat","danger","wild","nature","roar"],char:'🐯',fitzpatrick_scale:false,category:"animals_and_nature"},lion:{keywords:["animal","nature"],char:'🦁',fitzpatrick_scale:false,category:"animals_and_nature"},cow:{keywords:["beef","ox","animal","nature","moo","milk"],char:'🐮',fitzpatrick_scale:false,category:"animals_and_nature"},pig:{keywords:["animal","oink","nature"],char:'🐷',fitzpatrick_scale:false,category:"animals_and_nature"},pig_nose:{keywords:["animal","oink"],char:'🐽',fitzpatrick_scale:false,category:"animals_and_nature"},frog:{keywords:["animal","nature","croak","toad"],char:'🐸',fitzpatrick_scale:false,category:"animals_and_nature"},squid:{keywords:["animal","nature","ocean","sea"],char:'🦑',fitzpatrick_scale:false,category:"animals_and_nature"},octopus:{keywords:["animal","creature","ocean","sea","nature","beach"],char:'🐙',fitzpatrick_scale:false,category:"animals_and_nature"},shrimp:{keywords:["animal","ocean","nature","seafood"],char:'🦐',fitzpatrick_scale:false,category:"animals_and_nature"},monkey_face:{keywords:["animal","nature","circus"],char:'🐵',fitzpatrick_scale:false,category:"animals_and_nature"},gorilla:{keywords:["animal","nature","circus"],char:'🦍',fitzpatrick_scale:false,category:"animals_and_nature"},see_no_evil:{keywords:["monkey","animal","nature","haha"],char:'🙈',fitzpatrick_scale:false,category:"animals_and_nature"},hear_no_evil:{keywords:["animal","monkey","nature"],char:'🙉',fitzpatrick_scale:false,category:"animals_and_nature"},speak_no_evil:{keywords:["monkey","animal","nature","omg"],char:'🙊',fitzpatrick_scale:false,category:"animals_and_nature"},monkey:{keywords:["animal","nature","banana","circus"],char:'🐒',fitzpatrick_scale:false,category:"animals_and_nature"},chicken:{keywords:["animal","cluck","nature","bird"],char:'🐔',fitzpatrick_scale:false,category:"animals_and_nature"},penguin:{keywords:["animal","nature"],char:'🐧',fitzpatrick_scale:false,category:"animals_and_nature"},bird:{keywords:["animal","nature","fly","tweet","spring"],char:'🐦',fitzpatrick_scale:false,category:"animals_and_nature"},baby_chick:{keywords:["animal","chicken","bird"],char:'🐤',fitzpatrick_scale:false,category:"animals_and_nature"},hatching_chick:{keywords:["animal","chicken","egg","born","baby","bird"],char:'🐣',fitzpatrick_scale:false,category:"animals_and_nature"},hatched_chick:{keywords:["animal","chicken","baby","bird"],char:'🐥',fitzpatrick_scale:false,category:"animals_and_nature"},duck:{keywords:["animal","nature","bird","mallard"],char:'🦆',fitzpatrick_scale:false,category:"animals_and_nature"},eagle:{keywords:["animal","nature","bird"],char:'🦅',fitzpatrick_scale:false,category:"animals_and_nature"},owl:{keywords:["animal","nature","bird","hoot"],char:'🦉',fitzpatrick_scale:false,category:"animals_and_nature"},bat:{keywords:["animal","nature","blind","vampire"],char:'🦇',fitzpatrick_scale:false,category:"animals_and_nature"},wolf:{keywords:["animal","nature","wild"],char:'🐺',fitzpatrick_scale:false,category:"animals_and_nature"},boar:{keywords:["animal","nature"],char:'🐗',fitzpatrick_scale:false,category:"animals_and_nature"},horse:{keywords:["animal","brown","nature"],char:'🐴',fitzpatrick_scale:false,category:"animals_and_nature"},unicorn:{keywords:["animal","nature","mystical"],char:'🦄',fitzpatrick_scale:false,category:"animals_and_nature"},honeybee:{keywords:["animal","insect","nature","bug","spring","honey"],char:'🐝',fitzpatrick_scale:false,category:"animals_and_nature"},bug:{keywords:["animal","insect","nature","worm"],char:'🐛',fitzpatrick_scale:false,category:"animals_and_nature"},butterfly:{keywords:["animal","insect","nature","caterpillar"],char:'🦋',fitzpatrick_scale:false,category:"animals_and_nature"},snail:{keywords:["slow","animal","shell"],char:'🐌',fitzpatrick_scale:false,category:"animals_and_nature"},beetle:{keywords:["animal","insect","nature","ladybug"],char:'🐞',fitzpatrick_scale:false,category:"animals_and_nature"},ant:{keywords:["animal","insect","nature","bug"],char:'🐜',fitzpatrick_scale:false,category:"animals_and_nature"},grasshopper:{keywords:["animal","cricket","chirp"],char:'🦗',fitzpatrick_scale:false,category:"animals_and_nature"},spider:{keywords:["animal","arachnid"],char:'🕷',fitzpatrick_scale:false,category:"animals_and_nature"},scorpion:{keywords:["animal","arachnid"],char:'🦂',fitzpatrick_scale:false,category:"animals_and_nature"},crab:{keywords:["animal","crustacean"],char:'🦀',fitzpatrick_scale:false,category:"animals_and_nature"},snake:{keywords:["animal","evil","nature","hiss","python"],char:'🐍',fitzpatrick_scale:false,category:"animals_and_nature"},lizard:{keywords:["animal","nature","reptile"],char:'🦎',fitzpatrick_scale:false,category:"animals_and_nature"},"t-rex":{keywords:["animal","nature","dinosaur","tyrannosaurus","extinct"],char:'🦖',fitzpatrick_scale:false,category:"animals_and_nature"},sauropod:{keywords:["animal","nature","dinosaur","brachiosaurus","brontosaurus","diplodocus","extinct"],char:'🦕',fitzpatrick_scale:false,category:"animals_and_nature"},turtle:{keywords:["animal","slow","nature","tortoise"],char:'🐢',fitzpatrick_scale:false,category:"animals_and_nature"},tropical_fish:{keywords:["animal","swim","ocean","beach","nemo"],char:'🐠',fitzpatrick_scale:false,category:"animals_and_nature"},fish:{keywords:["animal","food","nature"],char:'🐟',fitzpatrick_scale:false,category:"animals_and_nature"},blowfish:{keywords:["animal","nature","food","sea","ocean"],char:'🐡',fitzpatrick_scale:false,category:"animals_and_nature"},dolphin:{keywords:["animal","nature","fish","sea","ocean","flipper","fins","beach"],char:'🐬',fitzpatrick_scale:false,category:"animals_and_nature"},shark:{keywords:["animal","nature","fish","sea","ocean","jaws","fins","beach"],char:'🦈',fitzpatrick_scale:false,category:"animals_and_nature"},whale:{keywords:["animal","nature","sea","ocean"],char:'🐳',fitzpatrick_scale:false,category:"animals_and_nature"},whale2:{keywords:["animal","nature","sea","ocean"],char:'🐋',fitzpatrick_scale:false,category:"animals_and_nature"},crocodile:{keywords:["animal","nature","reptile","lizard","alligator"],char:'🐊',fitzpatrick_scale:false,category:"animals_and_nature"},leopard:{keywords:["animal","nature"],char:'🐆',fitzpatrick_scale:false,category:"animals_and_nature"},zebra:{keywords:["animal","nature","stripes","safari"],char:'🦓',fitzpatrick_scale:false,category:"animals_and_nature"},tiger2:{keywords:["animal","nature","roar"],char:'🐅',fitzpatrick_scale:false,category:"animals_and_nature"},water_buffalo:{keywords:["animal","nature","ox","cow"],char:'🐃',fitzpatrick_scale:false,category:"animals_and_nature"},ox:{keywords:["animal","cow","beef"],char:'🐂',fitzpatrick_scale:false,category:"animals_and_nature"},cow2:{keywords:["beef","ox","animal","nature","moo","milk"],char:'🐄',fitzpatrick_scale:false,category:"animals_and_nature"},deer:{keywords:["animal","nature","horns","venison"],char:'🦌',fitzpatrick_scale:false,category:"animals_and_nature"},dromedary_camel:{keywords:["animal","hot","desert","hump"],char:'🐪',fitzpatrick_scale:false,category:"animals_and_nature"},camel:{keywords:["animal","nature","hot","desert","hump"],char:'🐫',fitzpatrick_scale:false,category:"animals_and_nature"},giraffe:{keywords:["animal","nature","spots","safari"],char:'🦒',fitzpatrick_scale:false,category:"animals_and_nature"},elephant:{keywords:["animal","nature","nose","th","circus"],char:'🐘',fitzpatrick_scale:false,category:"animals_and_nature"},rhinoceros:{keywords:["animal","nature","horn"],char:'🦏',fitzpatrick_scale:false,category:"animals_and_nature"},goat:{keywords:["animal","nature"],char:'🐐',fitzpatrick_scale:false,category:"animals_and_nature"},ram:{keywords:["animal","sheep","nature"],char:'🐏',fitzpatrick_scale:false,category:"animals_and_nature"},sheep:{keywords:["animal","nature","wool","shipit"],char:'🐑',fitzpatrick_scale:false,category:"animals_and_nature"},racehorse:{keywords:["animal","gamble","luck"],char:'🐎',fitzpatrick_scale:false,category:"animals_and_nature"},pig2:{keywords:["animal","nature"],char:'🐖',fitzpatrick_scale:false,category:"animals_and_nature"},rat:{keywords:["animal","mouse","rodent"],char:'🐀',fitzpatrick_scale:false,category:"animals_and_nature"},mouse2:{keywords:["animal","nature","rodent"],char:'🐁',fitzpatrick_scale:false,category:"animals_and_nature"},rooster:{keywords:["animal","nature","chicken"],char:'🐓',fitzpatrick_scale:false,category:"animals_and_nature"},turkey:{keywords:["animal","bird"],char:'🦃',fitzpatrick_scale:false,category:"animals_and_nature"},dove:{keywords:["animal","bird"],char:'🕊',fitzpatrick_scale:false,category:"animals_and_nature"},dog2:{keywords:["animal","nature","friend","doge","pet","faithful"],char:'🐕',fitzpatrick_scale:false,category:"animals_and_nature"},poodle:{keywords:["dog","animal","101","nature","pet"],char:'🐩',fitzpatrick_scale:false,category:"animals_and_nature"},cat2:{keywords:["animal","meow","pet","cats"],char:'🐈',fitzpatrick_scale:false,category:"animals_and_nature"},rabbit2:{keywords:["animal","nature","pet","magic","spring"],char:'🐇',fitzpatrick_scale:false,category:"animals_and_nature"},chipmunk:{keywords:["animal","nature","rodent","squirrel"],char:'🐿',fitzpatrick_scale:false,category:"animals_and_nature"},hedgehog:{keywords:["animal","nature","spiny"],char:'🦔',fitzpatrick_scale:false,category:"animals_and_nature"},raccoon:{keywords:["animal","nature"],char:'🦝',fitzpatrick_scale:false,category:"animals_and_nature"},llama:{keywords:["animal","nature","alpaca"],char:'🦙',fitzpatrick_scale:false,category:"animals_and_nature"},hippopotamus:{keywords:["animal","nature"],char:'🦛',fitzpatrick_scale:false,category:"animals_and_nature"},kangaroo:{keywords:["animal","nature","australia","joey","hop","marsupial"],char:'🦘',fitzpatrick_scale:false,category:"animals_and_nature"},badger:{keywords:["animal","nature","honey"],char:'🦡',fitzpatrick_scale:false,category:"animals_and_nature"},swan:{keywords:["animal","nature","bird"],char:'🦢',fitzpatrick_scale:false,category:"animals_and_nature"},peacock:{keywords:["animal","nature","peahen","bird"],char:'🦚',fitzpatrick_scale:false,category:"animals_and_nature"},parrot:{keywords:["animal","nature","bird","pirate","talk"],char:'🦜',fitzpatrick_scale:false,category:"animals_and_nature"},lobster:{keywords:["animal","nature","bisque","claws","seafood"],char:'🦞',fitzpatrick_scale:false,category:"animals_and_nature"},mosquito:{keywords:["animal","nature","insect","malaria"],char:'🦟',fitzpatrick_scale:false,category:"animals_and_nature"},paw_prints:{keywords:["animal","tracking","footprints","dog","cat","pet","feet"],char:'🐾',fitzpatrick_scale:false,category:"animals_and_nature"},dragon:{keywords:["animal","myth","nature","chinese","green"],char:'🐉',fitzpatrick_scale:false,category:"animals_and_nature"},dragon_face:{keywords:["animal","myth","nature","chinese","green"],char:'🐲',fitzpatrick_scale:false,category:"animals_and_nature"},cactus:{keywords:["vegetable","plant","nature"],char:'🌵',fitzpatrick_scale:false,category:"animals_and_nature"},christmas_tree:{keywords:["festival","vacation","december","xmas","celebration"],char:'🎄',fitzpatrick_scale:false,category:"animals_and_nature"},evergreen_tree:{keywords:["plant","nature"],char:'🌲',fitzpatrick_scale:false,category:"animals_and_nature"},deciduous_tree:{keywords:["plant","nature"],char:'🌳',fitzpatrick_scale:false,category:"animals_and_nature"},palm_tree:{keywords:["plant","vegetable","nature","summer","beach","mojito","tropical"],char:'🌴',fitzpatrick_scale:false,category:"animals_and_nature"},seedling:{keywords:["plant","nature","grass","lawn","spring"],char:'🌱',fitzpatrick_scale:false,category:"animals_and_nature"},herb:{keywords:["vegetable","plant","medicine","weed","grass","lawn"],char:'🌿',fitzpatrick_scale:false,category:"animals_and_nature"},shamrock:{keywords:["vegetable","plant","nature","irish","clover"],char:'☘',fitzpatrick_scale:false,category:"animals_and_nature"},four_leaf_clover:{keywords:["vegetable","plant","nature","lucky","irish"],char:'🍀',fitzpatrick_scale:false,category:"animals_and_nature"},bamboo:{keywords:["plant","nature","vegetable","panda","pine_decoration"],char:'🎍',fitzpatrick_scale:false,category:"animals_and_nature"},tanabata_tree:{keywords:["plant","nature","branch","summer"],char:'🎋',fitzpatrick_scale:false,category:"animals_and_nature"},leaves:{keywords:["nature","plant","tree","vegetable","grass","lawn","spring"],char:'🍃',fitzpatrick_scale:false,category:"animals_and_nature"},fallen_leaf:{keywords:["nature","plant","vegetable","leaves"],char:'🍂',fitzpatrick_scale:false,category:"animals_and_nature"},maple_leaf:{keywords:["nature","plant","vegetable","ca","fall"],char:'🍁',fitzpatrick_scale:false,category:"animals_and_nature"},ear_of_rice:{keywords:["nature","plant"],char:'🌾',fitzpatrick_scale:false,category:"animals_and_nature"},hibiscus:{keywords:["plant","vegetable","flowers","beach"],char:'🌺',fitzpatrick_scale:false,category:"animals_and_nature"},sunflower:{keywords:["nature","plant","fall"],char:'🌻',fitzpatrick_scale:false,category:"animals_and_nature"},rose:{keywords:["flowers","valentines","love","spring"],char:'🌹',fitzpatrick_scale:false,category:"animals_and_nature"},wilted_flower:{keywords:["plant","nature","flower"],char:'🥀',fitzpatrick_scale:false,category:"animals_and_nature"},tulip:{keywords:["flowers","plant","nature","summer","spring"],char:'🌷',fitzpatrick_scale:false,category:"animals_and_nature"},blossom:{keywords:["nature","flowers","yellow"],char:'🌼',fitzpatrick_scale:false,category:"animals_and_nature"},cherry_blossom:{keywords:["nature","plant","spring","flower"],char:'🌸',fitzpatrick_scale:false,category:"animals_and_nature"},bouquet:{keywords:["flowers","nature","spring"],char:'💐',fitzpatrick_scale:false,category:"animals_and_nature"},mushroom:{keywords:["plant","vegetable"],char:'🍄',fitzpatrick_scale:false,category:"animals_and_nature"},chestnut:{keywords:["food","squirrel"],char:'🌰',fitzpatrick_scale:false,category:"animals_and_nature"},jack_o_lantern:{keywords:["halloween","light","pumpkin","creepy","fall"],char:'🎃',fitzpatrick_scale:false,category:"animals_and_nature"},shell:{keywords:["nature","sea","beach"],char:'🐚',fitzpatrick_scale:false,category:"animals_and_nature"},spider_web:{keywords:["animal","insect","arachnid","silk"],char:'🕸',fitzpatrick_scale:false,category:"animals_and_nature"},earth_americas:{keywords:["globe","world","USA","international"],char:'🌎',fitzpatrick_scale:false,category:"animals_and_nature"},earth_africa:{keywords:["globe","world","international"],char:'🌍',fitzpatrick_scale:false,category:"animals_and_nature"},earth_asia:{keywords:["globe","world","east","international"],char:'🌏',fitzpatrick_scale:false,category:"animals_and_nature"},full_moon:{keywords:["nature","yellow","twilight","planet","space","night","evening","sleep"],char:'🌕',fitzpatrick_scale:false,category:"animals_and_nature"},waning_gibbous_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep","waxing_gibbous_moon"],char:'🌖',fitzpatrick_scale:false,category:"animals_and_nature"},last_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'🌗',fitzpatrick_scale:false,category:"animals_and_nature"},waning_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'🌘',fitzpatrick_scale:false,category:"animals_and_nature"},new_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'🌑',fitzpatrick_scale:false,category:"animals_and_nature"},waxing_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'🌒',fitzpatrick_scale:false,category:"animals_and_nature"},first_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'🌓',fitzpatrick_scale:false,category:"animals_and_nature"},waxing_gibbous_moon:{keywords:["nature","night","sky","gray","twilight","planet","space","evening","sleep"],char:'🌔',fitzpatrick_scale:false,category:"animals_and_nature"},new_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'🌚',fitzpatrick_scale:false,category:"animals_and_nature"},full_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'🌝',fitzpatrick_scale:false,category:"animals_and_nature"},first_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'🌛',fitzpatrick_scale:false,category:"animals_and_nature"},last_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'🌜',fitzpatrick_scale:false,category:"animals_and_nature"},sun_with_face:{keywords:["nature","morning","sky"],char:'🌞',fitzpatrick_scale:false,category:"animals_and_nature"},crescent_moon:{keywords:["night","sleep","sky","evening","magic"],char:'🌙',fitzpatrick_scale:false,category:"animals_and_nature"},star:{keywords:["night","yellow"],char:'⭐',fitzpatrick_scale:false,category:"animals_and_nature"},star2:{keywords:["night","sparkle","awesome","good","magic"],char:'🌟',fitzpatrick_scale:false,category:"animals_and_nature"},dizzy:{keywords:["star","sparkle","shoot","magic"],char:'💫',fitzpatrick_scale:false,category:"animals_and_nature"},sparkles:{keywords:["stars","shine","shiny","cool","awesome","good","magic"],char:'✨',fitzpatrick_scale:false,category:"animals_and_nature"},comet:{keywords:["space"],char:'☄',fitzpatrick_scale:false,category:"animals_and_nature"},sunny:{keywords:["weather","nature","brightness","summer","beach","spring"],char:'☀️',fitzpatrick_scale:false,category:"animals_and_nature"},sun_behind_small_cloud:{keywords:["weather"],char:'🌤',fitzpatrick_scale:false,category:"animals_and_nature"},partly_sunny:{keywords:["weather","nature","cloudy","morning","fall","spring"],char:'⛅',fitzpatrick_scale:false,category:"animals_and_nature"},sun_behind_large_cloud:{keywords:["weather"],char:'🌥',fitzpatrick_scale:false,category:"animals_and_nature"},sun_behind_rain_cloud:{keywords:["weather"],char:'🌦',fitzpatrick_scale:false,category:"animals_and_nature"},cloud:{keywords:["weather","sky"],char:'☁️',fitzpatrick_scale:false,category:"animals_and_nature"},cloud_with_rain:{keywords:["weather"],char:'🌧',fitzpatrick_scale:false,category:"animals_and_nature"},cloud_with_lightning_and_rain:{keywords:["weather","lightning"],char:'⛈',fitzpatrick_scale:false,category:"animals_and_nature"},cloud_with_lightning:{keywords:["weather","thunder"],char:'🌩',fitzpatrick_scale:false,category:"animals_and_nature"},zap:{keywords:["thunder","weather","lightning bolt","fast"],char:'⚡',fitzpatrick_scale:false,category:"animals_and_nature"},fire:{keywords:["hot","cook","flame"],char:'🔥',fitzpatrick_scale:false,category:"animals_and_nature"},boom:{keywords:["bomb","explode","explosion","collision","blown"],char:'💥',fitzpatrick_scale:false,category:"animals_and_nature"},snowflake:{keywords:["winter","season","cold","weather","christmas","xmas"],char:'❄️',fitzpatrick_scale:false,category:"animals_and_nature"},cloud_with_snow:{keywords:["weather"],char:'🌨',fitzpatrick_scale:false,category:"animals_and_nature"},snowman:{keywords:["winter","season","cold","weather","christmas","xmas","frozen","without_snow"],char:'⛄',fitzpatrick_scale:false,category:"animals_and_nature"},snowman_with_snow:{keywords:["winter","season","cold","weather","christmas","xmas","frozen"],char:'☃',fitzpatrick_scale:false,category:"animals_and_nature"},wind_face:{keywords:["gust","air"],char:'🌬',fitzpatrick_scale:false,category:"animals_and_nature"},dash:{keywords:["wind","air","fast","shoo","fart","smoke","puff"],char:'💨',fitzpatrick_scale:false,category:"animals_and_nature"},tornado:{keywords:["weather","cyclone","twister"],char:'🌪',fitzpatrick_scale:false,category:"animals_and_nature"},fog:{keywords:["weather"],char:'🌫',fitzpatrick_scale:false,category:"animals_and_nature"},open_umbrella:{keywords:["weather","spring"],char:'☂',fitzpatrick_scale:false,category:"animals_and_nature"},umbrella:{keywords:["rainy","weather","spring"],char:'☔',fitzpatrick_scale:false,category:"animals_and_nature"},droplet:{keywords:["water","drip","faucet","spring"],char:'💧',fitzpatrick_scale:false,category:"animals_and_nature"},sweat_drops:{keywords:["water","drip","oops"],char:'💦',fitzpatrick_scale:false,category:"animals_and_nature"},ocean:{keywords:["sea","water","wave","nature","tsunami","disaster"],char:'🌊',fitzpatrick_scale:false,category:"animals_and_nature"},green_apple:{keywords:["fruit","nature"],char:'🍏',fitzpatrick_scale:false,category:"food_and_drink"},apple:{keywords:["fruit","mac","school"],char:'🍎',fitzpatrick_scale:false,category:"food_and_drink"},pear:{keywords:["fruit","nature","food"],char:'🍐',fitzpatrick_scale:false,category:"food_and_drink"},tangerine:{keywords:["food","fruit","nature","orange"],char:'🍊',fitzpatrick_scale:false,category:"food_and_drink"},lemon:{keywords:["fruit","nature"],char:'🍋',fitzpatrick_scale:false,category:"food_and_drink"},banana:{keywords:["fruit","food","monkey"],char:'🍌',fitzpatrick_scale:false,category:"food_and_drink"},watermelon:{keywords:["fruit","food","picnic","summer"],char:'🍉',fitzpatrick_scale:false,category:"food_and_drink"},grapes:{keywords:["fruit","food","wine"],char:'🍇',fitzpatrick_scale:false,category:"food_and_drink"},strawberry:{keywords:["fruit","food","nature"],char:'🍓',fitzpatrick_scale:false,category:"food_and_drink"},melon:{keywords:["fruit","nature","food"],char:'🍈',fitzpatrick_scale:false,category:"food_and_drink"},cherries:{keywords:["food","fruit"],char:'🍒',fitzpatrick_scale:false,category:"food_and_drink"},peach:{keywords:["fruit","nature","food"],char:'🍑',fitzpatrick_scale:false,category:"food_and_drink"},pineapple:{keywords:["fruit","nature","food"],char:'🍍',fitzpatrick_scale:false,category:"food_and_drink"},coconut:{keywords:["fruit","nature","food","palm"],char:'🥥',fitzpatrick_scale:false,category:"food_and_drink"},kiwi_fruit:{keywords:["fruit","food"],char:'🥝',fitzpatrick_scale:false,category:"food_and_drink"},mango:{keywords:["fruit","food","tropical"],char:'🥭',fitzpatrick_scale:false,category:"food_and_drink"},avocado:{keywords:["fruit","food"],char:'🥑',fitzpatrick_scale:false,category:"food_and_drink"},broccoli:{keywords:["fruit","food","vegetable"],char:'🥦',fitzpatrick_scale:false,category:"food_and_drink"},tomato:{keywords:["fruit","vegetable","nature","food"],char:'🍅',fitzpatrick_scale:false,category:"food_and_drink"},eggplant:{keywords:["vegetable","nature","food","aubergine"],char:'🍆',fitzpatrick_scale:false,category:"food_and_drink"},cucumber:{keywords:["fruit","food","pickle"],char:'🥒',fitzpatrick_scale:false,category:"food_and_drink"},carrot:{keywords:["vegetable","food","orange"],char:'🥕',fitzpatrick_scale:false,category:"food_and_drink"},hot_pepper:{keywords:["food","spicy","chilli","chili"],char:'🌶',fitzpatrick_scale:false,category:"food_and_drink"},potato:{keywords:["food","tuber","vegatable","starch"],char:'🥔',fitzpatrick_scale:false,category:"food_and_drink"},corn:{keywords:["food","vegetable","plant"],char:'🌽',fitzpatrick_scale:false,category:"food_and_drink"},leafy_greens:{keywords:["food","vegetable","plant","bok choy","cabbage","kale","lettuce"],char:'🥬',fitzpatrick_scale:false,category:"food_and_drink"},sweet_potato:{keywords:["food","nature"],char:'🍠',fitzpatrick_scale:false,category:"food_and_drink"},peanuts:{keywords:["food","nut"],char:'🥜',fitzpatrick_scale:false,category:"food_and_drink"},honey_pot:{keywords:["bees","sweet","kitchen"],char:'🍯',fitzpatrick_scale:false,category:"food_and_drink"},croissant:{keywords:["food","bread","french"],char:'🥐',fitzpatrick_scale:false,category:"food_and_drink"},bread:{keywords:["food","wheat","breakfast","toast"],char:'🍞',fitzpatrick_scale:false,category:"food_and_drink"},baguette_bread:{keywords:["food","bread","french"],char:'🥖',fitzpatrick_scale:false,category:"food_and_drink"},bagel:{keywords:["food","bread","bakery","schmear"],char:'🥯',fitzpatrick_scale:false,category:"food_and_drink"},pretzel:{keywords:["food","bread","twisted"],char:'🥨',fitzpatrick_scale:false,category:"food_and_drink"},cheese:{keywords:["food","chadder"],char:'🧀',fitzpatrick_scale:false,category:"food_and_drink"},egg:{keywords:["food","chicken","breakfast"],char:'🥚',fitzpatrick_scale:false,category:"food_and_drink"},bacon:{keywords:["food","breakfast","pork","pig","meat"],char:'🥓',fitzpatrick_scale:false,category:"food_and_drink"},steak:{keywords:["food","cow","meat","cut","chop","lambchop","porkchop"],char:'🥩',fitzpatrick_scale:false,category:"food_and_drink"},pancakes:{keywords:["food","breakfast","flapjacks","hotcakes"],char:'🥞',fitzpatrick_scale:false,category:"food_and_drink"},poultry_leg:{keywords:["food","meat","drumstick","bird","chicken","turkey"],char:'🍗',fitzpatrick_scale:false,category:"food_and_drink"},meat_on_bone:{keywords:["good","food","drumstick"],char:'🍖',fitzpatrick_scale:false,category:"food_and_drink"},bone:{keywords:["skeleton"],char:'🦴',fitzpatrick_scale:false,category:"food_and_drink"},fried_shrimp:{keywords:["food","animal","appetizer","summer"],char:'🍤',fitzpatrick_scale:false,category:"food_and_drink"},fried_egg:{keywords:["food","breakfast","kitchen","egg"],char:'🍳',fitzpatrick_scale:false,category:"food_and_drink"},hamburger:{keywords:["meat","fast food","beef","cheeseburger","mcdonalds","burger king"],char:'🍔',fitzpatrick_scale:false,category:"food_and_drink"},fries:{keywords:["chips","snack","fast food"],char:'🍟',fitzpatrick_scale:false,category:"food_and_drink"},stuffed_flatbread:{keywords:["food","flatbread","stuffed","gyro"],char:'🥙',fitzpatrick_scale:false,category:"food_and_drink"},hotdog:{keywords:["food","frankfurter"],char:'🌭',fitzpatrick_scale:false,category:"food_and_drink"},pizza:{keywords:["food","party"],char:'🍕',fitzpatrick_scale:false,category:"food_and_drink"},sandwich:{keywords:["food","lunch","bread"],char:'🥪',fitzpatrick_scale:false,category:"food_and_drink"},canned_food:{keywords:["food","soup"],char:'🥫',fitzpatrick_scale:false,category:"food_and_drink"},spaghetti:{keywords:["food","italian","noodle"],char:'🍝',fitzpatrick_scale:false,category:"food_and_drink"},taco:{keywords:["food","mexican"],char:'🌮',fitzpatrick_scale:false,category:"food_and_drink"},burrito:{keywords:["food","mexican"],char:'🌯',fitzpatrick_scale:false,category:"food_and_drink"},green_salad:{keywords:["food","healthy","lettuce"],char:'🥗',fitzpatrick_scale:false,category:"food_and_drink"},shallow_pan_of_food:{keywords:["food","cooking","casserole","paella"],char:'🥘',fitzpatrick_scale:false,category:"food_and_drink"},ramen:{keywords:["food","japanese","noodle","chopsticks"],char:'🍜',fitzpatrick_scale:false,category:"food_and_drink"},stew:{keywords:["food","meat","soup"],char:'🍲',fitzpatrick_scale:false,category:"food_and_drink"},fish_cake:{keywords:["food","japan","sea","beach","narutomaki","pink","swirl","kamaboko","surimi","ramen"],char:'🍥',fitzpatrick_scale:false,category:"food_and_drink"},fortune_cookie:{keywords:["food","prophecy"],char:'🥠',fitzpatrick_scale:false,category:"food_and_drink"},sushi:{keywords:["food","fish","japanese","rice"],char:'🍣',fitzpatrick_scale:false,category:"food_and_drink"},bento:{keywords:["food","japanese","box"],char:'🍱',fitzpatrick_scale:false,category:"food_and_drink"},curry:{keywords:["food","spicy","hot","indian"],char:'🍛',fitzpatrick_scale:false,category:"food_and_drink"},rice_ball:{keywords:["food","japanese"],char:'🍙',fitzpatrick_scale:false,category:"food_and_drink"},rice:{keywords:["food","china","asian"],char:'🍚',fitzpatrick_scale:false,category:"food_and_drink"},rice_cracker:{keywords:["food","japanese"],char:'🍘',fitzpatrick_scale:false,category:"food_and_drink"},oden:{keywords:["food","japanese"],char:'🍢',fitzpatrick_scale:false,category:"food_and_drink"},dango:{keywords:["food","dessert","sweet","japanese","barbecue","meat"],char:'🍡',fitzpatrick_scale:false,category:"food_and_drink"},shaved_ice:{keywords:["hot","dessert","summer"],char:'🍧',fitzpatrick_scale:false,category:"food_and_drink"},ice_cream:{keywords:["food","hot","dessert"],char:'🍨',fitzpatrick_scale:false,category:"food_and_drink"},icecream:{keywords:["food","hot","dessert","summer"],char:'🍦',fitzpatrick_scale:false,category:"food_and_drink"},pie:{keywords:["food","dessert","pastry"],char:'🥧',fitzpatrick_scale:false,category:"food_and_drink"},cake:{keywords:["food","dessert"],char:'🍰',fitzpatrick_scale:false,category:"food_and_drink"},cupcake:{keywords:["food","dessert","bakery","sweet"],char:'🧁',fitzpatrick_scale:false,category:"food_and_drink"},moon_cake:{keywords:["food","autumn"],char:'🥮',fitzpatrick_scale:false,category:"food_and_drink"},birthday:{keywords:["food","dessert","cake"],char:'🎂',fitzpatrick_scale:false,category:"food_and_drink"},custard:{keywords:["dessert","food"],char:'🍮',fitzpatrick_scale:false,category:"food_and_drink"},candy:{keywords:["snack","dessert","sweet","lolly"],char:'🍬',fitzpatrick_scale:false,category:"food_and_drink"},lollipop:{keywords:["food","snack","candy","sweet"],char:'🍭',fitzpatrick_scale:false,category:"food_and_drink"},chocolate_bar:{keywords:["food","snack","dessert","sweet"],char:'🍫',fitzpatrick_scale:false,category:"food_and_drink"},popcorn:{keywords:["food","movie theater","films","snack"],char:'🍿',fitzpatrick_scale:false,category:"food_and_drink"},dumpling:{keywords:["food","empanada","pierogi","potsticker"],char:'🥟',fitzpatrick_scale:false,category:"food_and_drink"},doughnut:{keywords:["food","dessert","snack","sweet","donut"],char:'🍩',fitzpatrick_scale:false,category:"food_and_drink"},cookie:{keywords:["food","snack","oreo","chocolate","sweet","dessert"],char:'🍪',fitzpatrick_scale:false,category:"food_and_drink"},milk_glass:{keywords:["beverage","drink","cow"],char:'🥛',fitzpatrick_scale:false,category:"food_and_drink"},beer:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:'🍺',fitzpatrick_scale:false,category:"food_and_drink"},beers:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:'🍻',fitzpatrick_scale:false,category:"food_and_drink"},clinking_glasses:{keywords:["beverage","drink","party","alcohol","celebrate","cheers","wine","champagne","toast"],char:'🥂',fitzpatrick_scale:false,category:"food_and_drink"},wine_glass:{keywords:["drink","beverage","drunk","alcohol","booze"],char:'🍷',fitzpatrick_scale:false,category:"food_and_drink"},tumbler_glass:{keywords:["drink","beverage","drunk","alcohol","liquor","booze","bourbon","scotch","whisky","glass","shot"],char:'🥃',fitzpatrick_scale:false,category:"food_and_drink"},cocktail:{keywords:["drink","drunk","alcohol","beverage","booze","mojito"],char:'🍸',fitzpatrick_scale:false,category:"food_and_drink"},tropical_drink:{keywords:["beverage","cocktail","summer","beach","alcohol","booze","mojito"],char:'🍹',fitzpatrick_scale:false,category:"food_and_drink"},champagne:{keywords:["drink","wine","bottle","celebration"],char:'🍾',fitzpatrick_scale:false,category:"food_and_drink"},sake:{keywords:["wine","drink","drunk","beverage","japanese","alcohol","booze"],char:'🍶',fitzpatrick_scale:false,category:"food_and_drink"},tea:{keywords:["drink","bowl","breakfast","green","british"],char:'🍵',fitzpatrick_scale:false,category:"food_and_drink"},cup_with_straw:{keywords:["drink","soda"],char:'🥤',fitzpatrick_scale:false,category:"food_and_drink"},coffee:{keywords:["beverage","caffeine","latte","espresso"],char:'☕',fitzpatrick_scale:false,category:"food_and_drink"},baby_bottle:{keywords:["food","container","milk"],char:'🍼',fitzpatrick_scale:false,category:"food_and_drink"},salt:{keywords:["condiment","shaker"],char:'🧂',fitzpatrick_scale:false,category:"food_and_drink"},spoon:{keywords:["cutlery","kitchen","tableware"],char:'🥄',fitzpatrick_scale:false,category:"food_and_drink"},fork_and_knife:{keywords:["cutlery","kitchen"],char:'🍴',fitzpatrick_scale:false,category:"food_and_drink"},plate_with_cutlery:{keywords:["food","eat","meal","lunch","dinner","restaurant"],char:'🍽',fitzpatrick_scale:false,category:"food_and_drink"},bowl_with_spoon:{keywords:["food","breakfast","cereal","oatmeal","porridge"],char:'🥣',fitzpatrick_scale:false,category:"food_and_drink"},takeout_box:{keywords:["food","leftovers"],char:'🥡',fitzpatrick_scale:false,category:"food_and_drink"},chopsticks:{keywords:["food"],char:'🥢',fitzpatrick_scale:false,category:"food_and_drink"},soccer:{keywords:["sports","football"],char:'⚽',fitzpatrick_scale:false,category:"activity"},basketball:{keywords:["sports","balls","NBA"],char:'🏀',fitzpatrick_scale:false,category:"activity"},football:{keywords:["sports","balls","NFL"],char:'🏈',fitzpatrick_scale:false,category:"activity"},baseball:{keywords:["sports","balls"],char:'⚾',fitzpatrick_scale:false,category:"activity"},softball:{keywords:["sports","balls"],char:'🥎',fitzpatrick_scale:false,category:"activity"},tennis:{keywords:["sports","balls","green"],char:'🎾',fitzpatrick_scale:false,category:"activity"},volleyball:{keywords:["sports","balls"],char:'🏐',fitzpatrick_scale:false,category:"activity"},rugby_football:{keywords:["sports","team"],char:'🏉',fitzpatrick_scale:false,category:"activity"},flying_disc:{keywords:["sports","frisbee","ultimate"],char:'🥏',fitzpatrick_scale:false,category:"activity"},"8ball":{keywords:["pool","hobby","game","luck","magic"],char:'🎱',fitzpatrick_scale:false,category:"activity"},golf:{keywords:["sports","business","flag","hole","summer"],char:'⛳',fitzpatrick_scale:false,category:"activity"},golfing_woman:{keywords:["sports","business","woman","female"],char:'🏌️‍♀️',fitzpatrick_scale:false,category:"activity"},golfing_man:{keywords:["sports","business"],char:'🏌',fitzpatrick_scale:true,category:"activity"},ping_pong:{keywords:["sports","pingpong"],char:'🏓',fitzpatrick_scale:false,category:"activity"},badminton:{keywords:["sports"],char:'🏸',fitzpatrick_scale:false,category:"activity"},goal_net:{keywords:["sports"],char:'🥅',fitzpatrick_scale:false,category:"activity"},ice_hockey:{keywords:["sports"],char:'🏒',fitzpatrick_scale:false,category:"activity"},field_hockey:{keywords:["sports"],char:'🏑',fitzpatrick_scale:false,category:"activity"},lacrosse:{keywords:["sports","ball","stick"],char:'🥍',fitzpatrick_scale:false,category:"activity"},cricket:{keywords:["sports"],char:'🏏',fitzpatrick_scale:false,category:"activity"},ski:{keywords:["sports","winter","cold","snow"],char:'🎿',fitzpatrick_scale:false,category:"activity"},skier:{keywords:["sports","winter","snow"],char:'⛷',fitzpatrick_scale:false,category:"activity"},snowboarder:{keywords:["sports","winter"],char:'🏂',fitzpatrick_scale:true,category:"activity"},person_fencing:{keywords:["sports","fencing","sword"],char:'🤺',fitzpatrick_scale:false,category:"activity"},women_wrestling:{keywords:["sports","wrestlers"],char:'🤼‍♀️',fitzpatrick_scale:false,category:"activity"},men_wrestling:{keywords:["sports","wrestlers"],char:'🤼‍♂️',fitzpatrick_scale:false,category:"activity"},woman_cartwheeling:{keywords:["gymnastics"],char:'🤸‍♀️',fitzpatrick_scale:true,category:"activity"},man_cartwheeling:{keywords:["gymnastics"],char:'🤸‍♂️',fitzpatrick_scale:true,category:"activity"},woman_playing_handball:{keywords:["sports"],char:'🤾‍♀️',fitzpatrick_scale:true,category:"activity"},man_playing_handball:{keywords:["sports"],char:'🤾‍♂️',fitzpatrick_scale:true,category:"activity"},ice_skate:{keywords:["sports"],char:'⛸',fitzpatrick_scale:false,category:"activity"},curling_stone:{keywords:["sports"],char:'🥌',fitzpatrick_scale:false,category:"activity"},skateboard:{keywords:["board"],char:'🛹',fitzpatrick_scale:false,category:"activity"},sled:{keywords:["sleigh","luge","toboggan"],char:'🛷',fitzpatrick_scale:false,category:"activity"},bow_and_arrow:{keywords:["sports"],char:'🏹',fitzpatrick_scale:false,category:"activity"},fishing_pole_and_fish:{keywords:["food","hobby","summer"],char:'🎣',fitzpatrick_scale:false,category:"activity"},boxing_glove:{keywords:["sports","fighting"],char:'🥊',fitzpatrick_scale:false,category:"activity"},martial_arts_uniform:{keywords:["judo","karate","taekwondo"],char:'🥋',fitzpatrick_scale:false,category:"activity"},rowing_woman:{keywords:["sports","hobby","water","ship","woman","female"],char:'🚣‍♀️',fitzpatrick_scale:true,category:"activity"},rowing_man:{keywords:["sports","hobby","water","ship"],char:'🚣',fitzpatrick_scale:true,category:"activity"},climbing_woman:{keywords:["sports","hobby","woman","female","rock"],char:'🧗‍♀️',fitzpatrick_scale:true,category:"activity"},climbing_man:{keywords:["sports","hobby","man","male","rock"],char:'🧗‍♂️',fitzpatrick_scale:true,category:"activity"},swimming_woman:{keywords:["sports","exercise","human","athlete","water","summer","woman","female"],char:'🏊‍♀️',fitzpatrick_scale:true,category:"activity"},swimming_man:{keywords:["sports","exercise","human","athlete","water","summer"],char:'🏊',fitzpatrick_scale:true,category:"activity"},woman_playing_water_polo:{keywords:["sports","pool"],char:'🤽‍♀️',fitzpatrick_scale:true,category:"activity"},man_playing_water_polo:{keywords:["sports","pool"],char:'🤽‍♂️',fitzpatrick_scale:true,category:"activity"},woman_in_lotus_position:{keywords:["woman","female","meditation","yoga","serenity","zen","mindfulness"],char:'🧘‍♀️',fitzpatrick_scale:true,category:"activity"},man_in_lotus_position:{keywords:["man","male","meditation","yoga","serenity","zen","mindfulness"],char:'🧘‍♂️',fitzpatrick_scale:true,category:"activity"},surfing_woman:{keywords:["sports","ocean","sea","summer","beach","woman","female"],char:'🏄‍♀️',fitzpatrick_scale:true,category:"activity"},surfing_man:{keywords:["sports","ocean","sea","summer","beach"],char:'🏄',fitzpatrick_scale:true,category:"activity"},bath:{keywords:["clean","shower","bathroom"],char:'🛀',fitzpatrick_scale:true,category:"activity"},basketball_woman:{keywords:["sports","human","woman","female"],char:'⛹️‍♀️',fitzpatrick_scale:true,category:"activity"},basketball_man:{keywords:["sports","human"],char:'⛹',fitzpatrick_scale:true,category:"activity"},weight_lifting_woman:{keywords:["sports","training","exercise","woman","female"],char:'🏋️‍♀️',fitzpatrick_scale:true,category:"activity"},weight_lifting_man:{keywords:["sports","training","exercise"],char:'🏋',fitzpatrick_scale:true,category:"activity"},biking_woman:{keywords:["sports","bike","exercise","hipster","woman","female"],char:'🚴‍♀️',fitzpatrick_scale:true,category:"activity"},biking_man:{keywords:["sports","bike","exercise","hipster"],char:'🚴',fitzpatrick_scale:true,category:"activity"},mountain_biking_woman:{keywords:["transportation","sports","human","race","bike","woman","female"],char:'🚵‍♀️',fitzpatrick_scale:true,category:"activity"},mountain_biking_man:{keywords:["transportation","sports","human","race","bike"],char:'🚵',fitzpatrick_scale:true,category:"activity"},horse_racing:{keywords:["animal","betting","competition","gambling","luck"],char:'🏇',fitzpatrick_scale:true,category:"activity"},business_suit_levitating:{keywords:["suit","business","levitate","hover","jump"],char:'🕴',fitzpatrick_scale:true,category:"activity"},trophy:{keywords:["win","award","contest","place","ftw","ceremony"],char:'🏆',fitzpatrick_scale:false,category:"activity"},running_shirt_with_sash:{keywords:["play","pageant"],char:'🎽',fitzpatrick_scale:false,category:"activity"},medal_sports:{keywords:["award","winning"],char:'🏅',fitzpatrick_scale:false,category:"activity"},medal_military:{keywords:["award","winning","army"],char:'🎖',fitzpatrick_scale:false,category:"activity"},"1st_place_medal":{keywords:["award","winning","first"],char:'🥇',fitzpatrick_scale:false,category:"activity"},"2nd_place_medal":{keywords:["award","second"],char:'🥈',fitzpatrick_scale:false,category:"activity"},"3rd_place_medal":{keywords:["award","third"],char:'🥉',fitzpatrick_scale:false,category:"activity"},reminder_ribbon:{keywords:["sports","cause","support","awareness"],char:'🎗',fitzpatrick_scale:false,category:"activity"},rosette:{keywords:["flower","decoration","military"],char:'🏵',fitzpatrick_scale:false,category:"activity"},ticket:{keywords:["event","concert","pass"],char:'🎫',fitzpatrick_scale:false,category:"activity"},tickets:{keywords:["sports","concert","entrance"],char:'🎟',fitzpatrick_scale:false,category:"activity"},performing_arts:{keywords:["acting","theater","drama"],char:'🎭',fitzpatrick_scale:false,category:"activity"},art:{keywords:["design","paint","draw","colors"],char:'🎨',fitzpatrick_scale:false,category:"activity"},circus_tent:{keywords:["festival","carnival","party"],char:'🎪',fitzpatrick_scale:false,category:"activity"},woman_juggling:{keywords:["juggle","balance","skill","multitask"],char:'🤹‍♀️',fitzpatrick_scale:true,category:"activity"},man_juggling:{keywords:["juggle","balance","skill","multitask"],char:'🤹‍♂️',fitzpatrick_scale:true,category:"activity"},microphone:{keywords:["sound","music","PA","sing","talkshow"],char:'🎤',fitzpatrick_scale:false,category:"activity"},headphones:{keywords:["music","score","gadgets"],char:'🎧',fitzpatrick_scale:false,category:"activity"},musical_score:{keywords:["treble","clef","compose"],char:'🎼',fitzpatrick_scale:false,category:"activity"},musical_keyboard:{keywords:["piano","instrument","compose"],char:'🎹',fitzpatrick_scale:false,category:"activity"},drum:{keywords:["music","instrument","drumsticks","snare"],char:'🥁',fitzpatrick_scale:false,category:"activity"},saxophone:{keywords:["music","instrument","jazz","blues"],char:'🎷',fitzpatrick_scale:false,category:"activity"},trumpet:{keywords:["music","brass"],char:'🎺',fitzpatrick_scale:false,category:"activity"},guitar:{keywords:["music","instrument"],char:'🎸',fitzpatrick_scale:false,category:"activity"},violin:{keywords:["music","instrument","orchestra","symphony"],char:'🎻',fitzpatrick_scale:false,category:"activity"},clapper:{keywords:["movie","film","record"],char:'🎬',fitzpatrick_scale:false,category:"activity"},video_game:{keywords:["play","console","PS4","controller"],char:'🎮',fitzpatrick_scale:false,category:"activity"},space_invader:{keywords:["game","arcade","play"],char:'👾',fitzpatrick_scale:false,category:"activity"},dart:{keywords:["game","play","bar","target","bullseye"],char:'🎯',fitzpatrick_scale:false,category:"activity"},game_die:{keywords:["dice","random","tabletop","play","luck"],char:'🎲',fitzpatrick_scale:false,category:"activity"},chess_pawn:{keywords:["expendable"],char:"♟",fitzpatrick_scale:false,category:"activity"},slot_machine:{keywords:["bet","gamble","vegas","fruit machine","luck","casino"],char:'🎰',fitzpatrick_scale:false,category:"activity"},jigsaw:{keywords:["interlocking","puzzle","piece"],char:'🧩',fitzpatrick_scale:false,category:"activity"},bowling:{keywords:["sports","fun","play"],char:'🎳',fitzpatrick_scale:false,category:"activity"},red_car:{keywords:["red","transportation","vehicle"],char:'🚗',fitzpatrick_scale:false,category:"travel_and_places"},taxi:{keywords:["uber","vehicle","cars","transportation"],char:'🚕',fitzpatrick_scale:false,category:"travel_and_places"},blue_car:{keywords:["transportation","vehicle"],char:'🚙',fitzpatrick_scale:false,category:"travel_and_places"},bus:{keywords:["car","vehicle","transportation"],char:'🚌',fitzpatrick_scale:false,category:"travel_and_places"},trolleybus:{keywords:["bart","transportation","vehicle"],char:'🚎',fitzpatrick_scale:false,category:"travel_and_places"},racing_car:{keywords:["sports","race","fast","formula","f1"],char:'🏎',fitzpatrick_scale:false,category:"travel_and_places"},police_car:{keywords:["vehicle","cars","transportation","law","legal","enforcement"],char:'🚓',fitzpatrick_scale:false,category:"travel_and_places"},ambulance:{keywords:["health","911","hospital"],char:'🚑',fitzpatrick_scale:false,category:"travel_and_places"},fire_engine:{keywords:["transportation","cars","vehicle"],char:'🚒',fitzpatrick_scale:false,category:"travel_and_places"},minibus:{keywords:["vehicle","car","transportation"],char:'🚐',fitzpatrick_scale:false,category:"travel_and_places"},truck:{keywords:["cars","transportation"],char:'🚚',fitzpatrick_scale:false,category:"travel_and_places"},articulated_lorry:{keywords:["vehicle","cars","transportation","express"],char:'🚛',fitzpatrick_scale:false,category:"travel_and_places"},tractor:{keywords:["vehicle","car","farming","agriculture"],char:'🚜',fitzpatrick_scale:false,category:"travel_and_places"},kick_scooter:{keywords:["vehicle","kick","razor"],char:'🛴',fitzpatrick_scale:false,category:"travel_and_places"},motorcycle:{keywords:["race","sports","fast"],char:'🏍',fitzpatrick_scale:false,category:"travel_and_places"},bike:{keywords:["sports","bicycle","exercise","hipster"],char:'🚲',fitzpatrick_scale:false,category:"travel_and_places"},motor_scooter:{keywords:["vehicle","vespa","sasha"],char:'🛵',fitzpatrick_scale:false,category:"travel_and_places"},rotating_light:{keywords:["police","ambulance","911","emergency","alert","error","pinged","law","legal"],char:'🚨',fitzpatrick_scale:false,category:"travel_and_places"},oncoming_police_car:{keywords:["vehicle","law","legal","enforcement","911"],char:'🚔',fitzpatrick_scale:false,category:"travel_and_places"},oncoming_bus:{keywords:["vehicle","transportation"],char:'🚍',fitzpatrick_scale:false,category:"travel_and_places"},oncoming_automobile:{keywords:["car","vehicle","transportation"],char:'🚘',fitzpatrick_scale:false,category:"travel_and_places"},oncoming_taxi:{keywords:["vehicle","cars","uber"],char:'🚖',fitzpatrick_scale:false,category:"travel_and_places"},aerial_tramway:{keywords:["transportation","vehicle","ski"],char:'🚡',fitzpatrick_scale:false,category:"travel_and_places"},mountain_cableway:{keywords:["transportation","vehicle","ski"],char:'🚠',fitzpatrick_scale:false,category:"travel_and_places"},suspension_railway:{keywords:["vehicle","transportation"],char:'🚟',fitzpatrick_scale:false,category:"travel_and_places"},railway_car:{keywords:["transportation","vehicle"],char:'🚃',fitzpatrick_scale:false,category:"travel_and_places"},train:{keywords:["transportation","vehicle","carriage","public","travel"],char:'🚋',fitzpatrick_scale:false,category:"travel_and_places"},monorail:{keywords:["transportation","vehicle"],char:'🚝',fitzpatrick_scale:false,category:"travel_and_places"},bullettrain_side:{keywords:["transportation","vehicle"],char:'🚄',fitzpatrick_scale:false,category:"travel_and_places"},bullettrain_front:{keywords:["transportation","vehicle","speed","fast","public","travel"],char:'🚅',fitzpatrick_scale:false,category:"travel_and_places"},light_rail:{keywords:["transportation","vehicle"],char:'🚈',fitzpatrick_scale:false,category:"travel_and_places"},mountain_railway:{keywords:["transportation","vehicle"],char:'🚞',fitzpatrick_scale:false,category:"travel_and_places"},steam_locomotive:{keywords:["transportation","vehicle","train"],char:'🚂',fitzpatrick_scale:false,category:"travel_and_places"},train2:{keywords:["transportation","vehicle"],char:'🚆',fitzpatrick_scale:false,category:"travel_and_places"},metro:{keywords:["transportation","blue-square","mrt","underground","tube"],char:'🚇',fitzpatrick_scale:false,category:"travel_and_places"},tram:{keywords:["transportation","vehicle"],char:'🚊',fitzpatrick_scale:false,category:"travel_and_places"},station:{keywords:["transportation","vehicle","public"],char:'🚉',fitzpatrick_scale:false,category:"travel_and_places"},flying_saucer:{keywords:["transportation","vehicle","ufo"],char:'🛸',fitzpatrick_scale:false,category:"travel_and_places"},helicopter:{keywords:["transportation","vehicle","fly"],char:'🚁',fitzpatrick_scale:false,category:"travel_and_places"},small_airplane:{keywords:["flight","transportation","fly","vehicle"],char:'🛩',fitzpatrick_scale:false,category:"travel_and_places"},airplane:{keywords:["vehicle","transportation","flight","fly"],char:'✈️',fitzpatrick_scale:false,category:"travel_and_places"},flight_departure:{keywords:["airport","flight","landing"],char:'🛫',fitzpatrick_scale:false,category:"travel_and_places"},flight_arrival:{keywords:["airport","flight","boarding"],char:'🛬',fitzpatrick_scale:false,category:"travel_and_places"},sailboat:{keywords:["ship","summer","transportation","water","sailing"],char:'⛵',fitzpatrick_scale:false,category:"travel_and_places"},motor_boat:{keywords:["ship"],char:'🛥',fitzpatrick_scale:false,category:"travel_and_places"},speedboat:{keywords:["ship","transportation","vehicle","summer"],char:'🚤',fitzpatrick_scale:false,category:"travel_and_places"},ferry:{keywords:["boat","ship","yacht"],char:'⛴',fitzpatrick_scale:false,category:"travel_and_places"},passenger_ship:{keywords:["yacht","cruise","ferry"],char:'🛳',fitzpatrick_scale:false,category:"travel_and_places"},rocket:{keywords:["launch","ship","staffmode","NASA","outer space","outer_space","fly"],char:'🚀',fitzpatrick_scale:false,category:"travel_and_places"},artificial_satellite:{keywords:["communication","gps","orbit","spaceflight","NASA","ISS"],char:'🛰',fitzpatrick_scale:false,category:"travel_and_places"},seat:{keywords:["sit","airplane","transport","bus","flight","fly"],char:'💺',fitzpatrick_scale:false,category:"travel_and_places"},canoe:{keywords:["boat","paddle","water","ship"],char:'🛶',fitzpatrick_scale:false,category:"travel_and_places"},anchor:{keywords:["ship","ferry","sea","boat"],char:'⚓',fitzpatrick_scale:false,category:"travel_and_places"},construction:{keywords:["wip","progress","caution","warning"],char:'🚧',fitzpatrick_scale:false,category:"travel_and_places"},fuelpump:{keywords:["gas station","petroleum"],char:'⛽',fitzpatrick_scale:false,category:"travel_and_places"},busstop:{keywords:["transportation","wait"],char:'🚏',fitzpatrick_scale:false,category:"travel_and_places"},vertical_traffic_light:{keywords:["transportation","driving"],char:'🚦',fitzpatrick_scale:false,category:"travel_and_places"},traffic_light:{keywords:["transportation","signal"],char:'🚥',fitzpatrick_scale:false,category:"travel_and_places"},checkered_flag:{keywords:["contest","finishline","race","gokart"],char:'🏁',fitzpatrick_scale:false,category:"travel_and_places"},ship:{keywords:["transportation","titanic","deploy"],char:'🚢',fitzpatrick_scale:false,category:"travel_and_places"},ferris_wheel:{keywords:["photo","carnival","londoneye"],char:'🎡',fitzpatrick_scale:false,category:"travel_and_places"},roller_coaster:{keywords:["carnival","playground","photo","fun"],char:'🎢',fitzpatrick_scale:false,category:"travel_and_places"},carousel_horse:{keywords:["photo","carnival"],char:'🎠',fitzpatrick_scale:false,category:"travel_and_places"},building_construction:{keywords:["wip","working","progress"],char:'🏗',fitzpatrick_scale:false,category:"travel_and_places"},foggy:{keywords:["photo","mountain"],char:'🌁',fitzpatrick_scale:false,category:"travel_and_places"},tokyo_tower:{keywords:["photo","japanese"],char:'🗼',fitzpatrick_scale:false,category:"travel_and_places"},factory:{keywords:["building","industry","pollution","smoke"],char:'🏭',fitzpatrick_scale:false,category:"travel_and_places"},fountain:{keywords:["photo","summer","water","fresh"],char:'⛲',fitzpatrick_scale:false,category:"travel_and_places"},rice_scene:{keywords:["photo","japan","asia","tsukimi"],char:'🎑',fitzpatrick_scale:false,category:"travel_and_places"},mountain:{keywords:["photo","nature","environment"],char:'⛰',fitzpatrick_scale:false,category:"travel_and_places"},mountain_snow:{keywords:["photo","nature","environment","winter","cold"],char:'🏔',fitzpatrick_scale:false,category:"travel_and_places"},mount_fuji:{keywords:["photo","mountain","nature","japanese"],char:'🗻',fitzpatrick_scale:false,category:"travel_and_places"},volcano:{keywords:["photo","nature","disaster"],char:'🌋',fitzpatrick_scale:false,category:"travel_and_places"},japan:{keywords:["nation","country","japanese","asia"],char:'🗾',fitzpatrick_scale:false,category:"travel_and_places"},camping:{keywords:["photo","outdoors","tent"],char:'🏕',fitzpatrick_scale:false,category:"travel_and_places"},tent:{keywords:["photo","camping","outdoors"],char:'⛺',fitzpatrick_scale:false,category:"travel_and_places"},national_park:{keywords:["photo","environment","nature"],char:'🏞',fitzpatrick_scale:false,category:"travel_and_places"},motorway:{keywords:["road","cupertino","interstate","highway"],char:'🛣',fitzpatrick_scale:false,category:"travel_and_places"},railway_track:{keywords:["train","transportation"],char:'🛤',fitzpatrick_scale:false,category:"travel_and_places"},sunrise:{keywords:["morning","view","vacation","photo"],char:'🌅',fitzpatrick_scale:false,category:"travel_and_places"},sunrise_over_mountains:{keywords:["view","vacation","photo"],char:'🌄',fitzpatrick_scale:false,category:"travel_and_places"},desert:{keywords:["photo","warm","saharah"],char:'🏜',fitzpatrick_scale:false,category:"travel_and_places"},beach_umbrella:{keywords:["weather","summer","sunny","sand","mojito"],char:'🏖',fitzpatrick_scale:false,category:"travel_and_places"},desert_island:{keywords:["photo","tropical","mojito"],char:'🏝',fitzpatrick_scale:false,category:"travel_and_places"},city_sunrise:{keywords:["photo","good morning","dawn"],char:'🌇',fitzpatrick_scale:false,category:"travel_and_places"},city_sunset:{keywords:["photo","evening","sky","buildings"],char:'🌆',fitzpatrick_scale:false,category:"travel_and_places"},cityscape:{keywords:["photo","night life","urban"],char:'🏙',fitzpatrick_scale:false,category:"travel_and_places"},night_with_stars:{keywords:["evening","city","downtown"],char:'🌃',fitzpatrick_scale:false,category:"travel_and_places"},bridge_at_night:{keywords:["photo","sanfrancisco"],char:'🌉',fitzpatrick_scale:false,category:"travel_and_places"},milky_way:{keywords:["photo","space","stars"],char:'🌌',fitzpatrick_scale:false,category:"travel_and_places"},stars:{keywords:["night","photo"],char:'🌠',fitzpatrick_scale:false,category:"travel_and_places"},sparkler:{keywords:["stars","night","shine"],char:'🎇',fitzpatrick_scale:false,category:"travel_and_places"},fireworks:{keywords:["photo","festival","carnival","congratulations"],char:'🎆',fitzpatrick_scale:false,category:"travel_and_places"},rainbow:{keywords:["nature","happy","unicorn_face","photo","sky","spring"],char:'🌈',fitzpatrick_scale:false,category:"travel_and_places"},houses:{keywords:["buildings","photo"],char:'🏘',fitzpatrick_scale:false,category:"travel_and_places"},european_castle:{keywords:["building","royalty","history"],char:'🏰',fitzpatrick_scale:false,category:"travel_and_places"},japanese_castle:{keywords:["photo","building"],char:'🏯',fitzpatrick_scale:false,category:"travel_and_places"},stadium:{keywords:["photo","place","sports","concert","venue"],char:'🏟',fitzpatrick_scale:false,category:"travel_and_places"},statue_of_liberty:{keywords:["american","newyork"],char:'🗽',fitzpatrick_scale:false,category:"travel_and_places"},house:{keywords:["building","home"],char:'🏠',fitzpatrick_scale:false,category:"travel_and_places"},house_with_garden:{keywords:["home","plant","nature"],char:'🏡',fitzpatrick_scale:false,category:"travel_and_places"},derelict_house:{keywords:["abandon","evict","broken","building"],char:'🏚',fitzpatrick_scale:false,category:"travel_and_places"},office:{keywords:["building","bureau","work"],char:'🏢',fitzpatrick_scale:false,category:"travel_and_places"},department_store:{keywords:["building","shopping","mall"],char:'🏬',fitzpatrick_scale:false,category:"travel_and_places"},post_office:{keywords:["building","envelope","communication"],char:'🏣',fitzpatrick_scale:false,category:"travel_and_places"},european_post_office:{keywords:["building","email"],char:'🏤',fitzpatrick_scale:false,category:"travel_and_places"},hospital:{keywords:["building","health","surgery","doctor"],char:'🏥',fitzpatrick_scale:false,category:"travel_and_places"},bank:{keywords:["building","money","sales","cash","business","enterprise"],char:'🏦',fitzpatrick_scale:false,category:"travel_and_places"},hotel:{keywords:["building","accomodation","checkin"],char:'🏨',fitzpatrick_scale:false,category:"travel_and_places"},convenience_store:{keywords:["building","shopping","groceries"],char:'🏪',fitzpatrick_scale:false,category:"travel_and_places"},school:{keywords:["building","student","education","learn","teach"],char:'🏫',fitzpatrick_scale:false,category:"travel_and_places"},love_hotel:{keywords:["like","affection","dating"],char:'🏩',fitzpatrick_scale:false,category:"travel_and_places"},wedding:{keywords:["love","like","affection","couple","marriage","bride","groom"],char:'💒',fitzpatrick_scale:false,category:"travel_and_places"},classical_building:{keywords:["art","culture","history"],char:'🏛',fitzpatrick_scale:false,category:"travel_and_places"},church:{keywords:["building","religion","christ"],char:'⛪',fitzpatrick_scale:false,category:"travel_and_places"},mosque:{keywords:["islam","worship","minaret"],char:'🕌',fitzpatrick_scale:false,category:"travel_and_places"},synagogue:{keywords:["judaism","worship","temple","jewish"],char:'🕍',fitzpatrick_scale:false,category:"travel_and_places"},kaaba:{keywords:["mecca","mosque","islam"],char:'🕋',fitzpatrick_scale:false,category:"travel_and_places"},shinto_shrine:{keywords:["temple","japan","kyoto"],char:'⛩',fitzpatrick_scale:false,category:"travel_and_places"},watch:{keywords:["time","accessories"],char:'⌚',fitzpatrick_scale:false,category:"objects"},iphone:{keywords:["technology","apple","gadgets","dial"],char:'📱',fitzpatrick_scale:false,category:"objects"},calling:{keywords:["iphone","incoming"],char:'📲',fitzpatrick_scale:false,category:"objects"},computer:{keywords:["technology","laptop","screen","display","monitor"],char:'💻',fitzpatrick_scale:false,category:"objects"},keyboard:{keywords:["technology","computer","type","input","text"],char:'⌨',fitzpatrick_scale:false,category:"objects"},desktop_computer:{keywords:["technology","computing","screen"],char:'🖥',fitzpatrick_scale:false,category:"objects"},printer:{keywords:["paper","ink"],char:'🖨',fitzpatrick_scale:false,category:"objects"},computer_mouse:{keywords:["click"],char:'🖱',fitzpatrick_scale:false,category:"objects"},trackball:{keywords:["technology","trackpad"],char:'🖲',fitzpatrick_scale:false,category:"objects"},joystick:{keywords:["game","play"],char:'🕹',fitzpatrick_scale:false,category:"objects"},clamp:{keywords:["tool"],char:'🗜',fitzpatrick_scale:false,category:"objects"},minidisc:{keywords:["technology","record","data","disk","90s"],char:'💽',fitzpatrick_scale:false,category:"objects"},floppy_disk:{keywords:["oldschool","technology","save","90s","80s"],char:'💾',fitzpatrick_scale:false,category:"objects"},cd:{keywords:["technology","dvd","disk","disc","90s"],char:'💿',fitzpatrick_scale:false,category:"objects"},dvd:{keywords:["cd","disk","disc"],char:'📀',fitzpatrick_scale:false,category:"objects"},vhs:{keywords:["record","video","oldschool","90s","80s"],char:'📼',fitzpatrick_scale:false,category:"objects"},camera:{keywords:["gadgets","photography"],char:'📷',fitzpatrick_scale:false,category:"objects"},camera_flash:{keywords:["photography","gadgets"],char:'📸',fitzpatrick_scale:false,category:"objects"},video_camera:{keywords:["film","record"],char:'📹',fitzpatrick_scale:false,category:"objects"},movie_camera:{keywords:["film","record"],char:'🎥',fitzpatrick_scale:false,category:"objects"},film_projector:{keywords:["video","tape","record","movie"],char:'📽',fitzpatrick_scale:false,category:"objects"},film_strip:{keywords:["movie"],char:'🎞',fitzpatrick_scale:false,category:"objects"},telephone_receiver:{keywords:["technology","communication","dial"],char:'📞',fitzpatrick_scale:false,category:"objects"},phone:{keywords:["technology","communication","dial","telephone"],char:'☎️',fitzpatrick_scale:false,category:"objects"},pager:{keywords:["bbcall","oldschool","90s"],char:'📟',fitzpatrick_scale:false,category:"objects"},fax:{keywords:["communication","technology"],char:'📠',fitzpatrick_scale:false,category:"objects"},tv:{keywords:["technology","program","oldschool","show","television"],char:'📺',fitzpatrick_scale:false,category:"objects"},radio:{keywords:["communication","music","podcast","program"],char:'📻',fitzpatrick_scale:false,category:"objects"},studio_microphone:{keywords:["sing","recording","artist","talkshow"],char:'🎙',fitzpatrick_scale:false,category:"objects"},level_slider:{keywords:["scale"],char:'🎚',fitzpatrick_scale:false,category:"objects"},control_knobs:{keywords:["dial"],char:'🎛',fitzpatrick_scale:false,category:"objects"},compass:{keywords:["magnetic","navigation","orienteering"],char:'🧭',fitzpatrick_scale:false,category:"objects"},stopwatch:{keywords:["time","deadline"],char:'⏱',fitzpatrick_scale:false,category:"objects"},timer_clock:{keywords:["alarm"],char:'⏲',fitzpatrick_scale:false,category:"objects"},alarm_clock:{keywords:["time","wake"],char:'⏰',fitzpatrick_scale:false,category:"objects"},mantelpiece_clock:{keywords:["time"],char:'🕰',fitzpatrick_scale:false,category:"objects"},hourglass_flowing_sand:{keywords:["oldschool","time","countdown"],char:'⏳',fitzpatrick_scale:false,category:"objects"},hourglass:{keywords:["time","clock","oldschool","limit","exam","quiz","test"],char:'⌛',fitzpatrick_scale:false,category:"objects"},satellite:{keywords:["communication","future","radio","space"],char:'📡',fitzpatrick_scale:false,category:"objects"},battery:{keywords:["power","energy","sustain"],char:'🔋',fitzpatrick_scale:false,category:"objects"},electric_plug:{keywords:["charger","power"],char:'🔌',fitzpatrick_scale:false,category:"objects"},bulb:{keywords:["light","electricity","idea"],char:'💡',fitzpatrick_scale:false,category:"objects"},flashlight:{keywords:["dark","camping","sight","night"],char:'🔦',fitzpatrick_scale:false,category:"objects"},candle:{keywords:["fire","wax"],char:'🕯',fitzpatrick_scale:false,category:"objects"},fire_extinguisher:{keywords:["quench"],char:'🧯',fitzpatrick_scale:false,category:"objects"},wastebasket:{keywords:["bin","trash","rubbish","garbage","toss"],char:'🗑',fitzpatrick_scale:false,category:"objects"},oil_drum:{keywords:["barrell"],char:'🛢',fitzpatrick_scale:false,category:"objects"},money_with_wings:{keywords:["dollar","bills","payment","sale"],char:'💸',fitzpatrick_scale:false,category:"objects"},dollar:{keywords:["money","sales","bill","currency"],char:'💵',fitzpatrick_scale:false,category:"objects"},yen:{keywords:["money","sales","japanese","dollar","currency"],char:'💴',fitzpatrick_scale:false,category:"objects"},euro:{keywords:["money","sales","dollar","currency"],char:'💶',fitzpatrick_scale:false,category:"objects"},pound:{keywords:["british","sterling","money","sales","bills","uk","england","currency"],char:'💷',fitzpatrick_scale:false,category:"objects"},moneybag:{keywords:["dollar","payment","coins","sale"],char:'💰',fitzpatrick_scale:false,category:"objects"},credit_card:{keywords:["money","sales","dollar","bill","payment","shopping"],char:'💳',fitzpatrick_scale:false,category:"objects"},gem:{keywords:["blue","ruby","diamond","jewelry"],char:'💎',fitzpatrick_scale:false,category:"objects"},balance_scale:{keywords:["law","fairness","weight"],char:'⚖',fitzpatrick_scale:false,category:"objects"},toolbox:{keywords:["tools","diy","fix","maintainer","mechanic"],char:'🧰',fitzpatrick_scale:false,category:"objects"},wrench:{keywords:["tools","diy","ikea","fix","maintainer"],char:'🔧',fitzpatrick_scale:false,category:"objects"},hammer:{keywords:["tools","build","create"],char:'🔨',fitzpatrick_scale:false,category:"objects"},hammer_and_pick:{keywords:["tools","build","create"],char:'⚒',fitzpatrick_scale:false,category:"objects"},hammer_and_wrench:{keywords:["tools","build","create"],char:'🛠',fitzpatrick_scale:false,category:"objects"},pick:{keywords:["tools","dig"],char:'⛏',fitzpatrick_scale:false,category:"objects"},nut_and_bolt:{keywords:["handy","tools","fix"],char:'🔩',fitzpatrick_scale:false,category:"objects"},gear:{keywords:["cog"],char:'⚙',fitzpatrick_scale:false,category:"objects"},brick:{keywords:["bricks"],char:'🧱',fitzpatrick_scale:false,category:"objects"},chains:{keywords:["lock","arrest"],char:'⛓',fitzpatrick_scale:false,category:"objects"},magnet:{keywords:["attraction","magnetic"],char:'🧲',fitzpatrick_scale:false,category:"objects"},gun:{keywords:["violence","weapon","pistol","revolver"],char:'🔫',fitzpatrick_scale:false,category:"objects"},bomb:{keywords:["boom","explode","explosion","terrorism"],char:'💣',fitzpatrick_scale:false,category:"objects"},firecracker:{keywords:["dynamite","boom","explode","explosion","explosive"],char:'🧨',fitzpatrick_scale:false,category:"objects"},hocho:{keywords:["knife","blade","cutlery","kitchen","weapon"],char:'🔪',fitzpatrick_scale:false,category:"objects"},dagger:{keywords:["weapon"],char:'🗡',fitzpatrick_scale:false,category:"objects"},crossed_swords:{keywords:["weapon"],char:'⚔',fitzpatrick_scale:false,category:"objects"},shield:{keywords:["protection","security"],char:'🛡',fitzpatrick_scale:false,category:"objects"},smoking:{keywords:["kills","tobacco","cigarette","joint","smoke"],char:'🚬',fitzpatrick_scale:false,category:"objects"},skull_and_crossbones:{keywords:["poison","danger","deadly","scary","death","pirate","evil"],char:'☠',fitzpatrick_scale:false,category:"objects"},coffin:{keywords:["vampire","dead","die","death","rip","graveyard","cemetery","casket","funeral","box"],char:'⚰',fitzpatrick_scale:false,category:"objects"},funeral_urn:{keywords:["dead","die","death","rip","ashes"],char:'⚱',fitzpatrick_scale:false,category:"objects"},amphora:{keywords:["vase","jar"],char:'🏺',fitzpatrick_scale:false,category:"objects"},crystal_ball:{keywords:["disco","party","magic","circus","fortune_teller"],char:'🔮',fitzpatrick_scale:false,category:"objects"},prayer_beads:{keywords:["dhikr","religious"],char:'📿',fitzpatrick_scale:false,category:"objects"},nazar_amulet:{keywords:["bead","charm"],char:'🧿',fitzpatrick_scale:false,category:"objects"},barber:{keywords:["hair","salon","style"],char:'💈',fitzpatrick_scale:false,category:"objects"},alembic:{keywords:["distilling","science","experiment","chemistry"],char:'⚗',fitzpatrick_scale:false,category:"objects"},telescope:{keywords:["stars","space","zoom","science","astronomy"],char:'🔭',fitzpatrick_scale:false,category:"objects"},microscope:{keywords:["laboratory","experiment","zoomin","science","study"],char:'🔬',fitzpatrick_scale:false,category:"objects"},hole:{keywords:["embarrassing"],char:'🕳',fitzpatrick_scale:false,category:"objects"},pill:{keywords:["health","medicine","doctor","pharmacy","drug"],char:'💊',fitzpatrick_scale:false,category:"objects"},syringe:{keywords:["health","hospital","drugs","blood","medicine","needle","doctor","nurse"],char:'💉',fitzpatrick_scale:false,category:"objects"},dna:{keywords:["biologist","genetics","life"],char:'🧬',fitzpatrick_scale:false,category:"objects"},microbe:{keywords:["amoeba","bacteria","germs"],char:'🦠',fitzpatrick_scale:false,category:"objects"},petri_dish:{keywords:["bacteria","biology","culture","lab"],char:'🧫',fitzpatrick_scale:false,category:"objects"},test_tube:{keywords:["chemistry","experiment","lab","science"],char:'🧪',fitzpatrick_scale:false,category:"objects"},thermometer:{keywords:["weather","temperature","hot","cold"],char:'🌡',fitzpatrick_scale:false,category:"objects"},broom:{keywords:["cleaning","sweeping","witch"],char:'🧹',fitzpatrick_scale:false,category:"objects"},basket:{keywords:["laundry"],char:'🧺',fitzpatrick_scale:false,category:"objects"},toilet_paper:{keywords:["roll"],char:'🧻',fitzpatrick_scale:false,category:"objects"},label:{keywords:["sale","tag"],char:'🏷',fitzpatrick_scale:false,category:"objects"},bookmark:{keywords:["favorite","label","save"],char:'🔖',fitzpatrick_scale:false,category:"objects"},toilet:{keywords:["restroom","wc","washroom","bathroom","potty"],char:'🚽',fitzpatrick_scale:false,category:"objects"},shower:{keywords:["clean","water","bathroom"],char:'🚿',fitzpatrick_scale:false,category:"objects"},bathtub:{keywords:["clean","shower","bathroom"],char:'🛁',fitzpatrick_scale:false,category:"objects"},soap:{keywords:["bar","bathing","cleaning","lather"],char:'🧼',fitzpatrick_scale:false,category:"objects"},sponge:{keywords:["absorbing","cleaning","porous"],char:'🧽',fitzpatrick_scale:false,category:"objects"},lotion_bottle:{keywords:["moisturizer","sunscreen"],char:'🧴',fitzpatrick_scale:false,category:"objects"},key:{keywords:["lock","door","password"],char:'🔑',fitzpatrick_scale:false,category:"objects"},old_key:{keywords:["lock","door","password"],char:'🗝',fitzpatrick_scale:false,category:"objects"},couch_and_lamp:{keywords:["read","chill"],char:'🛋',fitzpatrick_scale:false,category:"objects"},sleeping_bed:{keywords:["bed","rest"],char:'🛌',fitzpatrick_scale:true,category:"objects"},bed:{keywords:["sleep","rest"],char:'🛏',fitzpatrick_scale:false,category:"objects"},door:{keywords:["house","entry","exit"],char:'🚪',fitzpatrick_scale:false,category:"objects"},bellhop_bell:{keywords:["service"],char:'🛎',fitzpatrick_scale:false,category:"objects"},teddy_bear:{keywords:["plush","stuffed"],char:'🧸',fitzpatrick_scale:false,category:"objects"},framed_picture:{keywords:["photography"],char:'🖼',fitzpatrick_scale:false,category:"objects"},world_map:{keywords:["location","direction"],char:'🗺',fitzpatrick_scale:false,category:"objects"},parasol_on_ground:{keywords:["weather","summer"],char:'⛱',fitzpatrick_scale:false,category:"objects"},moyai:{keywords:["rock","easter island","moai"],char:'🗿',fitzpatrick_scale:false,category:"objects"},shopping:{keywords:["mall","buy","purchase"],char:'🛍',fitzpatrick_scale:false,category:"objects"},shopping_cart:{keywords:["trolley"],char:'🛒',fitzpatrick_scale:false,category:"objects"},balloon:{keywords:["party","celebration","birthday","circus"],char:'🎈',fitzpatrick_scale:false,category:"objects"},flags:{keywords:["fish","japanese","koinobori","carp","banner"],char:'🎏',fitzpatrick_scale:false,category:"objects"},ribbon:{keywords:["decoration","pink","girl","bowtie"],char:'🎀',fitzpatrick_scale:false,category:"objects"},gift:{keywords:["present","birthday","christmas","xmas"],char:'🎁',fitzpatrick_scale:false,category:"objects"},confetti_ball:{keywords:["festival","party","birthday","circus"],char:'🎊',fitzpatrick_scale:false,category:"objects"},tada:{keywords:["party","congratulations","birthday","magic","circus","celebration"],char:'🎉',fitzpatrick_scale:false,category:"objects"},dolls:{keywords:["japanese","toy","kimono"],char:'🎎',fitzpatrick_scale:false,category:"objects"},wind_chime:{keywords:["nature","ding","spring","bell"],char:'🎐',fitzpatrick_scale:false,category:"objects"},crossed_flags:{keywords:["japanese","nation","country","border"],char:'🎌',fitzpatrick_scale:false,category:"objects"},izakaya_lantern:{keywords:["light","paper","halloween","spooky"],char:'🏮',fitzpatrick_scale:false,category:"objects"},red_envelope:{keywords:["gift"],char:'🧧',fitzpatrick_scale:false,category:"objects"},email:{keywords:["letter","postal","inbox","communication"],char:'✉️',fitzpatrick_scale:false,category:"objects"},envelope_with_arrow:{keywords:["email","communication"],char:'📩',fitzpatrick_scale:false,category:"objects"},incoming_envelope:{keywords:["email","inbox"],char:'📨',fitzpatrick_scale:false,category:"objects"},"e-mail":{keywords:["communication","inbox"],char:'📧',fitzpatrick_scale:false,category:"objects"},love_letter:{keywords:["email","like","affection","envelope","valentines"],char:'💌',fitzpatrick_scale:false,category:"objects"},postbox:{keywords:["email","letter","envelope"],char:'📮',fitzpatrick_scale:false,category:"objects"},mailbox_closed:{keywords:["email","communication","inbox"],char:'📪',fitzpatrick_scale:false,category:"objects"},mailbox:{keywords:["email","inbox","communication"],char:'📫',fitzpatrick_scale:false,category:"objects"},mailbox_with_mail:{keywords:["email","inbox","communication"],char:'📬',fitzpatrick_scale:false,category:"objects"},mailbox_with_no_mail:{keywords:["email","inbox"],char:'📭',fitzpatrick_scale:false,category:"objects"},package:{keywords:["mail","gift","cardboard","box","moving"],char:'📦',fitzpatrick_scale:false,category:"objects"},postal_horn:{keywords:["instrument","music"],char:'📯',fitzpatrick_scale:false,category:"objects"},inbox_tray:{keywords:["email","documents"],char:'📥',fitzpatrick_scale:false,category:"objects"},outbox_tray:{keywords:["inbox","email"],char:'📤',fitzpatrick_scale:false,category:"objects"},scroll:{keywords:["documents","ancient","history","paper"],char:'📜',fitzpatrick_scale:false,category:"objects"},page_with_curl:{keywords:["documents","office","paper"],char:'📃',fitzpatrick_scale:false,category:"objects"},bookmark_tabs:{keywords:["favorite","save","order","tidy"],char:'📑',fitzpatrick_scale:false,category:"objects"},receipt:{keywords:["accounting","expenses"],char:'🧾',fitzpatrick_scale:false,category:"objects"},bar_chart:{keywords:["graph","presentation","stats"],char:'📊',fitzpatrick_scale:false,category:"objects"},chart_with_upwards_trend:{keywords:["graph","presentation","stats","recovery","business","economics","money","sales","good","success"],char:'📈',fitzpatrick_scale:false,category:"objects"},chart_with_downwards_trend:{keywords:["graph","presentation","stats","recession","business","economics","money","sales","bad","failure"],char:'📉',fitzpatrick_scale:false,category:"objects"},page_facing_up:{keywords:["documents","office","paper","information"],char:'📄',fitzpatrick_scale:false,category:"objects"},date:{keywords:["calendar","schedule"],char:'📅',fitzpatrick_scale:false,category:"objects"},calendar:{keywords:["schedule","date","planning"],char:'📆',fitzpatrick_scale:false,category:"objects"},spiral_calendar:{keywords:["date","schedule","planning"],char:'🗓',fitzpatrick_scale:false,category:"objects"},card_index:{keywords:["business","stationery"],char:'📇',fitzpatrick_scale:false,category:"objects"},card_file_box:{keywords:["business","stationery"],char:'🗃',fitzpatrick_scale:false,category:"objects"},ballot_box:{keywords:["election","vote"],char:'🗳',fitzpatrick_scale:false,category:"objects"},file_cabinet:{keywords:["filing","organizing"],char:'🗄',fitzpatrick_scale:false,category:"objects"},clipboard:{keywords:["stationery","documents"],char:'📋',fitzpatrick_scale:false,category:"objects"},spiral_notepad:{keywords:["memo","stationery"],char:'🗒',fitzpatrick_scale:false,category:"objects"},file_folder:{keywords:["documents","business","office"],char:'📁',fitzpatrick_scale:false,category:"objects"},open_file_folder:{keywords:["documents","load"],char:'📂',fitzpatrick_scale:false,category:"objects"},card_index_dividers:{keywords:["organizing","business","stationery"],char:'🗂',fitzpatrick_scale:false,category:"objects"},newspaper_roll:{keywords:["press","headline"],char:'🗞',fitzpatrick_scale:false,category:"objects"},newspaper:{keywords:["press","headline"],char:'📰',fitzpatrick_scale:false,category:"objects"},notebook:{keywords:["stationery","record","notes","paper","study"],char:'📓',fitzpatrick_scale:false,category:"objects"},closed_book:{keywords:["read","library","knowledge","textbook","learn"],char:'📕',fitzpatrick_scale:false,category:"objects"},green_book:{keywords:["read","library","knowledge","study"],char:'📗',fitzpatrick_scale:false,category:"objects"},blue_book:{keywords:["read","library","knowledge","learn","study"],char:'📘',fitzpatrick_scale:false,category:"objects"},orange_book:{keywords:["read","library","knowledge","textbook","study"],char:'📙',fitzpatrick_scale:false,category:"objects"},notebook_with_decorative_cover:{keywords:["classroom","notes","record","paper","study"],char:'📔',fitzpatrick_scale:false,category:"objects"},ledger:{keywords:["notes","paper"],char:'📒',fitzpatrick_scale:false,category:"objects"},books:{keywords:["literature","library","study"],char:'📚',fitzpatrick_scale:false,category:"objects"},open_book:{keywords:["book","read","library","knowledge","literature","learn","study"],char:'📖',fitzpatrick_scale:false,category:"objects"},safety_pin:{keywords:["diaper"],char:'🧷',fitzpatrick_scale:false,category:"objects"},link:{keywords:["rings","url"],char:'🔗',fitzpatrick_scale:false,category:"objects"},paperclip:{keywords:["documents","stationery"],char:'📎',fitzpatrick_scale:false,category:"objects"},paperclips:{keywords:["documents","stationery"],char:'🖇',fitzpatrick_scale:false,category:"objects"},scissors:{keywords:["stationery","cut"],char:'✂️',fitzpatrick_scale:false,category:"objects"},triangular_ruler:{keywords:["stationery","math","architect","sketch"],char:'📐',fitzpatrick_scale:false,category:"objects"},straight_ruler:{keywords:["stationery","calculate","length","math","school","drawing","architect","sketch"],char:'📏',fitzpatrick_scale:false,category:"objects"},abacus:{keywords:["calculation"],char:'🧮',fitzpatrick_scale:false,category:"objects"},pushpin:{keywords:["stationery","mark","here"],char:'📌',fitzpatrick_scale:false,category:"objects"},round_pushpin:{keywords:["stationery","location","map","here"],char:'📍',fitzpatrick_scale:false,category:"objects"},triangular_flag_on_post:{keywords:["mark","milestone","place"],char:'🚩',fitzpatrick_scale:false,category:"objects"},white_flag:{keywords:["losing","loser","lost","surrender","give up","fail"],char:'🏳',fitzpatrick_scale:false,category:"objects"},black_flag:{keywords:["pirate"],char:'🏴',fitzpatrick_scale:false,category:"objects"},rainbow_flag:{keywords:["flag","rainbow","pride","gay","lgbt","glbt","queer","homosexual","lesbian","bisexual","transgender"],char:'🏳️‍🌈',fitzpatrick_scale:false,category:"objects"},closed_lock_with_key:{keywords:["security","privacy"],char:'🔐',fitzpatrick_scale:false,category:"objects"},lock:{keywords:["security","password","padlock"],char:'🔒',fitzpatrick_scale:false,category:"objects"},unlock:{keywords:["privacy","security"],char:'🔓',fitzpatrick_scale:false,category:"objects"},lock_with_ink_pen:{keywords:["security","secret"],char:'🔏',fitzpatrick_scale:false,category:"objects"},pen:{keywords:["stationery","writing","write"],char:'🖊',fitzpatrick_scale:false,category:"objects"},fountain_pen:{keywords:["stationery","writing","write"],char:'🖋',fitzpatrick_scale:false,category:"objects"},black_nib:{keywords:["pen","stationery","writing","write"],char:'✒️',fitzpatrick_scale:false,category:"objects"},memo:{keywords:["write","documents","stationery","pencil","paper","writing","legal","exam","quiz","test","study","compose"],char:'📝',fitzpatrick_scale:false,category:"objects"},pencil2:{keywords:["stationery","write","paper","writing","school","study"],char:'✏️',fitzpatrick_scale:false,category:"objects"},crayon:{keywords:["drawing","creativity"],char:'🖍',fitzpatrick_scale:false,category:"objects"},paintbrush:{keywords:["drawing","creativity","art"],char:'🖌',fitzpatrick_scale:false,category:"objects"},mag:{keywords:["search","zoom","find","detective"],char:'🔍',fitzpatrick_scale:false,category:"objects"},mag_right:{keywords:["search","zoom","find","detective"],char:'🔎',fitzpatrick_scale:false,category:"objects"},heart:{keywords:["love","like","valentines"],char:'❤️',fitzpatrick_scale:false,category:"symbols"},orange_heart:{keywords:["love","like","affection","valentines"],char:'🧡',fitzpatrick_scale:false,category:"symbols"},yellow_heart:{keywords:["love","like","affection","valentines"],char:'💛',fitzpatrick_scale:false,category:"symbols"},green_heart:{keywords:["love","like","affection","valentines"],char:'💚',fitzpatrick_scale:false,category:"symbols"},blue_heart:{keywords:["love","like","affection","valentines"],char:'💙',fitzpatrick_scale:false,category:"symbols"},purple_heart:{keywords:["love","like","affection","valentines"],char:'💜',fitzpatrick_scale:false,category:"symbols"},black_heart:{keywords:["evil"],char:'🖤',fitzpatrick_scale:false,category:"symbols"},broken_heart:{keywords:["sad","sorry","break","heart","heartbreak"],char:'💔',fitzpatrick_scale:false,category:"symbols"},heavy_heart_exclamation:{keywords:["decoration","love"],char:'❣',fitzpatrick_scale:false,category:"symbols"},two_hearts:{keywords:["love","like","affection","valentines","heart"],char:'💕',fitzpatrick_scale:false,category:"symbols"},revolving_hearts:{keywords:["love","like","affection","valentines"],char:'💞',fitzpatrick_scale:false,category:"symbols"},heartbeat:{keywords:["love","like","affection","valentines","pink","heart"],char:'💓',fitzpatrick_scale:false,category:"symbols"},heartpulse:{keywords:["like","love","affection","valentines","pink"],char:'💗',fitzpatrick_scale:false,category:"symbols"},sparkling_heart:{keywords:["love","like","affection","valentines"],char:'💖',fitzpatrick_scale:false,category:"symbols"},cupid:{keywords:["love","like","heart","affection","valentines"],char:'💘',fitzpatrick_scale:false,category:"symbols"},gift_heart:{keywords:["love","valentines"],char:'💝',fitzpatrick_scale:false,category:"symbols"},heart_decoration:{keywords:["purple-square","love","like"],char:'💟',fitzpatrick_scale:false,category:"symbols"},peace_symbol:{keywords:["hippie"],char:'☮',fitzpatrick_scale:false,category:"symbols"},latin_cross:{keywords:["christianity"],char:'✝',fitzpatrick_scale:false,category:"symbols"},star_and_crescent:{keywords:["islam"],char:'☪',fitzpatrick_scale:false,category:"symbols"},om:{keywords:["hinduism","buddhism","sikhism","jainism"],char:'🕉',fitzpatrick_scale:false,category:"symbols"},wheel_of_dharma:{keywords:["hinduism","buddhism","sikhism","jainism"],char:'☸',fitzpatrick_scale:false,category:"symbols"},star_of_david:{keywords:["judaism"],char:'✡',fitzpatrick_scale:false,category:"symbols"},six_pointed_star:{keywords:["purple-square","religion","jewish","hexagram"],char:'🔯',fitzpatrick_scale:false,category:"symbols"},menorah:{keywords:["hanukkah","candles","jewish"],char:'🕎',fitzpatrick_scale:false,category:"symbols"},yin_yang:{keywords:["balance"],char:'☯',fitzpatrick_scale:false,category:"symbols"},orthodox_cross:{keywords:["suppedaneum","religion"],char:'☦',fitzpatrick_scale:false,category:"symbols"},place_of_worship:{keywords:["religion","church","temple","prayer"],char:'🛐',fitzpatrick_scale:false,category:"symbols"},ophiuchus:{keywords:["sign","purple-square","constellation","astrology"],char:'⛎',fitzpatrick_scale:false,category:"symbols"},aries:{keywords:["sign","purple-square","zodiac","astrology"],char:'♈',fitzpatrick_scale:false,category:"symbols"},taurus:{keywords:["purple-square","sign","zodiac","astrology"],char:'♉',fitzpatrick_scale:false,category:"symbols"},gemini:{keywords:["sign","zodiac","purple-square","astrology"],char:'♊',fitzpatrick_scale:false,category:"symbols"},cancer:{keywords:["sign","zodiac","purple-square","astrology"],char:'♋',fitzpatrick_scale:false,category:"symbols"},leo:{keywords:["sign","purple-square","zodiac","astrology"],char:'♌',fitzpatrick_scale:false,category:"symbols"},virgo:{keywords:["sign","zodiac","purple-square","astrology"],char:'♍',fitzpatrick_scale:false,category:"symbols"},libra:{keywords:["sign","purple-square","zodiac","astrology"],char:'♎',fitzpatrick_scale:false,category:"symbols"},scorpius:{keywords:["sign","zodiac","purple-square","astrology","scorpio"],char:'♏',fitzpatrick_scale:false,category:"symbols"},sagittarius:{keywords:["sign","zodiac","purple-square","astrology"],char:'♐',fitzpatrick_scale:false,category:"symbols"},capricorn:{keywords:["sign","zodiac","purple-square","astrology"],char:'♑',fitzpatrick_scale:false,category:"symbols"},aquarius:{keywords:["sign","purple-square","zodiac","astrology"],char:'♒',fitzpatrick_scale:false,category:"symbols"},pisces:{keywords:["purple-square","sign","zodiac","astrology"],char:'♓',fitzpatrick_scale:false,category:"symbols"},id:{keywords:["purple-square","words"],char:'🆔',fitzpatrick_scale:false,category:"symbols"},atom_symbol:{keywords:["science","physics","chemistry"],char:'⚛',fitzpatrick_scale:false,category:"symbols"},u7a7a:{keywords:["kanji","japanese","chinese","empty","sky","blue-square"],char:'🈳',fitzpatrick_scale:false,category:"symbols"},u5272:{keywords:["cut","divide","chinese","kanji","pink-square"],char:'🈹',fitzpatrick_scale:false,category:"symbols"},radioactive:{keywords:["nuclear","danger"],char:'☢',fitzpatrick_scale:false,category:"symbols"},biohazard:{keywords:["danger"],char:'☣',fitzpatrick_scale:false,category:"symbols"},mobile_phone_off:{keywords:["mute","orange-square","silence","quiet"],char:'📴',fitzpatrick_scale:false,category:"symbols"},vibration_mode:{keywords:["orange-square","phone"],char:'📳',fitzpatrick_scale:false,category:"symbols"},u6709:{keywords:["orange-square","chinese","have","kanji"],char:'🈶',fitzpatrick_scale:false,category:"symbols"},u7121:{keywords:["nothing","chinese","kanji","japanese","orange-square"],char:'🈚',fitzpatrick_scale:false,category:"symbols"},u7533:{keywords:["chinese","japanese","kanji","orange-square"],char:'🈸',fitzpatrick_scale:false,category:"symbols"},u55b6:{keywords:["japanese","opening hours","orange-square"],char:'🈺',fitzpatrick_scale:false,category:"symbols"},u6708:{keywords:["chinese","month","moon","japanese","orange-square","kanji"],char:'🈷️',fitzpatrick_scale:false,category:"symbols"},eight_pointed_black_star:{keywords:["orange-square","shape","polygon"],char:'✴️',fitzpatrick_scale:false,category:"symbols"},vs:{keywords:["words","orange-square"],char:'🆚',fitzpatrick_scale:false,category:"symbols"},accept:{keywords:["ok","good","chinese","kanji","agree","yes","orange-circle"],char:'🉑',fitzpatrick_scale:false,category:"symbols"},white_flower:{keywords:["japanese","spring"],char:'💮',fitzpatrick_scale:false,category:"symbols"},ideograph_advantage:{keywords:["chinese","kanji","obtain","get","circle"],char:'🉐',fitzpatrick_scale:false,category:"symbols"},secret:{keywords:["privacy","chinese","sshh","kanji","red-circle"],char:'㊙️',fitzpatrick_scale:false,category:"symbols"},congratulations:{keywords:["chinese","kanji","japanese","red-circle"],char:'㊗️',fitzpatrick_scale:false,category:"symbols"},u5408:{keywords:["japanese","chinese","join","kanji","red-square"],char:'🈴',fitzpatrick_scale:false,category:"symbols"},u6e80:{keywords:["full","chinese","japanese","red-square","kanji"],char:'🈵',fitzpatrick_scale:false,category:"symbols"},u7981:{keywords:["kanji","japanese","chinese","forbidden","limit","restricted","red-square"],char:'🈲',fitzpatrick_scale:false,category:"symbols"},a:{keywords:["red-square","alphabet","letter"],char:'🅰️',fitzpatrick_scale:false,category:"symbols"},b:{keywords:["red-square","alphabet","letter"],char:'🅱️',fitzpatrick_scale:false,category:"symbols"},ab:{keywords:["red-square","alphabet"],char:'🆎',fitzpatrick_scale:false,category:"symbols"},cl:{keywords:["alphabet","words","red-square"],char:'🆑',fitzpatrick_scale:false,category:"symbols"},o2:{keywords:["alphabet","red-square","letter"],char:'🅾️',fitzpatrick_scale:false,category:"symbols"},sos:{keywords:["help","red-square","words","emergency","911"],char:'🆘',fitzpatrick_scale:false,category:"symbols"},no_entry:{keywords:["limit","security","privacy","bad","denied","stop","circle"],char:'⛔',fitzpatrick_scale:false,category:"symbols"},name_badge:{keywords:["fire","forbid"],char:'📛',fitzpatrick_scale:false,category:"symbols"},no_entry_sign:{keywords:["forbid","stop","limit","denied","disallow","circle"],char:'🚫',fitzpatrick_scale:false,category:"symbols"},x:{keywords:["no","delete","remove","cancel","red"],char:'❌',fitzpatrick_scale:false,category:"symbols"},o:{keywords:["circle","round"],char:'⭕',fitzpatrick_scale:false,category:"symbols"},stop_sign:{keywords:["stop"],char:'🛑',fitzpatrick_scale:false,category:"symbols"},anger:{keywords:["angry","mad"],char:'💢',fitzpatrick_scale:false,category:"symbols"},hotsprings:{keywords:["bath","warm","relax"],char:'♨️',fitzpatrick_scale:false,category:"symbols"},no_pedestrians:{keywords:["rules","crossing","walking","circle"],char:'🚷',fitzpatrick_scale:false,category:"symbols"},do_not_litter:{keywords:["trash","bin","garbage","circle"],char:'🚯',fitzpatrick_scale:false,category:"symbols"},no_bicycles:{keywords:["cyclist","prohibited","circle"],char:'🚳',fitzpatrick_scale:false,category:"symbols"},"non-potable_water":{keywords:["drink","faucet","tap","circle"],char:'🚱',fitzpatrick_scale:false,category:"symbols"},underage:{keywords:["18","drink","pub","night","minor","circle"],char:'🔞',fitzpatrick_scale:false,category:"symbols"},no_mobile_phones:{keywords:["iphone","mute","circle"],char:'📵',fitzpatrick_scale:false,category:"symbols"},exclamation:{keywords:["heavy_exclamation_mark","danger","surprise","punctuation","wow","warning"],char:'❗',fitzpatrick_scale:false,category:"symbols"},grey_exclamation:{keywords:["surprise","punctuation","gray","wow","warning"],char:'❕',fitzpatrick_scale:false,category:"symbols"},question:{keywords:["doubt","confused"],char:'❓',fitzpatrick_scale:false,category:"symbols"},grey_question:{keywords:["doubts","gray","huh","confused"],char:'❔',fitzpatrick_scale:false,category:"symbols"},bangbang:{keywords:["exclamation","surprise"],char:'‼️',fitzpatrick_scale:false,category:"symbols"},interrobang:{keywords:["wat","punctuation","surprise"],char:'⁉️',fitzpatrick_scale:false,category:"symbols"},low_brightness:{keywords:["sun","afternoon","warm","summer"],char:'🔅',fitzpatrick_scale:false,category:"symbols"},high_brightness:{keywords:["sun","light"],char:'🔆',fitzpatrick_scale:false,category:"symbols"},trident:{keywords:["weapon","spear"],char:'🔱',fitzpatrick_scale:false,category:"symbols"},fleur_de_lis:{keywords:["decorative","scout"],char:'⚜',fitzpatrick_scale:false,category:"symbols"},part_alternation_mark:{keywords:["graph","presentation","stats","business","economics","bad"],char:'〽️',fitzpatrick_scale:false,category:"symbols"},warning:{keywords:["exclamation","wip","alert","error","problem","issue"],char:'⚠️',fitzpatrick_scale:false,category:"symbols"},children_crossing:{keywords:["school","warning","danger","sign","driving","yellow-diamond"],char:'🚸',fitzpatrick_scale:false,category:"symbols"},beginner:{keywords:["badge","shield"],char:'🔰',fitzpatrick_scale:false,category:"symbols"},recycle:{keywords:["arrow","environment","garbage","trash"],char:'♻️',fitzpatrick_scale:false,category:"symbols"},u6307:{keywords:["chinese","point","green-square","kanji"],char:'🈯',fitzpatrick_scale:false,category:"symbols"},chart:{keywords:["green-square","graph","presentation","stats"],char:'💹',fitzpatrick_scale:false,category:"symbols"},sparkle:{keywords:["stars","green-square","awesome","good","fireworks"],char:'❇️',fitzpatrick_scale:false,category:"symbols"},eight_spoked_asterisk:{keywords:["star","sparkle","green-square"],char:'✳️',fitzpatrick_scale:false,category:"symbols"},negative_squared_cross_mark:{keywords:["x","green-square","no","deny"],char:'❎',fitzpatrick_scale:false,category:"symbols"},white_check_mark:{keywords:["green-square","ok","agree","vote","election","answer","tick"],char:'✅',fitzpatrick_scale:false,category:"symbols"},diamond_shape_with_a_dot_inside:{keywords:["jewel","blue","gem","crystal","fancy"],char:'💠',fitzpatrick_scale:false,category:"symbols"},cyclone:{keywords:["weather","swirl","blue","cloud","vortex","spiral","whirlpool","spin","tornado","hurricane","typhoon"],char:'🌀',fitzpatrick_scale:false,category:"symbols"},loop:{keywords:["tape","cassette"],char:'➿',fitzpatrick_scale:false,category:"symbols"},globe_with_meridians:{keywords:["earth","international","world","internet","interweb","i18n"],char:'🌐',fitzpatrick_scale:false,category:"symbols"},m:{keywords:["alphabet","blue-circle","letter"],char:'Ⓜ️',fitzpatrick_scale:false,category:"symbols"},atm:{keywords:["money","sales","cash","blue-square","payment","bank"],char:'🏧',fitzpatrick_scale:false,category:"symbols"},sa:{keywords:["japanese","blue-square","katakana"],char:'🈂️',fitzpatrick_scale:false,category:"symbols"},passport_control:{keywords:["custom","blue-square"],char:'🛂',fitzpatrick_scale:false,category:"symbols"},customs:{keywords:["passport","border","blue-square"],char:'🛃',fitzpatrick_scale:false,category:"symbols"},baggage_claim:{keywords:["blue-square","airport","transport"],char:'🛄',fitzpatrick_scale:false,category:"symbols"},left_luggage:{keywords:["blue-square","travel"],char:'🛅',fitzpatrick_scale:false,category:"symbols"},wheelchair:{keywords:["blue-square","disabled","a11y","accessibility"],char:'♿',fitzpatrick_scale:false,category:"symbols"},no_smoking:{keywords:["cigarette","blue-square","smell","smoke"],char:'🚭',fitzpatrick_scale:false,category:"symbols"},wc:{keywords:["toilet","restroom","blue-square"],char:'🚾',fitzpatrick_scale:false,category:"symbols"},parking:{keywords:["cars","blue-square","alphabet","letter"],char:'🅿️',fitzpatrick_scale:false,category:"symbols"},potable_water:{keywords:["blue-square","liquid","restroom","cleaning","faucet"],char:'🚰',fitzpatrick_scale:false,category:"symbols"},mens:{keywords:["toilet","restroom","wc","blue-square","gender","male"],char:'🚹',fitzpatrick_scale:false,category:"symbols"},womens:{keywords:["purple-square","woman","female","toilet","loo","restroom","gender"],char:'🚺',fitzpatrick_scale:false,category:"symbols"},baby_symbol:{keywords:["orange-square","child"],char:'🚼',fitzpatrick_scale:false,category:"symbols"},restroom:{keywords:["blue-square","toilet","refresh","wc","gender"],char:'🚻',fitzpatrick_scale:false,category:"symbols"},put_litter_in_its_place:{keywords:["blue-square","sign","human","info"],char:'🚮',fitzpatrick_scale:false,category:"symbols"},cinema:{keywords:["blue-square","record","film","movie","curtain","stage","theater"],char:'🎦',fitzpatrick_scale:false,category:"symbols"},signal_strength:{keywords:["blue-square","reception","phone","internet","connection","wifi","bluetooth","bars"],char:'📶',fitzpatrick_scale:false,category:"symbols"},koko:{keywords:["blue-square","here","katakana","japanese","destination"],char:'🈁',fitzpatrick_scale:false,category:"symbols"},ng:{keywords:["blue-square","words","shape","icon"],char:'🆖',fitzpatrick_scale:false,category:"symbols"},ok:{keywords:["good","agree","yes","blue-square"],char:'🆗',fitzpatrick_scale:false,category:"symbols"},up:{keywords:["blue-square","above","high"],char:'🆙',fitzpatrick_scale:false,category:"symbols"},cool:{keywords:["words","blue-square"],char:'🆒',fitzpatrick_scale:false,category:"symbols"},new:{keywords:["blue-square","words","start"],char:'🆕',fitzpatrick_scale:false,category:"symbols"},free:{keywords:["blue-square","words"],char:'🆓',fitzpatrick_scale:false,category:"symbols"},zero:{keywords:["0","numbers","blue-square","null"],char:'0️⃣',fitzpatrick_scale:false,category:"symbols"},one:{keywords:["blue-square","numbers","1"],char:'1️⃣',fitzpatrick_scale:false,category:"symbols"},two:{keywords:["numbers","2","prime","blue-square"],char:'2️⃣',fitzpatrick_scale:false,category:"symbols"},three:{keywords:["3","numbers","prime","blue-square"],char:'3️⃣',fitzpatrick_scale:false,category:"symbols"},four:{keywords:["4","numbers","blue-square"],char:'4️⃣',fitzpatrick_scale:false,category:"symbols"},five:{keywords:["5","numbers","blue-square","prime"],char:'5️⃣',fitzpatrick_scale:false,category:"symbols"},six:{keywords:["6","numbers","blue-square"],char:'6️⃣',fitzpatrick_scale:false,category:"symbols"},seven:{keywords:["7","numbers","blue-square","prime"],char:'7️⃣',fitzpatrick_scale:false,category:"symbols"},eight:{keywords:["8","blue-square","numbers"],char:'8️⃣',fitzpatrick_scale:false,category:"symbols"},nine:{keywords:["blue-square","numbers","9"],char:'9️⃣',fitzpatrick_scale:false,category:"symbols"},keycap_ten:{keywords:["numbers","10","blue-square"],char:'🔟',fitzpatrick_scale:false,category:"symbols"},asterisk:{keywords:["star","keycap"],char:'*⃣',fitzpatrick_scale:false,category:"symbols"},eject_button:{keywords:["blue-square"],char:'⏏️',fitzpatrick_scale:false,category:"symbols"},arrow_forward:{keywords:["blue-square","right","direction","play"],char:'▶️',fitzpatrick_scale:false,category:"symbols"},pause_button:{keywords:["pause","blue-square"],char:'⏸',fitzpatrick_scale:false,category:"symbols"},next_track_button:{keywords:["forward","next","blue-square"],char:'⏭',fitzpatrick_scale:false,category:"symbols"},stop_button:{keywords:["blue-square"],char:'⏹',fitzpatrick_scale:false,category:"symbols"},record_button:{keywords:["blue-square"],char:'⏺',fitzpatrick_scale:false,category:"symbols"},play_or_pause_button:{keywords:["blue-square","play","pause"],char:'⏯',fitzpatrick_scale:false,category:"symbols"},previous_track_button:{keywords:["backward"],char:'⏮',fitzpatrick_scale:false,category:"symbols"},fast_forward:{keywords:["blue-square","play","speed","continue"],char:'⏩',fitzpatrick_scale:false,category:"symbols"},rewind:{keywords:["play","blue-square"],char:'⏪',fitzpatrick_scale:false,category:"symbols"},twisted_rightwards_arrows:{keywords:["blue-square","shuffle","music","random"],char:'🔀',fitzpatrick_scale:false,category:"symbols"},repeat:{keywords:["loop","record"],char:'🔁',fitzpatrick_scale:false,category:"symbols"},repeat_one:{keywords:["blue-square","loop"],char:'🔂',fitzpatrick_scale:false,category:"symbols"},arrow_backward:{keywords:["blue-square","left","direction"],char:'◀️',fitzpatrick_scale:false,category:"symbols"},arrow_up_small:{keywords:["blue-square","triangle","direction","point","forward","top"],char:'🔼',fitzpatrick_scale:false,category:"symbols"},arrow_down_small:{keywords:["blue-square","direction","bottom"],char:'🔽',fitzpatrick_scale:false,category:"symbols"},arrow_double_up:{keywords:["blue-square","direction","top"],char:'⏫',fitzpatrick_scale:false,category:"symbols"},arrow_double_down:{keywords:["blue-square","direction","bottom"],char:'⏬',fitzpatrick_scale:false,category:"symbols"},arrow_right:{keywords:["blue-square","next"],char:'➡️',fitzpatrick_scale:false,category:"symbols"},arrow_left:{keywords:["blue-square","previous","back"],char:'⬅️',fitzpatrick_scale:false,category:"symbols"},arrow_up:{keywords:["blue-square","continue","top","direction"],char:'⬆️',fitzpatrick_scale:false,category:"symbols"},arrow_down:{keywords:["blue-square","direction","bottom"],char:'⬇️',fitzpatrick_scale:false,category:"symbols"},arrow_upper_right:{keywords:["blue-square","point","direction","diagonal","northeast"],char:'↗️',fitzpatrick_scale:false,category:"symbols"},arrow_lower_right:{keywords:["blue-square","direction","diagonal","southeast"],char:'↘️',fitzpatrick_scale:false,category:"symbols"},arrow_lower_left:{keywords:["blue-square","direction","diagonal","southwest"],char:'↙️',fitzpatrick_scale:false,category:"symbols"},arrow_upper_left:{keywords:["blue-square","point","direction","diagonal","northwest"],char:'↖️',fitzpatrick_scale:false,category:"symbols"},arrow_up_down:{keywords:["blue-square","direction","way","vertical"],char:'↕️',fitzpatrick_scale:false,category:"symbols"},left_right_arrow:{keywords:["shape","direction","horizontal","sideways"],char:'↔️',fitzpatrick_scale:false,category:"symbols"},arrows_counterclockwise:{keywords:["blue-square","sync","cycle"],char:'🔄',fitzpatrick_scale:false,category:"symbols"},arrow_right_hook:{keywords:["blue-square","return","rotate","direction"],char:'↪️',fitzpatrick_scale:false,category:"symbols"},leftwards_arrow_with_hook:{keywords:["back","return","blue-square","undo","enter"],char:'↩️',fitzpatrick_scale:false,category:"symbols"},arrow_heading_up:{keywords:["blue-square","direction","top"],char:'⤴️',fitzpatrick_scale:false,category:"symbols"},arrow_heading_down:{keywords:["blue-square","direction","bottom"],char:'⤵️',fitzpatrick_scale:false,category:"symbols"},hash:{keywords:["symbol","blue-square","twitter"],char:'#️⃣',fitzpatrick_scale:false,category:"symbols"},information_source:{keywords:["blue-square","alphabet","letter"],char:'ℹ️',fitzpatrick_scale:false,category:"symbols"},abc:{keywords:["blue-square","alphabet"],char:'🔤',fitzpatrick_scale:false,category:"symbols"},abcd:{keywords:["blue-square","alphabet"],char:'🔡',fitzpatrick_scale:false,category:"symbols"},capital_abcd:{keywords:["alphabet","words","blue-square"],char:'🔠',fitzpatrick_scale:false,category:"symbols"},symbols:{keywords:["blue-square","music","note","ampersand","percent","glyphs","characters"],char:'🔣',fitzpatrick_scale:false,category:"symbols"},musical_note:{keywords:["score","tone","sound"],char:'🎵',fitzpatrick_scale:false,category:"symbols"},notes:{keywords:["music","score"],char:'🎶',fitzpatrick_scale:false,category:"symbols"},wavy_dash:{keywords:["draw","line","moustache","mustache","squiggle","scribble"],char:'〰️',fitzpatrick_scale:false,category:"symbols"},curly_loop:{keywords:["scribble","draw","shape","squiggle"],char:'➰',fitzpatrick_scale:false,category:"symbols"},heavy_check_mark:{keywords:["ok","nike","answer","yes","tick"],char:'✔️',fitzpatrick_scale:false,category:"symbols"},arrows_clockwise:{keywords:["sync","cycle","round","repeat"],char:'🔃',fitzpatrick_scale:false,category:"symbols"},heavy_plus_sign:{keywords:["math","calculation","addition","more","increase"],char:'➕',fitzpatrick_scale:false,category:"symbols"},heavy_minus_sign:{keywords:["math","calculation","subtract","less"],char:'➖',fitzpatrick_scale:false,category:"symbols"},heavy_division_sign:{keywords:["divide","math","calculation"],char:'➗',fitzpatrick_scale:false,category:"symbols"},heavy_multiplication_x:{keywords:["math","calculation"],char:'✖️',fitzpatrick_scale:false,category:"symbols"},infinity:{keywords:["forever"],char:'♾',fitzpatrick_scale:false,category:"symbols"},heavy_dollar_sign:{keywords:["money","sales","payment","currency","buck"],char:'💲',fitzpatrick_scale:false,category:"symbols"},currency_exchange:{keywords:["money","sales","dollar","travel"],char:'💱',fitzpatrick_scale:false,category:"symbols"},copyright:{keywords:["ip","license","circle","law","legal"],char:'©️',fitzpatrick_scale:false,category:"symbols"},registered:{keywords:["alphabet","circle"],char:'®️',fitzpatrick_scale:false,category:"symbols"},tm:{keywords:["trademark","brand","law","legal"],char:'™️',fitzpatrick_scale:false,category:"symbols"},end:{keywords:["words","arrow"],char:'🔚',fitzpatrick_scale:false,category:"symbols"},back:{keywords:["arrow","words","return"],char:'🔙',fitzpatrick_scale:false,category:"symbols"},on:{keywords:["arrow","words"],char:'🔛',fitzpatrick_scale:false,category:"symbols"},top:{keywords:["words","blue-square"],char:'🔝',fitzpatrick_scale:false,category:"symbols"},soon:{keywords:["arrow","words"],char:'🔜',fitzpatrick_scale:false,category:"symbols"},ballot_box_with_check:{keywords:["ok","agree","confirm","black-square","vote","election","yes","tick"],char:'☑️',fitzpatrick_scale:false,category:"symbols"},radio_button:{keywords:["input","old","music","circle"],char:'🔘',fitzpatrick_scale:false,category:"symbols"},white_circle:{keywords:["shape","round"],char:'⚪',fitzpatrick_scale:false,category:"symbols"},black_circle:{keywords:["shape","button","round"],char:'⚫',fitzpatrick_scale:false,category:"symbols"},red_circle:{keywords:["shape","error","danger"],char:'🔴',fitzpatrick_scale:false,category:"symbols"},large_blue_circle:{keywords:["shape","icon","button"],char:'🔵',fitzpatrick_scale:false,category:"symbols"},small_orange_diamond:{keywords:["shape","jewel","gem"],char:'🔸',fitzpatrick_scale:false,category:"symbols"},small_blue_diamond:{keywords:["shape","jewel","gem"],char:'🔹',fitzpatrick_scale:false,category:"symbols"},large_orange_diamond:{keywords:["shape","jewel","gem"],char:'🔶',fitzpatrick_scale:false,category:"symbols"},large_blue_diamond:{keywords:["shape","jewel","gem"],char:'🔷',fitzpatrick_scale:false,category:"symbols"},small_red_triangle:{keywords:["shape","direction","up","top"],char:'🔺',fitzpatrick_scale:false,category:"symbols"},black_small_square:{keywords:["shape","icon"],char:'▪️',fitzpatrick_scale:false,category:"symbols"},white_small_square:{keywords:["shape","icon"],char:'▫️',fitzpatrick_scale:false,category:"symbols"},black_large_square:{keywords:["shape","icon","button"],char:'⬛',fitzpatrick_scale:false,category:"symbols"},white_large_square:{keywords:["shape","icon","stone","button"],char:'⬜',fitzpatrick_scale:false,category:"symbols"},small_red_triangle_down:{keywords:["shape","direction","bottom"],char:'🔻',fitzpatrick_scale:false,category:"symbols"},black_medium_square:{keywords:["shape","button","icon"],char:'◼️',fitzpatrick_scale:false,category:"symbols"},white_medium_square:{keywords:["shape","stone","icon"],char:'◻️',fitzpatrick_scale:false,category:"symbols"},black_medium_small_square:{keywords:["icon","shape","button"],char:'◾',fitzpatrick_scale:false,category:"symbols"},white_medium_small_square:{keywords:["shape","stone","icon","button"],char:'◽',fitzpatrick_scale:false,category:"symbols"},black_square_button:{keywords:["shape","input","frame"],char:'🔲',fitzpatrick_scale:false,category:"symbols"},white_square_button:{keywords:["shape","input"],char:'🔳',fitzpatrick_scale:false,category:"symbols"},speaker:{keywords:["sound","volume","silence","broadcast"],char:'🔈',fitzpatrick_scale:false,category:"symbols"},sound:{keywords:["volume","speaker","broadcast"],char:'🔉',fitzpatrick_scale:false,category:"symbols"},loud_sound:{keywords:["volume","noise","noisy","speaker","broadcast"],char:'🔊',fitzpatrick_scale:false,category:"symbols"},mute:{keywords:["sound","volume","silence","quiet"],char:'🔇',fitzpatrick_scale:false,category:"symbols"},mega:{keywords:["sound","speaker","volume"],char:'📣',fitzpatrick_scale:false,category:"symbols"},loudspeaker:{keywords:["volume","sound"],char:'📢',fitzpatrick_scale:false,category:"symbols"},bell:{keywords:["sound","notification","christmas","xmas","chime"],char:'🔔',fitzpatrick_scale:false,category:"symbols"},no_bell:{keywords:["sound","volume","mute","quiet","silent"],char:'🔕',fitzpatrick_scale:false,category:"symbols"},black_joker:{keywords:["poker","cards","game","play","magic"],char:'🃏',fitzpatrick_scale:false,category:"symbols"},mahjong:{keywords:["game","play","chinese","kanji"],char:'🀄',fitzpatrick_scale:false,category:"symbols"},spades:{keywords:["poker","cards","suits","magic"],char:'♠️',fitzpatrick_scale:false,category:"symbols"},clubs:{keywords:["poker","cards","magic","suits"],char:'♣️',fitzpatrick_scale:false,category:"symbols"},hearts:{keywords:["poker","cards","magic","suits"],char:'♥️',fitzpatrick_scale:false,category:"symbols"},diamonds:{keywords:["poker","cards","magic","suits"],char:'♦️',fitzpatrick_scale:false,category:"symbols"},flower_playing_cards:{keywords:["game","sunset","red"],char:'🎴',fitzpatrick_scale:false,category:"symbols"},thought_balloon:{keywords:["bubble","cloud","speech","thinking","dream"],char:'💭',fitzpatrick_scale:false,category:"symbols"},right_anger_bubble:{keywords:["caption","speech","thinking","mad"],char:'🗯',fitzpatrick_scale:false,category:"symbols"},speech_balloon:{keywords:["bubble","words","message","talk","chatting"],char:'💬',fitzpatrick_scale:false,category:"symbols"},left_speech_bubble:{keywords:["words","message","talk","chatting"],char:'🗨',fitzpatrick_scale:false,category:"symbols"},clock1:{keywords:["time","late","early","schedule"],char:'🕐',fitzpatrick_scale:false,category:"symbols"},clock2:{keywords:["time","late","early","schedule"],char:'🕑',fitzpatrick_scale:false,category:"symbols"},clock3:{keywords:["time","late","early","schedule"],char:'🕒',fitzpatrick_scale:false,category:"symbols"},clock4:{keywords:["time","late","early","schedule"],char:'🕓',fitzpatrick_scale:false,category:"symbols"},clock5:{keywords:["time","late","early","schedule"],char:'🕔',fitzpatrick_scale:false,category:"symbols"},clock6:{keywords:["time","late","early","schedule","dawn","dusk"],char:'🕕',fitzpatrick_scale:false,category:"symbols"},clock7:{keywords:["time","late","early","schedule"],char:'🕖',fitzpatrick_scale:false,category:"symbols"},clock8:{keywords:["time","late","early","schedule"],char:'🕗',fitzpatrick_scale:false,category:"symbols"},clock9:{keywords:["time","late","early","schedule"],char:'🕘',fitzpatrick_scale:false,category:"symbols"},clock10:{keywords:["time","late","early","schedule"],char:'🕙',fitzpatrick_scale:false,category:"symbols"},clock11:{keywords:["time","late","early","schedule"],char:'🕚',fitzpatrick_scale:false,category:"symbols"},clock12:{keywords:["time","noon","midnight","midday","late","early","schedule"],char:'🕛',fitzpatrick_scale:false,category:"symbols"},clock130:{keywords:["time","late","early","schedule"],char:'🕜',fitzpatrick_scale:false,category:"symbols"},clock230:{keywords:["time","late","early","schedule"],char:'🕝',fitzpatrick_scale:false,category:"symbols"},clock330:{keywords:["time","late","early","schedule"],char:'🕞',fitzpatrick_scale:false,category:"symbols"},clock430:{keywords:["time","late","early","schedule"],char:'🕟',fitzpatrick_scale:false,category:"symbols"},clock530:{keywords:["time","late","early","schedule"],char:'🕠',fitzpatrick_scale:false,category:"symbols"},clock630:{keywords:["time","late","early","schedule"],char:'🕡',fitzpatrick_scale:false,category:"symbols"},clock730:{keywords:["time","late","early","schedule"],char:'🕢',fitzpatrick_scale:false,category:"symbols"},clock830:{keywords:["time","late","early","schedule"],char:'🕣',fitzpatrick_scale:false,category:"symbols"},clock930:{keywords:["time","late","early","schedule"],char:'🕤',fitzpatrick_scale:false,category:"symbols"},clock1030:{keywords:["time","late","early","schedule"],char:'🕥',fitzpatrick_scale:false,category:"symbols"},clock1130:{keywords:["time","late","early","schedule"],char:'🕦',fitzpatrick_scale:false,category:"symbols"},clock1230:{keywords:["time","late","early","schedule"],char:'🕧',fitzpatrick_scale:false,category:"symbols"},afghanistan:{keywords:["af","flag","nation","country","banner"],char:'🇦🇫',fitzpatrick_scale:false,category:"flags"},aland_islands:{keywords:["Åland","islands","flag","nation","country","banner"],char:'🇦🇽',fitzpatrick_scale:false,category:"flags"},albania:{keywords:["al","flag","nation","country","banner"],char:'🇦🇱',fitzpatrick_scale:false,category:"flags"},algeria:{keywords:["dz","flag","nation","country","banner"],char:'🇩🇿',fitzpatrick_scale:false,category:"flags"},american_samoa:{keywords:["american","ws","flag","nation","country","banner"],char:'🇦🇸',fitzpatrick_scale:false,category:"flags"},andorra:{keywords:["ad","flag","nation","country","banner"],char:'🇦🇩',fitzpatrick_scale:false,category:"flags"},angola:{keywords:["ao","flag","nation","country","banner"],char:'🇦🇴',fitzpatrick_scale:false,category:"flags"},anguilla:{keywords:["ai","flag","nation","country","banner"],char:'🇦🇮',fitzpatrick_scale:false,category:"flags"},antarctica:{keywords:["aq","flag","nation","country","banner"],char:'🇦🇶',fitzpatrick_scale:false,category:"flags"},antigua_barbuda:{keywords:["antigua","barbuda","flag","nation","country","banner"],char:'🇦🇬',fitzpatrick_scale:false,category:"flags"},argentina:{keywords:["ar","flag","nation","country","banner"],char:'🇦🇷',fitzpatrick_scale:false,category:"flags"},armenia:{keywords:["am","flag","nation","country","banner"],char:'🇦🇲',fitzpatrick_scale:false,category:"flags"},aruba:{keywords:["aw","flag","nation","country","banner"],char:'🇦🇼',fitzpatrick_scale:false,category:"flags"},australia:{keywords:["au","flag","nation","country","banner"],char:'🇦🇺',fitzpatrick_scale:false,category:"flags"},austria:{keywords:["at","flag","nation","country","banner"],char:'🇦🇹',fitzpatrick_scale:false,category:"flags"},azerbaijan:{keywords:["az","flag","nation","country","banner"],char:'🇦🇿',fitzpatrick_scale:false,category:"flags"},bahamas:{keywords:["bs","flag","nation","country","banner"],char:'🇧🇸',fitzpatrick_scale:false,category:"flags"},bahrain:{keywords:["bh","flag","nation","country","banner"],char:'🇧🇭',fitzpatrick_scale:false,category:"flags"},bangladesh:{keywords:["bd","flag","nation","country","banner"],char:'🇧🇩',fitzpatrick_scale:false,category:"flags"},barbados:{keywords:["bb","flag","nation","country","banner"],char:'🇧🇧',fitzpatrick_scale:false,category:"flags"},belarus:{keywords:["by","flag","nation","country","banner"],char:'🇧🇾',fitzpatrick_scale:false,category:"flags"},belgium:{keywords:["be","flag","nation","country","banner"],char:'🇧🇪',fitzpatrick_scale:false,category:"flags"},belize:{keywords:["bz","flag","nation","country","banner"],char:'🇧🇿',fitzpatrick_scale:false,category:"flags"},benin:{keywords:["bj","flag","nation","country","banner"],char:'🇧🇯',fitzpatrick_scale:false,category:"flags"},bermuda:{keywords:["bm","flag","nation","country","banner"],char:'🇧🇲',fitzpatrick_scale:false,category:"flags"},bhutan:{keywords:["bt","flag","nation","country","banner"],char:'🇧🇹',fitzpatrick_scale:false,category:"flags"},bolivia:{keywords:["bo","flag","nation","country","banner"],char:'🇧🇴',fitzpatrick_scale:false,category:"flags"},caribbean_netherlands:{keywords:["bonaire","flag","nation","country","banner"],char:'🇧🇶',fitzpatrick_scale:false,category:"flags"},bosnia_herzegovina:{keywords:["bosnia","herzegovina","flag","nation","country","banner"],char:'🇧🇦',fitzpatrick_scale:false,category:"flags"},botswana:{keywords:["bw","flag","nation","country","banner"],char:'🇧🇼',fitzpatrick_scale:false,category:"flags"},brazil:{keywords:["br","flag","nation","country","banner"],char:'🇧🇷',fitzpatrick_scale:false,category:"flags"},british_indian_ocean_territory:{keywords:["british","indian","ocean","territory","flag","nation","country","banner"],char:'🇮🇴',fitzpatrick_scale:false,category:"flags"},british_virgin_islands:{keywords:["british","virgin","islands","bvi","flag","nation","country","banner"],char:'🇻🇬',fitzpatrick_scale:false,category:"flags"},brunei:{keywords:["bn","darussalam","flag","nation","country","banner"],char:'🇧🇳',fitzpatrick_scale:false,category:"flags"},bulgaria:{keywords:["bg","flag","nation","country","banner"],char:'🇧🇬',fitzpatrick_scale:false,category:"flags"},burkina_faso:{keywords:["burkina","faso","flag","nation","country","banner"],char:'🇧🇫',fitzpatrick_scale:false,category:"flags"},burundi:{keywords:["bi","flag","nation","country","banner"],char:'🇧🇮',fitzpatrick_scale:false,category:"flags"},cape_verde:{keywords:["cabo","verde","flag","nation","country","banner"],char:'🇨🇻',fitzpatrick_scale:false,category:"flags"},cambodia:{keywords:["kh","flag","nation","country","banner"],char:'🇰🇭',fitzpatrick_scale:false,category:"flags"},cameroon:{keywords:["cm","flag","nation","country","banner"],char:'🇨🇲',fitzpatrick_scale:false,category:"flags"},canada:{keywords:["ca","flag","nation","country","banner"],char:'🇨🇦',fitzpatrick_scale:false,category:"flags"},canary_islands:{keywords:["canary","islands","flag","nation","country","banner"],char:'🇮🇨',fitzpatrick_scale:false,category:"flags"},cayman_islands:{keywords:["cayman","islands","flag","nation","country","banner"],char:'🇰🇾',fitzpatrick_scale:false,category:"flags"},central_african_republic:{keywords:["central","african","republic","flag","nation","country","banner"],char:'🇨🇫',fitzpatrick_scale:false,category:"flags"},chad:{keywords:["td","flag","nation","country","banner"],char:'🇹🇩',fitzpatrick_scale:false,category:"flags"},chile:{keywords:["flag","nation","country","banner"],char:'🇨🇱',fitzpatrick_scale:false,category:"flags"},cn:{keywords:["china","chinese","prc","flag","country","nation","banner"],char:'🇨🇳',fitzpatrick_scale:false,category:"flags"},christmas_island:{keywords:["christmas","island","flag","nation","country","banner"],char:'🇨🇽',fitzpatrick_scale:false,category:"flags"},cocos_islands:{keywords:["cocos","keeling","islands","flag","nation","country","banner"],char:'🇨🇨',fitzpatrick_scale:false,category:"flags"},colombia:{keywords:["co","flag","nation","country","banner"],char:'🇨🇴',fitzpatrick_scale:false,category:"flags"},comoros:{keywords:["km","flag","nation","country","banner"],char:'🇰🇲',fitzpatrick_scale:false,category:"flags"},congo_brazzaville:{keywords:["congo","flag","nation","country","banner"],char:'🇨🇬',fitzpatrick_scale:false,category:"flags"},congo_kinshasa:{keywords:["congo","democratic","republic","flag","nation","country","banner"],char:'🇨🇩',fitzpatrick_scale:false,category:"flags"},cook_islands:{keywords:["cook","islands","flag","nation","country","banner"],char:'🇨🇰',fitzpatrick_scale:false,category:"flags"},costa_rica:{keywords:["costa","rica","flag","nation","country","banner"],char:'🇨🇷',fitzpatrick_scale:false,category:"flags"},croatia:{keywords:["hr","flag","nation","country","banner"],char:'🇭🇷',fitzpatrick_scale:false,category:"flags"},cuba:{keywords:["cu","flag","nation","country","banner"],char:'🇨🇺',fitzpatrick_scale:false,category:"flags"},curacao:{keywords:["curaçao","flag","nation","country","banner"],char:'🇨🇼',fitzpatrick_scale:false,category:"flags"},cyprus:{keywords:["cy","flag","nation","country","banner"],char:'🇨🇾',fitzpatrick_scale:false,category:"flags"},czech_republic:{keywords:["cz","flag","nation","country","banner"],char:'🇨🇿',fitzpatrick_scale:false,category:"flags"},denmark:{keywords:["dk","flag","nation","country","banner"],char:'🇩🇰',fitzpatrick_scale:false,category:"flags"},djibouti:{keywords:["dj","flag","nation","country","banner"],char:'🇩🇯',fitzpatrick_scale:false,category:"flags"},dominica:{keywords:["dm","flag","nation","country","banner"],char:'🇩🇲',fitzpatrick_scale:false,category:"flags"},dominican_republic:{keywords:["dominican","republic","flag","nation","country","banner"],char:'🇩🇴',fitzpatrick_scale:false,category:"flags"},ecuador:{keywords:["ec","flag","nation","country","banner"],char:'🇪🇨',fitzpatrick_scale:false,category:"flags"},egypt:{keywords:["eg","flag","nation","country","banner"],char:'🇪🇬',fitzpatrick_scale:false,category:"flags"},el_salvador:{keywords:["el","salvador","flag","nation","country","banner"],char:'🇸🇻',fitzpatrick_scale:false,category:"flags"},equatorial_guinea:{keywords:["equatorial","gn","flag","nation","country","banner"],char:'🇬🇶',fitzpatrick_scale:false,category:"flags"},eritrea:{keywords:["er","flag","nation","country","banner"],char:'🇪🇷',fitzpatrick_scale:false,category:"flags"},estonia:{keywords:["ee","flag","nation","country","banner"],char:'🇪🇪',fitzpatrick_scale:false,category:"flags"},ethiopia:{keywords:["et","flag","nation","country","banner"],char:'🇪🇹',fitzpatrick_scale:false,category:"flags"},eu:{keywords:["european","union","flag","banner"],char:'🇪🇺',fitzpatrick_scale:false,category:"flags"},falkland_islands:{keywords:["falkland","islands","malvinas","flag","nation","country","banner"],char:'🇫🇰',fitzpatrick_scale:false,category:"flags"},faroe_islands:{keywords:["faroe","islands","flag","nation","country","banner"],char:'🇫🇴',fitzpatrick_scale:false,category:"flags"},fiji:{keywords:["fj","flag","nation","country","banner"],char:'🇫🇯',fitzpatrick_scale:false,category:"flags"},finland:{keywords:["fi","flag","nation","country","banner"],char:'🇫🇮',fitzpatrick_scale:false,category:"flags"},fr:{keywords:["banner","flag","nation","france","french","country"],char:'🇫🇷',fitzpatrick_scale:false,category:"flags"},french_guiana:{keywords:["french","guiana","flag","nation","country","banner"],char:'🇬🇫',fitzpatrick_scale:false,category:"flags"},french_polynesia:{keywords:["french","polynesia","flag","nation","country","banner"],char:'🇵🇫',fitzpatrick_scale:false,category:"flags"},french_southern_territories:{keywords:["french","southern","territories","flag","nation","country","banner"],char:'🇹🇫',fitzpatrick_scale:false,category:"flags"},gabon:{keywords:["ga","flag","nation","country","banner"],char:'🇬🇦',fitzpatrick_scale:false,category:"flags"},gambia:{keywords:["gm","flag","nation","country","banner"],char:'🇬🇲',fitzpatrick_scale:false,category:"flags"},georgia:{keywords:["ge","flag","nation","country","banner"],char:'🇬🇪',fitzpatrick_scale:false,category:"flags"},de:{keywords:["german","nation","flag","country","banner"],char:'🇩🇪',fitzpatrick_scale:false,category:"flags"},ghana:{keywords:["gh","flag","nation","country","banner"],char:'🇬🇭',fitzpatrick_scale:false,category:"flags"},gibraltar:{keywords:["gi","flag","nation","country","banner"],char:'🇬🇮',fitzpatrick_scale:false,category:"flags"},greece:{keywords:["gr","flag","nation","country","banner"],char:'🇬🇷',fitzpatrick_scale:false,category:"flags"},greenland:{keywords:["gl","flag","nation","country","banner"],char:'🇬🇱',fitzpatrick_scale:false,category:"flags"},grenada:{keywords:["gd","flag","nation","country","banner"],char:'🇬🇩',fitzpatrick_scale:false,category:"flags"},guadeloupe:{keywords:["gp","flag","nation","country","banner"],char:'🇬🇵',fitzpatrick_scale:false,category:"flags"},guam:{keywords:["gu","flag","nation","country","banner"],char:'🇬🇺',fitzpatrick_scale:false,category:"flags"},guatemala:{keywords:["gt","flag","nation","country","banner"],char:'🇬🇹',fitzpatrick_scale:false,category:"flags"},guernsey:{keywords:["gg","flag","nation","country","banner"],char:'🇬🇬',fitzpatrick_scale:false,category:"flags"},guinea:{keywords:["gn","flag","nation","country","banner"],char:'🇬🇳',fitzpatrick_scale:false,category:"flags"},guinea_bissau:{keywords:["gw","bissau","flag","nation","country","banner"],char:'🇬🇼',fitzpatrick_scale:false,category:"flags"},guyana:{keywords:["gy","flag","nation","country","banner"],char:'🇬🇾',fitzpatrick_scale:false,category:"flags"},haiti:{keywords:["ht","flag","nation","country","banner"],char:'🇭🇹',fitzpatrick_scale:false,category:"flags"},honduras:{keywords:["hn","flag","nation","country","banner"],char:'🇭🇳',fitzpatrick_scale:false,category:"flags"},hong_kong:{keywords:["hong","kong","flag","nation","country","banner"],char:'🇭🇰',fitzpatrick_scale:false,category:"flags"},hungary:{keywords:["hu","flag","nation","country","banner"],char:'🇭🇺',fitzpatrick_scale:false,category:"flags"},iceland:{keywords:["is","flag","nation","country","banner"],char:'🇮🇸',fitzpatrick_scale:false,category:"flags"},india:{keywords:["in","flag","nation","country","banner"],char:'🇮🇳',fitzpatrick_scale:false,category:"flags"},indonesia:{keywords:["flag","nation","country","banner"],char:'🇮🇩',fitzpatrick_scale:false,category:"flags"},iran:{keywords:["iran,","islamic","republic","flag","nation","country","banner"],char:'🇮🇷',fitzpatrick_scale:false,category:"flags"},iraq:{keywords:["iq","flag","nation","country","banner"],char:'🇮🇶',fitzpatrick_scale:false,category:"flags"},ireland:{keywords:["ie","flag","nation","country","banner"],char:'🇮🇪',fitzpatrick_scale:false,category:"flags"},isle_of_man:{keywords:["isle","man","flag","nation","country","banner"],char:'🇮🇲',fitzpatrick_scale:false,category:"flags"},israel:{keywords:["il","flag","nation","country","banner"],char:'🇮🇱',fitzpatrick_scale:false,category:"flags"},it:{keywords:["italy","flag","nation","country","banner"],char:'🇮🇹',fitzpatrick_scale:false,category:"flags"},cote_divoire:{keywords:["ivory","coast","flag","nation","country","banner"],char:'🇨🇮',fitzpatrick_scale:false,category:"flags"},jamaica:{keywords:["jm","flag","nation","country","banner"],char:'🇯🇲',fitzpatrick_scale:false,category:"flags"},jp:{keywords:["japanese","nation","flag","country","banner"],char:'🇯🇵',fitzpatrick_scale:false,category:"flags"},jersey:{keywords:["je","flag","nation","country","banner"],char:'🇯🇪',fitzpatrick_scale:false,category:"flags"},jordan:{keywords:["jo","flag","nation","country","banner"],char:'🇯🇴',fitzpatrick_scale:false,category:"flags"},kazakhstan:{keywords:["kz","flag","nation","country","banner"],char:'🇰🇿',fitzpatrick_scale:false,category:"flags"},kenya:{keywords:["ke","flag","nation","country","banner"],char:'🇰🇪',fitzpatrick_scale:false,category:"flags"},kiribati:{keywords:["ki","flag","nation","country","banner"],char:'🇰🇮',fitzpatrick_scale:false,category:"flags"},kosovo:{keywords:["xk","flag","nation","country","banner"],char:'🇽🇰',fitzpatrick_scale:false,category:"flags"},kuwait:{keywords:["kw","flag","nation","country","banner"],char:'🇰🇼',fitzpatrick_scale:false,category:"flags"},kyrgyzstan:{keywords:["kg","flag","nation","country","banner"],char:'🇰🇬',fitzpatrick_scale:false,category:"flags"},laos:{keywords:["lao","democratic","republic","flag","nation","country","banner"],char:'🇱🇦',fitzpatrick_scale:false,category:"flags"},latvia:{keywords:["lv","flag","nation","country","banner"],char:'🇱🇻',fitzpatrick_scale:false,category:"flags"},lebanon:{keywords:["lb","flag","nation","country","banner"],char:'🇱🇧',fitzpatrick_scale:false,category:"flags"},lesotho:{keywords:["ls","flag","nation","country","banner"],char:'🇱🇸',fitzpatrick_scale:false,category:"flags"},liberia:{keywords:["lr","flag","nation","country","banner"],char:'🇱🇷',fitzpatrick_scale:false,category:"flags"},libya:{keywords:["ly","flag","nation","country","banner"],char:'🇱🇾',fitzpatrick_scale:false,category:"flags"},liechtenstein:{keywords:["li","flag","nation","country","banner"],char:'🇱🇮',fitzpatrick_scale:false,category:"flags"},lithuania:{keywords:["lt","flag","nation","country","banner"],char:'🇱🇹',fitzpatrick_scale:false,category:"flags"},luxembourg:{keywords:["lu","flag","nation","country","banner"],char:'🇱🇺',fitzpatrick_scale:false,category:"flags"},macau:{keywords:["macao","flag","nation","country","banner"],char:'🇲🇴',fitzpatrick_scale:false,category:"flags"},macedonia:{keywords:["macedonia,","flag","nation","country","banner"],char:'🇲🇰',fitzpatrick_scale:false,category:"flags"},madagascar:{keywords:["mg","flag","nation","country","banner"],char:'🇲🇬',fitzpatrick_scale:false,category:"flags"},malawi:{keywords:["mw","flag","nation","country","banner"],char:'🇲🇼',fitzpatrick_scale:false,category:"flags"},malaysia:{keywords:["my","flag","nation","country","banner"],char:'🇲🇾',fitzpatrick_scale:false,category:"flags"},maldives:{keywords:["mv","flag","nation","country","banner"],char:'🇲🇻',fitzpatrick_scale:false,category:"flags"},mali:{keywords:["ml","flag","nation","country","banner"],char:'🇲🇱',fitzpatrick_scale:false,category:"flags"},malta:{keywords:["mt","flag","nation","country","banner"],char:'🇲🇹',fitzpatrick_scale:false,category:"flags"},marshall_islands:{keywords:["marshall","islands","flag","nation","country","banner"],char:'🇲🇭',fitzpatrick_scale:false,category:"flags"},martinique:{keywords:["mq","flag","nation","country","banner"],char:'🇲🇶',fitzpatrick_scale:false,category:"flags"},mauritania:{keywords:["mr","flag","nation","country","banner"],char:'🇲🇷',fitzpatrick_scale:false,category:"flags"},mauritius:{keywords:["mu","flag","nation","country","banner"],char:'🇲🇺',fitzpatrick_scale:false,category:"flags"},mayotte:{keywords:["yt","flag","nation","country","banner"],char:'🇾🇹',fitzpatrick_scale:false,category:"flags"},mexico:{keywords:["mx","flag","nation","country","banner"],char:'🇲🇽',fitzpatrick_scale:false,category:"flags"},micronesia:{keywords:["micronesia,","federated","states","flag","nation","country","banner"],char:'🇫🇲',fitzpatrick_scale:false,category:"flags"},moldova:{keywords:["moldova,","republic","flag","nation","country","banner"],char:'🇲🇩',fitzpatrick_scale:false,category:"flags"},monaco:{keywords:["mc","flag","nation","country","banner"],char:'🇲🇨',fitzpatrick_scale:false,category:"flags"},mongolia:{keywords:["mn","flag","nation","country","banner"],char:'🇲🇳',fitzpatrick_scale:false,category:"flags"},montenegro:{keywords:["me","flag","nation","country","banner"],char:'🇲🇪',fitzpatrick_scale:false,category:"flags"},montserrat:{keywords:["ms","flag","nation","country","banner"],char:'🇲🇸',fitzpatrick_scale:false,category:"flags"},morocco:{keywords:["ma","flag","nation","country","banner"],char:'🇲🇦',fitzpatrick_scale:false,category:"flags"},mozambique:{keywords:["mz","flag","nation","country","banner"],char:'🇲🇿',fitzpatrick_scale:false,category:"flags"},myanmar:{keywords:["mm","flag","nation","country","banner"],char:'🇲🇲',fitzpatrick_scale:false,category:"flags"},namibia:{keywords:["na","flag","nation","country","banner"],char:'🇳🇦',fitzpatrick_scale:false,category:"flags"},nauru:{keywords:["nr","flag","nation","country","banner"],char:'🇳🇷',fitzpatrick_scale:false,category:"flags"},nepal:{keywords:["np","flag","nation","country","banner"],char:'🇳🇵',fitzpatrick_scale:false,category:"flags"},netherlands:{keywords:["nl","flag","nation","country","banner"],char:'🇳🇱',fitzpatrick_scale:false,category:"flags"},new_caledonia:{keywords:["new","caledonia","flag","nation","country","banner"],char:'🇳🇨',fitzpatrick_scale:false,category:"flags"},new_zealand:{keywords:["new","zealand","flag","nation","country","banner"],char:'🇳🇿',fitzpatrick_scale:false,category:"flags"},nicaragua:{keywords:["ni","flag","nation","country","banner"],char:'🇳🇮',fitzpatrick_scale:false,category:"flags"},niger:{keywords:["ne","flag","nation","country","banner"],char:'🇳🇪',fitzpatrick_scale:false,category:"flags"},nigeria:{keywords:["flag","nation","country","banner"],char:'🇳🇬',fitzpatrick_scale:false,category:"flags"},niue:{keywords:["nu","flag","nation","country","banner"],char:'🇳🇺',fitzpatrick_scale:false,category:"flags"},norfolk_island:{keywords:["norfolk","island","flag","nation","country","banner"],char:'🇳🇫',fitzpatrick_scale:false,category:"flags"},northern_mariana_islands:{keywords:["northern","mariana","islands","flag","nation","country","banner"],char:'🇲🇵',fitzpatrick_scale:false,category:"flags"},north_korea:{keywords:["north","korea","nation","flag","country","banner"],char:'🇰🇵',fitzpatrick_scale:false,category:"flags"},norway:{keywords:["no","flag","nation","country","banner"],char:'🇳🇴',fitzpatrick_scale:false,category:"flags"},oman:{keywords:["om_symbol","flag","nation","country","banner"],char:'🇴🇲',fitzpatrick_scale:false,category:"flags"},pakistan:{keywords:["pk","flag","nation","country","banner"],char:'🇵🇰',fitzpatrick_scale:false,category:"flags"},palau:{keywords:["pw","flag","nation","country","banner"],char:'🇵🇼',fitzpatrick_scale:false,category:"flags"},palestinian_territories:{keywords:["palestine","palestinian","territories","flag","nation","country","banner"],char:'🇵🇸',fitzpatrick_scale:false,category:"flags"},panama:{keywords:["pa","flag","nation","country","banner"],char:'🇵🇦',fitzpatrick_scale:false,category:"flags"},papua_new_guinea:{keywords:["papua","new","guinea","flag","nation","country","banner"],char:'🇵🇬',fitzpatrick_scale:false,category:"flags"},paraguay:{keywords:["py","flag","nation","country","banner"],char:'🇵🇾',fitzpatrick_scale:false,category:"flags"},peru:{keywords:["pe","flag","nation","country","banner"],char:'🇵🇪',fitzpatrick_scale:false,category:"flags"},philippines:{keywords:["ph","flag","nation","country","banner"],char:'🇵🇭',fitzpatrick_scale:false,category:"flags"},pitcairn_islands:{keywords:["pitcairn","flag","nation","country","banner"],char:'🇵🇳',fitzpatrick_scale:false,category:"flags"},poland:{keywords:["pl","flag","nation","country","banner"],char:'🇵🇱',fitzpatrick_scale:false,category:"flags"},portugal:{keywords:["pt","flag","nation","country","banner"],char:'🇵🇹',fitzpatrick_scale:false,category:"flags"},puerto_rico:{keywords:["puerto","rico","flag","nation","country","banner"],char:'🇵🇷',fitzpatrick_scale:false,category:"flags"},qatar:{keywords:["qa","flag","nation","country","banner"],char:'🇶🇦',fitzpatrick_scale:false,category:"flags"},reunion:{keywords:["réunion","flag","nation","country","banner"],char:'🇷🇪',fitzpatrick_scale:false,category:"flags"},romania:{keywords:["ro","flag","nation","country","banner"],char:'🇷🇴',fitzpatrick_scale:false,category:"flags"},ru:{keywords:["russian","federation","flag","nation","country","banner"],char:'🇷🇺',fitzpatrick_scale:false,category:"flags"},rwanda:{keywords:["rw","flag","nation","country","banner"],char:'🇷🇼',fitzpatrick_scale:false,category:"flags"},st_barthelemy:{keywords:["saint","barthélemy","flag","nation","country","banner"],char:'🇧🇱',fitzpatrick_scale:false,category:"flags"},st_helena:{keywords:["saint","helena","ascension","tristan","cunha","flag","nation","country","banner"],char:'🇸🇭',fitzpatrick_scale:false,category:"flags"},st_kitts_nevis:{keywords:["saint","kitts","nevis","flag","nation","country","banner"],char:'🇰🇳',fitzpatrick_scale:false,category:"flags"},st_lucia:{keywords:["saint","lucia","flag","nation","country","banner"],char:'🇱🇨',fitzpatrick_scale:false,category:"flags"},st_pierre_miquelon:{keywords:["saint","pierre","miquelon","flag","nation","country","banner"],char:'🇵🇲',fitzpatrick_scale:false,category:"flags"},st_vincent_grenadines:{keywords:["saint","vincent","grenadines","flag","nation","country","banner"],char:'🇻🇨',fitzpatrick_scale:false,category:"flags"},samoa:{keywords:["ws","flag","nation","country","banner"],char:'🇼🇸',fitzpatrick_scale:false,category:"flags"},san_marino:{keywords:["san","marino","flag","nation","country","banner"],char:'🇸🇲',fitzpatrick_scale:false,category:"flags"},sao_tome_principe:{keywords:["sao","tome","principe","flag","nation","country","banner"],char:'🇸🇹',fitzpatrick_scale:false,category:"flags"},saudi_arabia:{keywords:["flag","nation","country","banner"],char:'🇸🇦',fitzpatrick_scale:false,category:"flags"},senegal:{keywords:["sn","flag","nation","country","banner"],char:'🇸🇳',fitzpatrick_scale:false,category:"flags"},serbia:{keywords:["rs","flag","nation","country","banner"],char:'🇷🇸',fitzpatrick_scale:false,category:"flags"},seychelles:{keywords:["sc","flag","nation","country","banner"],char:'🇸🇨',fitzpatrick_scale:false,category:"flags"},sierra_leone:{keywords:["sierra","leone","flag","nation","country","banner"],char:'🇸🇱',fitzpatrick_scale:false,category:"flags"},singapore:{keywords:["sg","flag","nation","country","banner"],char:'🇸🇬',fitzpatrick_scale:false,category:"flags"},sint_maarten:{keywords:["sint","maarten","dutch","flag","nation","country","banner"],char:'🇸🇽',fitzpatrick_scale:false,category:"flags"},slovakia:{keywords:["sk","flag","nation","country","banner"],char:'🇸🇰',fitzpatrick_scale:false,category:"flags"},slovenia:{keywords:["si","flag","nation","country","banner"],char:'🇸🇮',fitzpatrick_scale:false,category:"flags"},solomon_islands:{keywords:["solomon","islands","flag","nation","country","banner"],char:'🇸🇧',fitzpatrick_scale:false,category:"flags"},somalia:{keywords:["so","flag","nation","country","banner"],char:'🇸🇴',fitzpatrick_scale:false,category:"flags"},south_africa:{keywords:["south","africa","flag","nation","country","banner"],char:'🇿🇦',fitzpatrick_scale:false,category:"flags"},south_georgia_south_sandwich_islands:{keywords:["south","georgia","sandwich","islands","flag","nation","country","banner"],char:'🇬🇸',fitzpatrick_scale:false,category:"flags"},kr:{keywords:["south","korea","nation","flag","country","banner"],char:'🇰🇷',fitzpatrick_scale:false,category:"flags"},south_sudan:{keywords:["south","sd","flag","nation","country","banner"],char:'🇸🇸',fitzpatrick_scale:false,category:"flags"},es:{keywords:["spain","flag","nation","country","banner"],char:'🇪🇸',fitzpatrick_scale:false,category:"flags"},sri_lanka:{keywords:["sri","lanka","flag","nation","country","banner"],char:'🇱🇰',fitzpatrick_scale:false,category:"flags"},sudan:{keywords:["sd","flag","nation","country","banner"],char:'🇸🇩',fitzpatrick_scale:false,category:"flags"},suriname:{keywords:["sr","flag","nation","country","banner"],char:'🇸🇷',fitzpatrick_scale:false,category:"flags"},swaziland:{keywords:["sz","flag","nation","country","banner"],char:'🇸🇿',fitzpatrick_scale:false,category:"flags"},sweden:{keywords:["se","flag","nation","country","banner"],char:'🇸🇪',fitzpatrick_scale:false,category:"flags"},switzerland:{keywords:["ch","flag","nation","country","banner"],char:'🇨🇭',fitzpatrick_scale:false,category:"flags"},syria:{keywords:["syrian","arab","republic","flag","nation","country","banner"],char:'🇸🇾',fitzpatrick_scale:false,category:"flags"},taiwan:{keywords:["tw","flag","nation","country","banner"],char:'🇹🇼',fitzpatrick_scale:false,category:"flags"},tajikistan:{keywords:["tj","flag","nation","country","banner"],char:'🇹🇯',fitzpatrick_scale:false,category:"flags"},tanzania:{keywords:["tanzania,","united","republic","flag","nation","country","banner"],char:'🇹🇿',fitzpatrick_scale:false,category:"flags"},thailand:{keywords:["th","flag","nation","country","banner"],char:'🇹🇭',fitzpatrick_scale:false,category:"flags"},timor_leste:{keywords:["timor","leste","flag","nation","country","banner"],char:'🇹🇱',fitzpatrick_scale:false,category:"flags"},togo:{keywords:["tg","flag","nation","country","banner"],char:'🇹🇬',fitzpatrick_scale:false,category:"flags"},tokelau:{keywords:["tk","flag","nation","country","banner"],char:'🇹🇰',fitzpatrick_scale:false,category:"flags"},tonga:{keywords:["to","flag","nation","country","banner"],char:'🇹🇴',fitzpatrick_scale:false,category:"flags"},trinidad_tobago:{keywords:["trinidad","tobago","flag","nation","country","banner"],char:'🇹🇹',fitzpatrick_scale:false,category:"flags"},tunisia:{keywords:["tn","flag","nation","country","banner"],char:'🇹🇳',fitzpatrick_scale:false,category:"flags"},tr:{keywords:["turkey","flag","nation","country","banner"],char:'🇹🇷',fitzpatrick_scale:false,category:"flags"},turkmenistan:{keywords:["flag","nation","country","banner"],char:'🇹🇲',fitzpatrick_scale:false,category:"flags"},turks_caicos_islands:{keywords:["turks","caicos","islands","flag","nation","country","banner"],char:'🇹🇨',fitzpatrick_scale:false,category:"flags"},tuvalu:{keywords:["flag","nation","country","banner"],char:'🇹🇻',fitzpatrick_scale:false,category:"flags"},uganda:{keywords:["ug","flag","nation","country","banner"],char:'🇺🇬',fitzpatrick_scale:false,category:"flags"},ukraine:{keywords:["ua","flag","nation","country","banner"],char:'🇺🇦',fitzpatrick_scale:false,category:"flags"},united_arab_emirates:{keywords:["united","arab","emirates","flag","nation","country","banner"],char:'🇦🇪',fitzpatrick_scale:false,category:"flags"},uk:{keywords:["united","kingdom","great","britain","northern","ireland","flag","nation","country","banner","british","UK","english","england","union jack"],char:'🇬🇧',fitzpatrick_scale:false,category:"flags"},england:{keywords:["flag","english"],char:'🏴󠁧󠁢󠁥󠁮󠁧󠁿',fitzpatrick_scale:false,category:"flags"},scotland:{keywords:["flag","scottish"],char:'🏴󠁧󠁢󠁳󠁣󠁴󠁿',fitzpatrick_scale:false,category:"flags"},wales:{keywords:["flag","welsh"],char:'🏴󠁧󠁢󠁷󠁬󠁳󠁿',fitzpatrick_scale:false,category:"flags"},us:{keywords:["united","states","america","flag","nation","country","banner"],char:'🇺🇸',fitzpatrick_scale:false,category:"flags"},us_virgin_islands:{keywords:["virgin","islands","us","flag","nation","country","banner"],char:'🇻🇮',fitzpatrick_scale:false,category:"flags"},uruguay:{keywords:["uy","flag","nation","country","banner"],char:'🇺🇾',fitzpatrick_scale:false,category:"flags"},uzbekistan:{keywords:["uz","flag","nation","country","banner"],char:'🇺🇿',fitzpatrick_scale:false,category:"flags"},vanuatu:{keywords:["vu","flag","nation","country","banner"],char:'🇻🇺',fitzpatrick_scale:false,category:"flags"},vatican_city:{keywords:["vatican","city","flag","nation","country","banner"],char:'🇻🇦',fitzpatrick_scale:false,category:"flags"},venezuela:{keywords:["ve","bolivarian","republic","flag","nation","country","banner"],char:'🇻🇪',fitzpatrick_scale:false,category:"flags"},vietnam:{keywords:["viet","nam","flag","nation","country","banner"],char:'🇻🇳',fitzpatrick_scale:false,category:"flags"},wallis_futuna:{keywords:["wallis","futuna","flag","nation","country","banner"],char:'🇼🇫',fitzpatrick_scale:false,category:"flags"},western_sahara:{keywords:["western","sahara","flag","nation","country","banner"],char:'🇪🇭',fitzpatrick_scale:false,category:"flags"},yemen:{keywords:["ye","flag","nation","country","banner"],char:'🇾🇪',fitzpatrick_scale:false,category:"flags"},zambia:{keywords:["zm","flag","nation","country","banner"],char:'🇿🇲',fitzpatrick_scale:false,category:"flags"},zimbabwe:{keywords:["zw","flag","nation","country","banner"],char:'🇿🇼',fitzpatrick_scale:false,category:"flags"},united_nations:{keywords:["un","flag","banner"],char:'🇺🇳',fitzpatrick_scale:false,category:"flags"},pirate_flag:{keywords:["skull","crossbones","flag","banner"],char:'🏴‍☠️',fitzpatrick_scale:false,category:"flags"}}); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/emoticons/js/emojiimages.min.js b/public/resource/tinymce/plugins/emoticons/js/emojiimages.min.js new file mode 100644 index 0000000..37f3bcf --- /dev/null +++ b/public/resource/tinymce/plugins/emoticons/js/emojiimages.min.js @@ -0,0 +1,3 @@ +// Source: npm package: emojilib +// Images provided by twemoji: https://github.com/twitter/twemoji +window.tinymce.Resource.add("tinymce.plugins.emoticons",{100:{keywords:["score","perfect","numbers","century","exam","quiz","test","pass","hundred"],char:'\u{1f4af}',fitzpatrick_scale:!1,category:"symbols"},1234:{keywords:["numbers","blue-square"],char:'\u{1f522}',fitzpatrick_scale:!1,category:"symbols"},grinning:{keywords:["face","smile","happy","joy",":D","grin"],char:'\u{1f600}',fitzpatrick_scale:!1,category:"people"},grimacing:{keywords:["face","grimace","teeth"],char:'\u{1f62c}',fitzpatrick_scale:!1,category:"people"},grin:{keywords:["face","happy","smile","joy","kawaii"],char:'\u{1f601}',fitzpatrick_scale:!1,category:"people"},joy:{keywords:["face","cry","tears","weep","happy","happytears","haha"],char:'\u{1f602}',fitzpatrick_scale:!1,category:"people"},rofl:{keywords:["face","rolling","floor","laughing","lol","haha"],char:'\u{1f923}',fitzpatrick_scale:!1,category:"people"},partying:{keywords:["face","celebration","woohoo"],char:'\u{1f973}',fitzpatrick_scale:!1,category:"people"},smiley:{keywords:["face","happy","joy","haha",":D",":)","smile","funny"],char:'\u{1f603}',fitzpatrick_scale:!1,category:"people"},smile:{keywords:["face","happy","joy","funny","haha","laugh","like",":D",":)"],char:'\u{1f604}',fitzpatrick_scale:!1,category:"people"},sweat_smile:{keywords:["face","hot","happy","laugh","sweat","smile","relief"],char:'\u{1f605}',fitzpatrick_scale:!1,category:"people"},laughing:{keywords:["happy","joy","lol","satisfied","haha","face","glad","XD","laugh"],char:'\u{1f606}',fitzpatrick_scale:!1,category:"people"},innocent:{keywords:["face","angel","heaven","halo"],char:'\u{1f607}',fitzpatrick_scale:!1,category:"people"},wink:{keywords:["face","happy","mischievous","secret",";)","smile","eye"],char:'\u{1f609}',fitzpatrick_scale:!1,category:"people"},blush:{keywords:["face","smile","happy","flushed","crush","embarrassed","shy","joy"],char:'\u{1f60a}',fitzpatrick_scale:!1,category:"people"},slightly_smiling_face:{keywords:["face","smile"],char:'\u{1f642}',fitzpatrick_scale:!1,category:"people"},upside_down_face:{keywords:["face","flipped","silly","smile"],char:'\u{1f643}',fitzpatrick_scale:!1,category:"people"},relaxed:{keywords:["face","blush","massage","happiness"],char:'\u263a\ufe0f',fitzpatrick_scale:!1,category:"people"},yum:{keywords:["happy","joy","tongue","smile","face","silly","yummy","nom","delicious","savouring"],char:'\u{1f60b}',fitzpatrick_scale:!1,category:"people"},relieved:{keywords:["face","relaxed","phew","massage","happiness"],char:'\u{1f60c}',fitzpatrick_scale:!1,category:"people"},heart_eyes:{keywords:["face","love","like","affection","valentines","infatuation","crush","heart"],char:'\u{1f60d}',fitzpatrick_scale:!1,category:"people"},smiling_face_with_three_hearts:{keywords:["face","love","like","affection","valentines","infatuation","crush","hearts","adore"],char:'\u{1f970}',fitzpatrick_scale:!1,category:"people"},kissing_heart:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:'\u{1f618}',fitzpatrick_scale:!1,category:"people"},kissing:{keywords:["love","like","face","3","valentines","infatuation","kiss"],char:'\u{1f617}',fitzpatrick_scale:!1,category:"people"},kissing_smiling_eyes:{keywords:["face","affection","valentines","infatuation","kiss"],char:'\u{1f619}',fitzpatrick_scale:!1,category:"people"},kissing_closed_eyes:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:'\u{1f61a}',fitzpatrick_scale:!1,category:"people"},stuck_out_tongue_winking_eye:{keywords:["face","prank","childish","playful","mischievous","smile","wink","tongue"],char:'\u{1f61c}',fitzpatrick_scale:!1,category:"people"},zany:{keywords:["face","goofy","crazy"],char:'\u{1f92a}',fitzpatrick_scale:!1,category:"people"},raised_eyebrow:{keywords:["face","distrust","scepticism","disapproval","disbelief","surprise"],char:'\u{1f928}',fitzpatrick_scale:!1,category:"people"},monocle:{keywords:["face","stuffy","wealthy"],char:'\u{1f9d0}',fitzpatrick_scale:!1,category:"people"},stuck_out_tongue_closed_eyes:{keywords:["face","prank","playful","mischievous","smile","tongue"],char:'\u{1f61d}',fitzpatrick_scale:!1,category:"people"},stuck_out_tongue:{keywords:["face","prank","childish","playful","mischievous","smile","tongue"],char:'\u{1f61b}',fitzpatrick_scale:!1,category:"people"},money_mouth_face:{keywords:["face","rich","dollar","money"],char:'\u{1f911}',fitzpatrick_scale:!1,category:"people"},nerd_face:{keywords:["face","nerdy","geek","dork"],char:'\u{1f913}',fitzpatrick_scale:!1,category:"people"},sunglasses:{keywords:["face","cool","smile","summer","beach","sunglass"],char:'\u{1f60e}',fitzpatrick_scale:!1,category:"people"},star_struck:{keywords:["face","smile","starry","eyes","grinning"],char:'\u{1f929}',fitzpatrick_scale:!1,category:"people"},clown_face:{keywords:["face"],char:'\u{1f921}',fitzpatrick_scale:!1,category:"people"},cowboy_hat_face:{keywords:["face","cowgirl","hat"],char:'\u{1f920}',fitzpatrick_scale:!1,category:"people"},hugs:{keywords:["face","smile","hug"],char:'\u{1f917}',fitzpatrick_scale:!1,category:"people"},smirk:{keywords:["face","smile","mean","prank","smug","sarcasm"],char:'\u{1f60f}',fitzpatrick_scale:!1,category:"people"},no_mouth:{keywords:["face","hellokitty"],char:'\u{1f636}',fitzpatrick_scale:!1,category:"people"},neutral_face:{keywords:["indifference","meh",":|","neutral"],char:'\u{1f610}',fitzpatrick_scale:!1,category:"people"},expressionless:{keywords:["face","indifferent","-_-","meh","deadpan"],char:'\u{1f611}',fitzpatrick_scale:!1,category:"people"},unamused:{keywords:["indifference","bored","straight face","serious","sarcasm","unimpressed","skeptical","dubious","side_eye"],char:'\u{1f612}',fitzpatrick_scale:!1,category:"people"},roll_eyes:{keywords:["face","eyeroll","frustrated"],char:'\u{1f644}',fitzpatrick_scale:!1,category:"people"},thinking:{keywords:["face","hmmm","think","consider"],char:'\u{1f914}',fitzpatrick_scale:!1,category:"people"},lying_face:{keywords:["face","lie","pinocchio"],char:'\u{1f925}',fitzpatrick_scale:!1,category:"people"},hand_over_mouth:{keywords:["face","whoops","shock","surprise"],char:'\u{1f92d}',fitzpatrick_scale:!1,category:"people"},shushing:{keywords:["face","quiet","shhh"],char:'\u{1f92b}',fitzpatrick_scale:!1,category:"people"},symbols_over_mouth:{keywords:["face","swearing","cursing","cussing","profanity","expletive"],char:'\u{1f92c}',fitzpatrick_scale:!1,category:"people"},exploding_head:{keywords:["face","shocked","mind","blown"],char:'\u{1f92f}',fitzpatrick_scale:!1,category:"people"},flushed:{keywords:["face","blush","shy","flattered"],char:'\u{1f633}',fitzpatrick_scale:!1,category:"people"},disappointed:{keywords:["face","sad","upset","depressed",":("],char:'\u{1f61e}',fitzpatrick_scale:!1,category:"people"},worried:{keywords:["face","concern","nervous",":("],char:'\u{1f61f}',fitzpatrick_scale:!1,category:"people"},angry:{keywords:["mad","face","annoyed","frustrated"],char:'\u{1f620}',fitzpatrick_scale:!1,category:"people"},rage:{keywords:["angry","mad","hate","despise"],char:'\u{1f621}',fitzpatrick_scale:!1,category:"people"},pensive:{keywords:["face","sad","depressed","upset"],char:'\u{1f614}',fitzpatrick_scale:!1,category:"people"},confused:{keywords:["face","indifference","huh","weird","hmmm",":/"],char:'\u{1f615}',fitzpatrick_scale:!1,category:"people"},slightly_frowning_face:{keywords:["face","frowning","disappointed","sad","upset"],char:'\u{1f641}',fitzpatrick_scale:!1,category:"people"},frowning_face:{keywords:["face","sad","upset","frown"],char:'\u2639',fitzpatrick_scale:!1,category:"people"},persevere:{keywords:["face","sick","no","upset","oops"],char:'\u{1f623}',fitzpatrick_scale:!1,category:"people"},confounded:{keywords:["face","confused","sick","unwell","oops",":S"],char:'\u{1f616}',fitzpatrick_scale:!1,category:"people"},tired_face:{keywords:["sick","whine","upset","frustrated"],char:'\u{1f62b}',fitzpatrick_scale:!1,category:"people"},weary:{keywords:["face","tired","sleepy","sad","frustrated","upset"],char:'\u{1f629}',fitzpatrick_scale:!1,category:"people"},pleading:{keywords:["face","begging","mercy"],char:'\u{1f97a}',fitzpatrick_scale:!1,category:"people"},triumph:{keywords:["face","gas","phew","proud","pride"],char:'\u{1f624}',fitzpatrick_scale:!1,category:"people"},open_mouth:{keywords:["face","surprise","impressed","wow","whoa",":O"],char:'\u{1f62e}',fitzpatrick_scale:!1,category:"people"},scream:{keywords:["face","munch","scared","omg"],char:'\u{1f631}',fitzpatrick_scale:!1,category:"people"},fearful:{keywords:["face","scared","terrified","nervous","oops","huh"],char:'\u{1f628}',fitzpatrick_scale:!1,category:"people"},cold_sweat:{keywords:["face","nervous","sweat"],char:'\u{1f630}',fitzpatrick_scale:!1,category:"people"},hushed:{keywords:["face","woo","shh"],char:'\u{1f62f}',fitzpatrick_scale:!1,category:"people"},frowning:{keywords:["face","aw","what"],char:'\u{1f626}',fitzpatrick_scale:!1,category:"people"},anguished:{keywords:["face","stunned","nervous"],char:'\u{1f627}',fitzpatrick_scale:!1,category:"people"},cry:{keywords:["face","tears","sad","depressed","upset",":'("],char:'\u{1f622}',fitzpatrick_scale:!1,category:"people"},disappointed_relieved:{keywords:["face","phew","sweat","nervous"],char:'\u{1f625}',fitzpatrick_scale:!1,category:"people"},drooling_face:{keywords:["face"],char:'\u{1f924}',fitzpatrick_scale:!1,category:"people"},sleepy:{keywords:["face","tired","rest","nap"],char:'\u{1f62a}',fitzpatrick_scale:!1,category:"people"},sweat:{keywords:["face","hot","sad","tired","exercise"],char:'\u{1f613}',fitzpatrick_scale:!1,category:"people"},hot:{keywords:["face","feverish","heat","red","sweating"],char:'\u{1f975}',fitzpatrick_scale:!1,category:"people"},cold:{keywords:["face","blue","freezing","frozen","frostbite","icicles"],char:'\u{1f976}',fitzpatrick_scale:!1,category:"people"},sob:{keywords:["face","cry","tears","sad","upset","depressed"],char:'\u{1f62d}',fitzpatrick_scale:!1,category:"people"},dizzy_face:{keywords:["spent","unconscious","xox","dizzy"],char:'\u{1f635}',fitzpatrick_scale:!1,category:"people"},astonished:{keywords:["face","xox","surprised","poisoned"],char:'\u{1f632}',fitzpatrick_scale:!1,category:"people"},zipper_mouth_face:{keywords:["face","sealed","zipper","secret"],char:'\u{1f910}',fitzpatrick_scale:!1,category:"people"},nauseated_face:{keywords:["face","vomit","gross","green","sick","throw up","ill"],char:'\u{1f922}',fitzpatrick_scale:!1,category:"people"},sneezing_face:{keywords:["face","gesundheit","sneeze","sick","allergy"],char:'\u{1f927}',fitzpatrick_scale:!1,category:"people"},vomiting:{keywords:["face","sick"],char:'\u{1f92e}',fitzpatrick_scale:!1,category:"people"},mask:{keywords:["face","sick","ill","disease"],char:'\u{1f637}',fitzpatrick_scale:!1,category:"people"},face_with_thermometer:{keywords:["sick","temperature","thermometer","cold","fever"],char:'\u{1f912}',fitzpatrick_scale:!1,category:"people"},face_with_head_bandage:{keywords:["injured","clumsy","bandage","hurt"],char:'\u{1f915}',fitzpatrick_scale:!1,category:"people"},woozy:{keywords:["face","dizzy","intoxicated","tipsy","wavy"],char:'\u{1f974}',fitzpatrick_scale:!1,category:"people"},sleeping:{keywords:["face","tired","sleepy","night","zzz"],char:'\u{1f634}',fitzpatrick_scale:!1,category:"people"},zzz:{keywords:["sleepy","tired","dream"],char:'\u{1f4a4}',fitzpatrick_scale:!1,category:"people"},poop:{keywords:["hankey","shitface","fail","turd","shit"],char:'\u{1f4a9}',fitzpatrick_scale:!1,category:"people"},smiling_imp:{keywords:["devil","horns"],char:'\u{1f608}',fitzpatrick_scale:!1,category:"people"},imp:{keywords:["devil","angry","horns"],char:'\u{1f47f}',fitzpatrick_scale:!1,category:"people"},japanese_ogre:{keywords:["monster","red","mask","halloween","scary","creepy","devil","demon","japanese","ogre"],char:'\u{1f479}',fitzpatrick_scale:!1,category:"people"},japanese_goblin:{keywords:["red","evil","mask","monster","scary","creepy","japanese","goblin"],char:'\u{1f47a}',fitzpatrick_scale:!1,category:"people"},skull:{keywords:["dead","skeleton","creepy","death"],char:'\u{1f480}',fitzpatrick_scale:!1,category:"people"},ghost:{keywords:["halloween","spooky","scary"],char:'\u{1f47b}',fitzpatrick_scale:!1,category:"people"},alien:{keywords:["UFO","paul","weird","outer_space"],char:'\u{1f47d}',fitzpatrick_scale:!1,category:"people"},robot:{keywords:["computer","machine","bot"],char:'\u{1f916}',fitzpatrick_scale:!1,category:"people"},smiley_cat:{keywords:["animal","cats","happy","smile"],char:'\u{1f63a}',fitzpatrick_scale:!1,category:"people"},smile_cat:{keywords:["animal","cats","smile"],char:'\u{1f638}',fitzpatrick_scale:!1,category:"people"},joy_cat:{keywords:["animal","cats","haha","happy","tears"],char:'\u{1f639}',fitzpatrick_scale:!1,category:"people"},heart_eyes_cat:{keywords:["animal","love","like","affection","cats","valentines","heart"],char:'\u{1f63b}',fitzpatrick_scale:!1,category:"people"},smirk_cat:{keywords:["animal","cats","smirk"],char:'\u{1f63c}',fitzpatrick_scale:!1,category:"people"},kissing_cat:{keywords:["animal","cats","kiss"],char:'\u{1f63d}',fitzpatrick_scale:!1,category:"people"},scream_cat:{keywords:["animal","cats","munch","scared","scream"],char:'\u{1f640}',fitzpatrick_scale:!1,category:"people"},crying_cat_face:{keywords:["animal","tears","weep","sad","cats","upset","cry"],char:'\u{1f63f}',fitzpatrick_scale:!1,category:"people"},pouting_cat:{keywords:["animal","cats"],char:'\u{1f63e}',fitzpatrick_scale:!1,category:"people"},palms_up:{keywords:["hands","gesture","cupped","prayer"],char:'\u{1f932}',fitzpatrick_scale:!0,category:"people"},raised_hands:{keywords:["gesture","hooray","yea","celebration","hands"],char:'\u{1f64c}',fitzpatrick_scale:!0,category:"people"},clap:{keywords:["hands","praise","applause","congrats","yay"],char:'\u{1f44f}',fitzpatrick_scale:!0,category:"people"},wave:{keywords:["hands","gesture","goodbye","solong","farewell","hello","hi","palm"],char:'\u{1f44b}',fitzpatrick_scale:!0,category:"people"},call_me_hand:{keywords:["hands","gesture"],char:'\u{1f919}',fitzpatrick_scale:!0,category:"people"},"+1":{keywords:["thumbsup","yes","awesome","good","agree","accept","cool","hand","like"],char:'\u{1f44d}',fitzpatrick_scale:!0,category:"people"},"-1":{keywords:["thumbsdown","no","dislike","hand"],char:'\u{1f44e}',fitzpatrick_scale:!0,category:"people"},facepunch:{keywords:["angry","violence","fist","hit","attack","hand"],char:'\u{1f44a}',fitzpatrick_scale:!0,category:"people"},fist:{keywords:["fingers","hand","grasp"],char:'\u270a',fitzpatrick_scale:!0,category:"people"},fist_left:{keywords:["hand","fistbump"],char:'\u{1f91b}',fitzpatrick_scale:!0,category:"people"},fist_right:{keywords:["hand","fistbump"],char:'\u{1f91c}',fitzpatrick_scale:!0,category:"people"},v:{keywords:["fingers","ohyeah","hand","peace","victory","two"],char:'\u270c',fitzpatrick_scale:!0,category:"people"},ok_hand:{keywords:["fingers","limbs","perfect","ok","okay"],char:'\u{1f44c}',fitzpatrick_scale:!0,category:"people"},raised_hand:{keywords:["fingers","stop","highfive","palm","ban"],char:'\u270b',fitzpatrick_scale:!0,category:"people"},raised_back_of_hand:{keywords:["fingers","raised","backhand"],char:'\u{1f91a}',fitzpatrick_scale:!0,category:"people"},open_hands:{keywords:["fingers","butterfly","hands","open"],char:'\u{1f450}',fitzpatrick_scale:!0,category:"people"},muscle:{keywords:["arm","flex","hand","summer","strong","biceps"],char:'\u{1f4aa}',fitzpatrick_scale:!0,category:"people"},pray:{keywords:["please","hope","wish","namaste","highfive"],char:'\u{1f64f}',fitzpatrick_scale:!0,category:"people"},foot:{keywords:["kick","stomp"],char:'\u{1f9b6}',fitzpatrick_scale:!0,category:"people"},leg:{keywords:["kick","limb"],char:'\u{1f9b5}',fitzpatrick_scale:!0,category:"people"},handshake:{keywords:["agreement","shake"],char:'\u{1f91d}',fitzpatrick_scale:!1,category:"people"},point_up:{keywords:["hand","fingers","direction","up"],char:'\u261d',fitzpatrick_scale:!0,category:"people"},point_up_2:{keywords:["fingers","hand","direction","up"],char:'\u{1f446}',fitzpatrick_scale:!0,category:"people"},point_down:{keywords:["fingers","hand","direction","down"],char:'\u{1f447}',fitzpatrick_scale:!0,category:"people"},point_left:{keywords:["direction","fingers","hand","left"],char:'\u{1f448}',fitzpatrick_scale:!0,category:"people"},point_right:{keywords:["fingers","hand","direction","right"],char:'\u{1f449}',fitzpatrick_scale:!0,category:"people"},fu:{keywords:["hand","fingers","rude","middle","flipping"],char:'\u{1f595}',fitzpatrick_scale:!0,category:"people"},raised_hand_with_fingers_splayed:{keywords:["hand","fingers","palm"],char:'\u{1f590}',fitzpatrick_scale:!0,category:"people"},love_you:{keywords:["hand","fingers","gesture"],char:'\u{1f91f}',fitzpatrick_scale:!0,category:"people"},metal:{keywords:["hand","fingers","evil_eye","sign_of_horns","rock_on"],char:'\u{1f918}',fitzpatrick_scale:!0,category:"people"},crossed_fingers:{keywords:["good","lucky"],char:'\u{1f91e}',fitzpatrick_scale:!0,category:"people"},vulcan_salute:{keywords:["hand","fingers","spock","star trek"],char:'\u{1f596}',fitzpatrick_scale:!0,category:"people"},writing_hand:{keywords:["lower_left_ballpoint_pen","stationery","write","compose"],char:'\u270d',fitzpatrick_scale:!0,category:"people"},selfie:{keywords:["camera","phone"],char:'\u{1f933}',fitzpatrick_scale:!0,category:"people"},nail_care:{keywords:["beauty","manicure","finger","fashion","nail"],char:'\u{1f485}',fitzpatrick_scale:!0,category:"people"},lips:{keywords:["mouth","kiss"],char:'\u{1f444}',fitzpatrick_scale:!1,category:"people"},tooth:{keywords:["teeth","dentist"],char:'\u{1f9b7}',fitzpatrick_scale:!1,category:"people"},tongue:{keywords:["mouth","playful"],char:'\u{1f445}',fitzpatrick_scale:!1,category:"people"},ear:{keywords:["face","hear","sound","listen"],char:'\u{1f442}',fitzpatrick_scale:!0,category:"people"},nose:{keywords:["smell","sniff"],char:'\u{1f443}',fitzpatrick_scale:!0,category:"people"},eye:{keywords:["face","look","see","watch","stare"],char:'\u{1f441}',fitzpatrick_scale:!1,category:"people"},eyes:{keywords:["look","watch","stalk","peek","see"],char:'\u{1f440}',fitzpatrick_scale:!1,category:"people"},brain:{keywords:["smart","intelligent"],char:'\u{1f9e0}',fitzpatrick_scale:!1,category:"people"},bust_in_silhouette:{keywords:["user","person","human"],char:'\u{1f464}',fitzpatrick_scale:!1,category:"people"},busts_in_silhouette:{keywords:["user","person","human","group","team"],char:'\u{1f465}',fitzpatrick_scale:!1,category:"people"},speaking_head:{keywords:["user","person","human","sing","say","talk"],char:'\u{1f5e3}',fitzpatrick_scale:!1,category:"people"},baby:{keywords:["child","boy","girl","toddler"],char:'\u{1f476}',fitzpatrick_scale:!0,category:"people"},child:{keywords:["gender-neutral","young"],char:'\u{1f9d2}',fitzpatrick_scale:!0,category:"people"},boy:{keywords:["man","male","guy","teenager"],char:'\u{1f466}',fitzpatrick_scale:!0,category:"people"},girl:{keywords:["female","woman","teenager"],char:'\u{1f467}',fitzpatrick_scale:!0,category:"people"},adult:{keywords:["gender-neutral","person"],char:'\u{1f9d1}',fitzpatrick_scale:!0,category:"people"},man:{keywords:["mustache","father","dad","guy","classy","sir","moustache"],char:'\u{1f468}',fitzpatrick_scale:!0,category:"people"},woman:{keywords:["female","girls","lady"],char:'\u{1f469}',fitzpatrick_scale:!0,category:"people"},blonde_woman:{keywords:["woman","female","girl","blonde","person"],char:'\u{1f471}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},blonde_man:{keywords:["man","male","boy","blonde","guy","person"],char:'\u{1f471}',fitzpatrick_scale:!0,category:"people"},bearded_person:{keywords:["person","bewhiskered"],char:'\u{1f9d4}',fitzpatrick_scale:!0,category:"people"},older_adult:{keywords:["human","elder","senior","gender-neutral"],char:'\u{1f9d3}',fitzpatrick_scale:!0,category:"people"},older_man:{keywords:["human","male","men","old","elder","senior"],char:'\u{1f474}',fitzpatrick_scale:!0,category:"people"},older_woman:{keywords:["human","female","women","lady","old","elder","senior"],char:'\u{1f475}',fitzpatrick_scale:!0,category:"people"},man_with_gua_pi_mao:{keywords:["male","boy","chinese"],char:'\u{1f472}',fitzpatrick_scale:!0,category:"people"},woman_with_headscarf:{keywords:["female","hijab","mantilla","tichel"],char:'\u{1f9d5}',fitzpatrick_scale:!0,category:"people"},woman_with_turban:{keywords:["female","indian","hinduism","arabs","woman"],char:'\u{1f473}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_with_turban:{keywords:["male","indian","hinduism","arabs"],char:'\u{1f473}',fitzpatrick_scale:!0,category:"people"},policewoman:{keywords:["woman","police","law","legal","enforcement","arrest","911","female"],char:'\u{1f46e}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},policeman:{keywords:["man","police","law","legal","enforcement","arrest","911"],char:'\u{1f46e}',fitzpatrick_scale:!0,category:"people"},construction_worker_woman:{keywords:["female","human","wip","build","construction","worker","labor","woman"],char:'\u{1f477}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},construction_worker_man:{keywords:["male","human","wip","guy","build","construction","worker","labor"],char:'\u{1f477}',fitzpatrick_scale:!0,category:"people"},guardswoman:{keywords:["uk","gb","british","female","royal","woman"],char:'\u{1f482}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},guardsman:{keywords:["uk","gb","british","male","guy","royal"],char:'\u{1f482}',fitzpatrick_scale:!0,category:"people"},female_detective:{keywords:["human","spy","detective","female","woman"],char:'\u{1f575}\ufe0f\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},male_detective:{keywords:["human","spy","detective"],char:'\u{1f575}',fitzpatrick_scale:!0,category:"people"},woman_health_worker:{keywords:["doctor","nurse","therapist","healthcare","woman","human"],char:'\u{1f469}\u200d\u2695\ufe0f',fitzpatrick_scale:!0,category:"people"},man_health_worker:{keywords:["doctor","nurse","therapist","healthcare","man","human"],char:'\u{1f468}\u200d\u2695\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_farmer:{keywords:["rancher","gardener","woman","human"],char:'\u{1f469}\u200d\u{1f33e}',fitzpatrick_scale:!0,category:"people"},man_farmer:{keywords:["rancher","gardener","man","human"],char:'\u{1f468}\u200d\u{1f33e}',fitzpatrick_scale:!0,category:"people"},woman_cook:{keywords:["chef","woman","human"],char:'\u{1f469}\u200d\u{1f373}',fitzpatrick_scale:!0,category:"people"},man_cook:{keywords:["chef","man","human"],char:'\u{1f468}\u200d\u{1f373}',fitzpatrick_scale:!0,category:"people"},woman_student:{keywords:["graduate","woman","human"],char:'\u{1f469}\u200d\u{1f393}',fitzpatrick_scale:!0,category:"people"},man_student:{keywords:["graduate","man","human"],char:'\u{1f468}\u200d\u{1f393}',fitzpatrick_scale:!0,category:"people"},woman_singer:{keywords:["rockstar","entertainer","woman","human"],char:'\u{1f469}\u200d\u{1f3a4}',fitzpatrick_scale:!0,category:"people"},man_singer:{keywords:["rockstar","entertainer","man","human"],char:'\u{1f468}\u200d\u{1f3a4}',fitzpatrick_scale:!0,category:"people"},woman_teacher:{keywords:["instructor","professor","woman","human"],char:'\u{1f469}\u200d\u{1f3eb}',fitzpatrick_scale:!0,category:"people"},man_teacher:{keywords:["instructor","professor","man","human"],char:'\u{1f468}\u200d\u{1f3eb}',fitzpatrick_scale:!0,category:"people"},woman_factory_worker:{keywords:["assembly","industrial","woman","human"],char:'\u{1f469}\u200d\u{1f3ed}',fitzpatrick_scale:!0,category:"people"},man_factory_worker:{keywords:["assembly","industrial","man","human"],char:'\u{1f468}\u200d\u{1f3ed}',fitzpatrick_scale:!0,category:"people"},woman_technologist:{keywords:["coder","developer","engineer","programmer","software","woman","human","laptop","computer"],char:'\u{1f469}\u200d\u{1f4bb}',fitzpatrick_scale:!0,category:"people"},man_technologist:{keywords:["coder","developer","engineer","programmer","software","man","human","laptop","computer"],char:'\u{1f468}\u200d\u{1f4bb}',fitzpatrick_scale:!0,category:"people"},woman_office_worker:{keywords:["business","manager","woman","human"],char:'\u{1f469}\u200d\u{1f4bc}',fitzpatrick_scale:!0,category:"people"},man_office_worker:{keywords:["business","manager","man","human"],char:'\u{1f468}\u200d\u{1f4bc}',fitzpatrick_scale:!0,category:"people"},woman_mechanic:{keywords:["plumber","woman","human","wrench"],char:'\u{1f469}\u200d\u{1f527}',fitzpatrick_scale:!0,category:"people"},man_mechanic:{keywords:["plumber","man","human","wrench"],char:'\u{1f468}\u200d\u{1f527}',fitzpatrick_scale:!0,category:"people"},woman_scientist:{keywords:["biologist","chemist","engineer","physicist","woman","human"],char:'\u{1f469}\u200d\u{1f52c}',fitzpatrick_scale:!0,category:"people"},man_scientist:{keywords:["biologist","chemist","engineer","physicist","man","human"],char:'\u{1f468}\u200d\u{1f52c}',fitzpatrick_scale:!0,category:"people"},woman_artist:{keywords:["painter","woman","human"],char:'\u{1f469}\u200d\u{1f3a8}',fitzpatrick_scale:!0,category:"people"},man_artist:{keywords:["painter","man","human"],char:'\u{1f468}\u200d\u{1f3a8}',fitzpatrick_scale:!0,category:"people"},woman_firefighter:{keywords:["fireman","woman","human"],char:'\u{1f469}\u200d\u{1f692}',fitzpatrick_scale:!0,category:"people"},man_firefighter:{keywords:["fireman","man","human"],char:'\u{1f468}\u200d\u{1f692}',fitzpatrick_scale:!0,category:"people"},woman_pilot:{keywords:["aviator","plane","woman","human"],char:'\u{1f469}\u200d\u2708\ufe0f',fitzpatrick_scale:!0,category:"people"},man_pilot:{keywords:["aviator","plane","man","human"],char:'\u{1f468}\u200d\u2708\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_astronaut:{keywords:["space","rocket","woman","human"],char:'\u{1f469}\u200d\u{1f680}',fitzpatrick_scale:!0,category:"people"},man_astronaut:{keywords:["space","rocket","man","human"],char:'\u{1f468}\u200d\u{1f680}',fitzpatrick_scale:!0,category:"people"},woman_judge:{keywords:["justice","court","woman","human"],char:'\u{1f469}\u200d\u2696\ufe0f',fitzpatrick_scale:!0,category:"people"},man_judge:{keywords:["justice","court","man","human"],char:'\u{1f468}\u200d\u2696\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_superhero:{keywords:["woman","female","good","heroine","superpowers"],char:'\u{1f9b8}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_superhero:{keywords:["man","male","good","hero","superpowers"],char:'\u{1f9b8}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_supervillain:{keywords:["woman","female","evil","bad","criminal","heroine","superpowers"],char:'\u{1f9b9}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_supervillain:{keywords:["man","male","evil","bad","criminal","hero","superpowers"],char:'\u{1f9b9}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},mrs_claus:{keywords:["woman","female","xmas","mother christmas"],char:'\u{1f936}',fitzpatrick_scale:!0,category:"people"},santa:{keywords:["festival","man","male","xmas","father christmas"],char:'\u{1f385}',fitzpatrick_scale:!0,category:"people"},sorceress:{keywords:["woman","female","mage","witch"],char:'\u{1f9d9}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},wizard:{keywords:["man","male","mage","sorcerer"],char:'\u{1f9d9}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_elf:{keywords:["woman","female"],char:'\u{1f9dd}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_elf:{keywords:["man","male"],char:'\u{1f9dd}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_vampire:{keywords:["woman","female"],char:'\u{1f9db}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_vampire:{keywords:["man","male","dracula"],char:'\u{1f9db}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_zombie:{keywords:["woman","female","undead","walking dead"],char:'\u{1f9df}\u200d\u2640\ufe0f',fitzpatrick_scale:!1,category:"people"},man_zombie:{keywords:["man","male","dracula","undead","walking dead"],char:'\u{1f9df}\u200d\u2642\ufe0f',fitzpatrick_scale:!1,category:"people"},woman_genie:{keywords:["woman","female"],char:'\u{1f9de}\u200d\u2640\ufe0f',fitzpatrick_scale:!1,category:"people"},man_genie:{keywords:["man","male"],char:'\u{1f9de}\u200d\u2642\ufe0f',fitzpatrick_scale:!1,category:"people"},mermaid:{keywords:["woman","female","merwoman","ariel"],char:'\u{1f9dc}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},merman:{keywords:["man","male","triton"],char:'\u{1f9dc}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_fairy:{keywords:["woman","female"],char:'\u{1f9da}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_fairy:{keywords:["man","male"],char:'\u{1f9da}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},angel:{keywords:["heaven","wings","halo"],char:'\u{1f47c}',fitzpatrick_scale:!0,category:"people"},pregnant_woman:{keywords:["baby"],char:'\u{1f930}',fitzpatrick_scale:!0,category:"people"},breastfeeding:{keywords:["nursing","baby"],char:'\u{1f931}',fitzpatrick_scale:!0,category:"people"},princess:{keywords:["girl","woman","female","blond","crown","royal","queen"],char:'\u{1f478}',fitzpatrick_scale:!0,category:"people"},prince:{keywords:["boy","man","male","crown","royal","king"],char:'\u{1f934}',fitzpatrick_scale:!0,category:"people"},bride_with_veil:{keywords:["couple","marriage","wedding","woman","bride"],char:'\u{1f470}',fitzpatrick_scale:!0,category:"people"},man_in_tuxedo:{keywords:["couple","marriage","wedding","groom"],char:'\u{1f935}',fitzpatrick_scale:!0,category:"people"},running_woman:{keywords:["woman","walking","exercise","race","running","female"],char:'\u{1f3c3}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},running_man:{keywords:["man","walking","exercise","race","running"],char:'\u{1f3c3}',fitzpatrick_scale:!0,category:"people"},walking_woman:{keywords:["human","feet","steps","woman","female"],char:'\u{1f6b6}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},walking_man:{keywords:["human","feet","steps"],char:'\u{1f6b6}',fitzpatrick_scale:!0,category:"people"},dancer:{keywords:["female","girl","woman","fun"],char:'\u{1f483}',fitzpatrick_scale:!0,category:"people"},man_dancing:{keywords:["male","boy","fun","dancer"],char:'\u{1f57a}',fitzpatrick_scale:!0,category:"people"},dancing_women:{keywords:["female","bunny","women","girls"],char:'\u{1f46f}',fitzpatrick_scale:!1,category:"people"},dancing_men:{keywords:["male","bunny","men","boys"],char:'\u{1f46f}\u200d\u2642\ufe0f',fitzpatrick_scale:!1,category:"people"},couple:{keywords:["pair","people","human","love","date","dating","like","affection","valentines","marriage"],char:'\u{1f46b}',fitzpatrick_scale:!1,category:"people"},two_men_holding_hands:{keywords:["pair","couple","love","like","bromance","friendship","people","human"],char:'\u{1f46c}',fitzpatrick_scale:!1,category:"people"},two_women_holding_hands:{keywords:["pair","friendship","couple","love","like","female","people","human"],char:'\u{1f46d}',fitzpatrick_scale:!1,category:"people"},bowing_woman:{keywords:["woman","female","girl"],char:'\u{1f647}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},bowing_man:{keywords:["man","male","boy"],char:'\u{1f647}',fitzpatrick_scale:!0,category:"people"},man_facepalming:{keywords:["man","male","boy","disbelief"],char:'\u{1f926}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_facepalming:{keywords:["woman","female","girl","disbelief"],char:'\u{1f926}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_shrugging:{keywords:["woman","female","girl","confused","indifferent","doubt"],char:'\u{1f937}',fitzpatrick_scale:!0,category:"people"},man_shrugging:{keywords:["man","male","boy","confused","indifferent","doubt"],char:'\u{1f937}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},tipping_hand_woman:{keywords:["female","girl","woman","human","information"],char:'\u{1f481}',fitzpatrick_scale:!0,category:"people"},tipping_hand_man:{keywords:["male","boy","man","human","information"],char:'\u{1f481}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},no_good_woman:{keywords:["female","girl","woman","nope"],char:'\u{1f645}',fitzpatrick_scale:!0,category:"people"},no_good_man:{keywords:["male","boy","man","nope"],char:'\u{1f645}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},ok_woman:{keywords:["women","girl","female","pink","human","woman"],char:'\u{1f646}',fitzpatrick_scale:!0,category:"people"},ok_man:{keywords:["men","boy","male","blue","human","man"],char:'\u{1f646}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},raising_hand_woman:{keywords:["female","girl","woman"],char:'\u{1f64b}',fitzpatrick_scale:!0,category:"people"},raising_hand_man:{keywords:["male","boy","man"],char:'\u{1f64b}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},pouting_woman:{keywords:["female","girl","woman"],char:'\u{1f64e}',fitzpatrick_scale:!0,category:"people"},pouting_man:{keywords:["male","boy","man"],char:'\u{1f64e}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},frowning_woman:{keywords:["female","girl","woman","sad","depressed","discouraged","unhappy"],char:'\u{1f64d}',fitzpatrick_scale:!0,category:"people"},frowning_man:{keywords:["male","boy","man","sad","depressed","discouraged","unhappy"],char:'\u{1f64d}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},haircut_woman:{keywords:["female","girl","woman"],char:'\u{1f487}',fitzpatrick_scale:!0,category:"people"},haircut_man:{keywords:["male","boy","man"],char:'\u{1f487}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},massage_woman:{keywords:["female","girl","woman","head"],char:'\u{1f486}',fitzpatrick_scale:!0,category:"people"},massage_man:{keywords:["male","boy","man","head"],char:'\u{1f486}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_in_steamy_room:{keywords:["female","woman","spa","steamroom","sauna"],char:'\u{1f9d6}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_in_steamy_room:{keywords:["male","man","spa","steamroom","sauna"],char:'\u{1f9d6}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},couple_with_heart_woman_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:'\u{1f491}',fitzpatrick_scale:!1,category:"people"},couple_with_heart_woman_woman:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:'\u{1f469}\u200d\u2764\ufe0f\u200d\u{1f469}',fitzpatrick_scale:!1,category:"people"},couple_with_heart_man_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:'\u{1f468}\u200d\u2764\ufe0f\u200d\u{1f468}',fitzpatrick_scale:!1,category:"people"},couplekiss_man_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:'\u{1f48f}',fitzpatrick_scale:!1,category:"people"},couplekiss_woman_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:'\u{1f469}\u200d\u2764\ufe0f\u200d\u{1f48b}\u200d\u{1f469}',fitzpatrick_scale:!1,category:"people"},couplekiss_man_man:{keywords:["pair","valentines","love","like","dating","marriage"],char:'\u{1f468}\u200d\u2764\ufe0f\u200d\u{1f48b}\u200d\u{1f468}',fitzpatrick_scale:!1,category:"people"},family_man_woman_boy:{keywords:["home","parents","child","mom","dad","father","mother","people","human"],char:'\u{1f46a}',fitzpatrick_scale:!1,category:"people"},family_man_woman_girl:{keywords:["home","parents","people","human","child"],char:'\u{1f468}\u200d\u{1f469}\u200d\u{1f467}',fitzpatrick_scale:!1,category:"people"},family_man_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:'\u{1f468}\u200d\u{1f469}\u200d\u{1f467}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_man_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:'\u{1f468}\u200d\u{1f469}\u200d\u{1f466}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_man_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:'\u{1f468}\u200d\u{1f469}\u200d\u{1f467}\u200d\u{1f467}',fitzpatrick_scale:!1,category:"people"},family_woman_woman_boy:{keywords:["home","parents","people","human","children"],char:'\u{1f469}\u200d\u{1f469}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl:{keywords:["home","parents","people","human","children"],char:'\u{1f469}\u200d\u{1f469}\u200d\u{1f467}',fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:'\u{1f469}\u200d\u{1f469}\u200d\u{1f467}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_woman_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:'\u{1f469}\u200d\u{1f469}\u200d\u{1f466}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:'\u{1f469}\u200d\u{1f469}\u200d\u{1f467}\u200d\u{1f467}',fitzpatrick_scale:!1,category:"people"},family_man_man_boy:{keywords:["home","parents","people","human","children"],char:'\u{1f468}\u200d\u{1f468}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_man_man_girl:{keywords:["home","parents","people","human","children"],char:'\u{1f468}\u200d\u{1f468}\u200d\u{1f467}',fitzpatrick_scale:!1,category:"people"},family_man_man_girl_boy:{keywords:["home","parents","people","human","children"],char:'\u{1f468}\u200d\u{1f468}\u200d\u{1f467}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_man_man_boy_boy:{keywords:["home","parents","people","human","children"],char:'\u{1f468}\u200d\u{1f468}\u200d\u{1f466}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_man_man_girl_girl:{keywords:["home","parents","people","human","children"],char:'\u{1f468}\u200d\u{1f468}\u200d\u{1f467}\u200d\u{1f467}',fitzpatrick_scale:!1,category:"people"},family_woman_boy:{keywords:["home","parent","people","human","child"],char:'\u{1f469}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_woman_girl:{keywords:["home","parent","people","human","child"],char:'\u{1f469}\u200d\u{1f467}',fitzpatrick_scale:!1,category:"people"},family_woman_girl_boy:{keywords:["home","parent","people","human","children"],char:'\u{1f469}\u200d\u{1f467}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_woman_boy_boy:{keywords:["home","parent","people","human","children"],char:'\u{1f469}\u200d\u{1f466}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_woman_girl_girl:{keywords:["home","parent","people","human","children"],char:'\u{1f469}\u200d\u{1f467}\u200d\u{1f467}',fitzpatrick_scale:!1,category:"people"},family_man_boy:{keywords:["home","parent","people","human","child"],char:'\u{1f468}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_man_girl:{keywords:["home","parent","people","human","child"],char:'\u{1f468}\u200d\u{1f467}',fitzpatrick_scale:!1,category:"people"},family_man_girl_boy:{keywords:["home","parent","people","human","children"],char:'\u{1f468}\u200d\u{1f467}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_man_boy_boy:{keywords:["home","parent","people","human","children"],char:'\u{1f468}\u200d\u{1f466}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_man_girl_girl:{keywords:["home","parent","people","human","children"],char:'\u{1f468}\u200d\u{1f467}\u200d\u{1f467}',fitzpatrick_scale:!1,category:"people"},yarn:{keywords:["ball","crochet","knit"],char:'\u{1f9f6}',fitzpatrick_scale:!1,category:"people"},thread:{keywords:["needle","sewing","spool","string"],char:'\u{1f9f5}',fitzpatrick_scale:!1,category:"people"},coat:{keywords:["jacket"],char:'\u{1f9e5}',fitzpatrick_scale:!1,category:"people"},labcoat:{keywords:["doctor","experiment","scientist","chemist"],char:'\u{1f97c}',fitzpatrick_scale:!1,category:"people"},womans_clothes:{keywords:["fashion","shopping_bags","female"],char:'\u{1f45a}',fitzpatrick_scale:!1,category:"people"},tshirt:{keywords:["fashion","cloth","casual","shirt","tee"],char:'\u{1f455}',fitzpatrick_scale:!1,category:"people"},jeans:{keywords:["fashion","shopping"],char:'\u{1f456}',fitzpatrick_scale:!1,category:"people"},necktie:{keywords:["shirt","suitup","formal","fashion","cloth","business"],char:'\u{1f454}',fitzpatrick_scale:!1,category:"people"},dress:{keywords:["clothes","fashion","shopping"],char:'\u{1f457}',fitzpatrick_scale:!1,category:"people"},bikini:{keywords:["swimming","female","woman","girl","fashion","beach","summer"],char:'\u{1f459}',fitzpatrick_scale:!1,category:"people"},kimono:{keywords:["dress","fashion","women","female","japanese"],char:'\u{1f458}',fitzpatrick_scale:!1,category:"people"},lipstick:{keywords:["female","girl","fashion","woman"],char:'\u{1f484}',fitzpatrick_scale:!1,category:"people"},kiss:{keywords:["face","lips","love","like","affection","valentines"],char:'\u{1f48b}',fitzpatrick_scale:!1,category:"people"},footprints:{keywords:["feet","tracking","walking","beach"],char:'\u{1f463}',fitzpatrick_scale:!1,category:"people"},flat_shoe:{keywords:["ballet","slip-on","slipper"],char:'\u{1f97f}',fitzpatrick_scale:!1,category:"people"},high_heel:{keywords:["fashion","shoes","female","pumps","stiletto"],char:'\u{1f460}',fitzpatrick_scale:!1,category:"people"},sandal:{keywords:["shoes","fashion","flip flops"],char:'\u{1f461}',fitzpatrick_scale:!1,category:"people"},boot:{keywords:["shoes","fashion"],char:'\u{1f462}',fitzpatrick_scale:!1,category:"people"},mans_shoe:{keywords:["fashion","male"],char:'\u{1f45e}',fitzpatrick_scale:!1,category:"people"},athletic_shoe:{keywords:["shoes","sports","sneakers"],char:'\u{1f45f}',fitzpatrick_scale:!1,category:"people"},hiking_boot:{keywords:["backpacking","camping","hiking"],char:'\u{1f97e}',fitzpatrick_scale:!1,category:"people"},socks:{keywords:["stockings","clothes"],char:'\u{1f9e6}',fitzpatrick_scale:!1,category:"people"},gloves:{keywords:["hands","winter","clothes"],char:'\u{1f9e4}',fitzpatrick_scale:!1,category:"people"},scarf:{keywords:["neck","winter","clothes"],char:'\u{1f9e3}',fitzpatrick_scale:!1,category:"people"},womans_hat:{keywords:["fashion","accessories","female","lady","spring"],char:'\u{1f452}',fitzpatrick_scale:!1,category:"people"},tophat:{keywords:["magic","gentleman","classy","circus"],char:'\u{1f3a9}',fitzpatrick_scale:!1,category:"people"},billed_hat:{keywords:["cap","baseball"],char:'\u{1f9e2}',fitzpatrick_scale:!1,category:"people"},rescue_worker_helmet:{keywords:["construction","build"],char:'\u26d1',fitzpatrick_scale:!1,category:"people"},mortar_board:{keywords:["school","college","degree","university","graduation","cap","hat","legal","learn","education"],char:'\u{1f393}',fitzpatrick_scale:!1,category:"people"},crown:{keywords:["king","kod","leader","royalty","lord"],char:'\u{1f451}',fitzpatrick_scale:!1,category:"people"},school_satchel:{keywords:["student","education","bag","backpack"],char:'\u{1f392}',fitzpatrick_scale:!1,category:"people"},luggage:{keywords:["packing","travel"],char:'\u{1f9f3}',fitzpatrick_scale:!1,category:"people"},pouch:{keywords:["bag","accessories","shopping"],char:'\u{1f45d}',fitzpatrick_scale:!1,category:"people"},purse:{keywords:["fashion","accessories","money","sales","shopping"],char:'\u{1f45b}',fitzpatrick_scale:!1,category:"people"},handbag:{keywords:["fashion","accessory","accessories","shopping"],char:'\u{1f45c}',fitzpatrick_scale:!1,category:"people"},briefcase:{keywords:["business","documents","work","law","legal","job","career"],char:'\u{1f4bc}',fitzpatrick_scale:!1,category:"people"},eyeglasses:{keywords:["fashion","accessories","eyesight","nerdy","dork","geek"],char:'\u{1f453}',fitzpatrick_scale:!1,category:"people"},dark_sunglasses:{keywords:["face","cool","accessories"],char:'\u{1f576}',fitzpatrick_scale:!1,category:"people"},goggles:{keywords:["eyes","protection","safety"],char:'\u{1f97d}',fitzpatrick_scale:!1,category:"people"},ring:{keywords:["wedding","propose","marriage","valentines","diamond","fashion","jewelry","gem","engagement"],char:'\u{1f48d}',fitzpatrick_scale:!1,category:"people"},closed_umbrella:{keywords:["weather","rain","drizzle"],char:'\u{1f302}',fitzpatrick_scale:!1,category:"people"},dog:{keywords:["animal","friend","nature","woof","puppy","pet","faithful"],char:'\u{1f436}',fitzpatrick_scale:!1,category:"animals_and_nature"},cat:{keywords:["animal","meow","nature","pet","kitten"],char:'\u{1f431}',fitzpatrick_scale:!1,category:"animals_and_nature"},mouse:{keywords:["animal","nature","cheese_wedge","rodent"],char:'\u{1f42d}',fitzpatrick_scale:!1,category:"animals_and_nature"},hamster:{keywords:["animal","nature"],char:'\u{1f439}',fitzpatrick_scale:!1,category:"animals_and_nature"},rabbit:{keywords:["animal","nature","pet","spring","magic","bunny"],char:'\u{1f430}',fitzpatrick_scale:!1,category:"animals_and_nature"},fox_face:{keywords:["animal","nature","face"],char:'\u{1f98a}',fitzpatrick_scale:!1,category:"animals_and_nature"},bear:{keywords:["animal","nature","wild"],char:'\u{1f43b}',fitzpatrick_scale:!1,category:"animals_and_nature"},panda_face:{keywords:["animal","nature","panda"],char:'\u{1f43c}',fitzpatrick_scale:!1,category:"animals_and_nature"},koala:{keywords:["animal","nature"],char:'\u{1f428}',fitzpatrick_scale:!1,category:"animals_and_nature"},tiger:{keywords:["animal","cat","danger","wild","nature","roar"],char:'\u{1f42f}',fitzpatrick_scale:!1,category:"animals_and_nature"},lion:{keywords:["animal","nature"],char:'\u{1f981}',fitzpatrick_scale:!1,category:"animals_and_nature"},cow:{keywords:["beef","ox","animal","nature","moo","milk"],char:'\u{1f42e}',fitzpatrick_scale:!1,category:"animals_and_nature"},pig:{keywords:["animal","oink","nature"],char:'\u{1f437}',fitzpatrick_scale:!1,category:"animals_and_nature"},pig_nose:{keywords:["animal","oink"],char:'\u{1f43d}',fitzpatrick_scale:!1,category:"animals_and_nature"},frog:{keywords:["animal","nature","croak","toad"],char:'\u{1f438}',fitzpatrick_scale:!1,category:"animals_and_nature"},squid:{keywords:["animal","nature","ocean","sea"],char:'\u{1f991}',fitzpatrick_scale:!1,category:"animals_and_nature"},octopus:{keywords:["animal","creature","ocean","sea","nature","beach"],char:'\u{1f419}',fitzpatrick_scale:!1,category:"animals_and_nature"},shrimp:{keywords:["animal","ocean","nature","seafood"],char:'\u{1f990}',fitzpatrick_scale:!1,category:"animals_and_nature"},monkey_face:{keywords:["animal","nature","circus"],char:'\u{1f435}',fitzpatrick_scale:!1,category:"animals_and_nature"},gorilla:{keywords:["animal","nature","circus"],char:'\u{1f98d}',fitzpatrick_scale:!1,category:"animals_and_nature"},see_no_evil:{keywords:["monkey","animal","nature","haha"],char:'\u{1f648}',fitzpatrick_scale:!1,category:"animals_and_nature"},hear_no_evil:{keywords:["animal","monkey","nature"],char:'\u{1f649}',fitzpatrick_scale:!1,category:"animals_and_nature"},speak_no_evil:{keywords:["monkey","animal","nature","omg"],char:'\u{1f64a}',fitzpatrick_scale:!1,category:"animals_and_nature"},monkey:{keywords:["animal","nature","banana","circus"],char:'\u{1f412}',fitzpatrick_scale:!1,category:"animals_and_nature"},chicken:{keywords:["animal","cluck","nature","bird"],char:'\u{1f414}',fitzpatrick_scale:!1,category:"animals_and_nature"},penguin:{keywords:["animal","nature"],char:'\u{1f427}',fitzpatrick_scale:!1,category:"animals_and_nature"},bird:{keywords:["animal","nature","fly","tweet","spring"],char:'\u{1f426}',fitzpatrick_scale:!1,category:"animals_and_nature"},baby_chick:{keywords:["animal","chicken","bird"],char:'\u{1f424}',fitzpatrick_scale:!1,category:"animals_and_nature"},hatching_chick:{keywords:["animal","chicken","egg","born","baby","bird"],char:'\u{1f423}',fitzpatrick_scale:!1,category:"animals_and_nature"},hatched_chick:{keywords:["animal","chicken","baby","bird"],char:'\u{1f425}',fitzpatrick_scale:!1,category:"animals_and_nature"},duck:{keywords:["animal","nature","bird","mallard"],char:'\u{1f986}',fitzpatrick_scale:!1,category:"animals_and_nature"},eagle:{keywords:["animal","nature","bird"],char:'\u{1f985}',fitzpatrick_scale:!1,category:"animals_and_nature"},owl:{keywords:["animal","nature","bird","hoot"],char:'\u{1f989}',fitzpatrick_scale:!1,category:"animals_and_nature"},bat:{keywords:["animal","nature","blind","vampire"],char:'\u{1f987}',fitzpatrick_scale:!1,category:"animals_and_nature"},wolf:{keywords:["animal","nature","wild"],char:'\u{1f43a}',fitzpatrick_scale:!1,category:"animals_and_nature"},boar:{keywords:["animal","nature"],char:'\u{1f417}',fitzpatrick_scale:!1,category:"animals_and_nature"},horse:{keywords:["animal","brown","nature"],char:'\u{1f434}',fitzpatrick_scale:!1,category:"animals_and_nature"},unicorn:{keywords:["animal","nature","mystical"],char:'\u{1f984}',fitzpatrick_scale:!1,category:"animals_and_nature"},honeybee:{keywords:["animal","insect","nature","bug","spring","honey"],char:'\u{1f41d}',fitzpatrick_scale:!1,category:"animals_and_nature"},bug:{keywords:["animal","insect","nature","worm"],char:'\u{1f41b}',fitzpatrick_scale:!1,category:"animals_and_nature"},butterfly:{keywords:["animal","insect","nature","caterpillar"],char:'\u{1f98b}',fitzpatrick_scale:!1,category:"animals_and_nature"},snail:{keywords:["slow","animal","shell"],char:'\u{1f40c}',fitzpatrick_scale:!1,category:"animals_and_nature"},beetle:{keywords:["animal","insect","nature","ladybug"],char:'\u{1f41e}',fitzpatrick_scale:!1,category:"animals_and_nature"},ant:{keywords:["animal","insect","nature","bug"],char:'\u{1f41c}',fitzpatrick_scale:!1,category:"animals_and_nature"},grasshopper:{keywords:["animal","cricket","chirp"],char:'\u{1f997}',fitzpatrick_scale:!1,category:"animals_and_nature"},spider:{keywords:["animal","arachnid"],char:'\u{1f577}',fitzpatrick_scale:!1,category:"animals_and_nature"},scorpion:{keywords:["animal","arachnid"],char:'\u{1f982}',fitzpatrick_scale:!1,category:"animals_and_nature"},crab:{keywords:["animal","crustacean"],char:'\u{1f980}',fitzpatrick_scale:!1,category:"animals_and_nature"},snake:{keywords:["animal","evil","nature","hiss","python"],char:'\u{1f40d}',fitzpatrick_scale:!1,category:"animals_and_nature"},lizard:{keywords:["animal","nature","reptile"],char:'\u{1f98e}',fitzpatrick_scale:!1,category:"animals_and_nature"},"t-rex":{keywords:["animal","nature","dinosaur","tyrannosaurus","extinct"],char:'\u{1f996}',fitzpatrick_scale:!1,category:"animals_and_nature"},sauropod:{keywords:["animal","nature","dinosaur","brachiosaurus","brontosaurus","diplodocus","extinct"],char:'\u{1f995}',fitzpatrick_scale:!1,category:"animals_and_nature"},turtle:{keywords:["animal","slow","nature","tortoise"],char:'\u{1f422}',fitzpatrick_scale:!1,category:"animals_and_nature"},tropical_fish:{keywords:["animal","swim","ocean","beach","nemo"],char:'\u{1f420}',fitzpatrick_scale:!1,category:"animals_and_nature"},fish:{keywords:["animal","food","nature"],char:'\u{1f41f}',fitzpatrick_scale:!1,category:"animals_and_nature"},blowfish:{keywords:["animal","nature","food","sea","ocean"],char:'\u{1f421}',fitzpatrick_scale:!1,category:"animals_and_nature"},dolphin:{keywords:["animal","nature","fish","sea","ocean","flipper","fins","beach"],char:'\u{1f42c}',fitzpatrick_scale:!1,category:"animals_and_nature"},shark:{keywords:["animal","nature","fish","sea","ocean","jaws","fins","beach"],char:'\u{1f988}',fitzpatrick_scale:!1,category:"animals_and_nature"},whale:{keywords:["animal","nature","sea","ocean"],char:'\u{1f433}',fitzpatrick_scale:!1,category:"animals_and_nature"},whale2:{keywords:["animal","nature","sea","ocean"],char:'\u{1f40b}',fitzpatrick_scale:!1,category:"animals_and_nature"},crocodile:{keywords:["animal","nature","reptile","lizard","alligator"],char:'\u{1f40a}',fitzpatrick_scale:!1,category:"animals_and_nature"},leopard:{keywords:["animal","nature"],char:'\u{1f406}',fitzpatrick_scale:!1,category:"animals_and_nature"},zebra:{keywords:["animal","nature","stripes","safari"],char:'\u{1f993}',fitzpatrick_scale:!1,category:"animals_and_nature"},tiger2:{keywords:["animal","nature","roar"],char:'\u{1f405}',fitzpatrick_scale:!1,category:"animals_and_nature"},water_buffalo:{keywords:["animal","nature","ox","cow"],char:'\u{1f403}',fitzpatrick_scale:!1,category:"animals_and_nature"},ox:{keywords:["animal","cow","beef"],char:'\u{1f402}',fitzpatrick_scale:!1,category:"animals_and_nature"},cow2:{keywords:["beef","ox","animal","nature","moo","milk"],char:'\u{1f404}',fitzpatrick_scale:!1,category:"animals_and_nature"},deer:{keywords:["animal","nature","horns","venison"],char:'\u{1f98c}',fitzpatrick_scale:!1,category:"animals_and_nature"},dromedary_camel:{keywords:["animal","hot","desert","hump"],char:'\u{1f42a}',fitzpatrick_scale:!1,category:"animals_and_nature"},camel:{keywords:["animal","nature","hot","desert","hump"],char:'\u{1f42b}',fitzpatrick_scale:!1,category:"animals_and_nature"},giraffe:{keywords:["animal","nature","spots","safari"],char:'\u{1f992}',fitzpatrick_scale:!1,category:"animals_and_nature"},elephant:{keywords:["animal","nature","nose","th","circus"],char:'\u{1f418}',fitzpatrick_scale:!1,category:"animals_and_nature"},rhinoceros:{keywords:["animal","nature","horn"],char:'\u{1f98f}',fitzpatrick_scale:!1,category:"animals_and_nature"},goat:{keywords:["animal","nature"],char:'\u{1f410}',fitzpatrick_scale:!1,category:"animals_and_nature"},ram:{keywords:["animal","sheep","nature"],char:'\u{1f40f}',fitzpatrick_scale:!1,category:"animals_and_nature"},sheep:{keywords:["animal","nature","wool","shipit"],char:'\u{1f411}',fitzpatrick_scale:!1,category:"animals_and_nature"},racehorse:{keywords:["animal","gamble","luck"],char:'\u{1f40e}',fitzpatrick_scale:!1,category:"animals_and_nature"},pig2:{keywords:["animal","nature"],char:'\u{1f416}',fitzpatrick_scale:!1,category:"animals_and_nature"},rat:{keywords:["animal","mouse","rodent"],char:'\u{1f400}',fitzpatrick_scale:!1,category:"animals_and_nature"},mouse2:{keywords:["animal","nature","rodent"],char:'\u{1f401}',fitzpatrick_scale:!1,category:"animals_and_nature"},rooster:{keywords:["animal","nature","chicken"],char:'\u{1f413}',fitzpatrick_scale:!1,category:"animals_and_nature"},turkey:{keywords:["animal","bird"],char:'\u{1f983}',fitzpatrick_scale:!1,category:"animals_and_nature"},dove:{keywords:["animal","bird"],char:'\u{1f54a}',fitzpatrick_scale:!1,category:"animals_and_nature"},dog2:{keywords:["animal","nature","friend","doge","pet","faithful"],char:'\u{1f415}',fitzpatrick_scale:!1,category:"animals_and_nature"},poodle:{keywords:["dog","animal","101","nature","pet"],char:'\u{1f429}',fitzpatrick_scale:!1,category:"animals_and_nature"},cat2:{keywords:["animal","meow","pet","cats"],char:'\u{1f408}',fitzpatrick_scale:!1,category:"animals_and_nature"},rabbit2:{keywords:["animal","nature","pet","magic","spring"],char:'\u{1f407}',fitzpatrick_scale:!1,category:"animals_and_nature"},chipmunk:{keywords:["animal","nature","rodent","squirrel"],char:'\u{1f43f}',fitzpatrick_scale:!1,category:"animals_and_nature"},hedgehog:{keywords:["animal","nature","spiny"],char:'\u{1f994}',fitzpatrick_scale:!1,category:"animals_and_nature"},raccoon:{keywords:["animal","nature"],char:'\u{1f99d}',fitzpatrick_scale:!1,category:"animals_and_nature"},llama:{keywords:["animal","nature","alpaca"],char:'\u{1f999}',fitzpatrick_scale:!1,category:"animals_and_nature"},hippopotamus:{keywords:["animal","nature"],char:'\u{1f99b}',fitzpatrick_scale:!1,category:"animals_and_nature"},kangaroo:{keywords:["animal","nature","australia","joey","hop","marsupial"],char:'\u{1f998}',fitzpatrick_scale:!1,category:"animals_and_nature"},badger:{keywords:["animal","nature","honey"],char:'\u{1f9a1}',fitzpatrick_scale:!1,category:"animals_and_nature"},swan:{keywords:["animal","nature","bird"],char:'\u{1f9a2}',fitzpatrick_scale:!1,category:"animals_and_nature"},peacock:{keywords:["animal","nature","peahen","bird"],char:'\u{1f99a}',fitzpatrick_scale:!1,category:"animals_and_nature"},parrot:{keywords:["animal","nature","bird","pirate","talk"],char:'\u{1f99c}',fitzpatrick_scale:!1,category:"animals_and_nature"},lobster:{keywords:["animal","nature","bisque","claws","seafood"],char:'\u{1f99e}',fitzpatrick_scale:!1,category:"animals_and_nature"},mosquito:{keywords:["animal","nature","insect","malaria"],char:'\u{1f99f}',fitzpatrick_scale:!1,category:"animals_and_nature"},paw_prints:{keywords:["animal","tracking","footprints","dog","cat","pet","feet"],char:'\u{1f43e}',fitzpatrick_scale:!1,category:"animals_and_nature"},dragon:{keywords:["animal","myth","nature","chinese","green"],char:'\u{1f409}',fitzpatrick_scale:!1,category:"animals_and_nature"},dragon_face:{keywords:["animal","myth","nature","chinese","green"],char:'\u{1f432}',fitzpatrick_scale:!1,category:"animals_and_nature"},cactus:{keywords:["vegetable","plant","nature"],char:'\u{1f335}',fitzpatrick_scale:!1,category:"animals_and_nature"},christmas_tree:{keywords:["festival","vacation","december","xmas","celebration"],char:'\u{1f384}',fitzpatrick_scale:!1,category:"animals_and_nature"},evergreen_tree:{keywords:["plant","nature"],char:'\u{1f332}',fitzpatrick_scale:!1,category:"animals_and_nature"},deciduous_tree:{keywords:["plant","nature"],char:'\u{1f333}',fitzpatrick_scale:!1,category:"animals_and_nature"},palm_tree:{keywords:["plant","vegetable","nature","summer","beach","mojito","tropical"],char:'\u{1f334}',fitzpatrick_scale:!1,category:"animals_and_nature"},seedling:{keywords:["plant","nature","grass","lawn","spring"],char:'\u{1f331}',fitzpatrick_scale:!1,category:"animals_and_nature"},herb:{keywords:["vegetable","plant","medicine","weed","grass","lawn"],char:'\u{1f33f}',fitzpatrick_scale:!1,category:"animals_and_nature"},shamrock:{keywords:["vegetable","plant","nature","irish","clover"],char:'\u2618',fitzpatrick_scale:!1,category:"animals_and_nature"},four_leaf_clover:{keywords:["vegetable","plant","nature","lucky","irish"],char:'\u{1f340}',fitzpatrick_scale:!1,category:"animals_and_nature"},bamboo:{keywords:["plant","nature","vegetable","panda","pine_decoration"],char:'\u{1f38d}',fitzpatrick_scale:!1,category:"animals_and_nature"},tanabata_tree:{keywords:["plant","nature","branch","summer"],char:'\u{1f38b}',fitzpatrick_scale:!1,category:"animals_and_nature"},leaves:{keywords:["nature","plant","tree","vegetable","grass","lawn","spring"],char:'\u{1f343}',fitzpatrick_scale:!1,category:"animals_and_nature"},fallen_leaf:{keywords:["nature","plant","vegetable","leaves"],char:'\u{1f342}',fitzpatrick_scale:!1,category:"animals_and_nature"},maple_leaf:{keywords:["nature","plant","vegetable","ca","fall"],char:'\u{1f341}',fitzpatrick_scale:!1,category:"animals_and_nature"},ear_of_rice:{keywords:["nature","plant"],char:'\u{1f33e}',fitzpatrick_scale:!1,category:"animals_and_nature"},hibiscus:{keywords:["plant","vegetable","flowers","beach"],char:'\u{1f33a}',fitzpatrick_scale:!1,category:"animals_and_nature"},sunflower:{keywords:["nature","plant","fall"],char:'\u{1f33b}',fitzpatrick_scale:!1,category:"animals_and_nature"},rose:{keywords:["flowers","valentines","love","spring"],char:'\u{1f339}',fitzpatrick_scale:!1,category:"animals_and_nature"},wilted_flower:{keywords:["plant","nature","flower"],char:'\u{1f940}',fitzpatrick_scale:!1,category:"animals_and_nature"},tulip:{keywords:["flowers","plant","nature","summer","spring"],char:'\u{1f337}',fitzpatrick_scale:!1,category:"animals_and_nature"},blossom:{keywords:["nature","flowers","yellow"],char:'\u{1f33c}',fitzpatrick_scale:!1,category:"animals_and_nature"},cherry_blossom:{keywords:["nature","plant","spring","flower"],char:'\u{1f338}',fitzpatrick_scale:!1,category:"animals_and_nature"},bouquet:{keywords:["flowers","nature","spring"],char:'\u{1f490}',fitzpatrick_scale:!1,category:"animals_and_nature"},mushroom:{keywords:["plant","vegetable"],char:'\u{1f344}',fitzpatrick_scale:!1,category:"animals_and_nature"},chestnut:{keywords:["food","squirrel"],char:'\u{1f330}',fitzpatrick_scale:!1,category:"animals_and_nature"},jack_o_lantern:{keywords:["halloween","light","pumpkin","creepy","fall"],char:'\u{1f383}',fitzpatrick_scale:!1,category:"animals_and_nature"},shell:{keywords:["nature","sea","beach"],char:'\u{1f41a}',fitzpatrick_scale:!1,category:"animals_and_nature"},spider_web:{keywords:["animal","insect","arachnid","silk"],char:'\u{1f578}',fitzpatrick_scale:!1,category:"animals_and_nature"},earth_americas:{keywords:["globe","world","USA","international"],char:'\u{1f30e}',fitzpatrick_scale:!1,category:"animals_and_nature"},earth_africa:{keywords:["globe","world","international"],char:'\u{1f30d}',fitzpatrick_scale:!1,category:"animals_and_nature"},earth_asia:{keywords:["globe","world","east","international"],char:'\u{1f30f}',fitzpatrick_scale:!1,category:"animals_and_nature"},full_moon:{keywords:["nature","yellow","twilight","planet","space","night","evening","sleep"],char:'\u{1f315}',fitzpatrick_scale:!1,category:"animals_and_nature"},waning_gibbous_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep","waxing_gibbous_moon"],char:'\u{1f316}',fitzpatrick_scale:!1,category:"animals_and_nature"},last_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\u{1f317}',fitzpatrick_scale:!1,category:"animals_and_nature"},waning_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\u{1f318}',fitzpatrick_scale:!1,category:"animals_and_nature"},new_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\u{1f311}',fitzpatrick_scale:!1,category:"animals_and_nature"},waxing_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\u{1f312}',fitzpatrick_scale:!1,category:"animals_and_nature"},first_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\u{1f313}',fitzpatrick_scale:!1,category:"animals_and_nature"},waxing_gibbous_moon:{keywords:["nature","night","sky","gray","twilight","planet","space","evening","sleep"],char:'\u{1f314}',fitzpatrick_scale:!1,category:"animals_and_nature"},new_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\u{1f31a}',fitzpatrick_scale:!1,category:"animals_and_nature"},full_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\u{1f31d}',fitzpatrick_scale:!1,category:"animals_and_nature"},first_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\u{1f31b}',fitzpatrick_scale:!1,category:"animals_and_nature"},last_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\u{1f31c}',fitzpatrick_scale:!1,category:"animals_and_nature"},sun_with_face:{keywords:["nature","morning","sky"],char:'\u{1f31e}',fitzpatrick_scale:!1,category:"animals_and_nature"},crescent_moon:{keywords:["night","sleep","sky","evening","magic"],char:'\u{1f319}',fitzpatrick_scale:!1,category:"animals_and_nature"},star:{keywords:["night","yellow"],char:'\u2b50',fitzpatrick_scale:!1,category:"animals_and_nature"},star2:{keywords:["night","sparkle","awesome","good","magic"],char:'\u{1f31f}',fitzpatrick_scale:!1,category:"animals_and_nature"},dizzy:{keywords:["star","sparkle","shoot","magic"],char:'\u{1f4ab}',fitzpatrick_scale:!1,category:"animals_and_nature"},sparkles:{keywords:["stars","shine","shiny","cool","awesome","good","magic"],char:'\u2728',fitzpatrick_scale:!1,category:"animals_and_nature"},comet:{keywords:["space"],char:'\u2604',fitzpatrick_scale:!1,category:"animals_and_nature"},sunny:{keywords:["weather","nature","brightness","summer","beach","spring"],char:'\u2600\ufe0f',fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_small_cloud:{keywords:["weather"],char:'\u{1f324}',fitzpatrick_scale:!1,category:"animals_and_nature"},partly_sunny:{keywords:["weather","nature","cloudy","morning","fall","spring"],char:'\u26c5',fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_large_cloud:{keywords:["weather"],char:'\u{1f325}',fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_rain_cloud:{keywords:["weather"],char:'\u{1f326}',fitzpatrick_scale:!1,category:"animals_and_nature"},cloud:{keywords:["weather","sky"],char:'\u2601\ufe0f',fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_rain:{keywords:["weather"],char:'\u{1f327}',fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_lightning_and_rain:{keywords:["weather","lightning"],char:'\u26c8',fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_lightning:{keywords:["weather","thunder"],char:'\u{1f329}',fitzpatrick_scale:!1,category:"animals_and_nature"},zap:{keywords:["thunder","weather","lightning bolt","fast"],char:'\u26a1',fitzpatrick_scale:!1,category:"animals_and_nature"},fire:{keywords:["hot","cook","flame"],char:'\u{1f525}',fitzpatrick_scale:!1,category:"animals_and_nature"},boom:{keywords:["bomb","explode","explosion","collision","blown"],char:'\u{1f4a5}',fitzpatrick_scale:!1,category:"animals_and_nature"},snowflake:{keywords:["winter","season","cold","weather","christmas","xmas"],char:'\u2744\ufe0f',fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_snow:{keywords:["weather"],char:'\u{1f328}',fitzpatrick_scale:!1,category:"animals_and_nature"},snowman:{keywords:["winter","season","cold","weather","christmas","xmas","frozen","without_snow"],char:'\u26c4',fitzpatrick_scale:!1,category:"animals_and_nature"},snowman_with_snow:{keywords:["winter","season","cold","weather","christmas","xmas","frozen"],char:'\u2603',fitzpatrick_scale:!1,category:"animals_and_nature"},wind_face:{keywords:["gust","air"],char:'\u{1f32c}',fitzpatrick_scale:!1,category:"animals_and_nature"},dash:{keywords:["wind","air","fast","shoo","fart","smoke","puff"],char:'\u{1f4a8}',fitzpatrick_scale:!1,category:"animals_and_nature"},tornado:{keywords:["weather","cyclone","twister"],char:'\u{1f32a}',fitzpatrick_scale:!1,category:"animals_and_nature"},fog:{keywords:["weather"],char:'\u{1f32b}',fitzpatrick_scale:!1,category:"animals_and_nature"},open_umbrella:{keywords:["weather","spring"],char:'\u2602',fitzpatrick_scale:!1,category:"animals_and_nature"},umbrella:{keywords:["rainy","weather","spring"],char:'\u2614',fitzpatrick_scale:!1,category:"animals_and_nature"},droplet:{keywords:["water","drip","faucet","spring"],char:'\u{1f4a7}',fitzpatrick_scale:!1,category:"animals_and_nature"},sweat_drops:{keywords:["water","drip","oops"],char:'\u{1f4a6}',fitzpatrick_scale:!1,category:"animals_and_nature"},ocean:{keywords:["sea","water","wave","nature","tsunami","disaster"],char:'\u{1f30a}',fitzpatrick_scale:!1,category:"animals_and_nature"},green_apple:{keywords:["fruit","nature"],char:'\u{1f34f}',fitzpatrick_scale:!1,category:"food_and_drink"},apple:{keywords:["fruit","mac","school"],char:'\u{1f34e}',fitzpatrick_scale:!1,category:"food_and_drink"},pear:{keywords:["fruit","nature","food"],char:'\u{1f350}',fitzpatrick_scale:!1,category:"food_and_drink"},tangerine:{keywords:["food","fruit","nature","orange"],char:'\u{1f34a}',fitzpatrick_scale:!1,category:"food_and_drink"},lemon:{keywords:["fruit","nature"],char:'\u{1f34b}',fitzpatrick_scale:!1,category:"food_and_drink"},banana:{keywords:["fruit","food","monkey"],char:'\u{1f34c}',fitzpatrick_scale:!1,category:"food_and_drink"},watermelon:{keywords:["fruit","food","picnic","summer"],char:'\u{1f349}',fitzpatrick_scale:!1,category:"food_and_drink"},grapes:{keywords:["fruit","food","wine"],char:'\u{1f347}',fitzpatrick_scale:!1,category:"food_and_drink"},strawberry:{keywords:["fruit","food","nature"],char:'\u{1f353}',fitzpatrick_scale:!1,category:"food_and_drink"},melon:{keywords:["fruit","nature","food"],char:'\u{1f348}',fitzpatrick_scale:!1,category:"food_and_drink"},cherries:{keywords:["food","fruit"],char:'\u{1f352}',fitzpatrick_scale:!1,category:"food_and_drink"},peach:{keywords:["fruit","nature","food"],char:'\u{1f351}',fitzpatrick_scale:!1,category:"food_and_drink"},pineapple:{keywords:["fruit","nature","food"],char:'\u{1f34d}',fitzpatrick_scale:!1,category:"food_and_drink"},coconut:{keywords:["fruit","nature","food","palm"],char:'\u{1f965}',fitzpatrick_scale:!1,category:"food_and_drink"},kiwi_fruit:{keywords:["fruit","food"],char:'\u{1f95d}',fitzpatrick_scale:!1,category:"food_and_drink"},mango:{keywords:["fruit","food","tropical"],char:'\u{1f96d}',fitzpatrick_scale:!1,category:"food_and_drink"},avocado:{keywords:["fruit","food"],char:'\u{1f951}',fitzpatrick_scale:!1,category:"food_and_drink"},broccoli:{keywords:["fruit","food","vegetable"],char:'\u{1f966}',fitzpatrick_scale:!1,category:"food_and_drink"},tomato:{keywords:["fruit","vegetable","nature","food"],char:'\u{1f345}',fitzpatrick_scale:!1,category:"food_and_drink"},eggplant:{keywords:["vegetable","nature","food","aubergine"],char:'\u{1f346}',fitzpatrick_scale:!1,category:"food_and_drink"},cucumber:{keywords:["fruit","food","pickle"],char:'\u{1f952}',fitzpatrick_scale:!1,category:"food_and_drink"},carrot:{keywords:["vegetable","food","orange"],char:'\u{1f955}',fitzpatrick_scale:!1,category:"food_and_drink"},hot_pepper:{keywords:["food","spicy","chilli","chili"],char:'\u{1f336}',fitzpatrick_scale:!1,category:"food_and_drink"},potato:{keywords:["food","tuber","vegatable","starch"],char:'\u{1f954}',fitzpatrick_scale:!1,category:"food_and_drink"},corn:{keywords:["food","vegetable","plant"],char:'\u{1f33d}',fitzpatrick_scale:!1,category:"food_and_drink"},leafy_greens:{keywords:["food","vegetable","plant","bok choy","cabbage","kale","lettuce"],char:'\u{1f96c}',fitzpatrick_scale:!1,category:"food_and_drink"},sweet_potato:{keywords:["food","nature"],char:'\u{1f360}',fitzpatrick_scale:!1,category:"food_and_drink"},peanuts:{keywords:["food","nut"],char:'\u{1f95c}',fitzpatrick_scale:!1,category:"food_and_drink"},honey_pot:{keywords:["bees","sweet","kitchen"],char:'\u{1f36f}',fitzpatrick_scale:!1,category:"food_and_drink"},croissant:{keywords:["food","bread","french"],char:'\u{1f950}',fitzpatrick_scale:!1,category:"food_and_drink"},bread:{keywords:["food","wheat","breakfast","toast"],char:'\u{1f35e}',fitzpatrick_scale:!1,category:"food_and_drink"},baguette_bread:{keywords:["food","bread","french"],char:'\u{1f956}',fitzpatrick_scale:!1,category:"food_and_drink"},bagel:{keywords:["food","bread","bakery","schmear"],char:'\u{1f96f}',fitzpatrick_scale:!1,category:"food_and_drink"},pretzel:{keywords:["food","bread","twisted"],char:'\u{1f968}',fitzpatrick_scale:!1,category:"food_and_drink"},cheese:{keywords:["food","chadder"],char:'\u{1f9c0}',fitzpatrick_scale:!1,category:"food_and_drink"},egg:{keywords:["food","chicken","breakfast"],char:'\u{1f95a}',fitzpatrick_scale:!1,category:"food_and_drink"},bacon:{keywords:["food","breakfast","pork","pig","meat"],char:'\u{1f953}',fitzpatrick_scale:!1,category:"food_and_drink"},steak:{keywords:["food","cow","meat","cut","chop","lambchop","porkchop"],char:'\u{1f969}',fitzpatrick_scale:!1,category:"food_and_drink"},pancakes:{keywords:["food","breakfast","flapjacks","hotcakes"],char:'\u{1f95e}',fitzpatrick_scale:!1,category:"food_and_drink"},poultry_leg:{keywords:["food","meat","drumstick","bird","chicken","turkey"],char:'\u{1f357}',fitzpatrick_scale:!1,category:"food_and_drink"},meat_on_bone:{keywords:["good","food","drumstick"],char:'\u{1f356}',fitzpatrick_scale:!1,category:"food_and_drink"},bone:{keywords:["skeleton"],char:'\u{1f9b4}',fitzpatrick_scale:!1,category:"food_and_drink"},fried_shrimp:{keywords:["food","animal","appetizer","summer"],char:'\u{1f364}',fitzpatrick_scale:!1,category:"food_and_drink"},fried_egg:{keywords:["food","breakfast","kitchen","egg"],char:'\u{1f373}',fitzpatrick_scale:!1,category:"food_and_drink"},hamburger:{keywords:["meat","fast food","beef","cheeseburger","mcdonalds","burger king"],char:'\u{1f354}',fitzpatrick_scale:!1,category:"food_and_drink"},fries:{keywords:["chips","snack","fast food"],char:'\u{1f35f}',fitzpatrick_scale:!1,category:"food_and_drink"},stuffed_flatbread:{keywords:["food","flatbread","stuffed","gyro"],char:'\u{1f959}',fitzpatrick_scale:!1,category:"food_and_drink"},hotdog:{keywords:["food","frankfurter"],char:'\u{1f32d}',fitzpatrick_scale:!1,category:"food_and_drink"},pizza:{keywords:["food","party"],char:'\u{1f355}',fitzpatrick_scale:!1,category:"food_and_drink"},sandwich:{keywords:["food","lunch","bread"],char:'\u{1f96a}',fitzpatrick_scale:!1,category:"food_and_drink"},canned_food:{keywords:["food","soup"],char:'\u{1f96b}',fitzpatrick_scale:!1,category:"food_and_drink"},spaghetti:{keywords:["food","italian","noodle"],char:'\u{1f35d}',fitzpatrick_scale:!1,category:"food_and_drink"},taco:{keywords:["food","mexican"],char:'\u{1f32e}',fitzpatrick_scale:!1,category:"food_and_drink"},burrito:{keywords:["food","mexican"],char:'\u{1f32f}',fitzpatrick_scale:!1,category:"food_and_drink"},green_salad:{keywords:["food","healthy","lettuce"],char:'\u{1f957}',fitzpatrick_scale:!1,category:"food_and_drink"},shallow_pan_of_food:{keywords:["food","cooking","casserole","paella"],char:'\u{1f958}',fitzpatrick_scale:!1,category:"food_and_drink"},ramen:{keywords:["food","japanese","noodle","chopsticks"],char:'\u{1f35c}',fitzpatrick_scale:!1,category:"food_and_drink"},stew:{keywords:["food","meat","soup"],char:'\u{1f372}',fitzpatrick_scale:!1,category:"food_and_drink"},fish_cake:{keywords:["food","japan","sea","beach","narutomaki","pink","swirl","kamaboko","surimi","ramen"],char:'\u{1f365}',fitzpatrick_scale:!1,category:"food_and_drink"},fortune_cookie:{keywords:["food","prophecy"],char:'\u{1f960}',fitzpatrick_scale:!1,category:"food_and_drink"},sushi:{keywords:["food","fish","japanese","rice"],char:'\u{1f363}',fitzpatrick_scale:!1,category:"food_and_drink"},bento:{keywords:["food","japanese","box"],char:'\u{1f371}',fitzpatrick_scale:!1,category:"food_and_drink"},curry:{keywords:["food","spicy","hot","indian"],char:'\u{1f35b}',fitzpatrick_scale:!1,category:"food_and_drink"},rice_ball:{keywords:["food","japanese"],char:'\u{1f359}',fitzpatrick_scale:!1,category:"food_and_drink"},rice:{keywords:["food","china","asian"],char:'\u{1f35a}',fitzpatrick_scale:!1,category:"food_and_drink"},rice_cracker:{keywords:["food","japanese"],char:'\u{1f358}',fitzpatrick_scale:!1,category:"food_and_drink"},oden:{keywords:["food","japanese"],char:'\u{1f362}',fitzpatrick_scale:!1,category:"food_and_drink"},dango:{keywords:["food","dessert","sweet","japanese","barbecue","meat"],char:'\u{1f361}',fitzpatrick_scale:!1,category:"food_and_drink"},shaved_ice:{keywords:["hot","dessert","summer"],char:'\u{1f367}',fitzpatrick_scale:!1,category:"food_and_drink"},ice_cream:{keywords:["food","hot","dessert"],char:'\u{1f368}',fitzpatrick_scale:!1,category:"food_and_drink"},icecream:{keywords:["food","hot","dessert","summer"],char:'\u{1f366}',fitzpatrick_scale:!1,category:"food_and_drink"},pie:{keywords:["food","dessert","pastry"],char:'\u{1f967}',fitzpatrick_scale:!1,category:"food_and_drink"},cake:{keywords:["food","dessert"],char:'\u{1f370}',fitzpatrick_scale:!1,category:"food_and_drink"},cupcake:{keywords:["food","dessert","bakery","sweet"],char:'\u{1f9c1}',fitzpatrick_scale:!1,category:"food_and_drink"},moon_cake:{keywords:["food","autumn"],char:'\u{1f96e}',fitzpatrick_scale:!1,category:"food_and_drink"},birthday:{keywords:["food","dessert","cake"],char:'\u{1f382}',fitzpatrick_scale:!1,category:"food_and_drink"},custard:{keywords:["dessert","food"],char:'\u{1f36e}',fitzpatrick_scale:!1,category:"food_and_drink"},candy:{keywords:["snack","dessert","sweet","lolly"],char:'\u{1f36c}',fitzpatrick_scale:!1,category:"food_and_drink"},lollipop:{keywords:["food","snack","candy","sweet"],char:'\u{1f36d}',fitzpatrick_scale:!1,category:"food_and_drink"},chocolate_bar:{keywords:["food","snack","dessert","sweet"],char:'\u{1f36b}',fitzpatrick_scale:!1,category:"food_and_drink"},popcorn:{keywords:["food","movie theater","films","snack"],char:'\u{1f37f}',fitzpatrick_scale:!1,category:"food_and_drink"},dumpling:{keywords:["food","empanada","pierogi","potsticker"],char:'\u{1f95f}',fitzpatrick_scale:!1,category:"food_and_drink"},doughnut:{keywords:["food","dessert","snack","sweet","donut"],char:'\u{1f369}',fitzpatrick_scale:!1,category:"food_and_drink"},cookie:{keywords:["food","snack","oreo","chocolate","sweet","dessert"],char:'\u{1f36a}',fitzpatrick_scale:!1,category:"food_and_drink"},milk_glass:{keywords:["beverage","drink","cow"],char:'\u{1f95b}',fitzpatrick_scale:!1,category:"food_and_drink"},beer:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:'\u{1f37a}',fitzpatrick_scale:!1,category:"food_and_drink"},beers:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:'\u{1f37b}',fitzpatrick_scale:!1,category:"food_and_drink"},clinking_glasses:{keywords:["beverage","drink","party","alcohol","celebrate","cheers","wine","champagne","toast"],char:'\u{1f942}',fitzpatrick_scale:!1,category:"food_and_drink"},wine_glass:{keywords:["drink","beverage","drunk","alcohol","booze"],char:'\u{1f377}',fitzpatrick_scale:!1,category:"food_and_drink"},tumbler_glass:{keywords:["drink","beverage","drunk","alcohol","liquor","booze","bourbon","scotch","whisky","glass","shot"],char:'\u{1f943}',fitzpatrick_scale:!1,category:"food_and_drink"},cocktail:{keywords:["drink","drunk","alcohol","beverage","booze","mojito"],char:'\u{1f378}',fitzpatrick_scale:!1,category:"food_and_drink"},tropical_drink:{keywords:["beverage","cocktail","summer","beach","alcohol","booze","mojito"],char:'\u{1f379}',fitzpatrick_scale:!1,category:"food_and_drink"},champagne:{keywords:["drink","wine","bottle","celebration"],char:'\u{1f37e}',fitzpatrick_scale:!1,category:"food_and_drink"},sake:{keywords:["wine","drink","drunk","beverage","japanese","alcohol","booze"],char:'\u{1f376}',fitzpatrick_scale:!1,category:"food_and_drink"},tea:{keywords:["drink","bowl","breakfast","green","british"],char:'\u{1f375}',fitzpatrick_scale:!1,category:"food_and_drink"},cup_with_straw:{keywords:["drink","soda"],char:'\u{1f964}',fitzpatrick_scale:!1,category:"food_and_drink"},coffee:{keywords:["beverage","caffeine","latte","espresso"],char:'\u2615',fitzpatrick_scale:!1,category:"food_and_drink"},baby_bottle:{keywords:["food","container","milk"],char:'\u{1f37c}',fitzpatrick_scale:!1,category:"food_and_drink"},salt:{keywords:["condiment","shaker"],char:'\u{1f9c2}',fitzpatrick_scale:!1,category:"food_and_drink"},spoon:{keywords:["cutlery","kitchen","tableware"],char:'\u{1f944}',fitzpatrick_scale:!1,category:"food_and_drink"},fork_and_knife:{keywords:["cutlery","kitchen"],char:'\u{1f374}',fitzpatrick_scale:!1,category:"food_and_drink"},plate_with_cutlery:{keywords:["food","eat","meal","lunch","dinner","restaurant"],char:'\u{1f37d}',fitzpatrick_scale:!1,category:"food_and_drink"},bowl_with_spoon:{keywords:["food","breakfast","cereal","oatmeal","porridge"],char:'\u{1f963}',fitzpatrick_scale:!1,category:"food_and_drink"},takeout_box:{keywords:["food","leftovers"],char:'\u{1f961}',fitzpatrick_scale:!1,category:"food_and_drink"},chopsticks:{keywords:["food"],char:'\u{1f962}',fitzpatrick_scale:!1,category:"food_and_drink"},soccer:{keywords:["sports","football"],char:'\u26bd',fitzpatrick_scale:!1,category:"activity"},basketball:{keywords:["sports","balls","NBA"],char:'\u{1f3c0}',fitzpatrick_scale:!1,category:"activity"},football:{keywords:["sports","balls","NFL"],char:'\u{1f3c8}',fitzpatrick_scale:!1,category:"activity"},baseball:{keywords:["sports","balls"],char:'\u26be',fitzpatrick_scale:!1,category:"activity"},softball:{keywords:["sports","balls"],char:'\u{1f94e}',fitzpatrick_scale:!1,category:"activity"},tennis:{keywords:["sports","balls","green"],char:'\u{1f3be}',fitzpatrick_scale:!1,category:"activity"},volleyball:{keywords:["sports","balls"],char:'\u{1f3d0}',fitzpatrick_scale:!1,category:"activity"},rugby_football:{keywords:["sports","team"],char:'\u{1f3c9}',fitzpatrick_scale:!1,category:"activity"},flying_disc:{keywords:["sports","frisbee","ultimate"],char:'\u{1f94f}',fitzpatrick_scale:!1,category:"activity"},"8ball":{keywords:["pool","hobby","game","luck","magic"],char:'\u{1f3b1}',fitzpatrick_scale:!1,category:"activity"},golf:{keywords:["sports","business","flag","hole","summer"],char:'\u26f3',fitzpatrick_scale:!1,category:"activity"},golfing_woman:{keywords:["sports","business","woman","female"],char:'\u{1f3cc}\ufe0f\u200d\u2640\ufe0f',fitzpatrick_scale:!1,category:"activity"},golfing_man:{keywords:["sports","business"],char:'\u{1f3cc}',fitzpatrick_scale:!0,category:"activity"},ping_pong:{keywords:["sports","pingpong"],char:'\u{1f3d3}',fitzpatrick_scale:!1,category:"activity"},badminton:{keywords:["sports"],char:'\u{1f3f8}',fitzpatrick_scale:!1,category:"activity"},goal_net:{keywords:["sports"],char:'\u{1f945}',fitzpatrick_scale:!1,category:"activity"},ice_hockey:{keywords:["sports"],char:'\u{1f3d2}',fitzpatrick_scale:!1,category:"activity"},field_hockey:{keywords:["sports"],char:'\u{1f3d1}',fitzpatrick_scale:!1,category:"activity"},lacrosse:{keywords:["sports","ball","stick"],char:'\u{1f94d}',fitzpatrick_scale:!1,category:"activity"},cricket:{keywords:["sports"],char:'\u{1f3cf}',fitzpatrick_scale:!1,category:"activity"},ski:{keywords:["sports","winter","cold","snow"],char:'\u{1f3bf}',fitzpatrick_scale:!1,category:"activity"},skier:{keywords:["sports","winter","snow"],char:'\u26f7',fitzpatrick_scale:!1,category:"activity"},snowboarder:{keywords:["sports","winter"],char:'\u{1f3c2}',fitzpatrick_scale:!0,category:"activity"},person_fencing:{keywords:["sports","fencing","sword"],char:'\u{1f93a}',fitzpatrick_scale:!1,category:"activity"},women_wrestling:{keywords:["sports","wrestlers"],char:'\u{1f93c}\u200d\u2640\ufe0f',fitzpatrick_scale:!1,category:"activity"},men_wrestling:{keywords:["sports","wrestlers"],char:'\u{1f93c}\u200d\u2642\ufe0f',fitzpatrick_scale:!1,category:"activity"},woman_cartwheeling:{keywords:["gymnastics"],char:'\u{1f938}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},man_cartwheeling:{keywords:["gymnastics"],char:'\u{1f938}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},woman_playing_handball:{keywords:["sports"],char:'\u{1f93e}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},man_playing_handball:{keywords:["sports"],char:'\u{1f93e}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},ice_skate:{keywords:["sports"],char:'\u26f8',fitzpatrick_scale:!1,category:"activity"},curling_stone:{keywords:["sports"],char:'\u{1f94c}',fitzpatrick_scale:!1,category:"activity"},skateboard:{keywords:["board"],char:'\u{1f6f9}',fitzpatrick_scale:!1,category:"activity"},sled:{keywords:["sleigh","luge","toboggan"],char:'\u{1f6f7}',fitzpatrick_scale:!1,category:"activity"},bow_and_arrow:{keywords:["sports"],char:'\u{1f3f9}',fitzpatrick_scale:!1,category:"activity"},fishing_pole_and_fish:{keywords:["food","hobby","summer"],char:'\u{1f3a3}',fitzpatrick_scale:!1,category:"activity"},boxing_glove:{keywords:["sports","fighting"],char:'\u{1f94a}',fitzpatrick_scale:!1,category:"activity"},martial_arts_uniform:{keywords:["judo","karate","taekwondo"],char:'\u{1f94b}',fitzpatrick_scale:!1,category:"activity"},rowing_woman:{keywords:["sports","hobby","water","ship","woman","female"],char:'\u{1f6a3}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},rowing_man:{keywords:["sports","hobby","water","ship"],char:'\u{1f6a3}',fitzpatrick_scale:!0,category:"activity"},climbing_woman:{keywords:["sports","hobby","woman","female","rock"],char:'\u{1f9d7}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},climbing_man:{keywords:["sports","hobby","man","male","rock"],char:'\u{1f9d7}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},swimming_woman:{keywords:["sports","exercise","human","athlete","water","summer","woman","female"],char:'\u{1f3ca}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},swimming_man:{keywords:["sports","exercise","human","athlete","water","summer"],char:'\u{1f3ca}',fitzpatrick_scale:!0,category:"activity"},woman_playing_water_polo:{keywords:["sports","pool"],char:'\u{1f93d}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},man_playing_water_polo:{keywords:["sports","pool"],char:'\u{1f93d}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},woman_in_lotus_position:{keywords:["woman","female","meditation","yoga","serenity","zen","mindfulness"],char:'\u{1f9d8}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},man_in_lotus_position:{keywords:["man","male","meditation","yoga","serenity","zen","mindfulness"],char:'\u{1f9d8}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},surfing_woman:{keywords:["sports","ocean","sea","summer","beach","woman","female"],char:'\u{1f3c4}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},surfing_man:{keywords:["sports","ocean","sea","summer","beach"],char:'\u{1f3c4}',fitzpatrick_scale:!0,category:"activity"},bath:{keywords:["clean","shower","bathroom"],char:'\u{1f6c0}',fitzpatrick_scale:!0,category:"activity"},basketball_woman:{keywords:["sports","human","woman","female"],char:'\u26f9\ufe0f\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},basketball_man:{keywords:["sports","human"],char:'\u26f9',fitzpatrick_scale:!0,category:"activity"},weight_lifting_woman:{keywords:["sports","training","exercise","woman","female"],char:'\u{1f3cb}\ufe0f\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},weight_lifting_man:{keywords:["sports","training","exercise"],char:'\u{1f3cb}',fitzpatrick_scale:!0,category:"activity"},biking_woman:{keywords:["sports","bike","exercise","hipster","woman","female"],char:'\u{1f6b4}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},biking_man:{keywords:["sports","bike","exercise","hipster"],char:'\u{1f6b4}',fitzpatrick_scale:!0,category:"activity"},mountain_biking_woman:{keywords:["transportation","sports","human","race","bike","woman","female"],char:'\u{1f6b5}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},mountain_biking_man:{keywords:["transportation","sports","human","race","bike"],char:'\u{1f6b5}',fitzpatrick_scale:!0,category:"activity"},horse_racing:{keywords:["animal","betting","competition","gambling","luck"],char:'\u{1f3c7}',fitzpatrick_scale:!0,category:"activity"},business_suit_levitating:{keywords:["suit","business","levitate","hover","jump"],char:'\u{1f574}',fitzpatrick_scale:!0,category:"activity"},trophy:{keywords:["win","award","contest","place","ftw","ceremony"],char:'\u{1f3c6}',fitzpatrick_scale:!1,category:"activity"},running_shirt_with_sash:{keywords:["play","pageant"],char:'\u{1f3bd}',fitzpatrick_scale:!1,category:"activity"},medal_sports:{keywords:["award","winning"],char:'\u{1f3c5}',fitzpatrick_scale:!1,category:"activity"},medal_military:{keywords:["award","winning","army"],char:'\u{1f396}',fitzpatrick_scale:!1,category:"activity"},"1st_place_medal":{keywords:["award","winning","first"],char:'\u{1f947}',fitzpatrick_scale:!1,category:"activity"},"2nd_place_medal":{keywords:["award","second"],char:'\u{1f948}',fitzpatrick_scale:!1,category:"activity"},"3rd_place_medal":{keywords:["award","third"],char:'\u{1f949}',fitzpatrick_scale:!1,category:"activity"},reminder_ribbon:{keywords:["sports","cause","support","awareness"],char:'\u{1f397}',fitzpatrick_scale:!1,category:"activity"},rosette:{keywords:["flower","decoration","military"],char:'\u{1f3f5}',fitzpatrick_scale:!1,category:"activity"},ticket:{keywords:["event","concert","pass"],char:'\u{1f3ab}',fitzpatrick_scale:!1,category:"activity"},tickets:{keywords:["sports","concert","entrance"],char:'\u{1f39f}',fitzpatrick_scale:!1,category:"activity"},performing_arts:{keywords:["acting","theater","drama"],char:'\u{1f3ad}',fitzpatrick_scale:!1,category:"activity"},art:{keywords:["design","paint","draw","colors"],char:'\u{1f3a8}',fitzpatrick_scale:!1,category:"activity"},circus_tent:{keywords:["festival","carnival","party"],char:'\u{1f3aa}',fitzpatrick_scale:!1,category:"activity"},woman_juggling:{keywords:["juggle","balance","skill","multitask"],char:'\u{1f939}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},man_juggling:{keywords:["juggle","balance","skill","multitask"],char:'\u{1f939}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},microphone:{keywords:["sound","music","PA","sing","talkshow"],char:'\u{1f3a4}',fitzpatrick_scale:!1,category:"activity"},headphones:{keywords:["music","score","gadgets"],char:'\u{1f3a7}',fitzpatrick_scale:!1,category:"activity"},musical_score:{keywords:["treble","clef","compose"],char:'\u{1f3bc}',fitzpatrick_scale:!1,category:"activity"},musical_keyboard:{keywords:["piano","instrument","compose"],char:'\u{1f3b9}',fitzpatrick_scale:!1,category:"activity"},drum:{keywords:["music","instrument","drumsticks","snare"],char:'\u{1f941}',fitzpatrick_scale:!1,category:"activity"},saxophone:{keywords:["music","instrument","jazz","blues"],char:'\u{1f3b7}',fitzpatrick_scale:!1,category:"activity"},trumpet:{keywords:["music","brass"],char:'\u{1f3ba}',fitzpatrick_scale:!1,category:"activity"},guitar:{keywords:["music","instrument"],char:'\u{1f3b8}',fitzpatrick_scale:!1,category:"activity"},violin:{keywords:["music","instrument","orchestra","symphony"],char:'\u{1f3bb}',fitzpatrick_scale:!1,category:"activity"},clapper:{keywords:["movie","film","record"],char:'\u{1f3ac}',fitzpatrick_scale:!1,category:"activity"},video_game:{keywords:["play","console","PS4","controller"],char:'\u{1f3ae}',fitzpatrick_scale:!1,category:"activity"},space_invader:{keywords:["game","arcade","play"],char:'\u{1f47e}',fitzpatrick_scale:!1,category:"activity"},dart:{keywords:["game","play","bar","target","bullseye"],char:'\u{1f3af}',fitzpatrick_scale:!1,category:"activity"},game_die:{keywords:["dice","random","tabletop","play","luck"],char:'\u{1f3b2}',fitzpatrick_scale:!1,category:"activity"},chess_pawn:{keywords:["expendable"],char:"\u265f",fitzpatrick_scale:!1,category:"activity"},slot_machine:{keywords:["bet","gamble","vegas","fruit machine","luck","casino"],char:'\u{1f3b0}',fitzpatrick_scale:!1,category:"activity"},jigsaw:{keywords:["interlocking","puzzle","piece"],char:'\u{1f9e9}',fitzpatrick_scale:!1,category:"activity"},bowling:{keywords:["sports","fun","play"],char:'\u{1f3b3}',fitzpatrick_scale:!1,category:"activity"},red_car:{keywords:["red","transportation","vehicle"],char:'\u{1f697}',fitzpatrick_scale:!1,category:"travel_and_places"},taxi:{keywords:["uber","vehicle","cars","transportation"],char:'\u{1f695}',fitzpatrick_scale:!1,category:"travel_and_places"},blue_car:{keywords:["transportation","vehicle"],char:'\u{1f699}',fitzpatrick_scale:!1,category:"travel_and_places"},bus:{keywords:["car","vehicle","transportation"],char:'\u{1f68c}',fitzpatrick_scale:!1,category:"travel_and_places"},trolleybus:{keywords:["bart","transportation","vehicle"],char:'\u{1f68e}',fitzpatrick_scale:!1,category:"travel_and_places"},racing_car:{keywords:["sports","race","fast","formula","f1"],char:'\u{1f3ce}',fitzpatrick_scale:!1,category:"travel_and_places"},police_car:{keywords:["vehicle","cars","transportation","law","legal","enforcement"],char:'\u{1f693}',fitzpatrick_scale:!1,category:"travel_and_places"},ambulance:{keywords:["health","911","hospital"],char:'\u{1f691}',fitzpatrick_scale:!1,category:"travel_and_places"},fire_engine:{keywords:["transportation","cars","vehicle"],char:'\u{1f692}',fitzpatrick_scale:!1,category:"travel_and_places"},minibus:{keywords:["vehicle","car","transportation"],char:'\u{1f690}',fitzpatrick_scale:!1,category:"travel_and_places"},truck:{keywords:["cars","transportation"],char:'\u{1f69a}',fitzpatrick_scale:!1,category:"travel_and_places"},articulated_lorry:{keywords:["vehicle","cars","transportation","express"],char:'\u{1f69b}',fitzpatrick_scale:!1,category:"travel_and_places"},tractor:{keywords:["vehicle","car","farming","agriculture"],char:'\u{1f69c}',fitzpatrick_scale:!1,category:"travel_and_places"},kick_scooter:{keywords:["vehicle","kick","razor"],char:'\u{1f6f4}',fitzpatrick_scale:!1,category:"travel_and_places"},motorcycle:{keywords:["race","sports","fast"],char:'\u{1f3cd}',fitzpatrick_scale:!1,category:"travel_and_places"},bike:{keywords:["sports","bicycle","exercise","hipster"],char:'\u{1f6b2}',fitzpatrick_scale:!1,category:"travel_and_places"},motor_scooter:{keywords:["vehicle","vespa","sasha"],char:'\u{1f6f5}',fitzpatrick_scale:!1,category:"travel_and_places"},rotating_light:{keywords:["police","ambulance","911","emergency","alert","error","pinged","law","legal"],char:'\u{1f6a8}',fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_police_car:{keywords:["vehicle","law","legal","enforcement","911"],char:'\u{1f694}',fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_bus:{keywords:["vehicle","transportation"],char:'\u{1f68d}',fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_automobile:{keywords:["car","vehicle","transportation"],char:'\u{1f698}',fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_taxi:{keywords:["vehicle","cars","uber"],char:'\u{1f696}',fitzpatrick_scale:!1,category:"travel_and_places"},aerial_tramway:{keywords:["transportation","vehicle","ski"],char:'\u{1f6a1}',fitzpatrick_scale:!1,category:"travel_and_places"},mountain_cableway:{keywords:["transportation","vehicle","ski"],char:'\u{1f6a0}',fitzpatrick_scale:!1,category:"travel_and_places"},suspension_railway:{keywords:["vehicle","transportation"],char:'\u{1f69f}',fitzpatrick_scale:!1,category:"travel_and_places"},railway_car:{keywords:["transportation","vehicle"],char:'\u{1f683}',fitzpatrick_scale:!1,category:"travel_and_places"},train:{keywords:["transportation","vehicle","carriage","public","travel"],char:'\u{1f68b}',fitzpatrick_scale:!1,category:"travel_and_places"},monorail:{keywords:["transportation","vehicle"],char:'\u{1f69d}',fitzpatrick_scale:!1,category:"travel_and_places"},bullettrain_side:{keywords:["transportation","vehicle"],char:'\u{1f684}',fitzpatrick_scale:!1,category:"travel_and_places"},bullettrain_front:{keywords:["transportation","vehicle","speed","fast","public","travel"],char:'\u{1f685}',fitzpatrick_scale:!1,category:"travel_and_places"},light_rail:{keywords:["transportation","vehicle"],char:'\u{1f688}',fitzpatrick_scale:!1,category:"travel_and_places"},mountain_railway:{keywords:["transportation","vehicle"],char:'\u{1f69e}',fitzpatrick_scale:!1,category:"travel_and_places"},steam_locomotive:{keywords:["transportation","vehicle","train"],char:'\u{1f682}',fitzpatrick_scale:!1,category:"travel_and_places"},train2:{keywords:["transportation","vehicle"],char:'\u{1f686}',fitzpatrick_scale:!1,category:"travel_and_places"},metro:{keywords:["transportation","blue-square","mrt","underground","tube"],char:'\u{1f687}',fitzpatrick_scale:!1,category:"travel_and_places"},tram:{keywords:["transportation","vehicle"],char:'\u{1f68a}',fitzpatrick_scale:!1,category:"travel_and_places"},station:{keywords:["transportation","vehicle","public"],char:'\u{1f689}',fitzpatrick_scale:!1,category:"travel_and_places"},flying_saucer:{keywords:["transportation","vehicle","ufo"],char:'\u{1f6f8}',fitzpatrick_scale:!1,category:"travel_and_places"},helicopter:{keywords:["transportation","vehicle","fly"],char:'\u{1f681}',fitzpatrick_scale:!1,category:"travel_and_places"},small_airplane:{keywords:["flight","transportation","fly","vehicle"],char:'\u{1f6e9}',fitzpatrick_scale:!1,category:"travel_and_places"},airplane:{keywords:["vehicle","transportation","flight","fly"],char:'\u2708\ufe0f',fitzpatrick_scale:!1,category:"travel_and_places"},flight_departure:{keywords:["airport","flight","landing"],char:'\u{1f6eb}',fitzpatrick_scale:!1,category:"travel_and_places"},flight_arrival:{keywords:["airport","flight","boarding"],char:'\u{1f6ec}',fitzpatrick_scale:!1,category:"travel_and_places"},sailboat:{keywords:["ship","summer","transportation","water","sailing"],char:'\u26f5',fitzpatrick_scale:!1,category:"travel_and_places"},motor_boat:{keywords:["ship"],char:'\u{1f6e5}',fitzpatrick_scale:!1,category:"travel_and_places"},speedboat:{keywords:["ship","transportation","vehicle","summer"],char:'\u{1f6a4}',fitzpatrick_scale:!1,category:"travel_and_places"},ferry:{keywords:["boat","ship","yacht"],char:'\u26f4',fitzpatrick_scale:!1,category:"travel_and_places"},passenger_ship:{keywords:["yacht","cruise","ferry"],char:'\u{1f6f3}',fitzpatrick_scale:!1,category:"travel_and_places"},rocket:{keywords:["launch","ship","staffmode","NASA","outer space","outer_space","fly"],char:'\u{1f680}',fitzpatrick_scale:!1,category:"travel_and_places"},artificial_satellite:{keywords:["communication","gps","orbit","spaceflight","NASA","ISS"],char:'\u{1f6f0}',fitzpatrick_scale:!1,category:"travel_and_places"},seat:{keywords:["sit","airplane","transport","bus","flight","fly"],char:'\u{1f4ba}',fitzpatrick_scale:!1,category:"travel_and_places"},canoe:{keywords:["boat","paddle","water","ship"],char:'\u{1f6f6}',fitzpatrick_scale:!1,category:"travel_and_places"},anchor:{keywords:["ship","ferry","sea","boat"],char:'\u2693',fitzpatrick_scale:!1,category:"travel_and_places"},construction:{keywords:["wip","progress","caution","warning"],char:'\u{1f6a7}',fitzpatrick_scale:!1,category:"travel_and_places"},fuelpump:{keywords:["gas station","petroleum"],char:'\u26fd',fitzpatrick_scale:!1,category:"travel_and_places"},busstop:{keywords:["transportation","wait"],char:'\u{1f68f}',fitzpatrick_scale:!1,category:"travel_and_places"},vertical_traffic_light:{keywords:["transportation","driving"],char:'\u{1f6a6}',fitzpatrick_scale:!1,category:"travel_and_places"},traffic_light:{keywords:["transportation","signal"],char:'\u{1f6a5}',fitzpatrick_scale:!1,category:"travel_and_places"},checkered_flag:{keywords:["contest","finishline","race","gokart"],char:'\u{1f3c1}',fitzpatrick_scale:!1,category:"travel_and_places"},ship:{keywords:["transportation","titanic","deploy"],char:'\u{1f6a2}',fitzpatrick_scale:!1,category:"travel_and_places"},ferris_wheel:{keywords:["photo","carnival","londoneye"],char:'\u{1f3a1}',fitzpatrick_scale:!1,category:"travel_and_places"},roller_coaster:{keywords:["carnival","playground","photo","fun"],char:'\u{1f3a2}',fitzpatrick_scale:!1,category:"travel_and_places"},carousel_horse:{keywords:["photo","carnival"],char:'\u{1f3a0}',fitzpatrick_scale:!1,category:"travel_and_places"},building_construction:{keywords:["wip","working","progress"],char:'\u{1f3d7}',fitzpatrick_scale:!1,category:"travel_and_places"},foggy:{keywords:["photo","mountain"],char:'\u{1f301}',fitzpatrick_scale:!1,category:"travel_and_places"},tokyo_tower:{keywords:["photo","japanese"],char:'\u{1f5fc}',fitzpatrick_scale:!1,category:"travel_and_places"},factory:{keywords:["building","industry","pollution","smoke"],char:'\u{1f3ed}',fitzpatrick_scale:!1,category:"travel_and_places"},fountain:{keywords:["photo","summer","water","fresh"],char:'\u26f2',fitzpatrick_scale:!1,category:"travel_and_places"},rice_scene:{keywords:["photo","japan","asia","tsukimi"],char:'\u{1f391}',fitzpatrick_scale:!1,category:"travel_and_places"},mountain:{keywords:["photo","nature","environment"],char:'\u26f0',fitzpatrick_scale:!1,category:"travel_and_places"},mountain_snow:{keywords:["photo","nature","environment","winter","cold"],char:'\u{1f3d4}',fitzpatrick_scale:!1,category:"travel_and_places"},mount_fuji:{keywords:["photo","mountain","nature","japanese"],char:'\u{1f5fb}',fitzpatrick_scale:!1,category:"travel_and_places"},volcano:{keywords:["photo","nature","disaster"],char:'\u{1f30b}',fitzpatrick_scale:!1,category:"travel_and_places"},japan:{keywords:["nation","country","japanese","asia"],char:'\u{1f5fe}',fitzpatrick_scale:!1,category:"travel_and_places"},camping:{keywords:["photo","outdoors","tent"],char:'\u{1f3d5}',fitzpatrick_scale:!1,category:"travel_and_places"},tent:{keywords:["photo","camping","outdoors"],char:'\u26fa',fitzpatrick_scale:!1,category:"travel_and_places"},national_park:{keywords:["photo","environment","nature"],char:'\u{1f3de}',fitzpatrick_scale:!1,category:"travel_and_places"},motorway:{keywords:["road","cupertino","interstate","highway"],char:'\u{1f6e3}',fitzpatrick_scale:!1,category:"travel_and_places"},railway_track:{keywords:["train","transportation"],char:'\u{1f6e4}',fitzpatrick_scale:!1,category:"travel_and_places"},sunrise:{keywords:["morning","view","vacation","photo"],char:'\u{1f305}',fitzpatrick_scale:!1,category:"travel_and_places"},sunrise_over_mountains:{keywords:["view","vacation","photo"],char:'\u{1f304}',fitzpatrick_scale:!1,category:"travel_and_places"},desert:{keywords:["photo","warm","saharah"],char:'\u{1f3dc}',fitzpatrick_scale:!1,category:"travel_and_places"},beach_umbrella:{keywords:["weather","summer","sunny","sand","mojito"],char:'\u{1f3d6}',fitzpatrick_scale:!1,category:"travel_and_places"},desert_island:{keywords:["photo","tropical","mojito"],char:'\u{1f3dd}',fitzpatrick_scale:!1,category:"travel_and_places"},city_sunrise:{keywords:["photo","good morning","dawn"],char:'\u{1f307}',fitzpatrick_scale:!1,category:"travel_and_places"},city_sunset:{keywords:["photo","evening","sky","buildings"],char:'\u{1f306}',fitzpatrick_scale:!1,category:"travel_and_places"},cityscape:{keywords:["photo","night life","urban"],char:'\u{1f3d9}',fitzpatrick_scale:!1,category:"travel_and_places"},night_with_stars:{keywords:["evening","city","downtown"],char:'\u{1f303}',fitzpatrick_scale:!1,category:"travel_and_places"},bridge_at_night:{keywords:["photo","sanfrancisco"],char:'\u{1f309}',fitzpatrick_scale:!1,category:"travel_and_places"},milky_way:{keywords:["photo","space","stars"],char:'\u{1f30c}',fitzpatrick_scale:!1,category:"travel_and_places"},stars:{keywords:["night","photo"],char:'\u{1f320}',fitzpatrick_scale:!1,category:"travel_and_places"},sparkler:{keywords:["stars","night","shine"],char:'\u{1f387}',fitzpatrick_scale:!1,category:"travel_and_places"},fireworks:{keywords:["photo","festival","carnival","congratulations"],char:'\u{1f386}',fitzpatrick_scale:!1,category:"travel_and_places"},rainbow:{keywords:["nature","happy","unicorn_face","photo","sky","spring"],char:'\u{1f308}',fitzpatrick_scale:!1,category:"travel_and_places"},houses:{keywords:["buildings","photo"],char:'\u{1f3d8}',fitzpatrick_scale:!1,category:"travel_and_places"},european_castle:{keywords:["building","royalty","history"],char:'\u{1f3f0}',fitzpatrick_scale:!1,category:"travel_and_places"},japanese_castle:{keywords:["photo","building"],char:'\u{1f3ef}',fitzpatrick_scale:!1,category:"travel_and_places"},stadium:{keywords:["photo","place","sports","concert","venue"],char:'\u{1f3df}',fitzpatrick_scale:!1,category:"travel_and_places"},statue_of_liberty:{keywords:["american","newyork"],char:'\u{1f5fd}',fitzpatrick_scale:!1,category:"travel_and_places"},house:{keywords:["building","home"],char:'\u{1f3e0}',fitzpatrick_scale:!1,category:"travel_and_places"},house_with_garden:{keywords:["home","plant","nature"],char:'\u{1f3e1}',fitzpatrick_scale:!1,category:"travel_and_places"},derelict_house:{keywords:["abandon","evict","broken","building"],char:'\u{1f3da}',fitzpatrick_scale:!1,category:"travel_and_places"},office:{keywords:["building","bureau","work"],char:'\u{1f3e2}',fitzpatrick_scale:!1,category:"travel_and_places"},department_store:{keywords:["building","shopping","mall"],char:'\u{1f3ec}',fitzpatrick_scale:!1,category:"travel_and_places"},post_office:{keywords:["building","envelope","communication"],char:'\u{1f3e3}',fitzpatrick_scale:!1,category:"travel_and_places"},european_post_office:{keywords:["building","email"],char:'\u{1f3e4}',fitzpatrick_scale:!1,category:"travel_and_places"},hospital:{keywords:["building","health","surgery","doctor"],char:'\u{1f3e5}',fitzpatrick_scale:!1,category:"travel_and_places"},bank:{keywords:["building","money","sales","cash","business","enterprise"],char:'\u{1f3e6}',fitzpatrick_scale:!1,category:"travel_and_places"},hotel:{keywords:["building","accomodation","checkin"],char:'\u{1f3e8}',fitzpatrick_scale:!1,category:"travel_and_places"},convenience_store:{keywords:["building","shopping","groceries"],char:'\u{1f3ea}',fitzpatrick_scale:!1,category:"travel_and_places"},school:{keywords:["building","student","education","learn","teach"],char:'\u{1f3eb}',fitzpatrick_scale:!1,category:"travel_and_places"},love_hotel:{keywords:["like","affection","dating"],char:'\u{1f3e9}',fitzpatrick_scale:!1,category:"travel_and_places"},wedding:{keywords:["love","like","affection","couple","marriage","bride","groom"],char:'\u{1f492}',fitzpatrick_scale:!1,category:"travel_and_places"},classical_building:{keywords:["art","culture","history"],char:'\u{1f3db}',fitzpatrick_scale:!1,category:"travel_and_places"},church:{keywords:["building","religion","christ"],char:'\u26ea',fitzpatrick_scale:!1,category:"travel_and_places"},mosque:{keywords:["islam","worship","minaret"],char:'\u{1f54c}',fitzpatrick_scale:!1,category:"travel_and_places"},synagogue:{keywords:["judaism","worship","temple","jewish"],char:'\u{1f54d}',fitzpatrick_scale:!1,category:"travel_and_places"},kaaba:{keywords:["mecca","mosque","islam"],char:'\u{1f54b}',fitzpatrick_scale:!1,category:"travel_and_places"},shinto_shrine:{keywords:["temple","japan","kyoto"],char:'\u26e9',fitzpatrick_scale:!1,category:"travel_and_places"},watch:{keywords:["time","accessories"],char:'\u231a',fitzpatrick_scale:!1,category:"objects"},iphone:{keywords:["technology","apple","gadgets","dial"],char:'\u{1f4f1}',fitzpatrick_scale:!1,category:"objects"},calling:{keywords:["iphone","incoming"],char:'\u{1f4f2}',fitzpatrick_scale:!1,category:"objects"},computer:{keywords:["technology","laptop","screen","display","monitor"],char:'\u{1f4bb}',fitzpatrick_scale:!1,category:"objects"},keyboard:{keywords:["technology","computer","type","input","text"],char:'\u2328',fitzpatrick_scale:!1,category:"objects"},desktop_computer:{keywords:["technology","computing","screen"],char:'\u{1f5a5}',fitzpatrick_scale:!1,category:"objects"},printer:{keywords:["paper","ink"],char:'\u{1f5a8}',fitzpatrick_scale:!1,category:"objects"},computer_mouse:{keywords:["click"],char:'\u{1f5b1}',fitzpatrick_scale:!1,category:"objects"},trackball:{keywords:["technology","trackpad"],char:'\u{1f5b2}',fitzpatrick_scale:!1,category:"objects"},joystick:{keywords:["game","play"],char:'\u{1f579}',fitzpatrick_scale:!1,category:"objects"},clamp:{keywords:["tool"],char:'\u{1f5dc}',fitzpatrick_scale:!1,category:"objects"},minidisc:{keywords:["technology","record","data","disk","90s"],char:'\u{1f4bd}',fitzpatrick_scale:!1,category:"objects"},floppy_disk:{keywords:["oldschool","technology","save","90s","80s"],char:'\u{1f4be}',fitzpatrick_scale:!1,category:"objects"},cd:{keywords:["technology","dvd","disk","disc","90s"],char:'\u{1f4bf}',fitzpatrick_scale:!1,category:"objects"},dvd:{keywords:["cd","disk","disc"],char:'\u{1f4c0}',fitzpatrick_scale:!1,category:"objects"},vhs:{keywords:["record","video","oldschool","90s","80s"],char:'\u{1f4fc}',fitzpatrick_scale:!1,category:"objects"},camera:{keywords:["gadgets","photography"],char:'\u{1f4f7}',fitzpatrick_scale:!1,category:"objects"},camera_flash:{keywords:["photography","gadgets"],char:'\u{1f4f8}',fitzpatrick_scale:!1,category:"objects"},video_camera:{keywords:["film","record"],char:'\u{1f4f9}',fitzpatrick_scale:!1,category:"objects"},movie_camera:{keywords:["film","record"],char:'\u{1f3a5}',fitzpatrick_scale:!1,category:"objects"},film_projector:{keywords:["video","tape","record","movie"],char:'\u{1f4fd}',fitzpatrick_scale:!1,category:"objects"},film_strip:{keywords:["movie"],char:'\u{1f39e}',fitzpatrick_scale:!1,category:"objects"},telephone_receiver:{keywords:["technology","communication","dial"],char:'\u{1f4de}',fitzpatrick_scale:!1,category:"objects"},phone:{keywords:["technology","communication","dial","telephone"],char:'\u260e\ufe0f',fitzpatrick_scale:!1,category:"objects"},pager:{keywords:["bbcall","oldschool","90s"],char:'\u{1f4df}',fitzpatrick_scale:!1,category:"objects"},fax:{keywords:["communication","technology"],char:'\u{1f4e0}',fitzpatrick_scale:!1,category:"objects"},tv:{keywords:["technology","program","oldschool","show","television"],char:'\u{1f4fa}',fitzpatrick_scale:!1,category:"objects"},radio:{keywords:["communication","music","podcast","program"],char:'\u{1f4fb}',fitzpatrick_scale:!1,category:"objects"},studio_microphone:{keywords:["sing","recording","artist","talkshow"],char:'\u{1f399}',fitzpatrick_scale:!1,category:"objects"},level_slider:{keywords:["scale"],char:'\u{1f39a}',fitzpatrick_scale:!1,category:"objects"},control_knobs:{keywords:["dial"],char:'\u{1f39b}',fitzpatrick_scale:!1,category:"objects"},compass:{keywords:["magnetic","navigation","orienteering"],char:'\u{1f9ed}',fitzpatrick_scale:!1,category:"objects"},stopwatch:{keywords:["time","deadline"],char:'\u23f1',fitzpatrick_scale:!1,category:"objects"},timer_clock:{keywords:["alarm"],char:'\u23f2',fitzpatrick_scale:!1,category:"objects"},alarm_clock:{keywords:["time","wake"],char:'\u23f0',fitzpatrick_scale:!1,category:"objects"},mantelpiece_clock:{keywords:["time"],char:'\u{1f570}',fitzpatrick_scale:!1,category:"objects"},hourglass_flowing_sand:{keywords:["oldschool","time","countdown"],char:'\u23f3',fitzpatrick_scale:!1,category:"objects"},hourglass:{keywords:["time","clock","oldschool","limit","exam","quiz","test"],char:'\u231b',fitzpatrick_scale:!1,category:"objects"},satellite:{keywords:["communication","future","radio","space"],char:'\u{1f4e1}',fitzpatrick_scale:!1,category:"objects"},battery:{keywords:["power","energy","sustain"],char:'\u{1f50b}',fitzpatrick_scale:!1,category:"objects"},electric_plug:{keywords:["charger","power"],char:'\u{1f50c}',fitzpatrick_scale:!1,category:"objects"},bulb:{keywords:["light","electricity","idea"],char:'\u{1f4a1}',fitzpatrick_scale:!1,category:"objects"},flashlight:{keywords:["dark","camping","sight","night"],char:'\u{1f526}',fitzpatrick_scale:!1,category:"objects"},candle:{keywords:["fire","wax"],char:'\u{1f56f}',fitzpatrick_scale:!1,category:"objects"},fire_extinguisher:{keywords:["quench"],char:'\u{1f9ef}',fitzpatrick_scale:!1,category:"objects"},wastebasket:{keywords:["bin","trash","rubbish","garbage","toss"],char:'\u{1f5d1}',fitzpatrick_scale:!1,category:"objects"},oil_drum:{keywords:["barrell"],char:'\u{1f6e2}',fitzpatrick_scale:!1,category:"objects"},money_with_wings:{keywords:["dollar","bills","payment","sale"],char:'\u{1f4b8}',fitzpatrick_scale:!1,category:"objects"},dollar:{keywords:["money","sales","bill","currency"],char:'\u{1f4b5}',fitzpatrick_scale:!1,category:"objects"},yen:{keywords:["money","sales","japanese","dollar","currency"],char:'\u{1f4b4}',fitzpatrick_scale:!1,category:"objects"},euro:{keywords:["money","sales","dollar","currency"],char:'\u{1f4b6}',fitzpatrick_scale:!1,category:"objects"},pound:{keywords:["british","sterling","money","sales","bills","uk","england","currency"],char:'\u{1f4b7}',fitzpatrick_scale:!1,category:"objects"},moneybag:{keywords:["dollar","payment","coins","sale"],char:'\u{1f4b0}',fitzpatrick_scale:!1,category:"objects"},credit_card:{keywords:["money","sales","dollar","bill","payment","shopping"],char:'\u{1f4b3}',fitzpatrick_scale:!1,category:"objects"},gem:{keywords:["blue","ruby","diamond","jewelry"],char:'\u{1f48e}',fitzpatrick_scale:!1,category:"objects"},balance_scale:{keywords:["law","fairness","weight"],char:'\u2696',fitzpatrick_scale:!1,category:"objects"},toolbox:{keywords:["tools","diy","fix","maintainer","mechanic"],char:'\u{1f9f0}',fitzpatrick_scale:!1,category:"objects"},wrench:{keywords:["tools","diy","ikea","fix","maintainer"],char:'\u{1f527}',fitzpatrick_scale:!1,category:"objects"},hammer:{keywords:["tools","build","create"],char:'\u{1f528}',fitzpatrick_scale:!1,category:"objects"},hammer_and_pick:{keywords:["tools","build","create"],char:'\u2692',fitzpatrick_scale:!1,category:"objects"},hammer_and_wrench:{keywords:["tools","build","create"],char:'\u{1f6e0}',fitzpatrick_scale:!1,category:"objects"},pick:{keywords:["tools","dig"],char:'\u26cf',fitzpatrick_scale:!1,category:"objects"},nut_and_bolt:{keywords:["handy","tools","fix"],char:'\u{1f529}',fitzpatrick_scale:!1,category:"objects"},gear:{keywords:["cog"],char:'\u2699',fitzpatrick_scale:!1,category:"objects"},brick:{keywords:["bricks"],char:'\u{1f9f1}',fitzpatrick_scale:!1,category:"objects"},chains:{keywords:["lock","arrest"],char:'\u26d3',fitzpatrick_scale:!1,category:"objects"},magnet:{keywords:["attraction","magnetic"],char:'\u{1f9f2}',fitzpatrick_scale:!1,category:"objects"},gun:{keywords:["violence","weapon","pistol","revolver"],char:'\u{1f52b}',fitzpatrick_scale:!1,category:"objects"},bomb:{keywords:["boom","explode","explosion","terrorism"],char:'\u{1f4a3}',fitzpatrick_scale:!1,category:"objects"},firecracker:{keywords:["dynamite","boom","explode","explosion","explosive"],char:'\u{1f9e8}',fitzpatrick_scale:!1,category:"objects"},hocho:{keywords:["knife","blade","cutlery","kitchen","weapon"],char:'\u{1f52a}',fitzpatrick_scale:!1,category:"objects"},dagger:{keywords:["weapon"],char:'\u{1f5e1}',fitzpatrick_scale:!1,category:"objects"},crossed_swords:{keywords:["weapon"],char:'\u2694',fitzpatrick_scale:!1,category:"objects"},shield:{keywords:["protection","security"],char:'\u{1f6e1}',fitzpatrick_scale:!1,category:"objects"},smoking:{keywords:["kills","tobacco","cigarette","joint","smoke"],char:'\u{1f6ac}',fitzpatrick_scale:!1,category:"objects"},skull_and_crossbones:{keywords:["poison","danger","deadly","scary","death","pirate","evil"],char:'\u2620',fitzpatrick_scale:!1,category:"objects"},coffin:{keywords:["vampire","dead","die","death","rip","graveyard","cemetery","casket","funeral","box"],char:'\u26b0',fitzpatrick_scale:!1,category:"objects"},funeral_urn:{keywords:["dead","die","death","rip","ashes"],char:'\u26b1',fitzpatrick_scale:!1,category:"objects"},amphora:{keywords:["vase","jar"],char:'\u{1f3fa}',fitzpatrick_scale:!1,category:"objects"},crystal_ball:{keywords:["disco","party","magic","circus","fortune_teller"],char:'\u{1f52e}',fitzpatrick_scale:!1,category:"objects"},prayer_beads:{keywords:["dhikr","religious"],char:'\u{1f4ff}',fitzpatrick_scale:!1,category:"objects"},nazar_amulet:{keywords:["bead","charm"],char:'\u{1f9ff}',fitzpatrick_scale:!1,category:"objects"},barber:{keywords:["hair","salon","style"],char:'\u{1f488}',fitzpatrick_scale:!1,category:"objects"},alembic:{keywords:["distilling","science","experiment","chemistry"],char:'\u2697',fitzpatrick_scale:!1,category:"objects"},telescope:{keywords:["stars","space","zoom","science","astronomy"],char:'\u{1f52d}',fitzpatrick_scale:!1,category:"objects"},microscope:{keywords:["laboratory","experiment","zoomin","science","study"],char:'\u{1f52c}',fitzpatrick_scale:!1,category:"objects"},hole:{keywords:["embarrassing"],char:'\u{1f573}',fitzpatrick_scale:!1,category:"objects"},pill:{keywords:["health","medicine","doctor","pharmacy","drug"],char:'\u{1f48a}',fitzpatrick_scale:!1,category:"objects"},syringe:{keywords:["health","hospital","drugs","blood","medicine","needle","doctor","nurse"],char:'\u{1f489}',fitzpatrick_scale:!1,category:"objects"},dna:{keywords:["biologist","genetics","life"],char:'\u{1f9ec}',fitzpatrick_scale:!1,category:"objects"},microbe:{keywords:["amoeba","bacteria","germs"],char:'\u{1f9a0}',fitzpatrick_scale:!1,category:"objects"},petri_dish:{keywords:["bacteria","biology","culture","lab"],char:'\u{1f9eb}',fitzpatrick_scale:!1,category:"objects"},test_tube:{keywords:["chemistry","experiment","lab","science"],char:'\u{1f9ea}',fitzpatrick_scale:!1,category:"objects"},thermometer:{keywords:["weather","temperature","hot","cold"],char:'\u{1f321}',fitzpatrick_scale:!1,category:"objects"},broom:{keywords:["cleaning","sweeping","witch"],char:'\u{1f9f9}',fitzpatrick_scale:!1,category:"objects"},basket:{keywords:["laundry"],char:'\u{1f9fa}',fitzpatrick_scale:!1,category:"objects"},toilet_paper:{keywords:["roll"],char:'\u{1f9fb}',fitzpatrick_scale:!1,category:"objects"},label:{keywords:["sale","tag"],char:'\u{1f3f7}',fitzpatrick_scale:!1,category:"objects"},bookmark:{keywords:["favorite","label","save"],char:'\u{1f516}',fitzpatrick_scale:!1,category:"objects"},toilet:{keywords:["restroom","wc","washroom","bathroom","potty"],char:'\u{1f6bd}',fitzpatrick_scale:!1,category:"objects"},shower:{keywords:["clean","water","bathroom"],char:'\u{1f6bf}',fitzpatrick_scale:!1,category:"objects"},bathtub:{keywords:["clean","shower","bathroom"],char:'\u{1f6c1}',fitzpatrick_scale:!1,category:"objects"},soap:{keywords:["bar","bathing","cleaning","lather"],char:'\u{1f9fc}',fitzpatrick_scale:!1,category:"objects"},sponge:{keywords:["absorbing","cleaning","porous"],char:'\u{1f9fd}',fitzpatrick_scale:!1,category:"objects"},lotion_bottle:{keywords:["moisturizer","sunscreen"],char:'\u{1f9f4}',fitzpatrick_scale:!1,category:"objects"},key:{keywords:["lock","door","password"],char:'\u{1f511}',fitzpatrick_scale:!1,category:"objects"},old_key:{keywords:["lock","door","password"],char:'\u{1f5dd}',fitzpatrick_scale:!1,category:"objects"},couch_and_lamp:{keywords:["read","chill"],char:'\u{1f6cb}',fitzpatrick_scale:!1,category:"objects"},sleeping_bed:{keywords:["bed","rest"],char:'\u{1f6cc}',fitzpatrick_scale:!0,category:"objects"},bed:{keywords:["sleep","rest"],char:'\u{1f6cf}',fitzpatrick_scale:!1,category:"objects"},door:{keywords:["house","entry","exit"],char:'\u{1f6aa}',fitzpatrick_scale:!1,category:"objects"},bellhop_bell:{keywords:["service"],char:'\u{1f6ce}',fitzpatrick_scale:!1,category:"objects"},teddy_bear:{keywords:["plush","stuffed"],char:'\u{1f9f8}',fitzpatrick_scale:!1,category:"objects"},framed_picture:{keywords:["photography"],char:'\u{1f5bc}',fitzpatrick_scale:!1,category:"objects"},world_map:{keywords:["location","direction"],char:'\u{1f5fa}',fitzpatrick_scale:!1,category:"objects"},parasol_on_ground:{keywords:["weather","summer"],char:'\u26f1',fitzpatrick_scale:!1,category:"objects"},moyai:{keywords:["rock","easter island","moai"],char:'\u{1f5ff}',fitzpatrick_scale:!1,category:"objects"},shopping:{keywords:["mall","buy","purchase"],char:'\u{1f6cd}',fitzpatrick_scale:!1,category:"objects"},shopping_cart:{keywords:["trolley"],char:'\u{1f6d2}',fitzpatrick_scale:!1,category:"objects"},balloon:{keywords:["party","celebration","birthday","circus"],char:'\u{1f388}',fitzpatrick_scale:!1,category:"objects"},flags:{keywords:["fish","japanese","koinobori","carp","banner"],char:'\u{1f38f}',fitzpatrick_scale:!1,category:"objects"},ribbon:{keywords:["decoration","pink","girl","bowtie"],char:'\u{1f380}',fitzpatrick_scale:!1,category:"objects"},gift:{keywords:["present","birthday","christmas","xmas"],char:'\u{1f381}',fitzpatrick_scale:!1,category:"objects"},confetti_ball:{keywords:["festival","party","birthday","circus"],char:'\u{1f38a}',fitzpatrick_scale:!1,category:"objects"},tada:{keywords:["party","congratulations","birthday","magic","circus","celebration"],char:'\u{1f389}',fitzpatrick_scale:!1,category:"objects"},dolls:{keywords:["japanese","toy","kimono"],char:'\u{1f38e}',fitzpatrick_scale:!1,category:"objects"},wind_chime:{keywords:["nature","ding","spring","bell"],char:'\u{1f390}',fitzpatrick_scale:!1,category:"objects"},crossed_flags:{keywords:["japanese","nation","country","border"],char:'\u{1f38c}',fitzpatrick_scale:!1,category:"objects"},izakaya_lantern:{keywords:["light","paper","halloween","spooky"],char:'\u{1f3ee}',fitzpatrick_scale:!1,category:"objects"},red_envelope:{keywords:["gift"],char:'\u{1f9e7}',fitzpatrick_scale:!1,category:"objects"},email:{keywords:["letter","postal","inbox","communication"],char:'\u2709\ufe0f',fitzpatrick_scale:!1,category:"objects"},envelope_with_arrow:{keywords:["email","communication"],char:'\u{1f4e9}',fitzpatrick_scale:!1,category:"objects"},incoming_envelope:{keywords:["email","inbox"],char:'\u{1f4e8}',fitzpatrick_scale:!1,category:"objects"},"e-mail":{keywords:["communication","inbox"],char:'\u{1f4e7}',fitzpatrick_scale:!1,category:"objects"},love_letter:{keywords:["email","like","affection","envelope","valentines"],char:'\u{1f48c}',fitzpatrick_scale:!1,category:"objects"},postbox:{keywords:["email","letter","envelope"],char:'\u{1f4ee}',fitzpatrick_scale:!1,category:"objects"},mailbox_closed:{keywords:["email","communication","inbox"],char:'\u{1f4ea}',fitzpatrick_scale:!1,category:"objects"},mailbox:{keywords:["email","inbox","communication"],char:'\u{1f4eb}',fitzpatrick_scale:!1,category:"objects"},mailbox_with_mail:{keywords:["email","inbox","communication"],char:'\u{1f4ec}',fitzpatrick_scale:!1,category:"objects"},mailbox_with_no_mail:{keywords:["email","inbox"],char:'\u{1f4ed}',fitzpatrick_scale:!1,category:"objects"},package:{keywords:["mail","gift","cardboard","box","moving"],char:'\u{1f4e6}',fitzpatrick_scale:!1,category:"objects"},postal_horn:{keywords:["instrument","music"],char:'\u{1f4ef}',fitzpatrick_scale:!1,category:"objects"},inbox_tray:{keywords:["email","documents"],char:'\u{1f4e5}',fitzpatrick_scale:!1,category:"objects"},outbox_tray:{keywords:["inbox","email"],char:'\u{1f4e4}',fitzpatrick_scale:!1,category:"objects"},scroll:{keywords:["documents","ancient","history","paper"],char:'\u{1f4dc}',fitzpatrick_scale:!1,category:"objects"},page_with_curl:{keywords:["documents","office","paper"],char:'\u{1f4c3}',fitzpatrick_scale:!1,category:"objects"},bookmark_tabs:{keywords:["favorite","save","order","tidy"],char:'\u{1f4d1}',fitzpatrick_scale:!1,category:"objects"},receipt:{keywords:["accounting","expenses"],char:'\u{1f9fe}',fitzpatrick_scale:!1,category:"objects"},bar_chart:{keywords:["graph","presentation","stats"],char:'\u{1f4ca}',fitzpatrick_scale:!1,category:"objects"},chart_with_upwards_trend:{keywords:["graph","presentation","stats","recovery","business","economics","money","sales","good","success"],char:'\u{1f4c8}',fitzpatrick_scale:!1,category:"objects"},chart_with_downwards_trend:{keywords:["graph","presentation","stats","recession","business","economics","money","sales","bad","failure"],char:'\u{1f4c9}',fitzpatrick_scale:!1,category:"objects"},page_facing_up:{keywords:["documents","office","paper","information"],char:'\u{1f4c4}',fitzpatrick_scale:!1,category:"objects"},date:{keywords:["calendar","schedule"],char:'\u{1f4c5}',fitzpatrick_scale:!1,category:"objects"},calendar:{keywords:["schedule","date","planning"],char:'\u{1f4c6}',fitzpatrick_scale:!1,category:"objects"},spiral_calendar:{keywords:["date","schedule","planning"],char:'\u{1f5d3}',fitzpatrick_scale:!1,category:"objects"},card_index:{keywords:["business","stationery"],char:'\u{1f4c7}',fitzpatrick_scale:!1,category:"objects"},card_file_box:{keywords:["business","stationery"],char:'\u{1f5c3}',fitzpatrick_scale:!1,category:"objects"},ballot_box:{keywords:["election","vote"],char:'\u{1f5f3}',fitzpatrick_scale:!1,category:"objects"},file_cabinet:{keywords:["filing","organizing"],char:'\u{1f5c4}',fitzpatrick_scale:!1,category:"objects"},clipboard:{keywords:["stationery","documents"],char:'\u{1f4cb}',fitzpatrick_scale:!1,category:"objects"},spiral_notepad:{keywords:["memo","stationery"],char:'\u{1f5d2}',fitzpatrick_scale:!1,category:"objects"},file_folder:{keywords:["documents","business","office"],char:'\u{1f4c1}',fitzpatrick_scale:!1,category:"objects"},open_file_folder:{keywords:["documents","load"],char:'\u{1f4c2}',fitzpatrick_scale:!1,category:"objects"},card_index_dividers:{keywords:["organizing","business","stationery"],char:'\u{1f5c2}',fitzpatrick_scale:!1,category:"objects"},newspaper_roll:{keywords:["press","headline"],char:'\u{1f5de}',fitzpatrick_scale:!1,category:"objects"},newspaper:{keywords:["press","headline"],char:'\u{1f4f0}',fitzpatrick_scale:!1,category:"objects"},notebook:{keywords:["stationery","record","notes","paper","study"],char:'\u{1f4d3}',fitzpatrick_scale:!1,category:"objects"},closed_book:{keywords:["read","library","knowledge","textbook","learn"],char:'\u{1f4d5}',fitzpatrick_scale:!1,category:"objects"},green_book:{keywords:["read","library","knowledge","study"],char:'\u{1f4d7}',fitzpatrick_scale:!1,category:"objects"},blue_book:{keywords:["read","library","knowledge","learn","study"],char:'\u{1f4d8}',fitzpatrick_scale:!1,category:"objects"},orange_book:{keywords:["read","library","knowledge","textbook","study"],char:'\u{1f4d9}',fitzpatrick_scale:!1,category:"objects"},notebook_with_decorative_cover:{keywords:["classroom","notes","record","paper","study"],char:'\u{1f4d4}',fitzpatrick_scale:!1,category:"objects"},ledger:{keywords:["notes","paper"],char:'\u{1f4d2}',fitzpatrick_scale:!1,category:"objects"},books:{keywords:["literature","library","study"],char:'\u{1f4da}',fitzpatrick_scale:!1,category:"objects"},open_book:{keywords:["book","read","library","knowledge","literature","learn","study"],char:'\u{1f4d6}',fitzpatrick_scale:!1,category:"objects"},safety_pin:{keywords:["diaper"],char:'\u{1f9f7}',fitzpatrick_scale:!1,category:"objects"},link:{keywords:["rings","url"],char:'\u{1f517}',fitzpatrick_scale:!1,category:"objects"},paperclip:{keywords:["documents","stationery"],char:'\u{1f4ce}',fitzpatrick_scale:!1,category:"objects"},paperclips:{keywords:["documents","stationery"],char:'\u{1f587}',fitzpatrick_scale:!1,category:"objects"},scissors:{keywords:["stationery","cut"],char:'\u2702\ufe0f',fitzpatrick_scale:!1,category:"objects"},triangular_ruler:{keywords:["stationery","math","architect","sketch"],char:'\u{1f4d0}',fitzpatrick_scale:!1,category:"objects"},straight_ruler:{keywords:["stationery","calculate","length","math","school","drawing","architect","sketch"],char:'\u{1f4cf}',fitzpatrick_scale:!1,category:"objects"},abacus:{keywords:["calculation"],char:'\u{1f9ee}',fitzpatrick_scale:!1,category:"objects"},pushpin:{keywords:["stationery","mark","here"],char:'\u{1f4cc}',fitzpatrick_scale:!1,category:"objects"},round_pushpin:{keywords:["stationery","location","map","here"],char:'\u{1f4cd}',fitzpatrick_scale:!1,category:"objects"},triangular_flag_on_post:{keywords:["mark","milestone","place"],char:'\u{1f6a9}',fitzpatrick_scale:!1,category:"objects"},white_flag:{keywords:["losing","loser","lost","surrender","give up","fail"],char:'\u{1f3f3}',fitzpatrick_scale:!1,category:"objects"},black_flag:{keywords:["pirate"],char:'\u{1f3f4}',fitzpatrick_scale:!1,category:"objects"},rainbow_flag:{keywords:["flag","rainbow","pride","gay","lgbt","glbt","queer","homosexual","lesbian","bisexual","transgender"],char:'\u{1f3f3}\ufe0f\u200d\u{1f308}',fitzpatrick_scale:!1,category:"objects"},closed_lock_with_key:{keywords:["security","privacy"],char:'\u{1f510}',fitzpatrick_scale:!1,category:"objects"},lock:{keywords:["security","password","padlock"],char:'\u{1f512}',fitzpatrick_scale:!1,category:"objects"},unlock:{keywords:["privacy","security"],char:'\u{1f513}',fitzpatrick_scale:!1,category:"objects"},lock_with_ink_pen:{keywords:["security","secret"],char:'\u{1f50f}',fitzpatrick_scale:!1,category:"objects"},pen:{keywords:["stationery","writing","write"],char:'\u{1f58a}',fitzpatrick_scale:!1,category:"objects"},fountain_pen:{keywords:["stationery","writing","write"],char:'\u{1f58b}',fitzpatrick_scale:!1,category:"objects"},black_nib:{keywords:["pen","stationery","writing","write"],char:'\u2712\ufe0f',fitzpatrick_scale:!1,category:"objects"},memo:{keywords:["write","documents","stationery","pencil","paper","writing","legal","exam","quiz","test","study","compose"],char:'\u{1f4dd}',fitzpatrick_scale:!1,category:"objects"},pencil2:{keywords:["stationery","write","paper","writing","school","study"],char:'\u270f\ufe0f',fitzpatrick_scale:!1,category:"objects"},crayon:{keywords:["drawing","creativity"],char:'\u{1f58d}',fitzpatrick_scale:!1,category:"objects"},paintbrush:{keywords:["drawing","creativity","art"],char:'\u{1f58c}',fitzpatrick_scale:!1,category:"objects"},mag:{keywords:["search","zoom","find","detective"],char:'\u{1f50d}',fitzpatrick_scale:!1,category:"objects"},mag_right:{keywords:["search","zoom","find","detective"],char:'\u{1f50e}',fitzpatrick_scale:!1,category:"objects"},heart:{keywords:["love","like","valentines"],char:'\u2764\ufe0f',fitzpatrick_scale:!1,category:"symbols"},orange_heart:{keywords:["love","like","affection","valentines"],char:'\u{1f9e1}',fitzpatrick_scale:!1,category:"symbols"},yellow_heart:{keywords:["love","like","affection","valentines"],char:'\u{1f49b}',fitzpatrick_scale:!1,category:"symbols"},green_heart:{keywords:["love","like","affection","valentines"],char:'\u{1f49a}',fitzpatrick_scale:!1,category:"symbols"},blue_heart:{keywords:["love","like","affection","valentines"],char:'\u{1f499}',fitzpatrick_scale:!1,category:"symbols"},purple_heart:{keywords:["love","like","affection","valentines"],char:'\u{1f49c}',fitzpatrick_scale:!1,category:"symbols"},black_heart:{keywords:["evil"],char:'\u{1f5a4}',fitzpatrick_scale:!1,category:"symbols"},broken_heart:{keywords:["sad","sorry","break","heart","heartbreak"],char:'\u{1f494}',fitzpatrick_scale:!1,category:"symbols"},heavy_heart_exclamation:{keywords:["decoration","love"],char:'\u2763',fitzpatrick_scale:!1,category:"symbols"},two_hearts:{keywords:["love","like","affection","valentines","heart"],char:'\u{1f495}',fitzpatrick_scale:!1,category:"symbols"},revolving_hearts:{keywords:["love","like","affection","valentines"],char:'\u{1f49e}',fitzpatrick_scale:!1,category:"symbols"},heartbeat:{keywords:["love","like","affection","valentines","pink","heart"],char:'\u{1f493}',fitzpatrick_scale:!1,category:"symbols"},heartpulse:{keywords:["like","love","affection","valentines","pink"],char:'\u{1f497}',fitzpatrick_scale:!1,category:"symbols"},sparkling_heart:{keywords:["love","like","affection","valentines"],char:'\u{1f496}',fitzpatrick_scale:!1,category:"symbols"},cupid:{keywords:["love","like","heart","affection","valentines"],char:'\u{1f498}',fitzpatrick_scale:!1,category:"symbols"},gift_heart:{keywords:["love","valentines"],char:'\u{1f49d}',fitzpatrick_scale:!1,category:"symbols"},heart_decoration:{keywords:["purple-square","love","like"],char:'\u{1f49f}',fitzpatrick_scale:!1,category:"symbols"},peace_symbol:{keywords:["hippie"],char:'\u262e',fitzpatrick_scale:!1,category:"symbols"},latin_cross:{keywords:["christianity"],char:'\u271d',fitzpatrick_scale:!1,category:"symbols"},star_and_crescent:{keywords:["islam"],char:'\u262a',fitzpatrick_scale:!1,category:"symbols"},om:{keywords:["hinduism","buddhism","sikhism","jainism"],char:'\u{1f549}',fitzpatrick_scale:!1,category:"symbols"},wheel_of_dharma:{keywords:["hinduism","buddhism","sikhism","jainism"],char:'\u2638',fitzpatrick_scale:!1,category:"symbols"},star_of_david:{keywords:["judaism"],char:'\u2721',fitzpatrick_scale:!1,category:"symbols"},six_pointed_star:{keywords:["purple-square","religion","jewish","hexagram"],char:'\u{1f52f}',fitzpatrick_scale:!1,category:"symbols"},menorah:{keywords:["hanukkah","candles","jewish"],char:'\u{1f54e}',fitzpatrick_scale:!1,category:"symbols"},yin_yang:{keywords:["balance"],char:'\u262f',fitzpatrick_scale:!1,category:"symbols"},orthodox_cross:{keywords:["suppedaneum","religion"],char:'\u2626',fitzpatrick_scale:!1,category:"symbols"},place_of_worship:{keywords:["religion","church","temple","prayer"],char:'\u{1f6d0}',fitzpatrick_scale:!1,category:"symbols"},ophiuchus:{keywords:["sign","purple-square","constellation","astrology"],char:'\u26ce',fitzpatrick_scale:!1,category:"symbols"},aries:{keywords:["sign","purple-square","zodiac","astrology"],char:'\u2648',fitzpatrick_scale:!1,category:"symbols"},taurus:{keywords:["purple-square","sign","zodiac","astrology"],char:'\u2649',fitzpatrick_scale:!1,category:"symbols"},gemini:{keywords:["sign","zodiac","purple-square","astrology"],char:'\u264a',fitzpatrick_scale:!1,category:"symbols"},cancer:{keywords:["sign","zodiac","purple-square","astrology"],char:'\u264b',fitzpatrick_scale:!1,category:"symbols"},leo:{keywords:["sign","purple-square","zodiac","astrology"],char:'\u264c',fitzpatrick_scale:!1,category:"symbols"},virgo:{keywords:["sign","zodiac","purple-square","astrology"],char:'\u264d',fitzpatrick_scale:!1,category:"symbols"},libra:{keywords:["sign","purple-square","zodiac","astrology"],char:'\u264e',fitzpatrick_scale:!1,category:"symbols"},scorpius:{keywords:["sign","zodiac","purple-square","astrology","scorpio"],char:'\u264f',fitzpatrick_scale:!1,category:"symbols"},sagittarius:{keywords:["sign","zodiac","purple-square","astrology"],char:'\u2650',fitzpatrick_scale:!1,category:"symbols"},capricorn:{keywords:["sign","zodiac","purple-square","astrology"],char:'\u2651',fitzpatrick_scale:!1,category:"symbols"},aquarius:{keywords:["sign","purple-square","zodiac","astrology"],char:'\u2652',fitzpatrick_scale:!1,category:"symbols"},pisces:{keywords:["purple-square","sign","zodiac","astrology"],char:'\u2653',fitzpatrick_scale:!1,category:"symbols"},id:{keywords:["purple-square","words"],char:'\u{1f194}',fitzpatrick_scale:!1,category:"symbols"},atom_symbol:{keywords:["science","physics","chemistry"],char:'\u269b',fitzpatrick_scale:!1,category:"symbols"},u7a7a:{keywords:["kanji","japanese","chinese","empty","sky","blue-square"],char:'\u{1f233}',fitzpatrick_scale:!1,category:"symbols"},u5272:{keywords:["cut","divide","chinese","kanji","pink-square"],char:'\u{1f239}',fitzpatrick_scale:!1,category:"symbols"},radioactive:{keywords:["nuclear","danger"],char:'\u2622',fitzpatrick_scale:!1,category:"symbols"},biohazard:{keywords:["danger"],char:'\u2623',fitzpatrick_scale:!1,category:"symbols"},mobile_phone_off:{keywords:["mute","orange-square","silence","quiet"],char:'\u{1f4f4}',fitzpatrick_scale:!1,category:"symbols"},vibration_mode:{keywords:["orange-square","phone"],char:'\u{1f4f3}',fitzpatrick_scale:!1,category:"symbols"},u6709:{keywords:["orange-square","chinese","have","kanji"],char:'\u{1f236}',fitzpatrick_scale:!1,category:"symbols"},u7121:{keywords:["nothing","chinese","kanji","japanese","orange-square"],char:'\u{1f21a}',fitzpatrick_scale:!1,category:"symbols"},u7533:{keywords:["chinese","japanese","kanji","orange-square"],char:'\u{1f238}',fitzpatrick_scale:!1,category:"symbols"},u55b6:{keywords:["japanese","opening hours","orange-square"],char:'\u{1f23a}',fitzpatrick_scale:!1,category:"symbols"},u6708:{keywords:["chinese","month","moon","japanese","orange-square","kanji"],char:'\u{1f237}\ufe0f',fitzpatrick_scale:!1,category:"symbols"},eight_pointed_black_star:{keywords:["orange-square","shape","polygon"],char:'\u2734\ufe0f',fitzpatrick_scale:!1,category:"symbols"},vs:{keywords:["words","orange-square"],char:'\u{1f19a}',fitzpatrick_scale:!1,category:"symbols"},accept:{keywords:["ok","good","chinese","kanji","agree","yes","orange-circle"],char:'\u{1f251}',fitzpatrick_scale:!1,category:"symbols"},white_flower:{keywords:["japanese","spring"],char:'\u{1f4ae}',fitzpatrick_scale:!1,category:"symbols"},ideograph_advantage:{keywords:["chinese","kanji","obtain","get","circle"],char:'\u{1f250}',fitzpatrick_scale:!1,category:"symbols"},secret:{keywords:["privacy","chinese","sshh","kanji","red-circle"],char:'\u3299\ufe0f',fitzpatrick_scale:!1,category:"symbols"},congratulations:{keywords:["chinese","kanji","japanese","red-circle"],char:'\u3297\ufe0f',fitzpatrick_scale:!1,category:"symbols"},u5408:{keywords:["japanese","chinese","join","kanji","red-square"],char:'\u{1f234}',fitzpatrick_scale:!1,category:"symbols"},u6e80:{keywords:["full","chinese","japanese","red-square","kanji"],char:'\u{1f235}',fitzpatrick_scale:!1,category:"symbols"},u7981:{keywords:["kanji","japanese","chinese","forbidden","limit","restricted","red-square"],char:'\u{1f232}',fitzpatrick_scale:!1,category:"symbols"},a:{keywords:["red-square","alphabet","letter"],char:'\u{1f170}\ufe0f',fitzpatrick_scale:!1,category:"symbols"},b:{keywords:["red-square","alphabet","letter"],char:'\u{1f171}\ufe0f',fitzpatrick_scale:!1,category:"symbols"},ab:{keywords:["red-square","alphabet"],char:'\u{1f18e}',fitzpatrick_scale:!1,category:"symbols"},cl:{keywords:["alphabet","words","red-square"],char:'\u{1f191}',fitzpatrick_scale:!1,category:"symbols"},o2:{keywords:["alphabet","red-square","letter"],char:'\u{1f17e}\ufe0f',fitzpatrick_scale:!1,category:"symbols"},sos:{keywords:["help","red-square","words","emergency","911"],char:'\u{1f198}',fitzpatrick_scale:!1,category:"symbols"},no_entry:{keywords:["limit","security","privacy","bad","denied","stop","circle"],char:'\u26d4',fitzpatrick_scale:!1,category:"symbols"},name_badge:{keywords:["fire","forbid"],char:'\u{1f4db}',fitzpatrick_scale:!1,category:"symbols"},no_entry_sign:{keywords:["forbid","stop","limit","denied","disallow","circle"],char:'\u{1f6ab}',fitzpatrick_scale:!1,category:"symbols"},x:{keywords:["no","delete","remove","cancel","red"],char:'\u274c',fitzpatrick_scale:!1,category:"symbols"},o:{keywords:["circle","round"],char:'\u2b55',fitzpatrick_scale:!1,category:"symbols"},stop_sign:{keywords:["stop"],char:'\u{1f6d1}',fitzpatrick_scale:!1,category:"symbols"},anger:{keywords:["angry","mad"],char:'\u{1f4a2}',fitzpatrick_scale:!1,category:"symbols"},hotsprings:{keywords:["bath","warm","relax"],char:'\u2668\ufe0f',fitzpatrick_scale:!1,category:"symbols"},no_pedestrians:{keywords:["rules","crossing","walking","circle"],char:'\u{1f6b7}',fitzpatrick_scale:!1,category:"symbols"},do_not_litter:{keywords:["trash","bin","garbage","circle"],char:'\u{1f6af}',fitzpatrick_scale:!1,category:"symbols"},no_bicycles:{keywords:["cyclist","prohibited","circle"],char:'\u{1f6b3}',fitzpatrick_scale:!1,category:"symbols"},"non-potable_water":{keywords:["drink","faucet","tap","circle"],char:'\u{1f6b1}',fitzpatrick_scale:!1,category:"symbols"},underage:{keywords:["18","drink","pub","night","minor","circle"],char:'\u{1f51e}',fitzpatrick_scale:!1,category:"symbols"},no_mobile_phones:{keywords:["iphone","mute","circle"],char:'\u{1f4f5}',fitzpatrick_scale:!1,category:"symbols"},exclamation:{keywords:["heavy_exclamation_mark","danger","surprise","punctuation","wow","warning"],char:'\u2757',fitzpatrick_scale:!1,category:"symbols"},grey_exclamation:{keywords:["surprise","punctuation","gray","wow","warning"],char:'\u2755',fitzpatrick_scale:!1,category:"symbols"},question:{keywords:["doubt","confused"],char:'\u2753',fitzpatrick_scale:!1,category:"symbols"},grey_question:{keywords:["doubts","gray","huh","confused"],char:'\u2754',fitzpatrick_scale:!1,category:"symbols"},bangbang:{keywords:["exclamation","surprise"],char:'\u203c\ufe0f',fitzpatrick_scale:!1,category:"symbols"},interrobang:{keywords:["wat","punctuation","surprise"],char:'\u2049\ufe0f',fitzpatrick_scale:!1,category:"symbols"},low_brightness:{keywords:["sun","afternoon","warm","summer"],char:'\u{1f505}',fitzpatrick_scale:!1,category:"symbols"},high_brightness:{keywords:["sun","light"],char:'\u{1f506}',fitzpatrick_scale:!1,category:"symbols"},trident:{keywords:["weapon","spear"],char:'\u{1f531}',fitzpatrick_scale:!1,category:"symbols"},fleur_de_lis:{keywords:["decorative","scout"],char:'\u269c',fitzpatrick_scale:!1,category:"symbols"},part_alternation_mark:{keywords:["graph","presentation","stats","business","economics","bad"],char:'\u303d\ufe0f',fitzpatrick_scale:!1,category:"symbols"},warning:{keywords:["exclamation","wip","alert","error","problem","issue"],char:'\u26a0\ufe0f',fitzpatrick_scale:!1,category:"symbols"},children_crossing:{keywords:["school","warning","danger","sign","driving","yellow-diamond"],char:'\u{1f6b8}',fitzpatrick_scale:!1,category:"symbols"},beginner:{keywords:["badge","shield"],char:'\u{1f530}',fitzpatrick_scale:!1,category:"symbols"},recycle:{keywords:["arrow","environment","garbage","trash"],char:'\u267b\ufe0f',fitzpatrick_scale:!1,category:"symbols"},u6307:{keywords:["chinese","point","green-square","kanji"],char:'\u{1f22f}',fitzpatrick_scale:!1,category:"symbols"},chart:{keywords:["green-square","graph","presentation","stats"],char:'\u{1f4b9}',fitzpatrick_scale:!1,category:"symbols"},sparkle:{keywords:["stars","green-square","awesome","good","fireworks"],char:'\u2747\ufe0f',fitzpatrick_scale:!1,category:"symbols"},eight_spoked_asterisk:{keywords:["star","sparkle","green-square"],char:'\u2733\ufe0f',fitzpatrick_scale:!1,category:"symbols"},negative_squared_cross_mark:{keywords:["x","green-square","no","deny"],char:'\u274e',fitzpatrick_scale:!1,category:"symbols"},white_check_mark:{keywords:["green-square","ok","agree","vote","election","answer","tick"],char:'\u2705',fitzpatrick_scale:!1,category:"symbols"},diamond_shape_with_a_dot_inside:{keywords:["jewel","blue","gem","crystal","fancy"],char:'\u{1f4a0}',fitzpatrick_scale:!1,category:"symbols"},cyclone:{keywords:["weather","swirl","blue","cloud","vortex","spiral","whirlpool","spin","tornado","hurricane","typhoon"],char:'\u{1f300}',fitzpatrick_scale:!1,category:"symbols"},loop:{keywords:["tape","cassette"],char:'\u27bf',fitzpatrick_scale:!1,category:"symbols"},globe_with_meridians:{keywords:["earth","international","world","internet","interweb","i18n"],char:'\u{1f310}',fitzpatrick_scale:!1,category:"symbols"},m:{keywords:["alphabet","blue-circle","letter"],char:'\u24c2\ufe0f',fitzpatrick_scale:!1,category:"symbols"},atm:{keywords:["money","sales","cash","blue-square","payment","bank"],char:'\u{1f3e7}',fitzpatrick_scale:!1,category:"symbols"},sa:{keywords:["japanese","blue-square","katakana"],char:'\u{1f202}\ufe0f',fitzpatrick_scale:!1,category:"symbols"},passport_control:{keywords:["custom","blue-square"],char:'\u{1f6c2}',fitzpatrick_scale:!1,category:"symbols"},customs:{keywords:["passport","border","blue-square"],char:'\u{1f6c3}',fitzpatrick_scale:!1,category:"symbols"},baggage_claim:{keywords:["blue-square","airport","transport"],char:'\u{1f6c4}',fitzpatrick_scale:!1,category:"symbols"},left_luggage:{keywords:["blue-square","travel"],char:'\u{1f6c5}',fitzpatrick_scale:!1,category:"symbols"},wheelchair:{keywords:["blue-square","disabled","a11y","accessibility"],char:'\u267f',fitzpatrick_scale:!1,category:"symbols"},no_smoking:{keywords:["cigarette","blue-square","smell","smoke"],char:'\u{1f6ad}',fitzpatrick_scale:!1,category:"symbols"},wc:{keywords:["toilet","restroom","blue-square"],char:'\u{1f6be}',fitzpatrick_scale:!1,category:"symbols"},parking:{keywords:["cars","blue-square","alphabet","letter"],char:'\u{1f17f}\ufe0f',fitzpatrick_scale:!1,category:"symbols"},potable_water:{keywords:["blue-square","liquid","restroom","cleaning","faucet"],char:'\u{1f6b0}',fitzpatrick_scale:!1,category:"symbols"},mens:{keywords:["toilet","restroom","wc","blue-square","gender","male"],char:'\u{1f6b9}',fitzpatrick_scale:!1,category:"symbols"},womens:{keywords:["purple-square","woman","female","toilet","loo","restroom","gender"],char:'\u{1f6ba}',fitzpatrick_scale:!1,category:"symbols"},baby_symbol:{keywords:["orange-square","child"],char:'\u{1f6bc}',fitzpatrick_scale:!1,category:"symbols"},restroom:{keywords:["blue-square","toilet","refresh","wc","gender"],char:'\u{1f6bb}',fitzpatrick_scale:!1,category:"symbols"},put_litter_in_its_place:{keywords:["blue-square","sign","human","info"],char:'\u{1f6ae}',fitzpatrick_scale:!1,category:"symbols"},cinema:{keywords:["blue-square","record","film","movie","curtain","stage","theater"],char:'\u{1f3a6}',fitzpatrick_scale:!1,category:"symbols"},signal_strength:{keywords:["blue-square","reception","phone","internet","connection","wifi","bluetooth","bars"],char:'\u{1f4f6}',fitzpatrick_scale:!1,category:"symbols"},koko:{keywords:["blue-square","here","katakana","japanese","destination"],char:'\u{1f201}',fitzpatrick_scale:!1,category:"symbols"},ng:{keywords:["blue-square","words","shape","icon"],char:'\u{1f196}',fitzpatrick_scale:!1,category:"symbols"},ok:{keywords:["good","agree","yes","blue-square"],char:'\u{1f197}',fitzpatrick_scale:!1,category:"symbols"},up:{keywords:["blue-square","above","high"],char:'\u{1f199}',fitzpatrick_scale:!1,category:"symbols"},cool:{keywords:["words","blue-square"],char:'\u{1f192}',fitzpatrick_scale:!1,category:"symbols"},new:{keywords:["blue-square","words","start"],char:'\u{1f195}',fitzpatrick_scale:!1,category:"symbols"},free:{keywords:["blue-square","words"],char:'\u{1f193}',fitzpatrick_scale:!1,category:"symbols"},zero:{keywords:["0","numbers","blue-square","null"],char:'0\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},one:{keywords:["blue-square","numbers","1"],char:'1\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},two:{keywords:["numbers","2","prime","blue-square"],char:'2\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},three:{keywords:["3","numbers","prime","blue-square"],char:'3\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},four:{keywords:["4","numbers","blue-square"],char:'4\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},five:{keywords:["5","numbers","blue-square","prime"],char:'5\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},six:{keywords:["6","numbers","blue-square"],char:'6\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},seven:{keywords:["7","numbers","blue-square","prime"],char:'7\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},eight:{keywords:["8","blue-square","numbers"],char:'8\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},nine:{keywords:["blue-square","numbers","9"],char:'9\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},keycap_ten:{keywords:["numbers","10","blue-square"],char:'\u{1f51f}',fitzpatrick_scale:!1,category:"symbols"},asterisk:{keywords:["star","keycap"],char:'*\u20e3',fitzpatrick_scale:!1,category:"symbols"},eject_button:{keywords:["blue-square"],char:'\u23cf\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_forward:{keywords:["blue-square","right","direction","play"],char:'\u25b6\ufe0f',fitzpatrick_scale:!1,category:"symbols"},pause_button:{keywords:["pause","blue-square"],char:'\u23f8',fitzpatrick_scale:!1,category:"symbols"},next_track_button:{keywords:["forward","next","blue-square"],char:'\u23ed',fitzpatrick_scale:!1,category:"symbols"},stop_button:{keywords:["blue-square"],char:'\u23f9',fitzpatrick_scale:!1,category:"symbols"},record_button:{keywords:["blue-square"],char:'\u23fa',fitzpatrick_scale:!1,category:"symbols"},play_or_pause_button:{keywords:["blue-square","play","pause"],char:'\u23ef',fitzpatrick_scale:!1,category:"symbols"},previous_track_button:{keywords:["backward"],char:'\u23ee',fitzpatrick_scale:!1,category:"symbols"},fast_forward:{keywords:["blue-square","play","speed","continue"],char:'\u23e9',fitzpatrick_scale:!1,category:"symbols"},rewind:{keywords:["play","blue-square"],char:'\u23ea',fitzpatrick_scale:!1,category:"symbols"},twisted_rightwards_arrows:{keywords:["blue-square","shuffle","music","random"],char:'\u{1f500}',fitzpatrick_scale:!1,category:"symbols"},repeat:{keywords:["loop","record"],char:'\u{1f501}',fitzpatrick_scale:!1,category:"symbols"},repeat_one:{keywords:["blue-square","loop"],char:'\u{1f502}',fitzpatrick_scale:!1,category:"symbols"},arrow_backward:{keywords:["blue-square","left","direction"],char:'\u25c0\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_up_small:{keywords:["blue-square","triangle","direction","point","forward","top"],char:'\u{1f53c}',fitzpatrick_scale:!1,category:"symbols"},arrow_down_small:{keywords:["blue-square","direction","bottom"],char:'\u{1f53d}',fitzpatrick_scale:!1,category:"symbols"},arrow_double_up:{keywords:["blue-square","direction","top"],char:'\u23eb',fitzpatrick_scale:!1,category:"symbols"},arrow_double_down:{keywords:["blue-square","direction","bottom"],char:'\u23ec',fitzpatrick_scale:!1,category:"symbols"},arrow_right:{keywords:["blue-square","next"],char:'\u27a1\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_left:{keywords:["blue-square","previous","back"],char:'\u2b05\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_up:{keywords:["blue-square","continue","top","direction"],char:'\u2b06\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_down:{keywords:["blue-square","direction","bottom"],char:'\u2b07\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_upper_right:{keywords:["blue-square","point","direction","diagonal","northeast"],char:'\u2197\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_lower_right:{keywords:["blue-square","direction","diagonal","southeast"],char:'\u2198\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_lower_left:{keywords:["blue-square","direction","diagonal","southwest"],char:'\u2199\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_upper_left:{keywords:["blue-square","point","direction","diagonal","northwest"],char:'\u2196\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_up_down:{keywords:["blue-square","direction","way","vertical"],char:'\u2195\ufe0f',fitzpatrick_scale:!1,category:"symbols"},left_right_arrow:{keywords:["shape","direction","horizontal","sideways"],char:'\u2194\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrows_counterclockwise:{keywords:["blue-square","sync","cycle"],char:'\u{1f504}',fitzpatrick_scale:!1,category:"symbols"},arrow_right_hook:{keywords:["blue-square","return","rotate","direction"],char:'\u21aa\ufe0f',fitzpatrick_scale:!1,category:"symbols"},leftwards_arrow_with_hook:{keywords:["back","return","blue-square","undo","enter"],char:'\u21a9\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_heading_up:{keywords:["blue-square","direction","top"],char:'\u2934\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_heading_down:{keywords:["blue-square","direction","bottom"],char:'\u2935\ufe0f',fitzpatrick_scale:!1,category:"symbols"},hash:{keywords:["symbol","blue-square","twitter"],char:'#\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},information_source:{keywords:["blue-square","alphabet","letter"],char:'\u2139\ufe0f',fitzpatrick_scale:!1,category:"symbols"},abc:{keywords:["blue-square","alphabet"],char:'\u{1f524}',fitzpatrick_scale:!1,category:"symbols"},abcd:{keywords:["blue-square","alphabet"],char:'\u{1f521}',fitzpatrick_scale:!1,category:"symbols"},capital_abcd:{keywords:["alphabet","words","blue-square"],char:'\u{1f520}',fitzpatrick_scale:!1,category:"symbols"},symbols:{keywords:["blue-square","music","note","ampersand","percent","glyphs","characters"],char:'\u{1f523}',fitzpatrick_scale:!1,category:"symbols"},musical_note:{keywords:["score","tone","sound"],char:'\u{1f3b5}',fitzpatrick_scale:!1,category:"symbols"},notes:{keywords:["music","score"],char:'\u{1f3b6}',fitzpatrick_scale:!1,category:"symbols"},wavy_dash:{keywords:["draw","line","moustache","mustache","squiggle","scribble"],char:'\u3030\ufe0f',fitzpatrick_scale:!1,category:"symbols"},curly_loop:{keywords:["scribble","draw","shape","squiggle"],char:'\u27b0',fitzpatrick_scale:!1,category:"symbols"},heavy_check_mark:{keywords:["ok","nike","answer","yes","tick"],char:'\u2714\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrows_clockwise:{keywords:["sync","cycle","round","repeat"],char:'\u{1f503}',fitzpatrick_scale:!1,category:"symbols"},heavy_plus_sign:{keywords:["math","calculation","addition","more","increase"],char:'\u2795',fitzpatrick_scale:!1,category:"symbols"},heavy_minus_sign:{keywords:["math","calculation","subtract","less"],char:'\u2796',fitzpatrick_scale:!1,category:"symbols"},heavy_division_sign:{keywords:["divide","math","calculation"],char:'\u2797',fitzpatrick_scale:!1,category:"symbols"},heavy_multiplication_x:{keywords:["math","calculation"],char:'\u2716\ufe0f',fitzpatrick_scale:!1,category:"symbols"},infinity:{keywords:["forever"],char:'\u267e',fitzpatrick_scale:!1,category:"symbols"},heavy_dollar_sign:{keywords:["money","sales","payment","currency","buck"],char:'\u{1f4b2}',fitzpatrick_scale:!1,category:"symbols"},currency_exchange:{keywords:["money","sales","dollar","travel"],char:'\u{1f4b1}',fitzpatrick_scale:!1,category:"symbols"},copyright:{keywords:["ip","license","circle","law","legal"],char:'\xa9\ufe0f',fitzpatrick_scale:!1,category:"symbols"},registered:{keywords:["alphabet","circle"],char:'\xae\ufe0f',fitzpatrick_scale:!1,category:"symbols"},tm:{keywords:["trademark","brand","law","legal"],char:'\u2122\ufe0f',fitzpatrick_scale:!1,category:"symbols"},end:{keywords:["words","arrow"],char:'\u{1f51a}',fitzpatrick_scale:!1,category:"symbols"},back:{keywords:["arrow","words","return"],char:'\u{1f519}',fitzpatrick_scale:!1,category:"symbols"},on:{keywords:["arrow","words"],char:'\u{1f51b}',fitzpatrick_scale:!1,category:"symbols"},top:{keywords:["words","blue-square"],char:'\u{1f51d}',fitzpatrick_scale:!1,category:"symbols"},soon:{keywords:["arrow","words"],char:'\u{1f51c}',fitzpatrick_scale:!1,category:"symbols"},ballot_box_with_check:{keywords:["ok","agree","confirm","black-square","vote","election","yes","tick"],char:'\u2611\ufe0f',fitzpatrick_scale:!1,category:"symbols"},radio_button:{keywords:["input","old","music","circle"],char:'\u{1f518}',fitzpatrick_scale:!1,category:"symbols"},white_circle:{keywords:["shape","round"],char:'\u26aa',fitzpatrick_scale:!1,category:"symbols"},black_circle:{keywords:["shape","button","round"],char:'\u26ab',fitzpatrick_scale:!1,category:"symbols"},red_circle:{keywords:["shape","error","danger"],char:'\u{1f534}',fitzpatrick_scale:!1,category:"symbols"},large_blue_circle:{keywords:["shape","icon","button"],char:'\u{1f535}',fitzpatrick_scale:!1,category:"symbols"},small_orange_diamond:{keywords:["shape","jewel","gem"],char:'\u{1f538}',fitzpatrick_scale:!1,category:"symbols"},small_blue_diamond:{keywords:["shape","jewel","gem"],char:'\u{1f539}',fitzpatrick_scale:!1,category:"symbols"},large_orange_diamond:{keywords:["shape","jewel","gem"],char:'\u{1f536}',fitzpatrick_scale:!1,category:"symbols"},large_blue_diamond:{keywords:["shape","jewel","gem"],char:'\u{1f537}',fitzpatrick_scale:!1,category:"symbols"},small_red_triangle:{keywords:["shape","direction","up","top"],char:'\u{1f53a}',fitzpatrick_scale:!1,category:"symbols"},black_small_square:{keywords:["shape","icon"],char:'\u25aa\ufe0f',fitzpatrick_scale:!1,category:"symbols"},white_small_square:{keywords:["shape","icon"],char:'\u25ab\ufe0f',fitzpatrick_scale:!1,category:"symbols"},black_large_square:{keywords:["shape","icon","button"],char:'\u2b1b',fitzpatrick_scale:!1,category:"symbols"},white_large_square:{keywords:["shape","icon","stone","button"],char:'\u2b1c',fitzpatrick_scale:!1,category:"symbols"},small_red_triangle_down:{keywords:["shape","direction","bottom"],char:'\u{1f53b}',fitzpatrick_scale:!1,category:"symbols"},black_medium_square:{keywords:["shape","button","icon"],char:'\u25fc\ufe0f',fitzpatrick_scale:!1,category:"symbols"},white_medium_square:{keywords:["shape","stone","icon"],char:'\u25fb\ufe0f',fitzpatrick_scale:!1,category:"symbols"},black_medium_small_square:{keywords:["icon","shape","button"],char:'\u25fe',fitzpatrick_scale:!1,category:"symbols"},white_medium_small_square:{keywords:["shape","stone","icon","button"],char:'\u25fd',fitzpatrick_scale:!1,category:"symbols"},black_square_button:{keywords:["shape","input","frame"],char:'\u{1f532}',fitzpatrick_scale:!1,category:"symbols"},white_square_button:{keywords:["shape","input"],char:'\u{1f533}',fitzpatrick_scale:!1,category:"symbols"},speaker:{keywords:["sound","volume","silence","broadcast"],char:'\u{1f508}',fitzpatrick_scale:!1,category:"symbols"},sound:{keywords:["volume","speaker","broadcast"],char:'\u{1f509}',fitzpatrick_scale:!1,category:"symbols"},loud_sound:{keywords:["volume","noise","noisy","speaker","broadcast"],char:'\u{1f50a}',fitzpatrick_scale:!1,category:"symbols"},mute:{keywords:["sound","volume","silence","quiet"],char:'\u{1f507}',fitzpatrick_scale:!1,category:"symbols"},mega:{keywords:["sound","speaker","volume"],char:'\u{1f4e3}',fitzpatrick_scale:!1,category:"symbols"},loudspeaker:{keywords:["volume","sound"],char:'\u{1f4e2}',fitzpatrick_scale:!1,category:"symbols"},bell:{keywords:["sound","notification","christmas","xmas","chime"],char:'\u{1f514}',fitzpatrick_scale:!1,category:"symbols"},no_bell:{keywords:["sound","volume","mute","quiet","silent"],char:'\u{1f515}',fitzpatrick_scale:!1,category:"symbols"},black_joker:{keywords:["poker","cards","game","play","magic"],char:'\u{1f0cf}',fitzpatrick_scale:!1,category:"symbols"},mahjong:{keywords:["game","play","chinese","kanji"],char:'\u{1f004}',fitzpatrick_scale:!1,category:"symbols"},spades:{keywords:["poker","cards","suits","magic"],char:'\u2660\ufe0f',fitzpatrick_scale:!1,category:"symbols"},clubs:{keywords:["poker","cards","magic","suits"],char:'\u2663\ufe0f',fitzpatrick_scale:!1,category:"symbols"},hearts:{keywords:["poker","cards","magic","suits"],char:'\u2665\ufe0f',fitzpatrick_scale:!1,category:"symbols"},diamonds:{keywords:["poker","cards","magic","suits"],char:'\u2666\ufe0f',fitzpatrick_scale:!1,category:"symbols"},flower_playing_cards:{keywords:["game","sunset","red"],char:'\u{1f3b4}',fitzpatrick_scale:!1,category:"symbols"},thought_balloon:{keywords:["bubble","cloud","speech","thinking","dream"],char:'\u{1f4ad}',fitzpatrick_scale:!1,category:"symbols"},right_anger_bubble:{keywords:["caption","speech","thinking","mad"],char:'\u{1f5ef}',fitzpatrick_scale:!1,category:"symbols"},speech_balloon:{keywords:["bubble","words","message","talk","chatting"],char:'\u{1f4ac}',fitzpatrick_scale:!1,category:"symbols"},left_speech_bubble:{keywords:["words","message","talk","chatting"],char:'\u{1f5e8}',fitzpatrick_scale:!1,category:"symbols"},clock1:{keywords:["time","late","early","schedule"],char:'\u{1f550}',fitzpatrick_scale:!1,category:"symbols"},clock2:{keywords:["time","late","early","schedule"],char:'\u{1f551}',fitzpatrick_scale:!1,category:"symbols"},clock3:{keywords:["time","late","early","schedule"],char:'\u{1f552}',fitzpatrick_scale:!1,category:"symbols"},clock4:{keywords:["time","late","early","schedule"],char:'\u{1f553}',fitzpatrick_scale:!1,category:"symbols"},clock5:{keywords:["time","late","early","schedule"],char:'\u{1f554}',fitzpatrick_scale:!1,category:"symbols"},clock6:{keywords:["time","late","early","schedule","dawn","dusk"],char:'\u{1f555}',fitzpatrick_scale:!1,category:"symbols"},clock7:{keywords:["time","late","early","schedule"],char:'\u{1f556}',fitzpatrick_scale:!1,category:"symbols"},clock8:{keywords:["time","late","early","schedule"],char:'\u{1f557}',fitzpatrick_scale:!1,category:"symbols"},clock9:{keywords:["time","late","early","schedule"],char:'\u{1f558}',fitzpatrick_scale:!1,category:"symbols"},clock10:{keywords:["time","late","early","schedule"],char:'\u{1f559}',fitzpatrick_scale:!1,category:"symbols"},clock11:{keywords:["time","late","early","schedule"],char:'\u{1f55a}',fitzpatrick_scale:!1,category:"symbols"},clock12:{keywords:["time","noon","midnight","midday","late","early","schedule"],char:'\u{1f55b}',fitzpatrick_scale:!1,category:"symbols"},clock130:{keywords:["time","late","early","schedule"],char:'\u{1f55c}',fitzpatrick_scale:!1,category:"symbols"},clock230:{keywords:["time","late","early","schedule"],char:'\u{1f55d}',fitzpatrick_scale:!1,category:"symbols"},clock330:{keywords:["time","late","early","schedule"],char:'\u{1f55e}',fitzpatrick_scale:!1,category:"symbols"},clock430:{keywords:["time","late","early","schedule"],char:'\u{1f55f}',fitzpatrick_scale:!1,category:"symbols"},clock530:{keywords:["time","late","early","schedule"],char:'\u{1f560}',fitzpatrick_scale:!1,category:"symbols"},clock630:{keywords:["time","late","early","schedule"],char:'\u{1f561}',fitzpatrick_scale:!1,category:"symbols"},clock730:{keywords:["time","late","early","schedule"],char:'\u{1f562}',fitzpatrick_scale:!1,category:"symbols"},clock830:{keywords:["time","late","early","schedule"],char:'\u{1f563}',fitzpatrick_scale:!1,category:"symbols"},clock930:{keywords:["time","late","early","schedule"],char:'\u{1f564}',fitzpatrick_scale:!1,category:"symbols"},clock1030:{keywords:["time","late","early","schedule"],char:'\u{1f565}',fitzpatrick_scale:!1,category:"symbols"},clock1130:{keywords:["time","late","early","schedule"],char:'\u{1f566}',fitzpatrick_scale:!1,category:"symbols"},clock1230:{keywords:["time","late","early","schedule"],char:'\u{1f567}',fitzpatrick_scale:!1,category:"symbols"},afghanistan:{keywords:["af","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1eb}',fitzpatrick_scale:!1,category:"flags"},aland_islands:{keywords:["\xc5land","islands","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1fd}',fitzpatrick_scale:!1,category:"flags"},albania:{keywords:["al","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1f1}',fitzpatrick_scale:!1,category:"flags"},algeria:{keywords:["dz","flag","nation","country","banner"],char:'\u{1f1e9}\u{1f1ff}',fitzpatrick_scale:!1,category:"flags"},american_samoa:{keywords:["american","ws","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},andorra:{keywords:["ad","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1e9}',fitzpatrick_scale:!1,category:"flags"},angola:{keywords:["ao","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},anguilla:{keywords:["ai","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1ee}',fitzpatrick_scale:!1,category:"flags"},antarctica:{keywords:["aq","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1f6}',fitzpatrick_scale:!1,category:"flags"},antigua_barbuda:{keywords:["antigua","barbuda","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},argentina:{keywords:["ar","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},armenia:{keywords:["am","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},aruba:{keywords:["aw","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1fc}',fitzpatrick_scale:!1,category:"flags"},australia:{keywords:["au","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1fa}',fitzpatrick_scale:!1,category:"flags"},austria:{keywords:["at","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},azerbaijan:{keywords:["az","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1ff}',fitzpatrick_scale:!1,category:"flags"},bahamas:{keywords:["bs","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},bahrain:{keywords:["bh","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1ed}',fitzpatrick_scale:!1,category:"flags"},bangladesh:{keywords:["bd","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1e9}',fitzpatrick_scale:!1,category:"flags"},barbados:{keywords:["bb","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1e7}',fitzpatrick_scale:!1,category:"flags"},belarus:{keywords:["by","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1fe}',fitzpatrick_scale:!1,category:"flags"},belgium:{keywords:["be","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},belize:{keywords:["bz","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1ff}',fitzpatrick_scale:!1,category:"flags"},benin:{keywords:["bj","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1ef}',fitzpatrick_scale:!1,category:"flags"},bermuda:{keywords:["bm","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},bhutan:{keywords:["bt","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},bolivia:{keywords:["bo","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},caribbean_netherlands:{keywords:["bonaire","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1f6}',fitzpatrick_scale:!1,category:"flags"},bosnia_herzegovina:{keywords:["bosnia","herzegovina","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},botswana:{keywords:["bw","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1fc}',fitzpatrick_scale:!1,category:"flags"},brazil:{keywords:["br","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},british_indian_ocean_territory:{keywords:["british","indian","ocean","territory","flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},british_virgin_islands:{keywords:["british","virgin","islands","bvi","flag","nation","country","banner"],char:'\u{1f1fb}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},brunei:{keywords:["bn","darussalam","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},bulgaria:{keywords:["bg","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},burkina_faso:{keywords:["burkina","faso","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1eb}',fitzpatrick_scale:!1,category:"flags"},burundi:{keywords:["bi","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1ee}',fitzpatrick_scale:!1,category:"flags"},cape_verde:{keywords:["cabo","verde","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1fb}',fitzpatrick_scale:!1,category:"flags"},cambodia:{keywords:["kh","flag","nation","country","banner"],char:'\u{1f1f0}\u{1f1ed}',fitzpatrick_scale:!1,category:"flags"},cameroon:{keywords:["cm","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},canada:{keywords:["ca","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},canary_islands:{keywords:["canary","islands","flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1e8}',fitzpatrick_scale:!1,category:"flags"},cayman_islands:{keywords:["cayman","islands","flag","nation","country","banner"],char:'\u{1f1f0}\u{1f1fe}',fitzpatrick_scale:!1,category:"flags"},central_african_republic:{keywords:["central","african","republic","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1eb}',fitzpatrick_scale:!1,category:"flags"},chad:{keywords:["td","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1e9}',fitzpatrick_scale:!1,category:"flags"},chile:{keywords:["flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1f1}',fitzpatrick_scale:!1,category:"flags"},cn:{keywords:["china","chinese","prc","flag","country","nation","banner"],char:'\u{1f1e8}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},christmas_island:{keywords:["christmas","island","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1fd}',fitzpatrick_scale:!1,category:"flags"},cocos_islands:{keywords:["cocos","keeling","islands","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1e8}',fitzpatrick_scale:!1,category:"flags"},colombia:{keywords:["co","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},comoros:{keywords:["km","flag","nation","country","banner"],char:'\u{1f1f0}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},congo_brazzaville:{keywords:["congo","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},congo_kinshasa:{keywords:["congo","democratic","republic","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1e9}',fitzpatrick_scale:!1,category:"flags"},cook_islands:{keywords:["cook","islands","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1f0}',fitzpatrick_scale:!1,category:"flags"},costa_rica:{keywords:["costa","rica","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},croatia:{keywords:["hr","flag","nation","country","banner"],char:'\u{1f1ed}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},cuba:{keywords:["cu","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1fa}',fitzpatrick_scale:!1,category:"flags"},curacao:{keywords:["cura\xe7ao","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1fc}',fitzpatrick_scale:!1,category:"flags"},cyprus:{keywords:["cy","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1fe}',fitzpatrick_scale:!1,category:"flags"},czech_republic:{keywords:["cz","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1ff}',fitzpatrick_scale:!1,category:"flags"},denmark:{keywords:["dk","flag","nation","country","banner"],char:'\u{1f1e9}\u{1f1f0}',fitzpatrick_scale:!1,category:"flags"},djibouti:{keywords:["dj","flag","nation","country","banner"],char:'\u{1f1e9}\u{1f1ef}',fitzpatrick_scale:!1,category:"flags"},dominica:{keywords:["dm","flag","nation","country","banner"],char:'\u{1f1e9}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},dominican_republic:{keywords:["dominican","republic","flag","nation","country","banner"],char:'\u{1f1e9}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},ecuador:{keywords:["ec","flag","nation","country","banner"],char:'\u{1f1ea}\u{1f1e8}',fitzpatrick_scale:!1,category:"flags"},egypt:{keywords:["eg","flag","nation","country","banner"],char:'\u{1f1ea}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},el_salvador:{keywords:["el","salvador","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1fb}',fitzpatrick_scale:!1,category:"flags"},equatorial_guinea:{keywords:["equatorial","gn","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1f6}',fitzpatrick_scale:!1,category:"flags"},eritrea:{keywords:["er","flag","nation","country","banner"],char:'\u{1f1ea}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},estonia:{keywords:["ee","flag","nation","country","banner"],char:'\u{1f1ea}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},ethiopia:{keywords:["et","flag","nation","country","banner"],char:'\u{1f1ea}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},eu:{keywords:["european","union","flag","banner"],char:'\u{1f1ea}\u{1f1fa}',fitzpatrick_scale:!1,category:"flags"},falkland_islands:{keywords:["falkland","islands","malvinas","flag","nation","country","banner"],char:'\u{1f1eb}\u{1f1f0}',fitzpatrick_scale:!1,category:"flags"},faroe_islands:{keywords:["faroe","islands","flag","nation","country","banner"],char:'\u{1f1eb}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},fiji:{keywords:["fj","flag","nation","country","banner"],char:'\u{1f1eb}\u{1f1ef}',fitzpatrick_scale:!1,category:"flags"},finland:{keywords:["fi","flag","nation","country","banner"],char:'\u{1f1eb}\u{1f1ee}',fitzpatrick_scale:!1,category:"flags"},fr:{keywords:["banner","flag","nation","france","french","country"],char:'\u{1f1eb}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},french_guiana:{keywords:["french","guiana","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1eb}',fitzpatrick_scale:!1,category:"flags"},french_polynesia:{keywords:["french","polynesia","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1eb}',fitzpatrick_scale:!1,category:"flags"},french_southern_territories:{keywords:["french","southern","territories","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1eb}',fitzpatrick_scale:!1,category:"flags"},gabon:{keywords:["ga","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},gambia:{keywords:["gm","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},georgia:{keywords:["ge","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},de:{keywords:["german","nation","flag","country","banner"],char:'\u{1f1e9}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},ghana:{keywords:["gh","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1ed}',fitzpatrick_scale:!1,category:"flags"},gibraltar:{keywords:["gi","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1ee}',fitzpatrick_scale:!1,category:"flags"},greece:{keywords:["gr","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},greenland:{keywords:["gl","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1f1}',fitzpatrick_scale:!1,category:"flags"},grenada:{keywords:["gd","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1e9}',fitzpatrick_scale:!1,category:"flags"},guadeloupe:{keywords:["gp","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1f5}',fitzpatrick_scale:!1,category:"flags"},guam:{keywords:["gu","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1fa}',fitzpatrick_scale:!1,category:"flags"},guatemala:{keywords:["gt","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},guernsey:{keywords:["gg","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},guinea:{keywords:["gn","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},guinea_bissau:{keywords:["gw","bissau","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1fc}',fitzpatrick_scale:!1,category:"flags"},guyana:{keywords:["gy","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1fe}',fitzpatrick_scale:!1,category:"flags"},haiti:{keywords:["ht","flag","nation","country","banner"],char:'\u{1f1ed}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},honduras:{keywords:["hn","flag","nation","country","banner"],char:'\u{1f1ed}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},hong_kong:{keywords:["hong","kong","flag","nation","country","banner"],char:'\u{1f1ed}\u{1f1f0}',fitzpatrick_scale:!1,category:"flags"},hungary:{keywords:["hu","flag","nation","country","banner"],char:'\u{1f1ed}\u{1f1fa}',fitzpatrick_scale:!1,category:"flags"},iceland:{keywords:["is","flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},india:{keywords:["in","flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},indonesia:{keywords:["flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1e9}',fitzpatrick_scale:!1,category:"flags"},iran:{keywords:["iran,","islamic","republic","flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},iraq:{keywords:["iq","flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1f6}',fitzpatrick_scale:!1,category:"flags"},ireland:{keywords:["ie","flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},isle_of_man:{keywords:["isle","man","flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},israel:{keywords:["il","flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1f1}',fitzpatrick_scale:!1,category:"flags"},it:{keywords:["italy","flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},cote_divoire:{keywords:["ivory","coast","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1ee}',fitzpatrick_scale:!1,category:"flags"},jamaica:{keywords:["jm","flag","nation","country","banner"],char:'\u{1f1ef}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},jp:{keywords:["japanese","nation","flag","country","banner"],char:'\u{1f1ef}\u{1f1f5}',fitzpatrick_scale:!1,category:"flags"},jersey:{keywords:["je","flag","nation","country","banner"],char:'\u{1f1ef}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},jordan:{keywords:["jo","flag","nation","country","banner"],char:'\u{1f1ef}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},kazakhstan:{keywords:["kz","flag","nation","country","banner"],char:'\u{1f1f0}\u{1f1ff}',fitzpatrick_scale:!1,category:"flags"},kenya:{keywords:["ke","flag","nation","country","banner"],char:'\u{1f1f0}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},kiribati:{keywords:["ki","flag","nation","country","banner"],char:'\u{1f1f0}\u{1f1ee}',fitzpatrick_scale:!1,category:"flags"},kosovo:{keywords:["xk","flag","nation","country","banner"],char:'\u{1f1fd}\u{1f1f0}',fitzpatrick_scale:!1,category:"flags"},kuwait:{keywords:["kw","flag","nation","country","banner"],char:'\u{1f1f0}\u{1f1fc}',fitzpatrick_scale:!1,category:"flags"},kyrgyzstan:{keywords:["kg","flag","nation","country","banner"],char:'\u{1f1f0}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},laos:{keywords:["lao","democratic","republic","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},latvia:{keywords:["lv","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1fb}',fitzpatrick_scale:!1,category:"flags"},lebanon:{keywords:["lb","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1e7}',fitzpatrick_scale:!1,category:"flags"},lesotho:{keywords:["ls","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},liberia:{keywords:["lr","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},libya:{keywords:["ly","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1fe}',fitzpatrick_scale:!1,category:"flags"},liechtenstein:{keywords:["li","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1ee}',fitzpatrick_scale:!1,category:"flags"},lithuania:{keywords:["lt","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},luxembourg:{keywords:["lu","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1fa}',fitzpatrick_scale:!1,category:"flags"},macau:{keywords:["macao","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},macedonia:{keywords:["macedonia,","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1f0}',fitzpatrick_scale:!1,category:"flags"},madagascar:{keywords:["mg","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},malawi:{keywords:["mw","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1fc}',fitzpatrick_scale:!1,category:"flags"},malaysia:{keywords:["my","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1fe}',fitzpatrick_scale:!1,category:"flags"},maldives:{keywords:["mv","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1fb}',fitzpatrick_scale:!1,category:"flags"},mali:{keywords:["ml","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1f1}',fitzpatrick_scale:!1,category:"flags"},malta:{keywords:["mt","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},marshall_islands:{keywords:["marshall","islands","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1ed}',fitzpatrick_scale:!1,category:"flags"},martinique:{keywords:["mq","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1f6}',fitzpatrick_scale:!1,category:"flags"},mauritania:{keywords:["mr","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},mauritius:{keywords:["mu","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1fa}',fitzpatrick_scale:!1,category:"flags"},mayotte:{keywords:["yt","flag","nation","country","banner"],char:'\u{1f1fe}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},mexico:{keywords:["mx","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1fd}',fitzpatrick_scale:!1,category:"flags"},micronesia:{keywords:["micronesia,","federated","states","flag","nation","country","banner"],char:'\u{1f1eb}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},moldova:{keywords:["moldova,","republic","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1e9}',fitzpatrick_scale:!1,category:"flags"},monaco:{keywords:["mc","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1e8}',fitzpatrick_scale:!1,category:"flags"},mongolia:{keywords:["mn","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},montenegro:{keywords:["me","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},montserrat:{keywords:["ms","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},morocco:{keywords:["ma","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},mozambique:{keywords:["mz","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1ff}',fitzpatrick_scale:!1,category:"flags"},myanmar:{keywords:["mm","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},namibia:{keywords:["na","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},nauru:{keywords:["nr","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},nepal:{keywords:["np","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1f5}',fitzpatrick_scale:!1,category:"flags"},netherlands:{keywords:["nl","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1f1}',fitzpatrick_scale:!1,category:"flags"},new_caledonia:{keywords:["new","caledonia","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1e8}',fitzpatrick_scale:!1,category:"flags"},new_zealand:{keywords:["new","zealand","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1ff}',fitzpatrick_scale:!1,category:"flags"},nicaragua:{keywords:["ni","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1ee}',fitzpatrick_scale:!1,category:"flags"},niger:{keywords:["ne","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},nigeria:{keywords:["flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},niue:{keywords:["nu","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1fa}',fitzpatrick_scale:!1,category:"flags"},norfolk_island:{keywords:["norfolk","island","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1eb}',fitzpatrick_scale:!1,category:"flags"},northern_mariana_islands:{keywords:["northern","mariana","islands","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1f5}',fitzpatrick_scale:!1,category:"flags"},north_korea:{keywords:["north","korea","nation","flag","country","banner"],char:'\u{1f1f0}\u{1f1f5}',fitzpatrick_scale:!1,category:"flags"},norway:{keywords:["no","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},oman:{keywords:["om_symbol","flag","nation","country","banner"],char:'\u{1f1f4}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},pakistan:{keywords:["pk","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1f0}',fitzpatrick_scale:!1,category:"flags"},palau:{keywords:["pw","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1fc}',fitzpatrick_scale:!1,category:"flags"},palestinian_territories:{keywords:["palestine","palestinian","territories","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},panama:{keywords:["pa","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},papua_new_guinea:{keywords:["papua","new","guinea","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},paraguay:{keywords:["py","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1fe}',fitzpatrick_scale:!1,category:"flags"},peru:{keywords:["pe","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},philippines:{keywords:["ph","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1ed}',fitzpatrick_scale:!1,category:"flags"},pitcairn_islands:{keywords:["pitcairn","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},poland:{keywords:["pl","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1f1}',fitzpatrick_scale:!1,category:"flags"},portugal:{keywords:["pt","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},puerto_rico:{keywords:["puerto","rico","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},qatar:{keywords:["qa","flag","nation","country","banner"],char:'\u{1f1f6}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},reunion:{keywords:["r\xe9union","flag","nation","country","banner"],char:'\u{1f1f7}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},romania:{keywords:["ro","flag","nation","country","banner"],char:'\u{1f1f7}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},ru:{keywords:["russian","federation","flag","nation","country","banner"],char:'\u{1f1f7}\u{1f1fa}',fitzpatrick_scale:!1,category:"flags"},rwanda:{keywords:["rw","flag","nation","country","banner"],char:'\u{1f1f7}\u{1f1fc}',fitzpatrick_scale:!1,category:"flags"},st_barthelemy:{keywords:["saint","barth\xe9lemy","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1f1}',fitzpatrick_scale:!1,category:"flags"},st_helena:{keywords:["saint","helena","ascension","tristan","cunha","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1ed}',fitzpatrick_scale:!1,category:"flags"},st_kitts_nevis:{keywords:["saint","kitts","nevis","flag","nation","country","banner"],char:'\u{1f1f0}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},st_lucia:{keywords:["saint","lucia","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1e8}',fitzpatrick_scale:!1,category:"flags"},st_pierre_miquelon:{keywords:["saint","pierre","miquelon","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},st_vincent_grenadines:{keywords:["saint","vincent","grenadines","flag","nation","country","banner"],char:'\u{1f1fb}\u{1f1e8}',fitzpatrick_scale:!1,category:"flags"},samoa:{keywords:["ws","flag","nation","country","banner"],char:'\u{1f1fc}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},san_marino:{keywords:["san","marino","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},sao_tome_principe:{keywords:["sao","tome","principe","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},saudi_arabia:{keywords:["flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},senegal:{keywords:["sn","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},serbia:{keywords:["rs","flag","nation","country","banner"],char:'\u{1f1f7}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},seychelles:{keywords:["sc","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1e8}',fitzpatrick_scale:!1,category:"flags"},sierra_leone:{keywords:["sierra","leone","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1f1}',fitzpatrick_scale:!1,category:"flags"},singapore:{keywords:["sg","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},sint_maarten:{keywords:["sint","maarten","dutch","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1fd}',fitzpatrick_scale:!1,category:"flags"},slovakia:{keywords:["sk","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1f0}',fitzpatrick_scale:!1,category:"flags"},slovenia:{keywords:["si","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1ee}',fitzpatrick_scale:!1,category:"flags"},solomon_islands:{keywords:["solomon","islands","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1e7}',fitzpatrick_scale:!1,category:"flags"},somalia:{keywords:["so","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},south_africa:{keywords:["south","africa","flag","nation","country","banner"],char:'\u{1f1ff}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},south_georgia_south_sandwich_islands:{keywords:["south","georgia","sandwich","islands","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},kr:{keywords:["south","korea","nation","flag","country","banner"],char:'\u{1f1f0}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},south_sudan:{keywords:["south","sd","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},es:{keywords:["spain","flag","nation","country","banner"],char:'\u{1f1ea}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},sri_lanka:{keywords:["sri","lanka","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1f0}',fitzpatrick_scale:!1,category:"flags"},sudan:{keywords:["sd","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1e9}',fitzpatrick_scale:!1,category:"flags"},suriname:{keywords:["sr","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},swaziland:{keywords:["sz","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1ff}',fitzpatrick_scale:!1,category:"flags"},sweden:{keywords:["se","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},switzerland:{keywords:["ch","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1ed}',fitzpatrick_scale:!1,category:"flags"},syria:{keywords:["syrian","arab","republic","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1fe}',fitzpatrick_scale:!1,category:"flags"},taiwan:{keywords:["tw","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1fc}',fitzpatrick_scale:!1,category:"flags"},tajikistan:{keywords:["tj","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1ef}',fitzpatrick_scale:!1,category:"flags"},tanzania:{keywords:["tanzania,","united","republic","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1ff}',fitzpatrick_scale:!1,category:"flags"},thailand:{keywords:["th","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1ed}',fitzpatrick_scale:!1,category:"flags"},timor_leste:{keywords:["timor","leste","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1f1}',fitzpatrick_scale:!1,category:"flags"},togo:{keywords:["tg","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},tokelau:{keywords:["tk","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1f0}',fitzpatrick_scale:!1,category:"flags"},tonga:{keywords:["to","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},trinidad_tobago:{keywords:["trinidad","tobago","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},tunisia:{keywords:["tn","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},tr:{keywords:["turkey","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},turkmenistan:{keywords:["flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},turks_caicos_islands:{keywords:["turks","caicos","islands","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1e8}',fitzpatrick_scale:!1,category:"flags"},tuvalu:{keywords:["flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1fb}',fitzpatrick_scale:!1,category:"flags"},uganda:{keywords:["ug","flag","nation","country","banner"],char:'\u{1f1fa}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},ukraine:{keywords:["ua","flag","nation","country","banner"],char:'\u{1f1fa}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},united_arab_emirates:{keywords:["united","arab","emirates","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},uk:{keywords:["united","kingdom","great","britain","northern","ireland","flag","nation","country","banner","british","UK","english","england","union jack"],char:'\u{1f1ec}\u{1f1e7}',fitzpatrick_scale:!1,category:"flags"},england:{keywords:["flag","english"],char:'\u{1f3f4}\u{e0067}\u{e0062}\u{e0065}\u{e006e}\u{e0067}\u{e007f}',fitzpatrick_scale:!1,category:"flags"},scotland:{keywords:["flag","scottish"],char:'\u{1f3f4}\u{e0067}\u{e0062}\u{e0073}\u{e0063}\u{e0074}\u{e007f}',fitzpatrick_scale:!1,category:"flags"},wales:{keywords:["flag","welsh"],char:'\u{1f3f4}\u{e0067}\u{e0062}\u{e0077}\u{e006c}\u{e0073}\u{e007f}',fitzpatrick_scale:!1,category:"flags"},us:{keywords:["united","states","america","flag","nation","country","banner"],char:'\u{1f1fa}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},us_virgin_islands:{keywords:["virgin","islands","us","flag","nation","country","banner"],char:'\u{1f1fb}\u{1f1ee}',fitzpatrick_scale:!1,category:"flags"},uruguay:{keywords:["uy","flag","nation","country","banner"],char:'\u{1f1fa}\u{1f1fe}',fitzpatrick_scale:!1,category:"flags"},uzbekistan:{keywords:["uz","flag","nation","country","banner"],char:'\u{1f1fa}\u{1f1ff}',fitzpatrick_scale:!1,category:"flags"},vanuatu:{keywords:["vu","flag","nation","country","banner"],char:'\u{1f1fb}\u{1f1fa}',fitzpatrick_scale:!1,category:"flags"},vatican_city:{keywords:["vatican","city","flag","nation","country","banner"],char:'\u{1f1fb}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},venezuela:{keywords:["ve","bolivarian","republic","flag","nation","country","banner"],char:'\u{1f1fb}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},vietnam:{keywords:["viet","nam","flag","nation","country","banner"],char:'\u{1f1fb}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},wallis_futuna:{keywords:["wallis","futuna","flag","nation","country","banner"],char:'\u{1f1fc}\u{1f1eb}',fitzpatrick_scale:!1,category:"flags"},western_sahara:{keywords:["western","sahara","flag","nation","country","banner"],char:'\u{1f1ea}\u{1f1ed}',fitzpatrick_scale:!1,category:"flags"},yemen:{keywords:["ye","flag","nation","country","banner"],char:'\u{1f1fe}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},zambia:{keywords:["zm","flag","nation","country","banner"],char:'\u{1f1ff}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},zimbabwe:{keywords:["zw","flag","nation","country","banner"],char:'\u{1f1ff}\u{1f1fc}',fitzpatrick_scale:!1,category:"flags"},united_nations:{keywords:["un","flag","banner"],char:'\u{1f1fa}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},pirate_flag:{keywords:["skull","crossbones","flag","banner"],char:'\u{1f3f4}\u200d\u2620\ufe0f',fitzpatrick_scale:!1,category:"flags"}}); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/emoticons/js/emojis.js b/public/resource/tinymce/plugins/emoticons/js/emojis.js new file mode 100644 index 0000000..88455e9 --- /dev/null +++ b/public/resource/tinymce/plugins/emoticons/js/emojis.js @@ -0,0 +1 @@ +window.tinymce.Resource.add("tinymce.plugins.emoticons",{grinning:{keywords:["face","smile","happy","joy",":D","grin"],char:"😀",fitzpatrick_scale:false,category:"people"},grimacing:{keywords:["face","grimace","teeth"],char:"😬",fitzpatrick_scale:false,category:"people"},grin:{keywords:["face","happy","smile","joy","kawaii"],char:"😁",fitzpatrick_scale:false,category:"people"},joy:{keywords:["face","cry","tears","weep","happy","happytears","haha"],char:"😂",fitzpatrick_scale:false,category:"people"},rofl:{keywords:["face","rolling","floor","laughing","lol","haha"],char:"🤣",fitzpatrick_scale:false,category:"people"},partying:{keywords:["face","celebration","woohoo"],char:"🥳",fitzpatrick_scale:false,category:"people"},smiley:{keywords:["face","happy","joy","haha",":D",":)","smile","funny"],char:"😃",fitzpatrick_scale:false,category:"people"},smile:{keywords:["face","happy","joy","funny","haha","laugh","like",":D",":)"],char:"😄",fitzpatrick_scale:false,category:"people"},sweat_smile:{keywords:["face","hot","happy","laugh","sweat","smile","relief"],char:"😅",fitzpatrick_scale:false,category:"people"},laughing:{keywords:["happy","joy","lol","satisfied","haha","face","glad","XD","laugh"],char:"😆",fitzpatrick_scale:false,category:"people"},innocent:{keywords:["face","angel","heaven","halo"],char:"😇",fitzpatrick_scale:false,category:"people"},wink:{keywords:["face","happy","mischievous","secret",";)","smile","eye"],char:"😉",fitzpatrick_scale:false,category:"people"},blush:{keywords:["face","smile","happy","flushed","crush","embarrassed","shy","joy"],char:"😊",fitzpatrick_scale:false,category:"people"},slightly_smiling_face:{keywords:["face","smile"],char:"🙂",fitzpatrick_scale:false,category:"people"},upside_down_face:{keywords:["face","flipped","silly","smile"],char:"🙃",fitzpatrick_scale:false,category:"people"},relaxed:{keywords:["face","blush","massage","happiness"],char:"☺️",fitzpatrick_scale:false,category:"people"},yum:{keywords:["happy","joy","tongue","smile","face","silly","yummy","nom","delicious","savouring"],char:"😋",fitzpatrick_scale:false,category:"people"},relieved:{keywords:["face","relaxed","phew","massage","happiness"],char:"😌",fitzpatrick_scale:false,category:"people"},heart_eyes:{keywords:["face","love","like","affection","valentines","infatuation","crush","heart"],char:"😍",fitzpatrick_scale:false,category:"people"},smiling_face_with_three_hearts:{keywords:["face","love","like","affection","valentines","infatuation","crush","hearts","adore"],char:"🥰",fitzpatrick_scale:false,category:"people"},kissing_heart:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:"😘",fitzpatrick_scale:false,category:"people"},kissing:{keywords:["love","like","face","3","valentines","infatuation","kiss"],char:"😗",fitzpatrick_scale:false,category:"people"},kissing_smiling_eyes:{keywords:["face","affection","valentines","infatuation","kiss"],char:"😙",fitzpatrick_scale:false,category:"people"},kissing_closed_eyes:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:"😚",fitzpatrick_scale:false,category:"people"},stuck_out_tongue_winking_eye:{keywords:["face","prank","childish","playful","mischievous","smile","wink","tongue"],char:"😜",fitzpatrick_scale:false,category:"people"},zany:{keywords:["face","goofy","crazy"],char:"🤪",fitzpatrick_scale:false,category:"people"},raised_eyebrow:{keywords:["face","distrust","scepticism","disapproval","disbelief","surprise"],char:"🤨",fitzpatrick_scale:false,category:"people"},monocle:{keywords:["face","stuffy","wealthy"],char:"🧐",fitzpatrick_scale:false,category:"people"},stuck_out_tongue_closed_eyes:{keywords:["face","prank","playful","mischievous","smile","tongue"],char:"😝",fitzpatrick_scale:false,category:"people"},stuck_out_tongue:{keywords:["face","prank","childish","playful","mischievous","smile","tongue"],char:"😛",fitzpatrick_scale:false,category:"people"},money_mouth_face:{keywords:["face","rich","dollar","money"],char:"🤑",fitzpatrick_scale:false,category:"people"},nerd_face:{keywords:["face","nerdy","geek","dork"],char:"🤓",fitzpatrick_scale:false,category:"people"},sunglasses:{keywords:["face","cool","smile","summer","beach","sunglass"],char:"😎",fitzpatrick_scale:false,category:"people"},star_struck:{keywords:["face","smile","starry","eyes","grinning"],char:"🤩",fitzpatrick_scale:false,category:"people"},clown_face:{keywords:["face"],char:"🤡",fitzpatrick_scale:false,category:"people"},cowboy_hat_face:{keywords:["face","cowgirl","hat"],char:"🤠",fitzpatrick_scale:false,category:"people"},hugs:{keywords:["face","smile","hug"],char:"🤗",fitzpatrick_scale:false,category:"people"},smirk:{keywords:["face","smile","mean","prank","smug","sarcasm"],char:"😏",fitzpatrick_scale:false,category:"people"},no_mouth:{keywords:["face","hellokitty"],char:"😶",fitzpatrick_scale:false,category:"people"},neutral_face:{keywords:["indifference","meh",":|","neutral"],char:"😐",fitzpatrick_scale:false,category:"people"},expressionless:{keywords:["face","indifferent","-_-","meh","deadpan"],char:"😑",fitzpatrick_scale:false,category:"people"},unamused:{keywords:["indifference","bored","straight face","serious","sarcasm","unimpressed","skeptical","dubious","side_eye"],char:"😒",fitzpatrick_scale:false,category:"people"},roll_eyes:{keywords:["face","eyeroll","frustrated"],char:"🙄",fitzpatrick_scale:false,category:"people"},thinking:{keywords:["face","hmmm","think","consider"],char:"🤔",fitzpatrick_scale:false,category:"people"},lying_face:{keywords:["face","lie","pinocchio"],char:"🤥",fitzpatrick_scale:false,category:"people"},hand_over_mouth:{keywords:["face","whoops","shock","surprise"],char:"🤭",fitzpatrick_scale:false,category:"people"},shushing:{keywords:["face","quiet","shhh"],char:"🤫",fitzpatrick_scale:false,category:"people"},symbols_over_mouth:{keywords:["face","swearing","cursing","cussing","profanity","expletive"],char:"🤬",fitzpatrick_scale:false,category:"people"},exploding_head:{keywords:["face","shocked","mind","blown"],char:"🤯",fitzpatrick_scale:false,category:"people"},flushed:{keywords:["face","blush","shy","flattered"],char:"😳",fitzpatrick_scale:false,category:"people"},disappointed:{keywords:["face","sad","upset","depressed",":("],char:"😞",fitzpatrick_scale:false,category:"people"},worried:{keywords:["face","concern","nervous",":("],char:"😟",fitzpatrick_scale:false,category:"people"},angry:{keywords:["mad","face","annoyed","frustrated"],char:"😠",fitzpatrick_scale:false,category:"people"},rage:{keywords:["angry","mad","hate","despise"],char:"😡",fitzpatrick_scale:false,category:"people"},pensive:{keywords:["face","sad","depressed","upset"],char:"😔",fitzpatrick_scale:false,category:"people"},confused:{keywords:["face","indifference","huh","weird","hmmm",":/"],char:"😕",fitzpatrick_scale:false,category:"people"},slightly_frowning_face:{keywords:["face","frowning","disappointed","sad","upset"],char:"🙁",fitzpatrick_scale:false,category:"people"},frowning_face:{keywords:["face","sad","upset","frown"],char:"☹",fitzpatrick_scale:false,category:"people"},persevere:{keywords:["face","sick","no","upset","oops"],char:"😣",fitzpatrick_scale:false,category:"people"},confounded:{keywords:["face","confused","sick","unwell","oops",":S"],char:"😖",fitzpatrick_scale:false,category:"people"},tired_face:{keywords:["sick","whine","upset","frustrated"],char:"😫",fitzpatrick_scale:false,category:"people"},weary:{keywords:["face","tired","sleepy","sad","frustrated","upset"],char:"😩",fitzpatrick_scale:false,category:"people"},pleading:{keywords:["face","begging","mercy"],char:"🥺",fitzpatrick_scale:false,category:"people"},triumph:{keywords:["face","gas","phew","proud","pride"],char:"😤",fitzpatrick_scale:false,category:"people"},open_mouth:{keywords:["face","surprise","impressed","wow","whoa",":O"],char:"😮",fitzpatrick_scale:false,category:"people"},scream:{keywords:["face","munch","scared","omg"],char:"😱",fitzpatrick_scale:false,category:"people"},fearful:{keywords:["face","scared","terrified","nervous","oops","huh"],char:"😨",fitzpatrick_scale:false,category:"people"},cold_sweat:{keywords:["face","nervous","sweat"],char:"😰",fitzpatrick_scale:false,category:"people"},hushed:{keywords:["face","woo","shh"],char:"😯",fitzpatrick_scale:false,category:"people"},frowning:{keywords:["face","aw","what"],char:"😦",fitzpatrick_scale:false,category:"people"},anguished:{keywords:["face","stunned","nervous"],char:"😧",fitzpatrick_scale:false,category:"people"},cry:{keywords:["face","tears","sad","depressed","upset",":'("],char:"😢",fitzpatrick_scale:false,category:"people"},disappointed_relieved:{keywords:["face","phew","sweat","nervous"],char:"😥",fitzpatrick_scale:false,category:"people"},drooling_face:{keywords:["face"],char:"🤤",fitzpatrick_scale:false,category:"people"},sleepy:{keywords:["face","tired","rest","nap"],char:"😪",fitzpatrick_scale:false,category:"people"},sweat:{keywords:["face","hot","sad","tired","exercise"],char:"😓",fitzpatrick_scale:false,category:"people"},hot:{keywords:["face","feverish","heat","red","sweating"],char:"🥵",fitzpatrick_scale:false,category:"people"},cold:{keywords:["face","blue","freezing","frozen","frostbite","icicles"],char:"🥶",fitzpatrick_scale:false,category:"people"},sob:{keywords:["face","cry","tears","sad","upset","depressed"],char:"😭",fitzpatrick_scale:false,category:"people"},dizzy_face:{keywords:["spent","unconscious","xox","dizzy"],char:"😵",fitzpatrick_scale:false,category:"people"},astonished:{keywords:["face","xox","surprised","poisoned"],char:"😲",fitzpatrick_scale:false,category:"people"},zipper_mouth_face:{keywords:["face","sealed","zipper","secret"],char:"🤐",fitzpatrick_scale:false,category:"people"},nauseated_face:{keywords:["face","vomit","gross","green","sick","throw up","ill"],char:"🤢",fitzpatrick_scale:false,category:"people"},sneezing_face:{keywords:["face","gesundheit","sneeze","sick","allergy"],char:"🤧",fitzpatrick_scale:false,category:"people"},vomiting:{keywords:["face","sick"],char:"🤮",fitzpatrick_scale:false,category:"people"},mask:{keywords:["face","sick","ill","disease"],char:"😷",fitzpatrick_scale:false,category:"people"},face_with_thermometer:{keywords:["sick","temperature","thermometer","cold","fever"],char:"🤒",fitzpatrick_scale:false,category:"people"},face_with_head_bandage:{keywords:["injured","clumsy","bandage","hurt"],char:"🤕",fitzpatrick_scale:false,category:"people"},woozy:{keywords:["face","dizzy","intoxicated","tipsy","wavy"],char:"🥴",fitzpatrick_scale:false,category:"people"},sleeping:{keywords:["face","tired","sleepy","night","zzz"],char:"😴",fitzpatrick_scale:false,category:"people"},zzz:{keywords:["sleepy","tired","dream"],char:"💤",fitzpatrick_scale:false,category:"people"},poop:{keywords:["hankey","shitface","fail","turd","shit"],char:"💩",fitzpatrick_scale:false,category:"people"},smiling_imp:{keywords:["devil","horns"],char:"😈",fitzpatrick_scale:false,category:"people"},imp:{keywords:["devil","angry","horns"],char:"👿",fitzpatrick_scale:false,category:"people"},japanese_ogre:{keywords:["monster","red","mask","halloween","scary","creepy","devil","demon","japanese","ogre"],char:"👹",fitzpatrick_scale:false,category:"people"},japanese_goblin:{keywords:["red","evil","mask","monster","scary","creepy","japanese","goblin"],char:"👺",fitzpatrick_scale:false,category:"people"},skull:{keywords:["dead","skeleton","creepy","death"],char:"💀",fitzpatrick_scale:false,category:"people"},ghost:{keywords:["halloween","spooky","scary"],char:"👻",fitzpatrick_scale:false,category:"people"},alien:{keywords:["UFO","paul","weird","outer_space"],char:"👽",fitzpatrick_scale:false,category:"people"},robot:{keywords:["computer","machine","bot"],char:"🤖",fitzpatrick_scale:false,category:"people"},smiley_cat:{keywords:["animal","cats","happy","smile"],char:"😺",fitzpatrick_scale:false,category:"people"},smile_cat:{keywords:["animal","cats","smile"],char:"😸",fitzpatrick_scale:false,category:"people"},joy_cat:{keywords:["animal","cats","haha","happy","tears"],char:"😹",fitzpatrick_scale:false,category:"people"},heart_eyes_cat:{keywords:["animal","love","like","affection","cats","valentines","heart"],char:"😻",fitzpatrick_scale:false,category:"people"},smirk_cat:{keywords:["animal","cats","smirk"],char:"😼",fitzpatrick_scale:false,category:"people"},kissing_cat:{keywords:["animal","cats","kiss"],char:"😽",fitzpatrick_scale:false,category:"people"},scream_cat:{keywords:["animal","cats","munch","scared","scream"],char:"🙀",fitzpatrick_scale:false,category:"people"},crying_cat_face:{keywords:["animal","tears","weep","sad","cats","upset","cry"],char:"😿",fitzpatrick_scale:false,category:"people"},pouting_cat:{keywords:["animal","cats"],char:"😾",fitzpatrick_scale:false,category:"people"},palms_up:{keywords:["hands","gesture","cupped","prayer"],char:"🤲",fitzpatrick_scale:true,category:"people"},raised_hands:{keywords:["gesture","hooray","yea","celebration","hands"],char:"🙌",fitzpatrick_scale:true,category:"people"},clap:{keywords:["hands","praise","applause","congrats","yay"],char:"👏",fitzpatrick_scale:true,category:"people"},wave:{keywords:["hands","gesture","goodbye","solong","farewell","hello","hi","palm"],char:"👋",fitzpatrick_scale:true,category:"people"},call_me_hand:{keywords:["hands","gesture"],char:"🤙",fitzpatrick_scale:true,category:"people"},"+1":{keywords:["thumbsup","yes","awesome","good","agree","accept","cool","hand","like"],char:"👍",fitzpatrick_scale:true,category:"people"},"-1":{keywords:["thumbsdown","no","dislike","hand"],char:"👎",fitzpatrick_scale:true,category:"people"},facepunch:{keywords:["angry","violence","fist","hit","attack","hand"],char:"👊",fitzpatrick_scale:true,category:"people"},fist:{keywords:["fingers","hand","grasp"],char:"✊",fitzpatrick_scale:true,category:"people"},fist_left:{keywords:["hand","fistbump"],char:"🤛",fitzpatrick_scale:true,category:"people"},fist_right:{keywords:["hand","fistbump"],char:"🤜",fitzpatrick_scale:true,category:"people"},v:{keywords:["fingers","ohyeah","hand","peace","victory","two"],char:"✌",fitzpatrick_scale:true,category:"people"},ok_hand:{keywords:["fingers","limbs","perfect","ok","okay"],char:"👌",fitzpatrick_scale:true,category:"people"},raised_hand:{keywords:["fingers","stop","highfive","palm","ban"],char:"✋",fitzpatrick_scale:true,category:"people"},raised_back_of_hand:{keywords:["fingers","raised","backhand"],char:"🤚",fitzpatrick_scale:true,category:"people"},open_hands:{keywords:["fingers","butterfly","hands","open"],char:"👐",fitzpatrick_scale:true,category:"people"},muscle:{keywords:["arm","flex","hand","summer","strong","biceps"],char:"💪",fitzpatrick_scale:true,category:"people"},pray:{keywords:["please","hope","wish","namaste","highfive"],char:"🙏",fitzpatrick_scale:true,category:"people"},foot:{keywords:["kick","stomp"],char:"🦶",fitzpatrick_scale:true,category:"people"},leg:{keywords:["kick","limb"],char:"🦵",fitzpatrick_scale:true,category:"people"},handshake:{keywords:["agreement","shake"],char:"🤝",fitzpatrick_scale:false,category:"people"},point_up:{keywords:["hand","fingers","direction","up"],char:"☝",fitzpatrick_scale:true,category:"people"},point_up_2:{keywords:["fingers","hand","direction","up"],char:"👆",fitzpatrick_scale:true,category:"people"},point_down:{keywords:["fingers","hand","direction","down"],char:"👇",fitzpatrick_scale:true,category:"people"},point_left:{keywords:["direction","fingers","hand","left"],char:"👈",fitzpatrick_scale:true,category:"people"},point_right:{keywords:["fingers","hand","direction","right"],char:"👉",fitzpatrick_scale:true,category:"people"},fu:{keywords:["hand","fingers","rude","middle","flipping"],char:"🖕",fitzpatrick_scale:true,category:"people"},raised_hand_with_fingers_splayed:{keywords:["hand","fingers","palm"],char:"🖐",fitzpatrick_scale:true,category:"people"},love_you:{keywords:["hand","fingers","gesture"],char:"🤟",fitzpatrick_scale:true,category:"people"},metal:{keywords:["hand","fingers","evil_eye","sign_of_horns","rock_on"],char:"🤘",fitzpatrick_scale:true,category:"people"},crossed_fingers:{keywords:["good","lucky"],char:"🤞",fitzpatrick_scale:true,category:"people"},vulcan_salute:{keywords:["hand","fingers","spock","star trek"],char:"🖖",fitzpatrick_scale:true,category:"people"},writing_hand:{keywords:["lower_left_ballpoint_pen","stationery","write","compose"],char:"✍",fitzpatrick_scale:true,category:"people"},selfie:{keywords:["camera","phone"],char:"🤳",fitzpatrick_scale:true,category:"people"},nail_care:{keywords:["beauty","manicure","finger","fashion","nail"],char:"💅",fitzpatrick_scale:true,category:"people"},lips:{keywords:["mouth","kiss"],char:"👄",fitzpatrick_scale:false,category:"people"},tooth:{keywords:["teeth","dentist"],char:"🦷",fitzpatrick_scale:false,category:"people"},tongue:{keywords:["mouth","playful"],char:"👅",fitzpatrick_scale:false,category:"people"},ear:{keywords:["face","hear","sound","listen"],char:"👂",fitzpatrick_scale:true,category:"people"},nose:{keywords:["smell","sniff"],char:"👃",fitzpatrick_scale:true,category:"people"},eye:{keywords:["face","look","see","watch","stare"],char:"👁",fitzpatrick_scale:false,category:"people"},eyes:{keywords:["look","watch","stalk","peek","see"],char:"👀",fitzpatrick_scale:false,category:"people"},brain:{keywords:["smart","intelligent"],char:"🧠",fitzpatrick_scale:false,category:"people"},bust_in_silhouette:{keywords:["user","person","human"],char:"👤",fitzpatrick_scale:false,category:"people"},busts_in_silhouette:{keywords:["user","person","human","group","team"],char:"👥",fitzpatrick_scale:false,category:"people"},speaking_head:{keywords:["user","person","human","sing","say","talk"],char:"🗣",fitzpatrick_scale:false,category:"people"},baby:{keywords:["child","boy","girl","toddler"],char:"👶",fitzpatrick_scale:true,category:"people"},child:{keywords:["gender-neutral","young"],char:"🧒",fitzpatrick_scale:true,category:"people"},boy:{keywords:["man","male","guy","teenager"],char:"👦",fitzpatrick_scale:true,category:"people"},girl:{keywords:["female","woman","teenager"],char:"👧",fitzpatrick_scale:true,category:"people"},adult:{keywords:["gender-neutral","person"],char:"🧑",fitzpatrick_scale:true,category:"people"},man:{keywords:["mustache","father","dad","guy","classy","sir","moustache"],char:"👨",fitzpatrick_scale:true,category:"people"},woman:{keywords:["female","girls","lady"],char:"👩",fitzpatrick_scale:true,category:"people"},blonde_woman:{keywords:["woman","female","girl","blonde","person"],char:"👱‍♀️",fitzpatrick_scale:true,category:"people"},blonde_man:{keywords:["man","male","boy","blonde","guy","person"],char:"👱",fitzpatrick_scale:true,category:"people"},bearded_person:{keywords:["person","bewhiskered"],char:"🧔",fitzpatrick_scale:true,category:"people"},older_adult:{keywords:["human","elder","senior","gender-neutral"],char:"🧓",fitzpatrick_scale:true,category:"people"},older_man:{keywords:["human","male","men","old","elder","senior"],char:"👴",fitzpatrick_scale:true,category:"people"},older_woman:{keywords:["human","female","women","lady","old","elder","senior"],char:"👵",fitzpatrick_scale:true,category:"people"},man_with_gua_pi_mao:{keywords:["male","boy","chinese"],char:"👲",fitzpatrick_scale:true,category:"people"},woman_with_headscarf:{keywords:["female","hijab","mantilla","tichel"],char:"🧕",fitzpatrick_scale:true,category:"people"},woman_with_turban:{keywords:["female","indian","hinduism","arabs","woman"],char:"👳‍♀️",fitzpatrick_scale:true,category:"people"},man_with_turban:{keywords:["male","indian","hinduism","arabs"],char:"👳",fitzpatrick_scale:true,category:"people"},policewoman:{keywords:["woman","police","law","legal","enforcement","arrest","911","female"],char:"👮‍♀️",fitzpatrick_scale:true,category:"people"},policeman:{keywords:["man","police","law","legal","enforcement","arrest","911"],char:"👮",fitzpatrick_scale:true,category:"people"},construction_worker_woman:{keywords:["female","human","wip","build","construction","worker","labor","woman"],char:"👷‍♀️",fitzpatrick_scale:true,category:"people"},construction_worker_man:{keywords:["male","human","wip","guy","build","construction","worker","labor"],char:"👷",fitzpatrick_scale:true,category:"people"},guardswoman:{keywords:["uk","gb","british","female","royal","woman"],char:"💂‍♀️",fitzpatrick_scale:true,category:"people"},guardsman:{keywords:["uk","gb","british","male","guy","royal"],char:"💂",fitzpatrick_scale:true,category:"people"},female_detective:{keywords:["human","spy","detective","female","woman"],char:"🕵️‍♀️",fitzpatrick_scale:true,category:"people"},male_detective:{keywords:["human","spy","detective"],char:"🕵",fitzpatrick_scale:true,category:"people"},woman_health_worker:{keywords:["doctor","nurse","therapist","healthcare","woman","human"],char:"👩‍⚕️",fitzpatrick_scale:true,category:"people"},man_health_worker:{keywords:["doctor","nurse","therapist","healthcare","man","human"],char:"👨‍⚕️",fitzpatrick_scale:true,category:"people"},woman_farmer:{keywords:["rancher","gardener","woman","human"],char:"👩‍🌾",fitzpatrick_scale:true,category:"people"},man_farmer:{keywords:["rancher","gardener","man","human"],char:"👨‍🌾",fitzpatrick_scale:true,category:"people"},woman_cook:{keywords:["chef","woman","human"],char:"👩‍🍳",fitzpatrick_scale:true,category:"people"},man_cook:{keywords:["chef","man","human"],char:"👨‍🍳",fitzpatrick_scale:true,category:"people"},woman_student:{keywords:["graduate","woman","human"],char:"👩‍🎓",fitzpatrick_scale:true,category:"people"},man_student:{keywords:["graduate","man","human"],char:"👨‍🎓",fitzpatrick_scale:true,category:"people"},woman_singer:{keywords:["rockstar","entertainer","woman","human"],char:"👩‍🎤",fitzpatrick_scale:true,category:"people"},man_singer:{keywords:["rockstar","entertainer","man","human"],char:"👨‍🎤",fitzpatrick_scale:true,category:"people"},woman_teacher:{keywords:["instructor","professor","woman","human"],char:"👩‍🏫",fitzpatrick_scale:true,category:"people"},man_teacher:{keywords:["instructor","professor","man","human"],char:"👨‍🏫",fitzpatrick_scale:true,category:"people"},woman_factory_worker:{keywords:["assembly","industrial","woman","human"],char:"👩‍🏭",fitzpatrick_scale:true,category:"people"},man_factory_worker:{keywords:["assembly","industrial","man","human"],char:"👨‍🏭",fitzpatrick_scale:true,category:"people"},woman_technologist:{keywords:["coder","developer","engineer","programmer","software","woman","human","laptop","computer"],char:"👩‍💻",fitzpatrick_scale:true,category:"people"},man_technologist:{keywords:["coder","developer","engineer","programmer","software","man","human","laptop","computer"],char:"👨‍💻",fitzpatrick_scale:true,category:"people"},woman_office_worker:{keywords:["business","manager","woman","human"],char:"👩‍💼",fitzpatrick_scale:true,category:"people"},man_office_worker:{keywords:["business","manager","man","human"],char:"👨‍💼",fitzpatrick_scale:true,category:"people"},woman_mechanic:{keywords:["plumber","woman","human","wrench"],char:"👩‍🔧",fitzpatrick_scale:true,category:"people"},man_mechanic:{keywords:["plumber","man","human","wrench"],char:"👨‍🔧",fitzpatrick_scale:true,category:"people"},woman_scientist:{keywords:["biologist","chemist","engineer","physicist","woman","human"],char:"👩‍🔬",fitzpatrick_scale:true,category:"people"},man_scientist:{keywords:["biologist","chemist","engineer","physicist","man","human"],char:"👨‍🔬",fitzpatrick_scale:true,category:"people"},woman_artist:{keywords:["painter","woman","human"],char:"👩‍🎨",fitzpatrick_scale:true,category:"people"},man_artist:{keywords:["painter","man","human"],char:"👨‍🎨",fitzpatrick_scale:true,category:"people"},woman_firefighter:{keywords:["fireman","woman","human"],char:"👩‍🚒",fitzpatrick_scale:true,category:"people"},man_firefighter:{keywords:["fireman","man","human"],char:"👨‍🚒",fitzpatrick_scale:true,category:"people"},woman_pilot:{keywords:["aviator","plane","woman","human"],char:"👩‍✈️",fitzpatrick_scale:true,category:"people"},man_pilot:{keywords:["aviator","plane","man","human"],char:"👨‍✈️",fitzpatrick_scale:true,category:"people"},woman_astronaut:{keywords:["space","rocket","woman","human"],char:"👩‍🚀",fitzpatrick_scale:true,category:"people"},man_astronaut:{keywords:["space","rocket","man","human"],char:"👨‍🚀",fitzpatrick_scale:true,category:"people"},woman_judge:{keywords:["justice","court","woman","human"],char:"👩‍⚖️",fitzpatrick_scale:true,category:"people"},man_judge:{keywords:["justice","court","man","human"],char:"👨‍⚖️",fitzpatrick_scale:true,category:"people"},woman_superhero:{keywords:["woman","female","good","heroine","superpowers"],char:"🦸‍♀️",fitzpatrick_scale:true,category:"people"},man_superhero:{keywords:["man","male","good","hero","superpowers"],char:"🦸‍♂️",fitzpatrick_scale:true,category:"people"},woman_supervillain:{keywords:["woman","female","evil","bad","criminal","heroine","superpowers"],char:"🦹‍♀️",fitzpatrick_scale:true,category:"people"},man_supervillain:{keywords:["man","male","evil","bad","criminal","hero","superpowers"],char:"🦹‍♂️",fitzpatrick_scale:true,category:"people"},mrs_claus:{keywords:["woman","female","xmas","mother christmas"],char:"🤶",fitzpatrick_scale:true,category:"people"},santa:{keywords:["festival","man","male","xmas","father christmas"],char:"🎅",fitzpatrick_scale:true,category:"people"},sorceress:{keywords:["woman","female","mage","witch"],char:"🧙‍♀️",fitzpatrick_scale:true,category:"people"},wizard:{keywords:["man","male","mage","sorcerer"],char:"🧙‍♂️",fitzpatrick_scale:true,category:"people"},woman_elf:{keywords:["woman","female"],char:"🧝‍♀️",fitzpatrick_scale:true,category:"people"},man_elf:{keywords:["man","male"],char:"🧝‍♂️",fitzpatrick_scale:true,category:"people"},woman_vampire:{keywords:["woman","female"],char:"🧛‍♀️",fitzpatrick_scale:true,category:"people"},man_vampire:{keywords:["man","male","dracula"],char:"🧛‍♂️",fitzpatrick_scale:true,category:"people"},woman_zombie:{keywords:["woman","female","undead","walking dead"],char:"🧟‍♀️",fitzpatrick_scale:false,category:"people"},man_zombie:{keywords:["man","male","dracula","undead","walking dead"],char:"🧟‍♂️",fitzpatrick_scale:false,category:"people"},woman_genie:{keywords:["woman","female"],char:"🧞‍♀️",fitzpatrick_scale:false,category:"people"},man_genie:{keywords:["man","male"],char:"🧞‍♂️",fitzpatrick_scale:false,category:"people"},mermaid:{keywords:["woman","female","merwoman","ariel"],char:"🧜‍♀️",fitzpatrick_scale:true,category:"people"},merman:{keywords:["man","male","triton"],char:"🧜‍♂️",fitzpatrick_scale:true,category:"people"},woman_fairy:{keywords:["woman","female"],char:"🧚‍♀️",fitzpatrick_scale:true,category:"people"},man_fairy:{keywords:["man","male"],char:"🧚‍♂️",fitzpatrick_scale:true,category:"people"},angel:{keywords:["heaven","wings","halo"],char:"👼",fitzpatrick_scale:true,category:"people"},pregnant_woman:{keywords:["baby"],char:"🤰",fitzpatrick_scale:true,category:"people"},breastfeeding:{keywords:["nursing","baby"],char:"🤱",fitzpatrick_scale:true,category:"people"},princess:{keywords:["girl","woman","female","blond","crown","royal","queen"],char:"👸",fitzpatrick_scale:true,category:"people"},prince:{keywords:["boy","man","male","crown","royal","king"],char:"🤴",fitzpatrick_scale:true,category:"people"},bride_with_veil:{keywords:["couple","marriage","wedding","woman","bride"],char:"👰",fitzpatrick_scale:true,category:"people"},man_in_tuxedo:{keywords:["couple","marriage","wedding","groom"],char:"🤵",fitzpatrick_scale:true,category:"people"},running_woman:{keywords:["woman","walking","exercise","race","running","female"],char:"🏃‍♀️",fitzpatrick_scale:true,category:"people"},running_man:{keywords:["man","walking","exercise","race","running"],char:"🏃",fitzpatrick_scale:true,category:"people"},walking_woman:{keywords:["human","feet","steps","woman","female"],char:"🚶‍♀️",fitzpatrick_scale:true,category:"people"},walking_man:{keywords:["human","feet","steps"],char:"🚶",fitzpatrick_scale:true,category:"people"},dancer:{keywords:["female","girl","woman","fun"],char:"💃",fitzpatrick_scale:true,category:"people"},man_dancing:{keywords:["male","boy","fun","dancer"],char:"🕺",fitzpatrick_scale:true,category:"people"},dancing_women:{keywords:["female","bunny","women","girls"],char:"👯",fitzpatrick_scale:false,category:"people"},dancing_men:{keywords:["male","bunny","men","boys"],char:"👯‍♂️",fitzpatrick_scale:false,category:"people"},couple:{keywords:["pair","people","human","love","date","dating","like","affection","valentines","marriage"],char:"👫",fitzpatrick_scale:false,category:"people"},two_men_holding_hands:{keywords:["pair","couple","love","like","bromance","friendship","people","human"],char:"👬",fitzpatrick_scale:false,category:"people"},two_women_holding_hands:{keywords:["pair","friendship","couple","love","like","female","people","human"],char:"👭",fitzpatrick_scale:false,category:"people"},bowing_woman:{keywords:["woman","female","girl"],char:"🙇‍♀️",fitzpatrick_scale:true,category:"people"},bowing_man:{keywords:["man","male","boy"],char:"🙇",fitzpatrick_scale:true,category:"people"},man_facepalming:{keywords:["man","male","boy","disbelief"],char:"🤦‍♂️",fitzpatrick_scale:true,category:"people"},woman_facepalming:{keywords:["woman","female","girl","disbelief"],char:"🤦‍♀️",fitzpatrick_scale:true,category:"people"},woman_shrugging:{keywords:["woman","female","girl","confused","indifferent","doubt"],char:"🤷",fitzpatrick_scale:true,category:"people"},man_shrugging:{keywords:["man","male","boy","confused","indifferent","doubt"],char:"🤷‍♂️",fitzpatrick_scale:true,category:"people"},tipping_hand_woman:{keywords:["female","girl","woman","human","information"],char:"💁",fitzpatrick_scale:true,category:"people"},tipping_hand_man:{keywords:["male","boy","man","human","information"],char:"💁‍♂️",fitzpatrick_scale:true,category:"people"},no_good_woman:{keywords:["female","girl","woman","nope"],char:"🙅",fitzpatrick_scale:true,category:"people"},no_good_man:{keywords:["male","boy","man","nope"],char:"🙅‍♂️",fitzpatrick_scale:true,category:"people"},ok_woman:{keywords:["women","girl","female","pink","human","woman"],char:"🙆",fitzpatrick_scale:true,category:"people"},ok_man:{keywords:["men","boy","male","blue","human","man"],char:"🙆‍♂️",fitzpatrick_scale:true,category:"people"},raising_hand_woman:{keywords:["female","girl","woman"],char:"🙋",fitzpatrick_scale:true,category:"people"},raising_hand_man:{keywords:["male","boy","man"],char:"🙋‍♂️",fitzpatrick_scale:true,category:"people"},pouting_woman:{keywords:["female","girl","woman"],char:"🙎",fitzpatrick_scale:true,category:"people"},pouting_man:{keywords:["male","boy","man"],char:"🙎‍♂️",fitzpatrick_scale:true,category:"people"},frowning_woman:{keywords:["female","girl","woman","sad","depressed","discouraged","unhappy"],char:"🙍",fitzpatrick_scale:true,category:"people"},frowning_man:{keywords:["male","boy","man","sad","depressed","discouraged","unhappy"],char:"🙍‍♂️",fitzpatrick_scale:true,category:"people"},haircut_woman:{keywords:["female","girl","woman"],char:"💇",fitzpatrick_scale:true,category:"people"},haircut_man:{keywords:["male","boy","man"],char:"💇‍♂️",fitzpatrick_scale:true,category:"people"},massage_woman:{keywords:["female","girl","woman","head"],char:"💆",fitzpatrick_scale:true,category:"people"},massage_man:{keywords:["male","boy","man","head"],char:"💆‍♂️",fitzpatrick_scale:true,category:"people"},woman_in_steamy_room:{keywords:["female","woman","spa","steamroom","sauna"],char:"🧖‍♀️",fitzpatrick_scale:true,category:"people"},man_in_steamy_room:{keywords:["male","man","spa","steamroom","sauna"],char:"🧖‍♂️",fitzpatrick_scale:true,category:"people"},couple_with_heart_woman_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:"💑",fitzpatrick_scale:false,category:"people"},couple_with_heart_woman_woman:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:"👩‍❤️‍👩",fitzpatrick_scale:false,category:"people"},couple_with_heart_man_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:"👨‍❤️‍👨",fitzpatrick_scale:false,category:"people"},couplekiss_man_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:"💏",fitzpatrick_scale:false,category:"people"},couplekiss_woman_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:"👩‍❤️‍💋‍👩",fitzpatrick_scale:false,category:"people"},couplekiss_man_man:{keywords:["pair","valentines","love","like","dating","marriage"],char:"👨‍❤️‍💋‍👨",fitzpatrick_scale:false,category:"people"},family_man_woman_boy:{keywords:["home","parents","child","mom","dad","father","mother","people","human"],char:"👪",fitzpatrick_scale:false,category:"people"},family_man_woman_girl:{keywords:["home","parents","people","human","child"],char:"👨‍👩‍👧",fitzpatrick_scale:false,category:"people"},family_man_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:"👨‍👩‍👧‍👦",fitzpatrick_scale:false,category:"people"},family_man_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:"👨‍👩‍👦‍👦",fitzpatrick_scale:false,category:"people"},family_man_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:"👨‍👩‍👧‍👧",fitzpatrick_scale:false,category:"people"},family_woman_woman_boy:{keywords:["home","parents","people","human","children"],char:"👩‍👩‍👦",fitzpatrick_scale:false,category:"people"},family_woman_woman_girl:{keywords:["home","parents","people","human","children"],char:"👩‍👩‍👧",fitzpatrick_scale:false,category:"people"},family_woman_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:"👩‍👩‍👧‍👦",fitzpatrick_scale:false,category:"people"},family_woman_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:"👩‍👩‍👦‍👦",fitzpatrick_scale:false,category:"people"},family_woman_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:"👩‍👩‍👧‍👧",fitzpatrick_scale:false,category:"people"},family_man_man_boy:{keywords:["home","parents","people","human","children"],char:"👨‍👨‍👦",fitzpatrick_scale:false,category:"people"},family_man_man_girl:{keywords:["home","parents","people","human","children"],char:"👨‍👨‍👧",fitzpatrick_scale:false,category:"people"},family_man_man_girl_boy:{keywords:["home","parents","people","human","children"],char:"👨‍👨‍👧‍👦",fitzpatrick_scale:false,category:"people"},family_man_man_boy_boy:{keywords:["home","parents","people","human","children"],char:"👨‍👨‍👦‍👦",fitzpatrick_scale:false,category:"people"},family_man_man_girl_girl:{keywords:["home","parents","people","human","children"],char:"👨‍👨‍👧‍👧",fitzpatrick_scale:false,category:"people"},family_woman_boy:{keywords:["home","parent","people","human","child"],char:"👩‍👦",fitzpatrick_scale:false,category:"people"},family_woman_girl:{keywords:["home","parent","people","human","child"],char:"👩‍👧",fitzpatrick_scale:false,category:"people"},family_woman_girl_boy:{keywords:["home","parent","people","human","children"],char:"👩‍👧‍👦",fitzpatrick_scale:false,category:"people"},family_woman_boy_boy:{keywords:["home","parent","people","human","children"],char:"👩‍👦‍👦",fitzpatrick_scale:false,category:"people"},family_woman_girl_girl:{keywords:["home","parent","people","human","children"],char:"👩‍👧‍👧",fitzpatrick_scale:false,category:"people"},family_man_boy:{keywords:["home","parent","people","human","child"],char:"👨‍👦",fitzpatrick_scale:false,category:"people"},family_man_girl:{keywords:["home","parent","people","human","child"],char:"👨‍👧",fitzpatrick_scale:false,category:"people"},family_man_girl_boy:{keywords:["home","parent","people","human","children"],char:"👨‍👧‍👦",fitzpatrick_scale:false,category:"people"},family_man_boy_boy:{keywords:["home","parent","people","human","children"],char:"👨‍👦‍👦",fitzpatrick_scale:false,category:"people"},family_man_girl_girl:{keywords:["home","parent","people","human","children"],char:"👨‍👧‍👧",fitzpatrick_scale:false,category:"people"},yarn:{keywords:["ball","crochet","knit"],char:"🧶",fitzpatrick_scale:false,category:"people"},thread:{keywords:["needle","sewing","spool","string"],char:"🧵",fitzpatrick_scale:false,category:"people"},coat:{keywords:["jacket"],char:"🧥",fitzpatrick_scale:false,category:"people"},labcoat:{keywords:["doctor","experiment","scientist","chemist"],char:"🥼",fitzpatrick_scale:false,category:"people"},womans_clothes:{keywords:["fashion","shopping_bags","female"],char:"👚",fitzpatrick_scale:false,category:"people"},tshirt:{keywords:["fashion","cloth","casual","shirt","tee"],char:"👕",fitzpatrick_scale:false,category:"people"},jeans:{keywords:["fashion","shopping"],char:"👖",fitzpatrick_scale:false,category:"people"},necktie:{keywords:["shirt","suitup","formal","fashion","cloth","business"],char:"👔",fitzpatrick_scale:false,category:"people"},dress:{keywords:["clothes","fashion","shopping"],char:"👗",fitzpatrick_scale:false,category:"people"},bikini:{keywords:["swimming","female","woman","girl","fashion","beach","summer"],char:"👙",fitzpatrick_scale:false,category:"people"},kimono:{keywords:["dress","fashion","women","female","japanese"],char:"👘",fitzpatrick_scale:false,category:"people"},lipstick:{keywords:["female","girl","fashion","woman"],char:"💄",fitzpatrick_scale:false,category:"people"},kiss:{keywords:["face","lips","love","like","affection","valentines"],char:"💋",fitzpatrick_scale:false,category:"people"},footprints:{keywords:["feet","tracking","walking","beach"],char:"👣",fitzpatrick_scale:false,category:"people"},flat_shoe:{keywords:["ballet","slip-on","slipper"],char:"🥿",fitzpatrick_scale:false,category:"people"},high_heel:{keywords:["fashion","shoes","female","pumps","stiletto"],char:"👠",fitzpatrick_scale:false,category:"people"},sandal:{keywords:["shoes","fashion","flip flops"],char:"👡",fitzpatrick_scale:false,category:"people"},boot:{keywords:["shoes","fashion"],char:"👢",fitzpatrick_scale:false,category:"people"},mans_shoe:{keywords:["fashion","male"],char:"👞",fitzpatrick_scale:false,category:"people"},athletic_shoe:{keywords:["shoes","sports","sneakers"],char:"👟",fitzpatrick_scale:false,category:"people"},hiking_boot:{keywords:["backpacking","camping","hiking"],char:"🥾",fitzpatrick_scale:false,category:"people"},socks:{keywords:["stockings","clothes"],char:"🧦",fitzpatrick_scale:false,category:"people"},gloves:{keywords:["hands","winter","clothes"],char:"🧤",fitzpatrick_scale:false,category:"people"},scarf:{keywords:["neck","winter","clothes"],char:"🧣",fitzpatrick_scale:false,category:"people"},womans_hat:{keywords:["fashion","accessories","female","lady","spring"],char:"👒",fitzpatrick_scale:false,category:"people"},tophat:{keywords:["magic","gentleman","classy","circus"],char:"🎩",fitzpatrick_scale:false,category:"people"},billed_hat:{keywords:["cap","baseball"],char:"🧢",fitzpatrick_scale:false,category:"people"},rescue_worker_helmet:{keywords:["construction","build"],char:"⛑",fitzpatrick_scale:false,category:"people"},mortar_board:{keywords:["school","college","degree","university","graduation","cap","hat","legal","learn","education"],char:"🎓",fitzpatrick_scale:false,category:"people"},crown:{keywords:["king","kod","leader","royalty","lord"],char:"👑",fitzpatrick_scale:false,category:"people"},school_satchel:{keywords:["student","education","bag","backpack"],char:"🎒",fitzpatrick_scale:false,category:"people"},luggage:{keywords:["packing","travel"],char:"🧳",fitzpatrick_scale:false,category:"people"},pouch:{keywords:["bag","accessories","shopping"],char:"👝",fitzpatrick_scale:false,category:"people"},purse:{keywords:["fashion","accessories","money","sales","shopping"],char:"👛",fitzpatrick_scale:false,category:"people"},handbag:{keywords:["fashion","accessory","accessories","shopping"],char:"👜",fitzpatrick_scale:false,category:"people"},briefcase:{keywords:["business","documents","work","law","legal","job","career"],char:"💼",fitzpatrick_scale:false,category:"people"},eyeglasses:{keywords:["fashion","accessories","eyesight","nerdy","dork","geek"],char:"👓",fitzpatrick_scale:false,category:"people"},dark_sunglasses:{keywords:["face","cool","accessories"],char:"🕶",fitzpatrick_scale:false,category:"people"},goggles:{keywords:["eyes","protection","safety"],char:"🥽",fitzpatrick_scale:false,category:"people"},ring:{keywords:["wedding","propose","marriage","valentines","diamond","fashion","jewelry","gem","engagement"],char:"💍",fitzpatrick_scale:false,category:"people"},closed_umbrella:{keywords:["weather","rain","drizzle"],char:"🌂",fitzpatrick_scale:false,category:"people"},dog:{keywords:["animal","friend","nature","woof","puppy","pet","faithful"],char:"🐶",fitzpatrick_scale:false,category:"animals_and_nature"},cat:{keywords:["animal","meow","nature","pet","kitten"],char:"🐱",fitzpatrick_scale:false,category:"animals_and_nature"},mouse:{keywords:["animal","nature","cheese_wedge","rodent"],char:"🐭",fitzpatrick_scale:false,category:"animals_and_nature"},hamster:{keywords:["animal","nature"],char:"🐹",fitzpatrick_scale:false,category:"animals_and_nature"},rabbit:{keywords:["animal","nature","pet","spring","magic","bunny"],char:"🐰",fitzpatrick_scale:false,category:"animals_and_nature"},fox_face:{keywords:["animal","nature","face"],char:"🦊",fitzpatrick_scale:false,category:"animals_and_nature"},bear:{keywords:["animal","nature","wild"],char:"🐻",fitzpatrick_scale:false,category:"animals_and_nature"},panda_face:{keywords:["animal","nature","panda"],char:"🐼",fitzpatrick_scale:false,category:"animals_and_nature"},koala:{keywords:["animal","nature"],char:"🐨",fitzpatrick_scale:false,category:"animals_and_nature"},tiger:{keywords:["animal","cat","danger","wild","nature","roar"],char:"🐯",fitzpatrick_scale:false,category:"animals_and_nature"},lion:{keywords:["animal","nature"],char:"🦁",fitzpatrick_scale:false,category:"animals_and_nature"},cow:{keywords:["beef","ox","animal","nature","moo","milk"],char:"🐮",fitzpatrick_scale:false,category:"animals_and_nature"},pig:{keywords:["animal","oink","nature"],char:"🐷",fitzpatrick_scale:false,category:"animals_and_nature"},pig_nose:{keywords:["animal","oink"],char:"🐽",fitzpatrick_scale:false,category:"animals_and_nature"},frog:{keywords:["animal","nature","croak","toad"],char:"🐸",fitzpatrick_scale:false,category:"animals_and_nature"},squid:{keywords:["animal","nature","ocean","sea"],char:"🦑",fitzpatrick_scale:false,category:"animals_and_nature"},octopus:{keywords:["animal","creature","ocean","sea","nature","beach"],char:"🐙",fitzpatrick_scale:false,category:"animals_and_nature"},shrimp:{keywords:["animal","ocean","nature","seafood"],char:"🦐",fitzpatrick_scale:false,category:"animals_and_nature"},monkey_face:{keywords:["animal","nature","circus"],char:"🐵",fitzpatrick_scale:false,category:"animals_and_nature"},gorilla:{keywords:["animal","nature","circus"],char:"🦍",fitzpatrick_scale:false,category:"animals_and_nature"},see_no_evil:{keywords:["monkey","animal","nature","haha"],char:"🙈",fitzpatrick_scale:false,category:"animals_and_nature"},hear_no_evil:{keywords:["animal","monkey","nature"],char:"🙉",fitzpatrick_scale:false,category:"animals_and_nature"},speak_no_evil:{keywords:["monkey","animal","nature","omg"],char:"🙊",fitzpatrick_scale:false,category:"animals_and_nature"},monkey:{keywords:["animal","nature","banana","circus"],char:"🐒",fitzpatrick_scale:false,category:"animals_and_nature"},chicken:{keywords:["animal","cluck","nature","bird"],char:"🐔",fitzpatrick_scale:false,category:"animals_and_nature"},penguin:{keywords:["animal","nature"],char:"🐧",fitzpatrick_scale:false,category:"animals_and_nature"},bird:{keywords:["animal","nature","fly","tweet","spring"],char:"🐦",fitzpatrick_scale:false,category:"animals_and_nature"},baby_chick:{keywords:["animal","chicken","bird"],char:"🐤",fitzpatrick_scale:false,category:"animals_and_nature"},hatching_chick:{keywords:["animal","chicken","egg","born","baby","bird"],char:"🐣",fitzpatrick_scale:false,category:"animals_and_nature"},hatched_chick:{keywords:["animal","chicken","baby","bird"],char:"🐥",fitzpatrick_scale:false,category:"animals_and_nature"},duck:{keywords:["animal","nature","bird","mallard"],char:"🦆",fitzpatrick_scale:false,category:"animals_and_nature"},eagle:{keywords:["animal","nature","bird"],char:"🦅",fitzpatrick_scale:false,category:"animals_and_nature"},owl:{keywords:["animal","nature","bird","hoot"],char:"🦉",fitzpatrick_scale:false,category:"animals_and_nature"},bat:{keywords:["animal","nature","blind","vampire"],char:"🦇",fitzpatrick_scale:false,category:"animals_and_nature"},wolf:{keywords:["animal","nature","wild"],char:"🐺",fitzpatrick_scale:false,category:"animals_and_nature"},boar:{keywords:["animal","nature"],char:"🐗",fitzpatrick_scale:false,category:"animals_and_nature"},horse:{keywords:["animal","brown","nature"],char:"🐴",fitzpatrick_scale:false,category:"animals_and_nature"},unicorn:{keywords:["animal","nature","mystical"],char:"🦄",fitzpatrick_scale:false,category:"animals_and_nature"},honeybee:{keywords:["animal","insect","nature","bug","spring","honey"],char:"🐝",fitzpatrick_scale:false,category:"animals_and_nature"},bug:{keywords:["animal","insect","nature","worm"],char:"🐛",fitzpatrick_scale:false,category:"animals_and_nature"},butterfly:{keywords:["animal","insect","nature","caterpillar"],char:"🦋",fitzpatrick_scale:false,category:"animals_and_nature"},snail:{keywords:["slow","animal","shell"],char:"🐌",fitzpatrick_scale:false,category:"animals_and_nature"},beetle:{keywords:["animal","insect","nature","ladybug"],char:"🐞",fitzpatrick_scale:false,category:"animals_and_nature"},ant:{keywords:["animal","insect","nature","bug"],char:"🐜",fitzpatrick_scale:false,category:"animals_and_nature"},grasshopper:{keywords:["animal","cricket","chirp"],char:"🦗",fitzpatrick_scale:false,category:"animals_and_nature"},spider:{keywords:["animal","arachnid"],char:"🕷",fitzpatrick_scale:false,category:"animals_and_nature"},scorpion:{keywords:["animal","arachnid"],char:"🦂",fitzpatrick_scale:false,category:"animals_and_nature"},crab:{keywords:["animal","crustacean"],char:"🦀",fitzpatrick_scale:false,category:"animals_and_nature"},snake:{keywords:["animal","evil","nature","hiss","python"],char:"🐍",fitzpatrick_scale:false,category:"animals_and_nature"},lizard:{keywords:["animal","nature","reptile"],char:"🦎",fitzpatrick_scale:false,category:"animals_and_nature"},"t-rex":{keywords:["animal","nature","dinosaur","tyrannosaurus","extinct"],char:"🦖",fitzpatrick_scale:false,category:"animals_and_nature"},sauropod:{keywords:["animal","nature","dinosaur","brachiosaurus","brontosaurus","diplodocus","extinct"],char:"🦕",fitzpatrick_scale:false,category:"animals_and_nature"},turtle:{keywords:["animal","slow","nature","tortoise"],char:"🐢",fitzpatrick_scale:false,category:"animals_and_nature"},tropical_fish:{keywords:["animal","swim","ocean","beach","nemo"],char:"🐠",fitzpatrick_scale:false,category:"animals_and_nature"},fish:{keywords:["animal","food","nature"],char:"🐟",fitzpatrick_scale:false,category:"animals_and_nature"},blowfish:{keywords:["animal","nature","food","sea","ocean"],char:"🐡",fitzpatrick_scale:false,category:"animals_and_nature"},dolphin:{keywords:["animal","nature","fish","sea","ocean","flipper","fins","beach"],char:"🐬",fitzpatrick_scale:false,category:"animals_and_nature"},shark:{keywords:["animal","nature","fish","sea","ocean","jaws","fins","beach"],char:"🦈",fitzpatrick_scale:false,category:"animals_and_nature"},whale:{keywords:["animal","nature","sea","ocean"],char:"🐳",fitzpatrick_scale:false,category:"animals_and_nature"},whale2:{keywords:["animal","nature","sea","ocean"],char:"🐋",fitzpatrick_scale:false,category:"animals_and_nature"},crocodile:{keywords:["animal","nature","reptile","lizard","alligator"],char:"🐊",fitzpatrick_scale:false,category:"animals_and_nature"},leopard:{keywords:["animal","nature"],char:"🐆",fitzpatrick_scale:false,category:"animals_and_nature"},zebra:{keywords:["animal","nature","stripes","safari"],char:"🦓",fitzpatrick_scale:false,category:"animals_and_nature"},tiger2:{keywords:["animal","nature","roar"],char:"🐅",fitzpatrick_scale:false,category:"animals_and_nature"},water_buffalo:{keywords:["animal","nature","ox","cow"],char:"🐃",fitzpatrick_scale:false,category:"animals_and_nature"},ox:{keywords:["animal","cow","beef"],char:"🐂",fitzpatrick_scale:false,category:"animals_and_nature"},cow2:{keywords:["beef","ox","animal","nature","moo","milk"],char:"🐄",fitzpatrick_scale:false,category:"animals_and_nature"},deer:{keywords:["animal","nature","horns","venison"],char:"🦌",fitzpatrick_scale:false,category:"animals_and_nature"},dromedary_camel:{keywords:["animal","hot","desert","hump"],char:"🐪",fitzpatrick_scale:false,category:"animals_and_nature"},camel:{keywords:["animal","nature","hot","desert","hump"],char:"🐫",fitzpatrick_scale:false,category:"animals_and_nature"},giraffe:{keywords:["animal","nature","spots","safari"],char:"🦒",fitzpatrick_scale:false,category:"animals_and_nature"},elephant:{keywords:["animal","nature","nose","th","circus"],char:"🐘",fitzpatrick_scale:false,category:"animals_and_nature"},rhinoceros:{keywords:["animal","nature","horn"],char:"🦏",fitzpatrick_scale:false,category:"animals_and_nature"},goat:{keywords:["animal","nature"],char:"🐐",fitzpatrick_scale:false,category:"animals_and_nature"},ram:{keywords:["animal","sheep","nature"],char:"🐏",fitzpatrick_scale:false,category:"animals_and_nature"},sheep:{keywords:["animal","nature","wool","shipit"],char:"🐑",fitzpatrick_scale:false,category:"animals_and_nature"},racehorse:{keywords:["animal","gamble","luck"],char:"🐎",fitzpatrick_scale:false,category:"animals_and_nature"},pig2:{keywords:["animal","nature"],char:"🐖",fitzpatrick_scale:false,category:"animals_and_nature"},rat:{keywords:["animal","mouse","rodent"],char:"🐀",fitzpatrick_scale:false,category:"animals_and_nature"},mouse2:{keywords:["animal","nature","rodent"],char:"🐁",fitzpatrick_scale:false,category:"animals_and_nature"},rooster:{keywords:["animal","nature","chicken"],char:"🐓",fitzpatrick_scale:false,category:"animals_and_nature"},turkey:{keywords:["animal","bird"],char:"🦃",fitzpatrick_scale:false,category:"animals_and_nature"},dove:{keywords:["animal","bird"],char:"🕊",fitzpatrick_scale:false,category:"animals_and_nature"},dog2:{keywords:["animal","nature","friend","doge","pet","faithful"],char:"🐕",fitzpatrick_scale:false,category:"animals_and_nature"},poodle:{keywords:["dog","animal","101","nature","pet"],char:"🐩",fitzpatrick_scale:false,category:"animals_and_nature"},cat2:{keywords:["animal","meow","pet","cats"],char:"🐈",fitzpatrick_scale:false,category:"animals_and_nature"},rabbit2:{keywords:["animal","nature","pet","magic","spring"],char:"🐇",fitzpatrick_scale:false,category:"animals_and_nature"},chipmunk:{keywords:["animal","nature","rodent","squirrel"],char:"🐿",fitzpatrick_scale:false,category:"animals_and_nature"},hedgehog:{keywords:["animal","nature","spiny"],char:"🦔",fitzpatrick_scale:false,category:"animals_and_nature"},raccoon:{keywords:["animal","nature"],char:"🦝",fitzpatrick_scale:false,category:"animals_and_nature"},llama:{keywords:["animal","nature","alpaca"],char:"🦙",fitzpatrick_scale:false,category:"animals_and_nature"},hippopotamus:{keywords:["animal","nature"],char:"🦛",fitzpatrick_scale:false,category:"animals_and_nature"},kangaroo:{keywords:["animal","nature","australia","joey","hop","marsupial"],char:"🦘",fitzpatrick_scale:false,category:"animals_and_nature"},badger:{keywords:["animal","nature","honey"],char:"🦡",fitzpatrick_scale:false,category:"animals_and_nature"},swan:{keywords:["animal","nature","bird"],char:"🦢",fitzpatrick_scale:false,category:"animals_and_nature"},peacock:{keywords:["animal","nature","peahen","bird"],char:"🦚",fitzpatrick_scale:false,category:"animals_and_nature"},parrot:{keywords:["animal","nature","bird","pirate","talk"],char:"🦜",fitzpatrick_scale:false,category:"animals_and_nature"},lobster:{keywords:["animal","nature","bisque","claws","seafood"],char:"🦞",fitzpatrick_scale:false,category:"animals_and_nature"},mosquito:{keywords:["animal","nature","insect","malaria"],char:"🦟",fitzpatrick_scale:false,category:"animals_and_nature"},paw_prints:{keywords:["animal","tracking","footprints","dog","cat","pet","feet"],char:"🐾",fitzpatrick_scale:false,category:"animals_and_nature"},dragon:{keywords:["animal","myth","nature","chinese","green"],char:"🐉",fitzpatrick_scale:false,category:"animals_and_nature"},dragon_face:{keywords:["animal","myth","nature","chinese","green"],char:"🐲",fitzpatrick_scale:false,category:"animals_and_nature"},cactus:{keywords:["vegetable","plant","nature"],char:"🌵",fitzpatrick_scale:false,category:"animals_and_nature"},christmas_tree:{keywords:["festival","vacation","december","xmas","celebration"],char:"🎄",fitzpatrick_scale:false,category:"animals_and_nature"},evergreen_tree:{keywords:["plant","nature"],char:"🌲",fitzpatrick_scale:false,category:"animals_and_nature"},deciduous_tree:{keywords:["plant","nature"],char:"🌳",fitzpatrick_scale:false,category:"animals_and_nature"},palm_tree:{keywords:["plant","vegetable","nature","summer","beach","mojito","tropical"],char:"🌴",fitzpatrick_scale:false,category:"animals_and_nature"},seedling:{keywords:["plant","nature","grass","lawn","spring"],char:"🌱",fitzpatrick_scale:false,category:"animals_and_nature"},herb:{keywords:["vegetable","plant","medicine","weed","grass","lawn"],char:"🌿",fitzpatrick_scale:false,category:"animals_and_nature"},shamrock:{keywords:["vegetable","plant","nature","irish","clover"],char:"☘",fitzpatrick_scale:false,category:"animals_and_nature"},four_leaf_clover:{keywords:["vegetable","plant","nature","lucky","irish"],char:"🍀",fitzpatrick_scale:false,category:"animals_and_nature"},bamboo:{keywords:["plant","nature","vegetable","panda","pine_decoration"],char:"🎍",fitzpatrick_scale:false,category:"animals_and_nature"},tanabata_tree:{keywords:["plant","nature","branch","summer"],char:"🎋",fitzpatrick_scale:false,category:"animals_and_nature"},leaves:{keywords:["nature","plant","tree","vegetable","grass","lawn","spring"],char:"🍃",fitzpatrick_scale:false,category:"animals_and_nature"},fallen_leaf:{keywords:["nature","plant","vegetable","leaves"],char:"🍂",fitzpatrick_scale:false,category:"animals_and_nature"},maple_leaf:{keywords:["nature","plant","vegetable","ca","fall"],char:"🍁",fitzpatrick_scale:false,category:"animals_and_nature"},ear_of_rice:{keywords:["nature","plant"],char:"🌾",fitzpatrick_scale:false,category:"animals_and_nature"},hibiscus:{keywords:["plant","vegetable","flowers","beach"],char:"🌺",fitzpatrick_scale:false,category:"animals_and_nature"},sunflower:{keywords:["nature","plant","fall"],char:"🌻",fitzpatrick_scale:false,category:"animals_and_nature"},rose:{keywords:["flowers","valentines","love","spring"],char:"🌹",fitzpatrick_scale:false,category:"animals_and_nature"},wilted_flower:{keywords:["plant","nature","flower"],char:"🥀",fitzpatrick_scale:false,category:"animals_and_nature"},tulip:{keywords:["flowers","plant","nature","summer","spring"],char:"🌷",fitzpatrick_scale:false,category:"animals_and_nature"},blossom:{keywords:["nature","flowers","yellow"],char:"🌼",fitzpatrick_scale:false,category:"animals_and_nature"},cherry_blossom:{keywords:["nature","plant","spring","flower"],char:"🌸",fitzpatrick_scale:false,category:"animals_and_nature"},bouquet:{keywords:["flowers","nature","spring"],char:"💐",fitzpatrick_scale:false,category:"animals_and_nature"},mushroom:{keywords:["plant","vegetable"],char:"🍄",fitzpatrick_scale:false,category:"animals_and_nature"},chestnut:{keywords:["food","squirrel"],char:"🌰",fitzpatrick_scale:false,category:"animals_and_nature"},jack_o_lantern:{keywords:["halloween","light","pumpkin","creepy","fall"],char:"🎃",fitzpatrick_scale:false,category:"animals_and_nature"},shell:{keywords:["nature","sea","beach"],char:"🐚",fitzpatrick_scale:false,category:"animals_and_nature"},spider_web:{keywords:["animal","insect","arachnid","silk"],char:"🕸",fitzpatrick_scale:false,category:"animals_and_nature"},earth_americas:{keywords:["globe","world","USA","international"],char:"🌎",fitzpatrick_scale:false,category:"animals_and_nature"},earth_africa:{keywords:["globe","world","international"],char:"🌍",fitzpatrick_scale:false,category:"animals_and_nature"},earth_asia:{keywords:["globe","world","east","international"],char:"🌏",fitzpatrick_scale:false,category:"animals_and_nature"},full_moon:{keywords:["nature","yellow","twilight","planet","space","night","evening","sleep"],char:"🌕",fitzpatrick_scale:false,category:"animals_and_nature"},waning_gibbous_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep","waxing_gibbous_moon"],char:"🌖",fitzpatrick_scale:false,category:"animals_and_nature"},last_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"🌗",fitzpatrick_scale:false,category:"animals_and_nature"},waning_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"🌘",fitzpatrick_scale:false,category:"animals_and_nature"},new_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"🌑",fitzpatrick_scale:false,category:"animals_and_nature"},waxing_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"🌒",fitzpatrick_scale:false,category:"animals_and_nature"},first_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"🌓",fitzpatrick_scale:false,category:"animals_and_nature"},waxing_gibbous_moon:{keywords:["nature","night","sky","gray","twilight","planet","space","evening","sleep"],char:"🌔",fitzpatrick_scale:false,category:"animals_and_nature"},new_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"🌚",fitzpatrick_scale:false,category:"animals_and_nature"},full_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"🌝",fitzpatrick_scale:false,category:"animals_and_nature"},first_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"🌛",fitzpatrick_scale:false,category:"animals_and_nature"},last_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"🌜",fitzpatrick_scale:false,category:"animals_and_nature"},sun_with_face:{keywords:["nature","morning","sky"],char:"🌞",fitzpatrick_scale:false,category:"animals_and_nature"},crescent_moon:{keywords:["night","sleep","sky","evening","magic"],char:"🌙",fitzpatrick_scale:false,category:"animals_and_nature"},star:{keywords:["night","yellow"],char:"⭐",fitzpatrick_scale:false,category:"animals_and_nature"},star2:{keywords:["night","sparkle","awesome","good","magic"],char:"🌟",fitzpatrick_scale:false,category:"animals_and_nature"},dizzy:{keywords:["star","sparkle","shoot","magic"],char:"💫",fitzpatrick_scale:false,category:"animals_and_nature"},sparkles:{keywords:["stars","shine","shiny","cool","awesome","good","magic"],char:"✨",fitzpatrick_scale:false,category:"animals_and_nature"},comet:{keywords:["space"],char:"☄",fitzpatrick_scale:false,category:"animals_and_nature"},sunny:{keywords:["weather","nature","brightness","summer","beach","spring"],char:"☀️",fitzpatrick_scale:false,category:"animals_and_nature"},sun_behind_small_cloud:{keywords:["weather"],char:"🌤",fitzpatrick_scale:false,category:"animals_and_nature"},partly_sunny:{keywords:["weather","nature","cloudy","morning","fall","spring"],char:"⛅",fitzpatrick_scale:false,category:"animals_and_nature"},sun_behind_large_cloud:{keywords:["weather"],char:"🌥",fitzpatrick_scale:false,category:"animals_and_nature"},sun_behind_rain_cloud:{keywords:["weather"],char:"🌦",fitzpatrick_scale:false,category:"animals_and_nature"},cloud:{keywords:["weather","sky"],char:"☁️",fitzpatrick_scale:false,category:"animals_and_nature"},cloud_with_rain:{keywords:["weather"],char:"🌧",fitzpatrick_scale:false,category:"animals_and_nature"},cloud_with_lightning_and_rain:{keywords:["weather","lightning"],char:"⛈",fitzpatrick_scale:false,category:"animals_and_nature"},cloud_with_lightning:{keywords:["weather","thunder"],char:"🌩",fitzpatrick_scale:false,category:"animals_and_nature"},zap:{keywords:["thunder","weather","lightning bolt","fast"],char:"⚡",fitzpatrick_scale:false,category:"animals_and_nature"},fire:{keywords:["hot","cook","flame"],char:"🔥",fitzpatrick_scale:false,category:"animals_and_nature"},boom:{keywords:["bomb","explode","explosion","collision","blown"],char:"💥",fitzpatrick_scale:false,category:"animals_and_nature"},snowflake:{keywords:["winter","season","cold","weather","christmas","xmas"],char:"❄️",fitzpatrick_scale:false,category:"animals_and_nature"},cloud_with_snow:{keywords:["weather"],char:"🌨",fitzpatrick_scale:false,category:"animals_and_nature"},snowman:{keywords:["winter","season","cold","weather","christmas","xmas","frozen","without_snow"],char:"⛄",fitzpatrick_scale:false,category:"animals_and_nature"},snowman_with_snow:{keywords:["winter","season","cold","weather","christmas","xmas","frozen"],char:"☃",fitzpatrick_scale:false,category:"animals_and_nature"},wind_face:{keywords:["gust","air"],char:"🌬",fitzpatrick_scale:false,category:"animals_and_nature"},dash:{keywords:["wind","air","fast","shoo","fart","smoke","puff"],char:"💨",fitzpatrick_scale:false,category:"animals_and_nature"},tornado:{keywords:["weather","cyclone","twister"],char:"🌪",fitzpatrick_scale:false,category:"animals_and_nature"},fog:{keywords:["weather"],char:"🌫",fitzpatrick_scale:false,category:"animals_and_nature"},open_umbrella:{keywords:["weather","spring"],char:"☂",fitzpatrick_scale:false,category:"animals_and_nature"},umbrella:{keywords:["rainy","weather","spring"],char:"☔",fitzpatrick_scale:false,category:"animals_and_nature"},droplet:{keywords:["water","drip","faucet","spring"],char:"💧",fitzpatrick_scale:false,category:"animals_and_nature"},sweat_drops:{keywords:["water","drip","oops"],char:"💦",fitzpatrick_scale:false,category:"animals_and_nature"},ocean:{keywords:["sea","water","wave","nature","tsunami","disaster"],char:"🌊",fitzpatrick_scale:false,category:"animals_and_nature"},green_apple:{keywords:["fruit","nature"],char:"🍏",fitzpatrick_scale:false,category:"food_and_drink"},apple:{keywords:["fruit","mac","school"],char:"🍎",fitzpatrick_scale:false,category:"food_and_drink"},pear:{keywords:["fruit","nature","food"],char:"🍐",fitzpatrick_scale:false,category:"food_and_drink"},tangerine:{keywords:["food","fruit","nature","orange"],char:"🍊",fitzpatrick_scale:false,category:"food_and_drink"},lemon:{keywords:["fruit","nature"],char:"🍋",fitzpatrick_scale:false,category:"food_and_drink"},banana:{keywords:["fruit","food","monkey"],char:"🍌",fitzpatrick_scale:false,category:"food_and_drink"},watermelon:{keywords:["fruit","food","picnic","summer"],char:"🍉",fitzpatrick_scale:false,category:"food_and_drink"},grapes:{keywords:["fruit","food","wine"],char:"🍇",fitzpatrick_scale:false,category:"food_and_drink"},strawberry:{keywords:["fruit","food","nature"],char:"🍓",fitzpatrick_scale:false,category:"food_and_drink"},melon:{keywords:["fruit","nature","food"],char:"🍈",fitzpatrick_scale:false,category:"food_and_drink"},cherries:{keywords:["food","fruit"],char:"🍒",fitzpatrick_scale:false,category:"food_and_drink"},peach:{keywords:["fruit","nature","food"],char:"🍑",fitzpatrick_scale:false,category:"food_and_drink"},pineapple:{keywords:["fruit","nature","food"],char:"🍍",fitzpatrick_scale:false,category:"food_and_drink"},coconut:{keywords:["fruit","nature","food","palm"],char:"🥥",fitzpatrick_scale:false,category:"food_and_drink"},kiwi_fruit:{keywords:["fruit","food"],char:"🥝",fitzpatrick_scale:false,category:"food_and_drink"},mango:{keywords:["fruit","food","tropical"],char:"🥭",fitzpatrick_scale:false,category:"food_and_drink"},avocado:{keywords:["fruit","food"],char:"🥑",fitzpatrick_scale:false,category:"food_and_drink"},broccoli:{keywords:["fruit","food","vegetable"],char:"🥦",fitzpatrick_scale:false,category:"food_and_drink"},tomato:{keywords:["fruit","vegetable","nature","food"],char:"🍅",fitzpatrick_scale:false,category:"food_and_drink"},eggplant:{keywords:["vegetable","nature","food","aubergine"],char:"🍆",fitzpatrick_scale:false,category:"food_and_drink"},cucumber:{keywords:["fruit","food","pickle"],char:"🥒",fitzpatrick_scale:false,category:"food_and_drink"},carrot:{keywords:["vegetable","food","orange"],char:"🥕",fitzpatrick_scale:false,category:"food_and_drink"},hot_pepper:{keywords:["food","spicy","chilli","chili"],char:"🌶",fitzpatrick_scale:false,category:"food_and_drink"},potato:{keywords:["food","tuber","vegatable","starch"],char:"🥔",fitzpatrick_scale:false,category:"food_and_drink"},corn:{keywords:["food","vegetable","plant"],char:"🌽",fitzpatrick_scale:false,category:"food_and_drink"},leafy_greens:{keywords:["food","vegetable","plant","bok choy","cabbage","kale","lettuce"],char:"🥬",fitzpatrick_scale:false,category:"food_and_drink"},sweet_potato:{keywords:["food","nature"],char:"🍠",fitzpatrick_scale:false,category:"food_and_drink"},peanuts:{keywords:["food","nut"],char:"🥜",fitzpatrick_scale:false,category:"food_and_drink"},honey_pot:{keywords:["bees","sweet","kitchen"],char:"🍯",fitzpatrick_scale:false,category:"food_and_drink"},croissant:{keywords:["food","bread","french"],char:"🥐",fitzpatrick_scale:false,category:"food_and_drink"},bread:{keywords:["food","wheat","breakfast","toast"],char:"🍞",fitzpatrick_scale:false,category:"food_and_drink"},baguette_bread:{keywords:["food","bread","french"],char:"🥖",fitzpatrick_scale:false,category:"food_and_drink"},bagel:{keywords:["food","bread","bakery","schmear"],char:"🥯",fitzpatrick_scale:false,category:"food_and_drink"},pretzel:{keywords:["food","bread","twisted"],char:"🥨",fitzpatrick_scale:false,category:"food_and_drink"},cheese:{keywords:["food","chadder"],char:"🧀",fitzpatrick_scale:false,category:"food_and_drink"},egg:{keywords:["food","chicken","breakfast"],char:"🥚",fitzpatrick_scale:false,category:"food_and_drink"},bacon:{keywords:["food","breakfast","pork","pig","meat"],char:"🥓",fitzpatrick_scale:false,category:"food_and_drink"},steak:{keywords:["food","cow","meat","cut","chop","lambchop","porkchop"],char:"🥩",fitzpatrick_scale:false,category:"food_and_drink"},pancakes:{keywords:["food","breakfast","flapjacks","hotcakes"],char:"🥞",fitzpatrick_scale:false,category:"food_and_drink"},poultry_leg:{keywords:["food","meat","drumstick","bird","chicken","turkey"],char:"🍗",fitzpatrick_scale:false,category:"food_and_drink"},meat_on_bone:{keywords:["good","food","drumstick"],char:"🍖",fitzpatrick_scale:false,category:"food_and_drink"},bone:{keywords:["skeleton"],char:"🦴",fitzpatrick_scale:false,category:"food_and_drink"},fried_shrimp:{keywords:["food","animal","appetizer","summer"],char:"🍤",fitzpatrick_scale:false,category:"food_and_drink"},fried_egg:{keywords:["food","breakfast","kitchen","egg"],char:"🍳",fitzpatrick_scale:false,category:"food_and_drink"},hamburger:{keywords:["meat","fast food","beef","cheeseburger","mcdonalds","burger king"],char:"🍔",fitzpatrick_scale:false,category:"food_and_drink"},fries:{keywords:["chips","snack","fast food"],char:"🍟",fitzpatrick_scale:false,category:"food_and_drink"},stuffed_flatbread:{keywords:["food","flatbread","stuffed","gyro"],char:"🥙",fitzpatrick_scale:false,category:"food_and_drink"},hotdog:{keywords:["food","frankfurter"],char:"🌭",fitzpatrick_scale:false,category:"food_and_drink"},pizza:{keywords:["food","party"],char:"🍕",fitzpatrick_scale:false,category:"food_and_drink"},sandwich:{keywords:["food","lunch","bread"],char:"🥪",fitzpatrick_scale:false,category:"food_and_drink"},canned_food:{keywords:["food","soup"],char:"🥫",fitzpatrick_scale:false,category:"food_and_drink"},spaghetti:{keywords:["food","italian","noodle"],char:"🍝",fitzpatrick_scale:false,category:"food_and_drink"},taco:{keywords:["food","mexican"],char:"🌮",fitzpatrick_scale:false,category:"food_and_drink"},burrito:{keywords:["food","mexican"],char:"🌯",fitzpatrick_scale:false,category:"food_and_drink"},green_salad:{keywords:["food","healthy","lettuce"],char:"🥗",fitzpatrick_scale:false,category:"food_and_drink"},shallow_pan_of_food:{keywords:["food","cooking","casserole","paella"],char:"🥘",fitzpatrick_scale:false,category:"food_and_drink"},ramen:{keywords:["food","japanese","noodle","chopsticks"],char:"🍜",fitzpatrick_scale:false,category:"food_and_drink"},stew:{keywords:["food","meat","soup"],char:"🍲",fitzpatrick_scale:false,category:"food_and_drink"},fish_cake:{keywords:["food","japan","sea","beach","narutomaki","pink","swirl","kamaboko","surimi","ramen"],char:"🍥",fitzpatrick_scale:false,category:"food_and_drink"},fortune_cookie:{keywords:["food","prophecy"],char:"🥠",fitzpatrick_scale:false,category:"food_and_drink"},sushi:{keywords:["food","fish","japanese","rice"],char:"🍣",fitzpatrick_scale:false,category:"food_and_drink"},bento:{keywords:["food","japanese","box"],char:"🍱",fitzpatrick_scale:false,category:"food_and_drink"},curry:{keywords:["food","spicy","hot","indian"],char:"🍛",fitzpatrick_scale:false,category:"food_and_drink"},rice_ball:{keywords:["food","japanese"],char:"🍙",fitzpatrick_scale:false,category:"food_and_drink"},rice:{keywords:["food","china","asian"],char:"🍚",fitzpatrick_scale:false,category:"food_and_drink"},rice_cracker:{keywords:["food","japanese"],char:"🍘",fitzpatrick_scale:false,category:"food_and_drink"},oden:{keywords:["food","japanese"],char:"🍢",fitzpatrick_scale:false,category:"food_and_drink"},dango:{keywords:["food","dessert","sweet","japanese","barbecue","meat"],char:"🍡",fitzpatrick_scale:false,category:"food_and_drink"},shaved_ice:{keywords:["hot","dessert","summer"],char:"🍧",fitzpatrick_scale:false,category:"food_and_drink"},ice_cream:{keywords:["food","hot","dessert"],char:"🍨",fitzpatrick_scale:false,category:"food_and_drink"},icecream:{keywords:["food","hot","dessert","summer"],char:"🍦",fitzpatrick_scale:false,category:"food_and_drink"},pie:{keywords:["food","dessert","pastry"],char:"🥧",fitzpatrick_scale:false,category:"food_and_drink"},cake:{keywords:["food","dessert"],char:"🍰",fitzpatrick_scale:false,category:"food_and_drink"},cupcake:{keywords:["food","dessert","bakery","sweet"],char:"🧁",fitzpatrick_scale:false,category:"food_and_drink"},moon_cake:{keywords:["food","autumn"],char:"🥮",fitzpatrick_scale:false,category:"food_and_drink"},birthday:{keywords:["food","dessert","cake"],char:"🎂",fitzpatrick_scale:false,category:"food_and_drink"},custard:{keywords:["dessert","food"],char:"🍮",fitzpatrick_scale:false,category:"food_and_drink"},candy:{keywords:["snack","dessert","sweet","lolly"],char:"🍬",fitzpatrick_scale:false,category:"food_and_drink"},lollipop:{keywords:["food","snack","candy","sweet"],char:"🍭",fitzpatrick_scale:false,category:"food_and_drink"},chocolate_bar:{keywords:["food","snack","dessert","sweet"],char:"🍫",fitzpatrick_scale:false,category:"food_and_drink"},popcorn:{keywords:["food","movie theater","films","snack"],char:"🍿",fitzpatrick_scale:false,category:"food_and_drink"},dumpling:{keywords:["food","empanada","pierogi","potsticker"],char:"🥟",fitzpatrick_scale:false,category:"food_and_drink"},doughnut:{keywords:["food","dessert","snack","sweet","donut"],char:"🍩",fitzpatrick_scale:false,category:"food_and_drink"},cookie:{keywords:["food","snack","oreo","chocolate","sweet","dessert"],char:"🍪",fitzpatrick_scale:false,category:"food_and_drink"},milk_glass:{keywords:["beverage","drink","cow"],char:"🥛",fitzpatrick_scale:false,category:"food_and_drink"},beer:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:"🍺",fitzpatrick_scale:false,category:"food_and_drink"},beers:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:"🍻",fitzpatrick_scale:false,category:"food_and_drink"},clinking_glasses:{keywords:["beverage","drink","party","alcohol","celebrate","cheers","wine","champagne","toast"],char:"🥂",fitzpatrick_scale:false,category:"food_and_drink"},wine_glass:{keywords:["drink","beverage","drunk","alcohol","booze"],char:"🍷",fitzpatrick_scale:false,category:"food_and_drink"},tumbler_glass:{keywords:["drink","beverage","drunk","alcohol","liquor","booze","bourbon","scotch","whisky","glass","shot"],char:"🥃",fitzpatrick_scale:false,category:"food_and_drink"},cocktail:{keywords:["drink","drunk","alcohol","beverage","booze","mojito"],char:"🍸",fitzpatrick_scale:false,category:"food_and_drink"},tropical_drink:{keywords:["beverage","cocktail","summer","beach","alcohol","booze","mojito"],char:"🍹",fitzpatrick_scale:false,category:"food_and_drink"},champagne:{keywords:["drink","wine","bottle","celebration"],char:"🍾",fitzpatrick_scale:false,category:"food_and_drink"},sake:{keywords:["wine","drink","drunk","beverage","japanese","alcohol","booze"],char:"🍶",fitzpatrick_scale:false,category:"food_and_drink"},tea:{keywords:["drink","bowl","breakfast","green","british"],char:"🍵",fitzpatrick_scale:false,category:"food_and_drink"},cup_with_straw:{keywords:["drink","soda"],char:"🥤",fitzpatrick_scale:false,category:"food_and_drink"},coffee:{keywords:["beverage","caffeine","latte","espresso"],char:"☕",fitzpatrick_scale:false,category:"food_and_drink"},baby_bottle:{keywords:["food","container","milk"],char:"🍼",fitzpatrick_scale:false,category:"food_and_drink"},salt:{keywords:["condiment","shaker"],char:"🧂",fitzpatrick_scale:false,category:"food_and_drink"},spoon:{keywords:["cutlery","kitchen","tableware"],char:"🥄",fitzpatrick_scale:false,category:"food_and_drink"},fork_and_knife:{keywords:["cutlery","kitchen"],char:"🍴",fitzpatrick_scale:false,category:"food_and_drink"},plate_with_cutlery:{keywords:["food","eat","meal","lunch","dinner","restaurant"],char:"🍽",fitzpatrick_scale:false,category:"food_and_drink"},bowl_with_spoon:{keywords:["food","breakfast","cereal","oatmeal","porridge"],char:"🥣",fitzpatrick_scale:false,category:"food_and_drink"},takeout_box:{keywords:["food","leftovers"],char:"🥡",fitzpatrick_scale:false,category:"food_and_drink"},chopsticks:{keywords:["food"],char:"🥢",fitzpatrick_scale:false,category:"food_and_drink"},soccer:{keywords:["sports","football"],char:"⚽",fitzpatrick_scale:false,category:"activity"},basketball:{keywords:["sports","balls","NBA"],char:"🏀",fitzpatrick_scale:false,category:"activity"},football:{keywords:["sports","balls","NFL"],char:"🏈",fitzpatrick_scale:false,category:"activity"},baseball:{keywords:["sports","balls"],char:"⚾",fitzpatrick_scale:false,category:"activity"},softball:{keywords:["sports","balls"],char:"🥎",fitzpatrick_scale:false,category:"activity"},tennis:{keywords:["sports","balls","green"],char:"🎾",fitzpatrick_scale:false,category:"activity"},volleyball:{keywords:["sports","balls"],char:"🏐",fitzpatrick_scale:false,category:"activity"},rugby_football:{keywords:["sports","team"],char:"🏉",fitzpatrick_scale:false,category:"activity"},flying_disc:{keywords:["sports","frisbee","ultimate"],char:"🥏",fitzpatrick_scale:false,category:"activity"},"8ball":{keywords:["pool","hobby","game","luck","magic"],char:"🎱",fitzpatrick_scale:false,category:"activity"},golf:{keywords:["sports","business","flag","hole","summer"],char:"⛳",fitzpatrick_scale:false,category:"activity"},golfing_woman:{keywords:["sports","business","woman","female"],char:"🏌️‍♀️",fitzpatrick_scale:false,category:"activity"},golfing_man:{keywords:["sports","business"],char:"🏌",fitzpatrick_scale:true,category:"activity"},ping_pong:{keywords:["sports","pingpong"],char:"🏓",fitzpatrick_scale:false,category:"activity"},badminton:{keywords:["sports"],char:"🏸",fitzpatrick_scale:false,category:"activity"},goal_net:{keywords:["sports"],char:"🥅",fitzpatrick_scale:false,category:"activity"},ice_hockey:{keywords:["sports"],char:"🏒",fitzpatrick_scale:false,category:"activity"},field_hockey:{keywords:["sports"],char:"🏑",fitzpatrick_scale:false,category:"activity"},lacrosse:{keywords:["sports","ball","stick"],char:"🥍",fitzpatrick_scale:false,category:"activity"},cricket:{keywords:["sports"],char:"🏏",fitzpatrick_scale:false,category:"activity"},ski:{keywords:["sports","winter","cold","snow"],char:"🎿",fitzpatrick_scale:false,category:"activity"},skier:{keywords:["sports","winter","snow"],char:"⛷",fitzpatrick_scale:false,category:"activity"},snowboarder:{keywords:["sports","winter"],char:"🏂",fitzpatrick_scale:true,category:"activity"},person_fencing:{keywords:["sports","fencing","sword"],char:"🤺",fitzpatrick_scale:false,category:"activity"},women_wrestling:{keywords:["sports","wrestlers"],char:"🤼‍♀️",fitzpatrick_scale:false,category:"activity"},men_wrestling:{keywords:["sports","wrestlers"],char:"🤼‍♂️",fitzpatrick_scale:false,category:"activity"},woman_cartwheeling:{keywords:["gymnastics"],char:"🤸‍♀️",fitzpatrick_scale:true,category:"activity"},man_cartwheeling:{keywords:["gymnastics"],char:"🤸‍♂️",fitzpatrick_scale:true,category:"activity"},woman_playing_handball:{keywords:["sports"],char:"🤾‍♀️",fitzpatrick_scale:true,category:"activity"},man_playing_handball:{keywords:["sports"],char:"🤾‍♂️",fitzpatrick_scale:true,category:"activity"},ice_skate:{keywords:["sports"],char:"⛸",fitzpatrick_scale:false,category:"activity"},curling_stone:{keywords:["sports"],char:"🥌",fitzpatrick_scale:false,category:"activity"},skateboard:{keywords:["board"],char:"🛹",fitzpatrick_scale:false,category:"activity"},sled:{keywords:["sleigh","luge","toboggan"],char:"🛷",fitzpatrick_scale:false,category:"activity"},bow_and_arrow:{keywords:["sports"],char:"🏹",fitzpatrick_scale:false,category:"activity"},fishing_pole_and_fish:{keywords:["food","hobby","summer"],char:"🎣",fitzpatrick_scale:false,category:"activity"},boxing_glove:{keywords:["sports","fighting"],char:"🥊",fitzpatrick_scale:false,category:"activity"},martial_arts_uniform:{keywords:["judo","karate","taekwondo"],char:"🥋",fitzpatrick_scale:false,category:"activity"},rowing_woman:{keywords:["sports","hobby","water","ship","woman","female"],char:"🚣‍♀️",fitzpatrick_scale:true,category:"activity"},rowing_man:{keywords:["sports","hobby","water","ship"],char:"🚣",fitzpatrick_scale:true,category:"activity"},climbing_woman:{keywords:["sports","hobby","woman","female","rock"],char:"🧗‍♀️",fitzpatrick_scale:true,category:"activity"},climbing_man:{keywords:["sports","hobby","man","male","rock"],char:"🧗‍♂️",fitzpatrick_scale:true,category:"activity"},swimming_woman:{keywords:["sports","exercise","human","athlete","water","summer","woman","female"],char:"🏊‍♀️",fitzpatrick_scale:true,category:"activity"},swimming_man:{keywords:["sports","exercise","human","athlete","water","summer"],char:"🏊",fitzpatrick_scale:true,category:"activity"},woman_playing_water_polo:{keywords:["sports","pool"],char:"🤽‍♀️",fitzpatrick_scale:true,category:"activity"},man_playing_water_polo:{keywords:["sports","pool"],char:"🤽‍♂️",fitzpatrick_scale:true,category:"activity"},woman_in_lotus_position:{keywords:["woman","female","meditation","yoga","serenity","zen","mindfulness"],char:"🧘‍♀️",fitzpatrick_scale:true,category:"activity"},man_in_lotus_position:{keywords:["man","male","meditation","yoga","serenity","zen","mindfulness"],char:"🧘‍♂️",fitzpatrick_scale:true,category:"activity"},surfing_woman:{keywords:["sports","ocean","sea","summer","beach","woman","female"],char:"🏄‍♀️",fitzpatrick_scale:true,category:"activity"},surfing_man:{keywords:["sports","ocean","sea","summer","beach"],char:"🏄",fitzpatrick_scale:true,category:"activity"},bath:{keywords:["clean","shower","bathroom"],char:"🛀",fitzpatrick_scale:true,category:"activity"},basketball_woman:{keywords:["sports","human","woman","female"],char:"⛹️‍♀️",fitzpatrick_scale:true,category:"activity"},basketball_man:{keywords:["sports","human"],char:"⛹",fitzpatrick_scale:true,category:"activity"},weight_lifting_woman:{keywords:["sports","training","exercise","woman","female"],char:"🏋️‍♀️",fitzpatrick_scale:true,category:"activity"},weight_lifting_man:{keywords:["sports","training","exercise"],char:"🏋",fitzpatrick_scale:true,category:"activity"},biking_woman:{keywords:["sports","bike","exercise","hipster","woman","female"],char:"🚴‍♀️",fitzpatrick_scale:true,category:"activity"},biking_man:{keywords:["sports","bike","exercise","hipster"],char:"🚴",fitzpatrick_scale:true,category:"activity"},mountain_biking_woman:{keywords:["transportation","sports","human","race","bike","woman","female"],char:"🚵‍♀️",fitzpatrick_scale:true,category:"activity"},mountain_biking_man:{keywords:["transportation","sports","human","race","bike"],char:"🚵",fitzpatrick_scale:true,category:"activity"},horse_racing:{keywords:["animal","betting","competition","gambling","luck"],char:"🏇",fitzpatrick_scale:true,category:"activity"},business_suit_levitating:{keywords:["suit","business","levitate","hover","jump"],char:"🕴",fitzpatrick_scale:true,category:"activity"},trophy:{keywords:["win","award","contest","place","ftw","ceremony"],char:"🏆",fitzpatrick_scale:false,category:"activity"},running_shirt_with_sash:{keywords:["play","pageant"],char:"🎽",fitzpatrick_scale:false,category:"activity"},medal_sports:{keywords:["award","winning"],char:"🏅",fitzpatrick_scale:false,category:"activity"},medal_military:{keywords:["award","winning","army"],char:"🎖",fitzpatrick_scale:false,category:"activity"},"1st_place_medal":{keywords:["award","winning","first"],char:"🥇",fitzpatrick_scale:false,category:"activity"},"2nd_place_medal":{keywords:["award","second"],char:"🥈",fitzpatrick_scale:false,category:"activity"},"3rd_place_medal":{keywords:["award","third"],char:"🥉",fitzpatrick_scale:false,category:"activity"},reminder_ribbon:{keywords:["sports","cause","support","awareness"],char:"🎗",fitzpatrick_scale:false,category:"activity"},rosette:{keywords:["flower","decoration","military"],char:"🏵",fitzpatrick_scale:false,category:"activity"},ticket:{keywords:["event","concert","pass"],char:"🎫",fitzpatrick_scale:false,category:"activity"},tickets:{keywords:["sports","concert","entrance"],char:"🎟",fitzpatrick_scale:false,category:"activity"},performing_arts:{keywords:["acting","theater","drama"],char:"🎭",fitzpatrick_scale:false,category:"activity"},art:{keywords:["design","paint","draw","colors"],char:"🎨",fitzpatrick_scale:false,category:"activity"},circus_tent:{keywords:["festival","carnival","party"],char:"🎪",fitzpatrick_scale:false,category:"activity"},woman_juggling:{keywords:["juggle","balance","skill","multitask"],char:"🤹‍♀️",fitzpatrick_scale:true,category:"activity"},man_juggling:{keywords:["juggle","balance","skill","multitask"],char:"🤹‍♂️",fitzpatrick_scale:true,category:"activity"},microphone:{keywords:["sound","music","PA","sing","talkshow"],char:"🎤",fitzpatrick_scale:false,category:"activity"},headphones:{keywords:["music","score","gadgets"],char:"🎧",fitzpatrick_scale:false,category:"activity"},musical_score:{keywords:["treble","clef","compose"],char:"🎼",fitzpatrick_scale:false,category:"activity"},musical_keyboard:{keywords:["piano","instrument","compose"],char:"🎹",fitzpatrick_scale:false,category:"activity"},drum:{keywords:["music","instrument","drumsticks","snare"],char:"🥁",fitzpatrick_scale:false,category:"activity"},saxophone:{keywords:["music","instrument","jazz","blues"],char:"🎷",fitzpatrick_scale:false,category:"activity"},trumpet:{keywords:["music","brass"],char:"🎺",fitzpatrick_scale:false,category:"activity"},guitar:{keywords:["music","instrument"],char:"🎸",fitzpatrick_scale:false,category:"activity"},violin:{keywords:["music","instrument","orchestra","symphony"],char:"🎻",fitzpatrick_scale:false,category:"activity"},clapper:{keywords:["movie","film","record"],char:"🎬",fitzpatrick_scale:false,category:"activity"},video_game:{keywords:["play","console","PS4","controller"],char:"🎮",fitzpatrick_scale:false,category:"activity"},space_invader:{keywords:["game","arcade","play"],char:"👾",fitzpatrick_scale:false,category:"activity"},dart:{keywords:["game","play","bar","target","bullseye"],char:"🎯",fitzpatrick_scale:false,category:"activity"},game_die:{keywords:["dice","random","tabletop","play","luck"],char:"🎲",fitzpatrick_scale:false,category:"activity"},chess_pawn:{keywords:["expendable"],char:"♟",fitzpatrick_scale:false,category:"activity"},slot_machine:{keywords:["bet","gamble","vegas","fruit machine","luck","casino"],char:"🎰",fitzpatrick_scale:false,category:"activity"},jigsaw:{keywords:["interlocking","puzzle","piece"],char:"🧩",fitzpatrick_scale:false,category:"activity"},bowling:{keywords:["sports","fun","play"],char:"🎳",fitzpatrick_scale:false,category:"activity"},red_car:{keywords:["red","transportation","vehicle"],char:"🚗",fitzpatrick_scale:false,category:"travel_and_places"},taxi:{keywords:["uber","vehicle","cars","transportation"],char:"🚕",fitzpatrick_scale:false,category:"travel_and_places"},blue_car:{keywords:["transportation","vehicle"],char:"🚙",fitzpatrick_scale:false,category:"travel_and_places"},bus:{keywords:["car","vehicle","transportation"],char:"🚌",fitzpatrick_scale:false,category:"travel_and_places"},trolleybus:{keywords:["bart","transportation","vehicle"],char:"🚎",fitzpatrick_scale:false,category:"travel_and_places"},racing_car:{keywords:["sports","race","fast","formula","f1"],char:"🏎",fitzpatrick_scale:false,category:"travel_and_places"},police_car:{keywords:["vehicle","cars","transportation","law","legal","enforcement"],char:"🚓",fitzpatrick_scale:false,category:"travel_and_places"},ambulance:{keywords:["health","911","hospital"],char:"🚑",fitzpatrick_scale:false,category:"travel_and_places"},fire_engine:{keywords:["transportation","cars","vehicle"],char:"🚒",fitzpatrick_scale:false,category:"travel_and_places"},minibus:{keywords:["vehicle","car","transportation"],char:"🚐",fitzpatrick_scale:false,category:"travel_and_places"},truck:{keywords:["cars","transportation"],char:"🚚",fitzpatrick_scale:false,category:"travel_and_places"},articulated_lorry:{keywords:["vehicle","cars","transportation","express"],char:"🚛",fitzpatrick_scale:false,category:"travel_and_places"},tractor:{keywords:["vehicle","car","farming","agriculture"],char:"🚜",fitzpatrick_scale:false,category:"travel_and_places"},kick_scooter:{keywords:["vehicle","kick","razor"],char:"🛴",fitzpatrick_scale:false,category:"travel_and_places"},motorcycle:{keywords:["race","sports","fast"],char:"🏍",fitzpatrick_scale:false,category:"travel_and_places"},bike:{keywords:["sports","bicycle","exercise","hipster"],char:"🚲",fitzpatrick_scale:false,category:"travel_and_places"},motor_scooter:{keywords:["vehicle","vespa","sasha"],char:"🛵",fitzpatrick_scale:false,category:"travel_and_places"},rotating_light:{keywords:["police","ambulance","911","emergency","alert","error","pinged","law","legal"],char:"🚨",fitzpatrick_scale:false,category:"travel_and_places"},oncoming_police_car:{keywords:["vehicle","law","legal","enforcement","911"],char:"🚔",fitzpatrick_scale:false,category:"travel_and_places"},oncoming_bus:{keywords:["vehicle","transportation"],char:"🚍",fitzpatrick_scale:false,category:"travel_and_places"},oncoming_automobile:{keywords:["car","vehicle","transportation"],char:"🚘",fitzpatrick_scale:false,category:"travel_and_places"},oncoming_taxi:{keywords:["vehicle","cars","uber"],char:"🚖",fitzpatrick_scale:false,category:"travel_and_places"},aerial_tramway:{keywords:["transportation","vehicle","ski"],char:"🚡",fitzpatrick_scale:false,category:"travel_and_places"},mountain_cableway:{keywords:["transportation","vehicle","ski"],char:"🚠",fitzpatrick_scale:false,category:"travel_and_places"},suspension_railway:{keywords:["vehicle","transportation"],char:"🚟",fitzpatrick_scale:false,category:"travel_and_places"},railway_car:{keywords:["transportation","vehicle"],char:"🚃",fitzpatrick_scale:false,category:"travel_and_places"},train:{keywords:["transportation","vehicle","carriage","public","travel"],char:"🚋",fitzpatrick_scale:false,category:"travel_and_places"},monorail:{keywords:["transportation","vehicle"],char:"🚝",fitzpatrick_scale:false,category:"travel_and_places"},bullettrain_side:{keywords:["transportation","vehicle"],char:"🚄",fitzpatrick_scale:false,category:"travel_and_places"},bullettrain_front:{keywords:["transportation","vehicle","speed","fast","public","travel"],char:"🚅",fitzpatrick_scale:false,category:"travel_and_places"},light_rail:{keywords:["transportation","vehicle"],char:"🚈",fitzpatrick_scale:false,category:"travel_and_places"},mountain_railway:{keywords:["transportation","vehicle"],char:"🚞",fitzpatrick_scale:false,category:"travel_and_places"},steam_locomotive:{keywords:["transportation","vehicle","train"],char:"🚂",fitzpatrick_scale:false,category:"travel_and_places"},train2:{keywords:["transportation","vehicle"],char:"🚆",fitzpatrick_scale:false,category:"travel_and_places"},metro:{keywords:["transportation","blue-square","mrt","underground","tube"],char:"🚇",fitzpatrick_scale:false,category:"travel_and_places"},tram:{keywords:["transportation","vehicle"],char:"🚊",fitzpatrick_scale:false,category:"travel_and_places"},station:{keywords:["transportation","vehicle","public"],char:"🚉",fitzpatrick_scale:false,category:"travel_and_places"},flying_saucer:{keywords:["transportation","vehicle","ufo"],char:"🛸",fitzpatrick_scale:false,category:"travel_and_places"},helicopter:{keywords:["transportation","vehicle","fly"],char:"🚁",fitzpatrick_scale:false,category:"travel_and_places"},small_airplane:{keywords:["flight","transportation","fly","vehicle"],char:"🛩",fitzpatrick_scale:false,category:"travel_and_places"},airplane:{keywords:["vehicle","transportation","flight","fly"],char:"✈️",fitzpatrick_scale:false,category:"travel_and_places"},flight_departure:{keywords:["airport","flight","landing"],char:"🛫",fitzpatrick_scale:false,category:"travel_and_places"},flight_arrival:{keywords:["airport","flight","boarding"],char:"🛬",fitzpatrick_scale:false,category:"travel_and_places"},sailboat:{keywords:["ship","summer","transportation","water","sailing"],char:"⛵",fitzpatrick_scale:false,category:"travel_and_places"},motor_boat:{keywords:["ship"],char:"🛥",fitzpatrick_scale:false,category:"travel_and_places"},speedboat:{keywords:["ship","transportation","vehicle","summer"],char:"🚤",fitzpatrick_scale:false,category:"travel_and_places"},ferry:{keywords:["boat","ship","yacht"],char:"⛴",fitzpatrick_scale:false,category:"travel_and_places"},passenger_ship:{keywords:["yacht","cruise","ferry"],char:"🛳",fitzpatrick_scale:false,category:"travel_and_places"},rocket:{keywords:["launch","ship","staffmode","NASA","outer space","outer_space","fly"],char:"🚀",fitzpatrick_scale:false,category:"travel_and_places"},artificial_satellite:{keywords:["communication","gps","orbit","spaceflight","NASA","ISS"],char:"🛰",fitzpatrick_scale:false,category:"travel_and_places"},seat:{keywords:["sit","airplane","transport","bus","flight","fly"],char:"💺",fitzpatrick_scale:false,category:"travel_and_places"},canoe:{keywords:["boat","paddle","water","ship"],char:"🛶",fitzpatrick_scale:false,category:"travel_and_places"},anchor:{keywords:["ship","ferry","sea","boat"],char:"⚓",fitzpatrick_scale:false,category:"travel_and_places"},construction:{keywords:["wip","progress","caution","warning"],char:"🚧",fitzpatrick_scale:false,category:"travel_and_places"},fuelpump:{keywords:["gas station","petroleum"],char:"⛽",fitzpatrick_scale:false,category:"travel_and_places"},busstop:{keywords:["transportation","wait"],char:"🚏",fitzpatrick_scale:false,category:"travel_and_places"},vertical_traffic_light:{keywords:["transportation","driving"],char:"🚦",fitzpatrick_scale:false,category:"travel_and_places"},traffic_light:{keywords:["transportation","signal"],char:"🚥",fitzpatrick_scale:false,category:"travel_and_places"},checkered_flag:{keywords:["contest","finishline","race","gokart"],char:"🏁",fitzpatrick_scale:false,category:"travel_and_places"},ship:{keywords:["transportation","titanic","deploy"],char:"🚢",fitzpatrick_scale:false,category:"travel_and_places"},ferris_wheel:{keywords:["photo","carnival","londoneye"],char:"🎡",fitzpatrick_scale:false,category:"travel_and_places"},roller_coaster:{keywords:["carnival","playground","photo","fun"],char:"🎢",fitzpatrick_scale:false,category:"travel_and_places"},carousel_horse:{keywords:["photo","carnival"],char:"🎠",fitzpatrick_scale:false,category:"travel_and_places"},building_construction:{keywords:["wip","working","progress"],char:"🏗",fitzpatrick_scale:false,category:"travel_and_places"},foggy:{keywords:["photo","mountain"],char:"🌁",fitzpatrick_scale:false,category:"travel_and_places"},tokyo_tower:{keywords:["photo","japanese"],char:"🗼",fitzpatrick_scale:false,category:"travel_and_places"},factory:{keywords:["building","industry","pollution","smoke"],char:"🏭",fitzpatrick_scale:false,category:"travel_and_places"},fountain:{keywords:["photo","summer","water","fresh"],char:"⛲",fitzpatrick_scale:false,category:"travel_and_places"},rice_scene:{keywords:["photo","japan","asia","tsukimi"],char:"🎑",fitzpatrick_scale:false,category:"travel_and_places"},mountain:{keywords:["photo","nature","environment"],char:"⛰",fitzpatrick_scale:false,category:"travel_and_places"},mountain_snow:{keywords:["photo","nature","environment","winter","cold"],char:"🏔",fitzpatrick_scale:false,category:"travel_and_places"},mount_fuji:{keywords:["photo","mountain","nature","japanese"],char:"🗻",fitzpatrick_scale:false,category:"travel_and_places"},volcano:{keywords:["photo","nature","disaster"],char:"🌋",fitzpatrick_scale:false,category:"travel_and_places"},japan:{keywords:["nation","country","japanese","asia"],char:"🗾",fitzpatrick_scale:false,category:"travel_and_places"},camping:{keywords:["photo","outdoors","tent"],char:"🏕",fitzpatrick_scale:false,category:"travel_and_places"},tent:{keywords:["photo","camping","outdoors"],char:"⛺",fitzpatrick_scale:false,category:"travel_and_places"},national_park:{keywords:["photo","environment","nature"],char:"🏞",fitzpatrick_scale:false,category:"travel_and_places"},motorway:{keywords:["road","cupertino","interstate","highway"],char:"🛣",fitzpatrick_scale:false,category:"travel_and_places"},railway_track:{keywords:["train","transportation"],char:"🛤",fitzpatrick_scale:false,category:"travel_and_places"},sunrise:{keywords:["morning","view","vacation","photo"],char:"🌅",fitzpatrick_scale:false,category:"travel_and_places"},sunrise_over_mountains:{keywords:["view","vacation","photo"],char:"🌄",fitzpatrick_scale:false,category:"travel_and_places"},desert:{keywords:["photo","warm","saharah"],char:"🏜",fitzpatrick_scale:false,category:"travel_and_places"},beach_umbrella:{keywords:["weather","summer","sunny","sand","mojito"],char:"🏖",fitzpatrick_scale:false,category:"travel_and_places"},desert_island:{keywords:["photo","tropical","mojito"],char:"🏝",fitzpatrick_scale:false,category:"travel_and_places"},city_sunrise:{keywords:["photo","good morning","dawn"],char:"🌇",fitzpatrick_scale:false,category:"travel_and_places"},city_sunset:{keywords:["photo","evening","sky","buildings"],char:"🌆",fitzpatrick_scale:false,category:"travel_and_places"},cityscape:{keywords:["photo","night life","urban"],char:"🏙",fitzpatrick_scale:false,category:"travel_and_places"},night_with_stars:{keywords:["evening","city","downtown"],char:"🌃",fitzpatrick_scale:false,category:"travel_and_places"},bridge_at_night:{keywords:["photo","sanfrancisco"],char:"🌉",fitzpatrick_scale:false,category:"travel_and_places"},milky_way:{keywords:["photo","space","stars"],char:"🌌",fitzpatrick_scale:false,category:"travel_and_places"},stars:{keywords:["night","photo"],char:"🌠",fitzpatrick_scale:false,category:"travel_and_places"},sparkler:{keywords:["stars","night","shine"],char:"🎇",fitzpatrick_scale:false,category:"travel_and_places"},fireworks:{keywords:["photo","festival","carnival","congratulations"],char:"🎆",fitzpatrick_scale:false,category:"travel_and_places"},rainbow:{keywords:["nature","happy","unicorn_face","photo","sky","spring"],char:"🌈",fitzpatrick_scale:false,category:"travel_and_places"},houses:{keywords:["buildings","photo"],char:"🏘",fitzpatrick_scale:false,category:"travel_and_places"},european_castle:{keywords:["building","royalty","history"],char:"🏰",fitzpatrick_scale:false,category:"travel_and_places"},japanese_castle:{keywords:["photo","building"],char:"🏯",fitzpatrick_scale:false,category:"travel_and_places"},stadium:{keywords:["photo","place","sports","concert","venue"],char:"🏟",fitzpatrick_scale:false,category:"travel_and_places"},statue_of_liberty:{keywords:["american","newyork"],char:"🗽",fitzpatrick_scale:false,category:"travel_and_places"},house:{keywords:["building","home"],char:"🏠",fitzpatrick_scale:false,category:"travel_and_places"},house_with_garden:{keywords:["home","plant","nature"],char:"🏡",fitzpatrick_scale:false,category:"travel_and_places"},derelict_house:{keywords:["abandon","evict","broken","building"],char:"🏚",fitzpatrick_scale:false,category:"travel_and_places"},office:{keywords:["building","bureau","work"],char:"🏢",fitzpatrick_scale:false,category:"travel_and_places"},department_store:{keywords:["building","shopping","mall"],char:"🏬",fitzpatrick_scale:false,category:"travel_and_places"},post_office:{keywords:["building","envelope","communication"],char:"🏣",fitzpatrick_scale:false,category:"travel_and_places"},european_post_office:{keywords:["building","email"],char:"🏤",fitzpatrick_scale:false,category:"travel_and_places"},hospital:{keywords:["building","health","surgery","doctor"],char:"🏥",fitzpatrick_scale:false,category:"travel_and_places"},bank:{keywords:["building","money","sales","cash","business","enterprise"],char:"🏦",fitzpatrick_scale:false,category:"travel_and_places"},hotel:{keywords:["building","accomodation","checkin"],char:"🏨",fitzpatrick_scale:false,category:"travel_and_places"},convenience_store:{keywords:["building","shopping","groceries"],char:"🏪",fitzpatrick_scale:false,category:"travel_and_places"},school:{keywords:["building","student","education","learn","teach"],char:"🏫",fitzpatrick_scale:false,category:"travel_and_places"},love_hotel:{keywords:["like","affection","dating"],char:"🏩",fitzpatrick_scale:false,category:"travel_and_places"},wedding:{keywords:["love","like","affection","couple","marriage","bride","groom"],char:"💒",fitzpatrick_scale:false,category:"travel_and_places"},classical_building:{keywords:["art","culture","history"],char:"🏛",fitzpatrick_scale:false,category:"travel_and_places"},church:{keywords:["building","religion","christ"],char:"⛪",fitzpatrick_scale:false,category:"travel_and_places"},mosque:{keywords:["islam","worship","minaret"],char:"🕌",fitzpatrick_scale:false,category:"travel_and_places"},synagogue:{keywords:["judaism","worship","temple","jewish"],char:"🕍",fitzpatrick_scale:false,category:"travel_and_places"},kaaba:{keywords:["mecca","mosque","islam"],char:"🕋",fitzpatrick_scale:false,category:"travel_and_places"},shinto_shrine:{keywords:["temple","japan","kyoto"],char:"⛩",fitzpatrick_scale:false,category:"travel_and_places"},watch:{keywords:["time","accessories"],char:"⌚",fitzpatrick_scale:false,category:"objects"},iphone:{keywords:["technology","apple","gadgets","dial"],char:"📱",fitzpatrick_scale:false,category:"objects"},calling:{keywords:["iphone","incoming"],char:"📲",fitzpatrick_scale:false,category:"objects"},computer:{keywords:["technology","laptop","screen","display","monitor"],char:"💻",fitzpatrick_scale:false,category:"objects"},keyboard:{keywords:["technology","computer","type","input","text"],char:"⌨",fitzpatrick_scale:false,category:"objects"},desktop_computer:{keywords:["technology","computing","screen"],char:"🖥",fitzpatrick_scale:false,category:"objects"},printer:{keywords:["paper","ink"],char:"🖨",fitzpatrick_scale:false,category:"objects"},computer_mouse:{keywords:["click"],char:"🖱",fitzpatrick_scale:false,category:"objects"},trackball:{keywords:["technology","trackpad"],char:"🖲",fitzpatrick_scale:false,category:"objects"},joystick:{keywords:["game","play"],char:"🕹",fitzpatrick_scale:false,category:"objects"},clamp:{keywords:["tool"],char:"🗜",fitzpatrick_scale:false,category:"objects"},minidisc:{keywords:["technology","record","data","disk","90s"],char:"💽",fitzpatrick_scale:false,category:"objects"},floppy_disk:{keywords:["oldschool","technology","save","90s","80s"],char:"💾",fitzpatrick_scale:false,category:"objects"},cd:{keywords:["technology","dvd","disk","disc","90s"],char:"💿",fitzpatrick_scale:false,category:"objects"},dvd:{keywords:["cd","disk","disc"],char:"📀",fitzpatrick_scale:false,category:"objects"},vhs:{keywords:["record","video","oldschool","90s","80s"],char:"📼",fitzpatrick_scale:false,category:"objects"},camera:{keywords:["gadgets","photography"],char:"📷",fitzpatrick_scale:false,category:"objects"},camera_flash:{keywords:["photography","gadgets"],char:"📸",fitzpatrick_scale:false,category:"objects"},video_camera:{keywords:["film","record"],char:"📹",fitzpatrick_scale:false,category:"objects"},movie_camera:{keywords:["film","record"],char:"🎥",fitzpatrick_scale:false,category:"objects"},film_projector:{keywords:["video","tape","record","movie"],char:"📽",fitzpatrick_scale:false,category:"objects"},film_strip:{keywords:["movie"],char:"🎞",fitzpatrick_scale:false,category:"objects"},telephone_receiver:{keywords:["technology","communication","dial"],char:"📞",fitzpatrick_scale:false,category:"objects"},phone:{keywords:["technology","communication","dial","telephone"],char:"☎️",fitzpatrick_scale:false,category:"objects"},pager:{keywords:["bbcall","oldschool","90s"],char:"📟",fitzpatrick_scale:false,category:"objects"},fax:{keywords:["communication","technology"],char:"📠",fitzpatrick_scale:false,category:"objects"},tv:{keywords:["technology","program","oldschool","show","television"],char:"📺",fitzpatrick_scale:false,category:"objects"},radio:{keywords:["communication","music","podcast","program"],char:"📻",fitzpatrick_scale:false,category:"objects"},studio_microphone:{keywords:["sing","recording","artist","talkshow"],char:"🎙",fitzpatrick_scale:false,category:"objects"},level_slider:{keywords:["scale"],char:"🎚",fitzpatrick_scale:false,category:"objects"},control_knobs:{keywords:["dial"],char:"🎛",fitzpatrick_scale:false,category:"objects"},compass:{keywords:["magnetic","navigation","orienteering"],char:"🧭",fitzpatrick_scale:false,category:"objects"},stopwatch:{keywords:["time","deadline"],char:"⏱",fitzpatrick_scale:false,category:"objects"},timer_clock:{keywords:["alarm"],char:"⏲",fitzpatrick_scale:false,category:"objects"},alarm_clock:{keywords:["time","wake"],char:"⏰",fitzpatrick_scale:false,category:"objects"},mantelpiece_clock:{keywords:["time"],char:"🕰",fitzpatrick_scale:false,category:"objects"},hourglass_flowing_sand:{keywords:["oldschool","time","countdown"],char:"⏳",fitzpatrick_scale:false,category:"objects"},hourglass:{keywords:["time","clock","oldschool","limit","exam","quiz","test"],char:"⌛",fitzpatrick_scale:false,category:"objects"},satellite:{keywords:["communication","future","radio","space"],char:"📡",fitzpatrick_scale:false,category:"objects"},battery:{keywords:["power","energy","sustain"],char:"🔋",fitzpatrick_scale:false,category:"objects"},electric_plug:{keywords:["charger","power"],char:"🔌",fitzpatrick_scale:false,category:"objects"},bulb:{keywords:["light","electricity","idea"],char:"💡",fitzpatrick_scale:false,category:"objects"},flashlight:{keywords:["dark","camping","sight","night"],char:"🔦",fitzpatrick_scale:false,category:"objects"},candle:{keywords:["fire","wax"],char:"🕯",fitzpatrick_scale:false,category:"objects"},fire_extinguisher:{keywords:["quench"],char:"🧯",fitzpatrick_scale:false,category:"objects"},wastebasket:{keywords:["bin","trash","rubbish","garbage","toss"],char:"🗑",fitzpatrick_scale:false,category:"objects"},oil_drum:{keywords:["barrell"],char:"🛢",fitzpatrick_scale:false,category:"objects"},money_with_wings:{keywords:["dollar","bills","payment","sale"],char:"💸",fitzpatrick_scale:false,category:"objects"},dollar:{keywords:["money","sales","bill","currency"],char:"💵",fitzpatrick_scale:false,category:"objects"},yen:{keywords:["money","sales","japanese","dollar","currency"],char:"💴",fitzpatrick_scale:false,category:"objects"},euro:{keywords:["money","sales","dollar","currency"],char:"💶",fitzpatrick_scale:false,category:"objects"},pound:{keywords:["british","sterling","money","sales","bills","uk","england","currency"],char:"💷",fitzpatrick_scale:false,category:"objects"},moneybag:{keywords:["dollar","payment","coins","sale"],char:"💰",fitzpatrick_scale:false,category:"objects"},credit_card:{keywords:["money","sales","dollar","bill","payment","shopping"],char:"💳",fitzpatrick_scale:false,category:"objects"},gem:{keywords:["blue","ruby","diamond","jewelry"],char:"💎",fitzpatrick_scale:false,category:"objects"},balance_scale:{keywords:["law","fairness","weight"],char:"⚖",fitzpatrick_scale:false,category:"objects"},toolbox:{keywords:["tools","diy","fix","maintainer","mechanic"],char:"🧰",fitzpatrick_scale:false,category:"objects"},wrench:{keywords:["tools","diy","ikea","fix","maintainer"],char:"🔧",fitzpatrick_scale:false,category:"objects"},hammer:{keywords:["tools","build","create"],char:"🔨",fitzpatrick_scale:false,category:"objects"},hammer_and_pick:{keywords:["tools","build","create"],char:"⚒",fitzpatrick_scale:false,category:"objects"},hammer_and_wrench:{keywords:["tools","build","create"],char:"🛠",fitzpatrick_scale:false,category:"objects"},pick:{keywords:["tools","dig"],char:"⛏",fitzpatrick_scale:false,category:"objects"},nut_and_bolt:{keywords:["handy","tools","fix"],char:"🔩",fitzpatrick_scale:false,category:"objects"},gear:{keywords:["cog"],char:"⚙",fitzpatrick_scale:false,category:"objects"},brick:{keywords:["bricks"],char:"🧱",fitzpatrick_scale:false,category:"objects"},chains:{keywords:["lock","arrest"],char:"⛓",fitzpatrick_scale:false,category:"objects"},magnet:{keywords:["attraction","magnetic"],char:"🧲",fitzpatrick_scale:false,category:"objects"},gun:{keywords:["violence","weapon","pistol","revolver"],char:"🔫",fitzpatrick_scale:false,category:"objects"},bomb:{keywords:["boom","explode","explosion","terrorism"],char:"💣",fitzpatrick_scale:false,category:"objects"},firecracker:{keywords:["dynamite","boom","explode","explosion","explosive"],char:"🧨",fitzpatrick_scale:false,category:"objects"},hocho:{keywords:["knife","blade","cutlery","kitchen","weapon"],char:"🔪",fitzpatrick_scale:false,category:"objects"},dagger:{keywords:["weapon"],char:"🗡",fitzpatrick_scale:false,category:"objects"},crossed_swords:{keywords:["weapon"],char:"⚔",fitzpatrick_scale:false,category:"objects"},shield:{keywords:["protection","security"],char:"🛡",fitzpatrick_scale:false,category:"objects"},smoking:{keywords:["kills","tobacco","cigarette","joint","smoke"],char:"🚬",fitzpatrick_scale:false,category:"objects"},skull_and_crossbones:{keywords:["poison","danger","deadly","scary","death","pirate","evil"],char:"☠",fitzpatrick_scale:false,category:"objects"},coffin:{keywords:["vampire","dead","die","death","rip","graveyard","cemetery","casket","funeral","box"],char:"⚰",fitzpatrick_scale:false,category:"objects"},funeral_urn:{keywords:["dead","die","death","rip","ashes"],char:"⚱",fitzpatrick_scale:false,category:"objects"},amphora:{keywords:["vase","jar"],char:"🏺",fitzpatrick_scale:false,category:"objects"},crystal_ball:{keywords:["disco","party","magic","circus","fortune_teller"],char:"🔮",fitzpatrick_scale:false,category:"objects"},prayer_beads:{keywords:["dhikr","religious"],char:"📿",fitzpatrick_scale:false,category:"objects"},nazar_amulet:{keywords:["bead","charm"],char:"🧿",fitzpatrick_scale:false,category:"objects"},barber:{keywords:["hair","salon","style"],char:"💈",fitzpatrick_scale:false,category:"objects"},alembic:{keywords:["distilling","science","experiment","chemistry"],char:"⚗",fitzpatrick_scale:false,category:"objects"},telescope:{keywords:["stars","space","zoom","science","astronomy"],char:"🔭",fitzpatrick_scale:false,category:"objects"},microscope:{keywords:["laboratory","experiment","zoomin","science","study"],char:"🔬",fitzpatrick_scale:false,category:"objects"},hole:{keywords:["embarrassing"],char:"🕳",fitzpatrick_scale:false,category:"objects"},pill:{keywords:["health","medicine","doctor","pharmacy","drug"],char:"💊",fitzpatrick_scale:false,category:"objects"},syringe:{keywords:["health","hospital","drugs","blood","medicine","needle","doctor","nurse"],char:"💉",fitzpatrick_scale:false,category:"objects"},dna:{keywords:["biologist","genetics","life"],char:"🧬",fitzpatrick_scale:false,category:"objects"},microbe:{keywords:["amoeba","bacteria","germs"],char:"🦠",fitzpatrick_scale:false,category:"objects"},petri_dish:{keywords:["bacteria","biology","culture","lab"],char:"🧫",fitzpatrick_scale:false,category:"objects"},test_tube:{keywords:["chemistry","experiment","lab","science"],char:"🧪",fitzpatrick_scale:false,category:"objects"},thermometer:{keywords:["weather","temperature","hot","cold"],char:"🌡",fitzpatrick_scale:false,category:"objects"},broom:{keywords:["cleaning","sweeping","witch"],char:"🧹",fitzpatrick_scale:false,category:"objects"},basket:{keywords:["laundry"],char:"🧺",fitzpatrick_scale:false,category:"objects"},toilet_paper:{keywords:["roll"],char:"🧻",fitzpatrick_scale:false,category:"objects"},label:{keywords:["sale","tag"],char:"🏷",fitzpatrick_scale:false,category:"objects"},bookmark:{keywords:["favorite","label","save"],char:"🔖",fitzpatrick_scale:false,category:"objects"},toilet:{keywords:["restroom","wc","washroom","bathroom","potty"],char:"🚽",fitzpatrick_scale:false,category:"objects"},shower:{keywords:["clean","water","bathroom"],char:"🚿",fitzpatrick_scale:false,category:"objects"},bathtub:{keywords:["clean","shower","bathroom"],char:"🛁",fitzpatrick_scale:false,category:"objects"},soap:{keywords:["bar","bathing","cleaning","lather"],char:"🧼",fitzpatrick_scale:false,category:"objects"},sponge:{keywords:["absorbing","cleaning","porous"],char:"🧽",fitzpatrick_scale:false,category:"objects"},lotion_bottle:{keywords:["moisturizer","sunscreen"],char:"🧴",fitzpatrick_scale:false,category:"objects"},key:{keywords:["lock","door","password"],char:"🔑",fitzpatrick_scale:false,category:"objects"},old_key:{keywords:["lock","door","password"],char:"🗝",fitzpatrick_scale:false,category:"objects"},couch_and_lamp:{keywords:["read","chill"],char:"🛋",fitzpatrick_scale:false,category:"objects"},sleeping_bed:{keywords:["bed","rest"],char:"🛌",fitzpatrick_scale:true,category:"objects"},bed:{keywords:["sleep","rest"],char:"🛏",fitzpatrick_scale:false,category:"objects"},door:{keywords:["house","entry","exit"],char:"🚪",fitzpatrick_scale:false,category:"objects"},bellhop_bell:{keywords:["service"],char:"🛎",fitzpatrick_scale:false,category:"objects"},teddy_bear:{keywords:["plush","stuffed"],char:"🧸",fitzpatrick_scale:false,category:"objects"},framed_picture:{keywords:["photography"],char:"🖼",fitzpatrick_scale:false,category:"objects"},world_map:{keywords:["location","direction"],char:"🗺",fitzpatrick_scale:false,category:"objects"},parasol_on_ground:{keywords:["weather","summer"],char:"⛱",fitzpatrick_scale:false,category:"objects"},moyai:{keywords:["rock","easter island","moai"],char:"🗿",fitzpatrick_scale:false,category:"objects"},shopping:{keywords:["mall","buy","purchase"],char:"🛍",fitzpatrick_scale:false,category:"objects"},shopping_cart:{keywords:["trolley"],char:"🛒",fitzpatrick_scale:false,category:"objects"},balloon:{keywords:["party","celebration","birthday","circus"],char:"🎈",fitzpatrick_scale:false,category:"objects"},flags:{keywords:["fish","japanese","koinobori","carp","banner"],char:"🎏",fitzpatrick_scale:false,category:"objects"},ribbon:{keywords:["decoration","pink","girl","bowtie"],char:"🎀",fitzpatrick_scale:false,category:"objects"},gift:{keywords:["present","birthday","christmas","xmas"],char:"🎁",fitzpatrick_scale:false,category:"objects"},confetti_ball:{keywords:["festival","party","birthday","circus"],char:"🎊",fitzpatrick_scale:false,category:"objects"},tada:{keywords:["party","congratulations","birthday","magic","circus","celebration"],char:"🎉",fitzpatrick_scale:false,category:"objects"},dolls:{keywords:["japanese","toy","kimono"],char:"🎎",fitzpatrick_scale:false,category:"objects"},wind_chime:{keywords:["nature","ding","spring","bell"],char:"🎐",fitzpatrick_scale:false,category:"objects"},crossed_flags:{keywords:["japanese","nation","country","border"],char:"🎌",fitzpatrick_scale:false,category:"objects"},izakaya_lantern:{keywords:["light","paper","halloween","spooky"],char:"🏮",fitzpatrick_scale:false,category:"objects"},red_envelope:{keywords:["gift"],char:"🧧",fitzpatrick_scale:false,category:"objects"},email:{keywords:["letter","postal","inbox","communication"],char:"✉️",fitzpatrick_scale:false,category:"objects"},envelope_with_arrow:{keywords:["email","communication"],char:"📩",fitzpatrick_scale:false,category:"objects"},incoming_envelope:{keywords:["email","inbox"],char:"📨",fitzpatrick_scale:false,category:"objects"},"e-mail":{keywords:["communication","inbox"],char:"📧",fitzpatrick_scale:false,category:"objects"},love_letter:{keywords:["email","like","affection","envelope","valentines"],char:"💌",fitzpatrick_scale:false,category:"objects"},postbox:{keywords:["email","letter","envelope"],char:"📮",fitzpatrick_scale:false,category:"objects"},mailbox_closed:{keywords:["email","communication","inbox"],char:"📪",fitzpatrick_scale:false,category:"objects"},mailbox:{keywords:["email","inbox","communication"],char:"📫",fitzpatrick_scale:false,category:"objects"},mailbox_with_mail:{keywords:["email","inbox","communication"],char:"📬",fitzpatrick_scale:false,category:"objects"},mailbox_with_no_mail:{keywords:["email","inbox"],char:"📭",fitzpatrick_scale:false,category:"objects"},package:{keywords:["mail","gift","cardboard","box","moving"],char:"📦",fitzpatrick_scale:false,category:"objects"},postal_horn:{keywords:["instrument","music"],char:"📯",fitzpatrick_scale:false,category:"objects"},inbox_tray:{keywords:["email","documents"],char:"📥",fitzpatrick_scale:false,category:"objects"},outbox_tray:{keywords:["inbox","email"],char:"📤",fitzpatrick_scale:false,category:"objects"},scroll:{keywords:["documents","ancient","history","paper"],char:"📜",fitzpatrick_scale:false,category:"objects"},page_with_curl:{keywords:["documents","office","paper"],char:"📃",fitzpatrick_scale:false,category:"objects"},bookmark_tabs:{keywords:["favorite","save","order","tidy"],char:"📑",fitzpatrick_scale:false,category:"objects"},receipt:{keywords:["accounting","expenses"],char:"🧾",fitzpatrick_scale:false,category:"objects"},bar_chart:{keywords:["graph","presentation","stats"],char:"📊",fitzpatrick_scale:false,category:"objects"},chart_with_upwards_trend:{keywords:["graph","presentation","stats","recovery","business","economics","money","sales","good","success"],char:"📈",fitzpatrick_scale:false,category:"objects"},chart_with_downwards_trend:{keywords:["graph","presentation","stats","recession","business","economics","money","sales","bad","failure"],char:"📉",fitzpatrick_scale:false,category:"objects"},page_facing_up:{keywords:["documents","office","paper","information"],char:"📄",fitzpatrick_scale:false,category:"objects"},date:{keywords:["calendar","schedule"],char:"📅",fitzpatrick_scale:false,category:"objects"},calendar:{keywords:["schedule","date","planning"],char:"📆",fitzpatrick_scale:false,category:"objects"},spiral_calendar:{keywords:["date","schedule","planning"],char:"🗓",fitzpatrick_scale:false,category:"objects"},card_index:{keywords:["business","stationery"],char:"📇",fitzpatrick_scale:false,category:"objects"},card_file_box:{keywords:["business","stationery"],char:"🗃",fitzpatrick_scale:false,category:"objects"},ballot_box:{keywords:["election","vote"],char:"🗳",fitzpatrick_scale:false,category:"objects"},file_cabinet:{keywords:["filing","organizing"],char:"🗄",fitzpatrick_scale:false,category:"objects"},clipboard:{keywords:["stationery","documents"],char:"📋",fitzpatrick_scale:false,category:"objects"},spiral_notepad:{keywords:["memo","stationery"],char:"🗒",fitzpatrick_scale:false,category:"objects"},file_folder:{keywords:["documents","business","office"],char:"📁",fitzpatrick_scale:false,category:"objects"},open_file_folder:{keywords:["documents","load"],char:"📂",fitzpatrick_scale:false,category:"objects"},card_index_dividers:{keywords:["organizing","business","stationery"],char:"🗂",fitzpatrick_scale:false,category:"objects"},newspaper_roll:{keywords:["press","headline"],char:"🗞",fitzpatrick_scale:false,category:"objects"},newspaper:{keywords:["press","headline"],char:"📰",fitzpatrick_scale:false,category:"objects"},notebook:{keywords:["stationery","record","notes","paper","study"],char:"📓",fitzpatrick_scale:false,category:"objects"},closed_book:{keywords:["read","library","knowledge","textbook","learn"],char:"📕",fitzpatrick_scale:false,category:"objects"},green_book:{keywords:["read","library","knowledge","study"],char:"📗",fitzpatrick_scale:false,category:"objects"},blue_book:{keywords:["read","library","knowledge","learn","study"],char:"📘",fitzpatrick_scale:false,category:"objects"},orange_book:{keywords:["read","library","knowledge","textbook","study"],char:"📙",fitzpatrick_scale:false,category:"objects"},notebook_with_decorative_cover:{keywords:["classroom","notes","record","paper","study"],char:"📔",fitzpatrick_scale:false,category:"objects"},ledger:{keywords:["notes","paper"],char:"📒",fitzpatrick_scale:false,category:"objects"},books:{keywords:["literature","library","study"],char:"📚",fitzpatrick_scale:false,category:"objects"},open_book:{keywords:["book","read","library","knowledge","literature","learn","study"],char:"📖",fitzpatrick_scale:false,category:"objects"},safety_pin:{keywords:["diaper"],char:"🧷",fitzpatrick_scale:false,category:"objects"},link:{keywords:["rings","url"],char:"🔗",fitzpatrick_scale:false,category:"objects"},paperclip:{keywords:["documents","stationery"],char:"📎",fitzpatrick_scale:false,category:"objects"},paperclips:{keywords:["documents","stationery"],char:"🖇",fitzpatrick_scale:false,category:"objects"},scissors:{keywords:["stationery","cut"],char:"✂️",fitzpatrick_scale:false,category:"objects"},triangular_ruler:{keywords:["stationery","math","architect","sketch"],char:"📐",fitzpatrick_scale:false,category:"objects"},straight_ruler:{keywords:["stationery","calculate","length","math","school","drawing","architect","sketch"],char:"📏",fitzpatrick_scale:false,category:"objects"},abacus:{keywords:["calculation"],char:"🧮",fitzpatrick_scale:false,category:"objects"},pushpin:{keywords:["stationery","mark","here"],char:"📌",fitzpatrick_scale:false,category:"objects"},round_pushpin:{keywords:["stationery","location","map","here"],char:"📍",fitzpatrick_scale:false,category:"objects"},triangular_flag_on_post:{keywords:["mark","milestone","place"],char:"🚩",fitzpatrick_scale:false,category:"objects"},white_flag:{keywords:["losing","loser","lost","surrender","give up","fail"],char:"🏳",fitzpatrick_scale:false,category:"objects"},black_flag:{keywords:["pirate"],char:"🏴",fitzpatrick_scale:false,category:"objects"},rainbow_flag:{keywords:["flag","rainbow","pride","gay","lgbt","glbt","queer","homosexual","lesbian","bisexual","transgender"],char:"🏳️‍🌈",fitzpatrick_scale:false,category:"objects"},closed_lock_with_key:{keywords:["security","privacy"],char:"🔐",fitzpatrick_scale:false,category:"objects"},lock:{keywords:["security","password","padlock"],char:"🔒",fitzpatrick_scale:false,category:"objects"},unlock:{keywords:["privacy","security"],char:"🔓",fitzpatrick_scale:false,category:"objects"},lock_with_ink_pen:{keywords:["security","secret"],char:"🔏",fitzpatrick_scale:false,category:"objects"},pen:{keywords:["stationery","writing","write"],char:"🖊",fitzpatrick_scale:false,category:"objects"},fountain_pen:{keywords:["stationery","writing","write"],char:"🖋",fitzpatrick_scale:false,category:"objects"},black_nib:{keywords:["pen","stationery","writing","write"],char:"✒️",fitzpatrick_scale:false,category:"objects"},memo:{keywords:["write","documents","stationery","pencil","paper","writing","legal","exam","quiz","test","study","compose"],char:"📝",fitzpatrick_scale:false,category:"objects"},pencil2:{keywords:["stationery","write","paper","writing","school","study"],char:"✏️",fitzpatrick_scale:false,category:"objects"},crayon:{keywords:["drawing","creativity"],char:"🖍",fitzpatrick_scale:false,category:"objects"},paintbrush:{keywords:["drawing","creativity","art"],char:"🖌",fitzpatrick_scale:false,category:"objects"},mag:{keywords:["search","zoom","find","detective"],char:"🔍",fitzpatrick_scale:false,category:"objects"},mag_right:{keywords:["search","zoom","find","detective"],char:"🔎",fitzpatrick_scale:false,category:"objects"},heart:{keywords:["love","like","valentines"],char:"❤️",fitzpatrick_scale:false,category:"symbols"},orange_heart:{keywords:["love","like","affection","valentines"],char:"🧡",fitzpatrick_scale:false,category:"symbols"},yellow_heart:{keywords:["love","like","affection","valentines"],char:"💛",fitzpatrick_scale:false,category:"symbols"},green_heart:{keywords:["love","like","affection","valentines"],char:"💚",fitzpatrick_scale:false,category:"symbols"},blue_heart:{keywords:["love","like","affection","valentines"],char:"💙",fitzpatrick_scale:false,category:"symbols"},purple_heart:{keywords:["love","like","affection","valentines"],char:"💜",fitzpatrick_scale:false,category:"symbols"},black_heart:{keywords:["evil"],char:"🖤",fitzpatrick_scale:false,category:"symbols"},broken_heart:{keywords:["sad","sorry","break","heart","heartbreak"],char:"💔",fitzpatrick_scale:false,category:"symbols"},heavy_heart_exclamation:{keywords:["decoration","love"],char:"❣",fitzpatrick_scale:false,category:"symbols"},two_hearts:{keywords:["love","like","affection","valentines","heart"],char:"💕",fitzpatrick_scale:false,category:"symbols"},revolving_hearts:{keywords:["love","like","affection","valentines"],char:"💞",fitzpatrick_scale:false,category:"symbols"},heartbeat:{keywords:["love","like","affection","valentines","pink","heart"],char:"💓",fitzpatrick_scale:false,category:"symbols"},heartpulse:{keywords:["like","love","affection","valentines","pink"],char:"💗",fitzpatrick_scale:false,category:"symbols"},sparkling_heart:{keywords:["love","like","affection","valentines"],char:"💖",fitzpatrick_scale:false,category:"symbols"},cupid:{keywords:["love","like","heart","affection","valentines"],char:"💘",fitzpatrick_scale:false,category:"symbols"},gift_heart:{keywords:["love","valentines"],char:"💝",fitzpatrick_scale:false,category:"symbols"},heart_decoration:{keywords:["purple-square","love","like"],char:"💟",fitzpatrick_scale:false,category:"symbols"},peace_symbol:{keywords:["hippie"],char:"☮",fitzpatrick_scale:false,category:"symbols"},latin_cross:{keywords:["christianity"],char:"✝",fitzpatrick_scale:false,category:"symbols"},star_and_crescent:{keywords:["islam"],char:"☪",fitzpatrick_scale:false,category:"symbols"},om:{keywords:["hinduism","buddhism","sikhism","jainism"],char:"🕉",fitzpatrick_scale:false,category:"symbols"},wheel_of_dharma:{keywords:["hinduism","buddhism","sikhism","jainism"],char:"☸",fitzpatrick_scale:false,category:"symbols"},star_of_david:{keywords:["judaism"],char:"✡",fitzpatrick_scale:false,category:"symbols"},six_pointed_star:{keywords:["purple-square","religion","jewish","hexagram"],char:"🔯",fitzpatrick_scale:false,category:"symbols"},menorah:{keywords:["hanukkah","candles","jewish"],char:"🕎",fitzpatrick_scale:false,category:"symbols"},yin_yang:{keywords:["balance"],char:"☯",fitzpatrick_scale:false,category:"symbols"},orthodox_cross:{keywords:["suppedaneum","religion"],char:"☦",fitzpatrick_scale:false,category:"symbols"},place_of_worship:{keywords:["religion","church","temple","prayer"],char:"🛐",fitzpatrick_scale:false,category:"symbols"},ophiuchus:{keywords:["sign","purple-square","constellation","astrology"],char:"⛎",fitzpatrick_scale:false,category:"symbols"},aries:{keywords:["sign","purple-square","zodiac","astrology"],char:"♈",fitzpatrick_scale:false,category:"symbols"},taurus:{keywords:["purple-square","sign","zodiac","astrology"],char:"♉",fitzpatrick_scale:false,category:"symbols"},gemini:{keywords:["sign","zodiac","purple-square","astrology"],char:"♊",fitzpatrick_scale:false,category:"symbols"},cancer:{keywords:["sign","zodiac","purple-square","astrology"],char:"♋",fitzpatrick_scale:false,category:"symbols"},leo:{keywords:["sign","purple-square","zodiac","astrology"],char:"♌",fitzpatrick_scale:false,category:"symbols"},virgo:{keywords:["sign","zodiac","purple-square","astrology"],char:"♍",fitzpatrick_scale:false,category:"symbols"},libra:{keywords:["sign","purple-square","zodiac","astrology"],char:"♎",fitzpatrick_scale:false,category:"symbols"},scorpius:{keywords:["sign","zodiac","purple-square","astrology","scorpio"],char:"♏",fitzpatrick_scale:false,category:"symbols"},sagittarius:{keywords:["sign","zodiac","purple-square","astrology"],char:"♐",fitzpatrick_scale:false,category:"symbols"},capricorn:{keywords:["sign","zodiac","purple-square","astrology"],char:"♑",fitzpatrick_scale:false,category:"symbols"},aquarius:{keywords:["sign","purple-square","zodiac","astrology"],char:"♒",fitzpatrick_scale:false,category:"symbols"},pisces:{keywords:["purple-square","sign","zodiac","astrology"],char:"♓",fitzpatrick_scale:false,category:"symbols"},id:{keywords:["purple-square","words"],char:"🆔",fitzpatrick_scale:false,category:"symbols"},atom_symbol:{keywords:["science","physics","chemistry"],char:"⚛",fitzpatrick_scale:false,category:"symbols"},u7a7a:{keywords:["kanji","japanese","chinese","empty","sky","blue-square"],char:"🈳",fitzpatrick_scale:false,category:"symbols"},u5272:{keywords:["cut","divide","chinese","kanji","pink-square"],char:"🈹",fitzpatrick_scale:false,category:"symbols"},radioactive:{keywords:["nuclear","danger"],char:"☢",fitzpatrick_scale:false,category:"symbols"},biohazard:{keywords:["danger"],char:"☣",fitzpatrick_scale:false,category:"symbols"},mobile_phone_off:{keywords:["mute","orange-square","silence","quiet"],char:"📴",fitzpatrick_scale:false,category:"symbols"},vibration_mode:{keywords:["orange-square","phone"],char:"📳",fitzpatrick_scale:false,category:"symbols"},u6709:{keywords:["orange-square","chinese","have","kanji"],char:"🈶",fitzpatrick_scale:false,category:"symbols"},u7121:{keywords:["nothing","chinese","kanji","japanese","orange-square"],char:"🈚",fitzpatrick_scale:false,category:"symbols"},u7533:{keywords:["chinese","japanese","kanji","orange-square"],char:"🈸",fitzpatrick_scale:false,category:"symbols"},u55b6:{keywords:["japanese","opening hours","orange-square"],char:"🈺",fitzpatrick_scale:false,category:"symbols"},u6708:{keywords:["chinese","month","moon","japanese","orange-square","kanji"],char:"🈷️",fitzpatrick_scale:false,category:"symbols"},eight_pointed_black_star:{keywords:["orange-square","shape","polygon"],char:"✴️",fitzpatrick_scale:false,category:"symbols"},vs:{keywords:["words","orange-square"],char:"🆚",fitzpatrick_scale:false,category:"symbols"},accept:{keywords:["ok","good","chinese","kanji","agree","yes","orange-circle"],char:"🉑",fitzpatrick_scale:false,category:"symbols"},white_flower:{keywords:["japanese","spring"],char:"💮",fitzpatrick_scale:false,category:"symbols"},ideograph_advantage:{keywords:["chinese","kanji","obtain","get","circle"],char:"🉐",fitzpatrick_scale:false,category:"symbols"},secret:{keywords:["privacy","chinese","sshh","kanji","red-circle"],char:"㊙️",fitzpatrick_scale:false,category:"symbols"},congratulations:{keywords:["chinese","kanji","japanese","red-circle"],char:"㊗️",fitzpatrick_scale:false,category:"symbols"},u5408:{keywords:["japanese","chinese","join","kanji","red-square"],char:"🈴",fitzpatrick_scale:false,category:"symbols"},u6e80:{keywords:["full","chinese","japanese","red-square","kanji"],char:"🈵",fitzpatrick_scale:false,category:"symbols"},u7981:{keywords:["kanji","japanese","chinese","forbidden","limit","restricted","red-square"],char:"🈲",fitzpatrick_scale:false,category:"symbols"},a:{keywords:["red-square","alphabet","letter"],char:"🅰️",fitzpatrick_scale:false,category:"symbols"},b:{keywords:["red-square","alphabet","letter"],char:"🅱️",fitzpatrick_scale:false,category:"symbols"},ab:{keywords:["red-square","alphabet"],char:"🆎",fitzpatrick_scale:false,category:"symbols"},cl:{keywords:["alphabet","words","red-square"],char:"🆑",fitzpatrick_scale:false,category:"symbols"},o2:{keywords:["alphabet","red-square","letter"],char:"🅾️",fitzpatrick_scale:false,category:"symbols"},sos:{keywords:["help","red-square","words","emergency","911"],char:"🆘",fitzpatrick_scale:false,category:"symbols"},no_entry:{keywords:["limit","security","privacy","bad","denied","stop","circle"],char:"⛔",fitzpatrick_scale:false,category:"symbols"},name_badge:{keywords:["fire","forbid"],char:"📛",fitzpatrick_scale:false,category:"symbols"},no_entry_sign:{keywords:["forbid","stop","limit","denied","disallow","circle"],char:"🚫",fitzpatrick_scale:false,category:"symbols"},x:{keywords:["no","delete","remove","cancel","red"],char:"❌",fitzpatrick_scale:false,category:"symbols"},o:{keywords:["circle","round"],char:"⭕",fitzpatrick_scale:false,category:"symbols"},stop_sign:{keywords:["stop"],char:"🛑",fitzpatrick_scale:false,category:"symbols"},anger:{keywords:["angry","mad"],char:"💢",fitzpatrick_scale:false,category:"symbols"},hotsprings:{keywords:["bath","warm","relax"],char:"♨️",fitzpatrick_scale:false,category:"symbols"},no_pedestrians:{keywords:["rules","crossing","walking","circle"],char:"🚷",fitzpatrick_scale:false,category:"symbols"},do_not_litter:{keywords:["trash","bin","garbage","circle"],char:"🚯",fitzpatrick_scale:false,category:"symbols"},no_bicycles:{keywords:["cyclist","prohibited","circle"],char:"🚳",fitzpatrick_scale:false,category:"symbols"},"non-potable_water":{keywords:["drink","faucet","tap","circle"],char:"🚱",fitzpatrick_scale:false,category:"symbols"},underage:{keywords:["18","drink","pub","night","minor","circle"],char:"🔞",fitzpatrick_scale:false,category:"symbols"},no_mobile_phones:{keywords:["iphone","mute","circle"],char:"📵",fitzpatrick_scale:false,category:"symbols"},exclamation:{keywords:["heavy_exclamation_mark","danger","surprise","punctuation","wow","warning"],char:"❗",fitzpatrick_scale:false,category:"symbols"},grey_exclamation:{keywords:["surprise","punctuation","gray","wow","warning"],char:"❕",fitzpatrick_scale:false,category:"symbols"},question:{keywords:["doubt","confused"],char:"❓",fitzpatrick_scale:false,category:"symbols"},grey_question:{keywords:["doubts","gray","huh","confused"],char:"❔",fitzpatrick_scale:false,category:"symbols"},bangbang:{keywords:["exclamation","surprise"],char:"‼️",fitzpatrick_scale:false,category:"symbols"},interrobang:{keywords:["wat","punctuation","surprise"],char:"⁉️",fitzpatrick_scale:false,category:"symbols"},100:{keywords:["score","perfect","numbers","century","exam","quiz","test","pass","hundred"],char:"💯",fitzpatrick_scale:false,category:"symbols"},low_brightness:{keywords:["sun","afternoon","warm","summer"],char:"🔅",fitzpatrick_scale:false,category:"symbols"},high_brightness:{keywords:["sun","light"],char:"🔆",fitzpatrick_scale:false,category:"symbols"},trident:{keywords:["weapon","spear"],char:"🔱",fitzpatrick_scale:false,category:"symbols"},fleur_de_lis:{keywords:["decorative","scout"],char:"⚜",fitzpatrick_scale:false,category:"symbols"},part_alternation_mark:{keywords:["graph","presentation","stats","business","economics","bad"],char:"〽️",fitzpatrick_scale:false,category:"symbols"},warning:{keywords:["exclamation","wip","alert","error","problem","issue"],char:"⚠️",fitzpatrick_scale:false,category:"symbols"},children_crossing:{keywords:["school","warning","danger","sign","driving","yellow-diamond"],char:"🚸",fitzpatrick_scale:false,category:"symbols"},beginner:{keywords:["badge","shield"],char:"🔰",fitzpatrick_scale:false,category:"symbols"},recycle:{keywords:["arrow","environment","garbage","trash"],char:"♻️",fitzpatrick_scale:false,category:"symbols"},u6307:{keywords:["chinese","point","green-square","kanji"],char:"🈯",fitzpatrick_scale:false,category:"symbols"},chart:{keywords:["green-square","graph","presentation","stats"],char:"💹",fitzpatrick_scale:false,category:"symbols"},sparkle:{keywords:["stars","green-square","awesome","good","fireworks"],char:"❇️",fitzpatrick_scale:false,category:"symbols"},eight_spoked_asterisk:{keywords:["star","sparkle","green-square"],char:"✳️",fitzpatrick_scale:false,category:"symbols"},negative_squared_cross_mark:{keywords:["x","green-square","no","deny"],char:"❎",fitzpatrick_scale:false,category:"symbols"},white_check_mark:{keywords:["green-square","ok","agree","vote","election","answer","tick"],char:"✅",fitzpatrick_scale:false,category:"symbols"},diamond_shape_with_a_dot_inside:{keywords:["jewel","blue","gem","crystal","fancy"],char:"💠",fitzpatrick_scale:false,category:"symbols"},cyclone:{keywords:["weather","swirl","blue","cloud","vortex","spiral","whirlpool","spin","tornado","hurricane","typhoon"],char:"🌀",fitzpatrick_scale:false,category:"symbols"},loop:{keywords:["tape","cassette"],char:"➿",fitzpatrick_scale:false,category:"symbols"},globe_with_meridians:{keywords:["earth","international","world","internet","interweb","i18n"],char:"🌐",fitzpatrick_scale:false,category:"symbols"},m:{keywords:["alphabet","blue-circle","letter"],char:"Ⓜ️",fitzpatrick_scale:false,category:"symbols"},atm:{keywords:["money","sales","cash","blue-square","payment","bank"],char:"🏧",fitzpatrick_scale:false,category:"symbols"},sa:{keywords:["japanese","blue-square","katakana"],char:"🈂️",fitzpatrick_scale:false,category:"symbols"},passport_control:{keywords:["custom","blue-square"],char:"🛂",fitzpatrick_scale:false,category:"symbols"},customs:{keywords:["passport","border","blue-square"],char:"🛃",fitzpatrick_scale:false,category:"symbols"},baggage_claim:{keywords:["blue-square","airport","transport"],char:"🛄",fitzpatrick_scale:false,category:"symbols"},left_luggage:{keywords:["blue-square","travel"],char:"🛅",fitzpatrick_scale:false,category:"symbols"},wheelchair:{keywords:["blue-square","disabled","a11y","accessibility"],char:"♿",fitzpatrick_scale:false,category:"symbols"},no_smoking:{keywords:["cigarette","blue-square","smell","smoke"],char:"🚭",fitzpatrick_scale:false,category:"symbols"},wc:{keywords:["toilet","restroom","blue-square"],char:"🚾",fitzpatrick_scale:false,category:"symbols"},parking:{keywords:["cars","blue-square","alphabet","letter"],char:"🅿️",fitzpatrick_scale:false,category:"symbols"},potable_water:{keywords:["blue-square","liquid","restroom","cleaning","faucet"],char:"🚰",fitzpatrick_scale:false,category:"symbols"},mens:{keywords:["toilet","restroom","wc","blue-square","gender","male"],char:"🚹",fitzpatrick_scale:false,category:"symbols"},womens:{keywords:["purple-square","woman","female","toilet","loo","restroom","gender"],char:"🚺",fitzpatrick_scale:false,category:"symbols"},baby_symbol:{keywords:["orange-square","child"],char:"🚼",fitzpatrick_scale:false,category:"symbols"},restroom:{keywords:["blue-square","toilet","refresh","wc","gender"],char:"🚻",fitzpatrick_scale:false,category:"symbols"},put_litter_in_its_place:{keywords:["blue-square","sign","human","info"],char:"🚮",fitzpatrick_scale:false,category:"symbols"},cinema:{keywords:["blue-square","record","film","movie","curtain","stage","theater"],char:"🎦",fitzpatrick_scale:false,category:"symbols"},signal_strength:{keywords:["blue-square","reception","phone","internet","connection","wifi","bluetooth","bars"],char:"📶",fitzpatrick_scale:false,category:"symbols"},koko:{keywords:["blue-square","here","katakana","japanese","destination"],char:"🈁",fitzpatrick_scale:false,category:"symbols"},ng:{keywords:["blue-square","words","shape","icon"],char:"🆖",fitzpatrick_scale:false,category:"symbols"},ok:{keywords:["good","agree","yes","blue-square"],char:"🆗",fitzpatrick_scale:false,category:"symbols"},up:{keywords:["blue-square","above","high"],char:"🆙",fitzpatrick_scale:false,category:"symbols"},cool:{keywords:["words","blue-square"],char:"🆒",fitzpatrick_scale:false,category:"symbols"},new:{keywords:["blue-square","words","start"],char:"🆕",fitzpatrick_scale:false,category:"symbols"},free:{keywords:["blue-square","words"],char:"🆓",fitzpatrick_scale:false,category:"symbols"},zero:{keywords:["0","numbers","blue-square","null"],char:"0️⃣",fitzpatrick_scale:false,category:"symbols"},one:{keywords:["blue-square","numbers","1"],char:"1️⃣",fitzpatrick_scale:false,category:"symbols"},two:{keywords:["numbers","2","prime","blue-square"],char:"2️⃣",fitzpatrick_scale:false,category:"symbols"},three:{keywords:["3","numbers","prime","blue-square"],char:"3️⃣",fitzpatrick_scale:false,category:"symbols"},four:{keywords:["4","numbers","blue-square"],char:"4️⃣",fitzpatrick_scale:false,category:"symbols"},five:{keywords:["5","numbers","blue-square","prime"],char:"5️⃣",fitzpatrick_scale:false,category:"symbols"},six:{keywords:["6","numbers","blue-square"],char:"6️⃣",fitzpatrick_scale:false,category:"symbols"},seven:{keywords:["7","numbers","blue-square","prime"],char:"7️⃣",fitzpatrick_scale:false,category:"symbols"},eight:{keywords:["8","blue-square","numbers"],char:"8️⃣",fitzpatrick_scale:false,category:"symbols"},nine:{keywords:["blue-square","numbers","9"],char:"9️⃣",fitzpatrick_scale:false,category:"symbols"},keycap_ten:{keywords:["numbers","10","blue-square"],char:"🔟",fitzpatrick_scale:false,category:"symbols"},asterisk:{keywords:["star","keycap"],char:"*⃣",fitzpatrick_scale:false,category:"symbols"},1234:{keywords:["numbers","blue-square"],char:"🔢",fitzpatrick_scale:false,category:"symbols"},eject_button:{keywords:["blue-square"],char:"⏏️",fitzpatrick_scale:false,category:"symbols"},arrow_forward:{keywords:["blue-square","right","direction","play"],char:"▶️",fitzpatrick_scale:false,category:"symbols"},pause_button:{keywords:["pause","blue-square"],char:"⏸",fitzpatrick_scale:false,category:"symbols"},next_track_button:{keywords:["forward","next","blue-square"],char:"⏭",fitzpatrick_scale:false,category:"symbols"},stop_button:{keywords:["blue-square"],char:"⏹",fitzpatrick_scale:false,category:"symbols"},record_button:{keywords:["blue-square"],char:"⏺",fitzpatrick_scale:false,category:"symbols"},play_or_pause_button:{keywords:["blue-square","play","pause"],char:"⏯",fitzpatrick_scale:false,category:"symbols"},previous_track_button:{keywords:["backward"],char:"⏮",fitzpatrick_scale:false,category:"symbols"},fast_forward:{keywords:["blue-square","play","speed","continue"],char:"⏩",fitzpatrick_scale:false,category:"symbols"},rewind:{keywords:["play","blue-square"],char:"⏪",fitzpatrick_scale:false,category:"symbols"},twisted_rightwards_arrows:{keywords:["blue-square","shuffle","music","random"],char:"🔀",fitzpatrick_scale:false,category:"symbols"},repeat:{keywords:["loop","record"],char:"🔁",fitzpatrick_scale:false,category:"symbols"},repeat_one:{keywords:["blue-square","loop"],char:"🔂",fitzpatrick_scale:false,category:"symbols"},arrow_backward:{keywords:["blue-square","left","direction"],char:"◀️",fitzpatrick_scale:false,category:"symbols"},arrow_up_small:{keywords:["blue-square","triangle","direction","point","forward","top"],char:"🔼",fitzpatrick_scale:false,category:"symbols"},arrow_down_small:{keywords:["blue-square","direction","bottom"],char:"🔽",fitzpatrick_scale:false,category:"symbols"},arrow_double_up:{keywords:["blue-square","direction","top"],char:"⏫",fitzpatrick_scale:false,category:"symbols"},arrow_double_down:{keywords:["blue-square","direction","bottom"],char:"⏬",fitzpatrick_scale:false,category:"symbols"},arrow_right:{keywords:["blue-square","next"],char:"➡️",fitzpatrick_scale:false,category:"symbols"},arrow_left:{keywords:["blue-square","previous","back"],char:"⬅️",fitzpatrick_scale:false,category:"symbols"},arrow_up:{keywords:["blue-square","continue","top","direction"],char:"⬆️",fitzpatrick_scale:false,category:"symbols"},arrow_down:{keywords:["blue-square","direction","bottom"],char:"⬇️",fitzpatrick_scale:false,category:"symbols"},arrow_upper_right:{keywords:["blue-square","point","direction","diagonal","northeast"],char:"↗️",fitzpatrick_scale:false,category:"symbols"},arrow_lower_right:{keywords:["blue-square","direction","diagonal","southeast"],char:"↘️",fitzpatrick_scale:false,category:"symbols"},arrow_lower_left:{keywords:["blue-square","direction","diagonal","southwest"],char:"↙️",fitzpatrick_scale:false,category:"symbols"},arrow_upper_left:{keywords:["blue-square","point","direction","diagonal","northwest"],char:"↖️",fitzpatrick_scale:false,category:"symbols"},arrow_up_down:{keywords:["blue-square","direction","way","vertical"],char:"↕️",fitzpatrick_scale:false,category:"symbols"},left_right_arrow:{keywords:["shape","direction","horizontal","sideways"],char:"↔️",fitzpatrick_scale:false,category:"symbols"},arrows_counterclockwise:{keywords:["blue-square","sync","cycle"],char:"🔄",fitzpatrick_scale:false,category:"symbols"},arrow_right_hook:{keywords:["blue-square","return","rotate","direction"],char:"↪️",fitzpatrick_scale:false,category:"symbols"},leftwards_arrow_with_hook:{keywords:["back","return","blue-square","undo","enter"],char:"↩️",fitzpatrick_scale:false,category:"symbols"},arrow_heading_up:{keywords:["blue-square","direction","top"],char:"⤴️",fitzpatrick_scale:false,category:"symbols"},arrow_heading_down:{keywords:["blue-square","direction","bottom"],char:"⤵️",fitzpatrick_scale:false,category:"symbols"},hash:{keywords:["symbol","blue-square","twitter"],char:"#️⃣",fitzpatrick_scale:false,category:"symbols"},information_source:{keywords:["blue-square","alphabet","letter"],char:"ℹ️",fitzpatrick_scale:false,category:"symbols"},abc:{keywords:["blue-square","alphabet"],char:"🔤",fitzpatrick_scale:false,category:"symbols"},abcd:{keywords:["blue-square","alphabet"],char:"🔡",fitzpatrick_scale:false,category:"symbols"},capital_abcd:{keywords:["alphabet","words","blue-square"],char:"🔠",fitzpatrick_scale:false,category:"symbols"},symbols:{keywords:["blue-square","music","note","ampersand","percent","glyphs","characters"],char:"🔣",fitzpatrick_scale:false,category:"symbols"},musical_note:{keywords:["score","tone","sound"],char:"🎵",fitzpatrick_scale:false,category:"symbols"},notes:{keywords:["music","score"],char:"🎶",fitzpatrick_scale:false,category:"symbols"},wavy_dash:{keywords:["draw","line","moustache","mustache","squiggle","scribble"],char:"〰️",fitzpatrick_scale:false,category:"symbols"},curly_loop:{keywords:["scribble","draw","shape","squiggle"],char:"➰",fitzpatrick_scale:false,category:"symbols"},heavy_check_mark:{keywords:["ok","nike","answer","yes","tick"],char:"✔️",fitzpatrick_scale:false,category:"symbols"},arrows_clockwise:{keywords:["sync","cycle","round","repeat"],char:"🔃",fitzpatrick_scale:false,category:"symbols"},heavy_plus_sign:{keywords:["math","calculation","addition","more","increase"],char:"➕",fitzpatrick_scale:false,category:"symbols"},heavy_minus_sign:{keywords:["math","calculation","subtract","less"],char:"➖",fitzpatrick_scale:false,category:"symbols"},heavy_division_sign:{keywords:["divide","math","calculation"],char:"➗",fitzpatrick_scale:false,category:"symbols"},heavy_multiplication_x:{keywords:["math","calculation"],char:"✖️",fitzpatrick_scale:false,category:"symbols"},infinity:{keywords:["forever"],char:"♾",fitzpatrick_scale:false,category:"symbols"},heavy_dollar_sign:{keywords:["money","sales","payment","currency","buck"],char:"💲",fitzpatrick_scale:false,category:"symbols"},currency_exchange:{keywords:["money","sales","dollar","travel"],char:"💱",fitzpatrick_scale:false,category:"symbols"},copyright:{keywords:["ip","license","circle","law","legal"],char:"©️",fitzpatrick_scale:false,category:"symbols"},registered:{keywords:["alphabet","circle"],char:"®️",fitzpatrick_scale:false,category:"symbols"},tm:{keywords:["trademark","brand","law","legal"],char:"™️",fitzpatrick_scale:false,category:"symbols"},end:{keywords:["words","arrow"],char:"🔚",fitzpatrick_scale:false,category:"symbols"},back:{keywords:["arrow","words","return"],char:"🔙",fitzpatrick_scale:false,category:"symbols"},on:{keywords:["arrow","words"],char:"🔛",fitzpatrick_scale:false,category:"symbols"},top:{keywords:["words","blue-square"],char:"🔝",fitzpatrick_scale:false,category:"symbols"},soon:{keywords:["arrow","words"],char:"🔜",fitzpatrick_scale:false,category:"symbols"},ballot_box_with_check:{keywords:["ok","agree","confirm","black-square","vote","election","yes","tick"],char:"☑️",fitzpatrick_scale:false,category:"symbols"},radio_button:{keywords:["input","old","music","circle"],char:"🔘",fitzpatrick_scale:false,category:"symbols"},white_circle:{keywords:["shape","round"],char:"⚪",fitzpatrick_scale:false,category:"symbols"},black_circle:{keywords:["shape","button","round"],char:"⚫",fitzpatrick_scale:false,category:"symbols"},red_circle:{keywords:["shape","error","danger"],char:"🔴",fitzpatrick_scale:false,category:"symbols"},large_blue_circle:{keywords:["shape","icon","button"],char:"🔵",fitzpatrick_scale:false,category:"symbols"},small_orange_diamond:{keywords:["shape","jewel","gem"],char:"🔸",fitzpatrick_scale:false,category:"symbols"},small_blue_diamond:{keywords:["shape","jewel","gem"],char:"🔹",fitzpatrick_scale:false,category:"symbols"},large_orange_diamond:{keywords:["shape","jewel","gem"],char:"🔶",fitzpatrick_scale:false,category:"symbols"},large_blue_diamond:{keywords:["shape","jewel","gem"],char:"🔷",fitzpatrick_scale:false,category:"symbols"},small_red_triangle:{keywords:["shape","direction","up","top"],char:"🔺",fitzpatrick_scale:false,category:"symbols"},black_small_square:{keywords:["shape","icon"],char:"▪️",fitzpatrick_scale:false,category:"symbols"},white_small_square:{keywords:["shape","icon"],char:"▫️",fitzpatrick_scale:false,category:"symbols"},black_large_square:{keywords:["shape","icon","button"],char:"⬛",fitzpatrick_scale:false,category:"symbols"},white_large_square:{keywords:["shape","icon","stone","button"],char:"⬜",fitzpatrick_scale:false,category:"symbols"},small_red_triangle_down:{keywords:["shape","direction","bottom"],char:"🔻",fitzpatrick_scale:false,category:"symbols"},black_medium_square:{keywords:["shape","button","icon"],char:"◼️",fitzpatrick_scale:false,category:"symbols"},white_medium_square:{keywords:["shape","stone","icon"],char:"◻️",fitzpatrick_scale:false,category:"symbols"},black_medium_small_square:{keywords:["icon","shape","button"],char:"◾",fitzpatrick_scale:false,category:"symbols"},white_medium_small_square:{keywords:["shape","stone","icon","button"],char:"◽",fitzpatrick_scale:false,category:"symbols"},black_square_button:{keywords:["shape","input","frame"],char:"🔲",fitzpatrick_scale:false,category:"symbols"},white_square_button:{keywords:["shape","input"],char:"🔳",fitzpatrick_scale:false,category:"symbols"},speaker:{keywords:["sound","volume","silence","broadcast"],char:"🔈",fitzpatrick_scale:false,category:"symbols"},sound:{keywords:["volume","speaker","broadcast"],char:"🔉",fitzpatrick_scale:false,category:"symbols"},loud_sound:{keywords:["volume","noise","noisy","speaker","broadcast"],char:"🔊",fitzpatrick_scale:false,category:"symbols"},mute:{keywords:["sound","volume","silence","quiet"],char:"🔇",fitzpatrick_scale:false,category:"symbols"},mega:{keywords:["sound","speaker","volume"],char:"📣",fitzpatrick_scale:false,category:"symbols"},loudspeaker:{keywords:["volume","sound"],char:"📢",fitzpatrick_scale:false,category:"symbols"},bell:{keywords:["sound","notification","christmas","xmas","chime"],char:"🔔",fitzpatrick_scale:false,category:"symbols"},no_bell:{keywords:["sound","volume","mute","quiet","silent"],char:"🔕",fitzpatrick_scale:false,category:"symbols"},black_joker:{keywords:["poker","cards","game","play","magic"],char:"🃏",fitzpatrick_scale:false,category:"symbols"},mahjong:{keywords:["game","play","chinese","kanji"],char:"🀄",fitzpatrick_scale:false,category:"symbols"},spades:{keywords:["poker","cards","suits","magic"],char:"♠️",fitzpatrick_scale:false,category:"symbols"},clubs:{keywords:["poker","cards","magic","suits"],char:"♣️",fitzpatrick_scale:false,category:"symbols"},hearts:{keywords:["poker","cards","magic","suits"],char:"♥️",fitzpatrick_scale:false,category:"symbols"},diamonds:{keywords:["poker","cards","magic","suits"],char:"♦️",fitzpatrick_scale:false,category:"symbols"},flower_playing_cards:{keywords:["game","sunset","red"],char:"🎴",fitzpatrick_scale:false,category:"symbols"},thought_balloon:{keywords:["bubble","cloud","speech","thinking","dream"],char:"💭",fitzpatrick_scale:false,category:"symbols"},right_anger_bubble:{keywords:["caption","speech","thinking","mad"],char:"🗯",fitzpatrick_scale:false,category:"symbols"},speech_balloon:{keywords:["bubble","words","message","talk","chatting"],char:"💬",fitzpatrick_scale:false,category:"symbols"},left_speech_bubble:{keywords:["words","message","talk","chatting"],char:"🗨",fitzpatrick_scale:false,category:"symbols"},clock1:{keywords:["time","late","early","schedule"],char:"🕐",fitzpatrick_scale:false,category:"symbols"},clock2:{keywords:["time","late","early","schedule"],char:"🕑",fitzpatrick_scale:false,category:"symbols"},clock3:{keywords:["time","late","early","schedule"],char:"🕒",fitzpatrick_scale:false,category:"symbols"},clock4:{keywords:["time","late","early","schedule"],char:"🕓",fitzpatrick_scale:false,category:"symbols"},clock5:{keywords:["time","late","early","schedule"],char:"🕔",fitzpatrick_scale:false,category:"symbols"},clock6:{keywords:["time","late","early","schedule","dawn","dusk"],char:"🕕",fitzpatrick_scale:false,category:"symbols"},clock7:{keywords:["time","late","early","schedule"],char:"🕖",fitzpatrick_scale:false,category:"symbols"},clock8:{keywords:["time","late","early","schedule"],char:"🕗",fitzpatrick_scale:false,category:"symbols"},clock9:{keywords:["time","late","early","schedule"],char:"🕘",fitzpatrick_scale:false,category:"symbols"},clock10:{keywords:["time","late","early","schedule"],char:"🕙",fitzpatrick_scale:false,category:"symbols"},clock11:{keywords:["time","late","early","schedule"],char:"🕚",fitzpatrick_scale:false,category:"symbols"},clock12:{keywords:["time","noon","midnight","midday","late","early","schedule"],char:"🕛",fitzpatrick_scale:false,category:"symbols"},clock130:{keywords:["time","late","early","schedule"],char:"🕜",fitzpatrick_scale:false,category:"symbols"},clock230:{keywords:["time","late","early","schedule"],char:"🕝",fitzpatrick_scale:false,category:"symbols"},clock330:{keywords:["time","late","early","schedule"],char:"🕞",fitzpatrick_scale:false,category:"symbols"},clock430:{keywords:["time","late","early","schedule"],char:"🕟",fitzpatrick_scale:false,category:"symbols"},clock530:{keywords:["time","late","early","schedule"],char:"🕠",fitzpatrick_scale:false,category:"symbols"},clock630:{keywords:["time","late","early","schedule"],char:"🕡",fitzpatrick_scale:false,category:"symbols"},clock730:{keywords:["time","late","early","schedule"],char:"🕢",fitzpatrick_scale:false,category:"symbols"},clock830:{keywords:["time","late","early","schedule"],char:"🕣",fitzpatrick_scale:false,category:"symbols"},clock930:{keywords:["time","late","early","schedule"],char:"🕤",fitzpatrick_scale:false,category:"symbols"},clock1030:{keywords:["time","late","early","schedule"],char:"🕥",fitzpatrick_scale:false,category:"symbols"},clock1130:{keywords:["time","late","early","schedule"],char:"🕦",fitzpatrick_scale:false,category:"symbols"},clock1230:{keywords:["time","late","early","schedule"],char:"🕧",fitzpatrick_scale:false,category:"symbols"},afghanistan:{keywords:["af","flag","nation","country","banner"],char:"🇦🇫",fitzpatrick_scale:false,category:"flags"},aland_islands:{keywords:["Åland","islands","flag","nation","country","banner"],char:"🇦🇽",fitzpatrick_scale:false,category:"flags"},albania:{keywords:["al","flag","nation","country","banner"],char:"🇦🇱",fitzpatrick_scale:false,category:"flags"},algeria:{keywords:["dz","flag","nation","country","banner"],char:"🇩🇿",fitzpatrick_scale:false,category:"flags"},american_samoa:{keywords:["american","ws","flag","nation","country","banner"],char:"🇦🇸",fitzpatrick_scale:false,category:"flags"},andorra:{keywords:["ad","flag","nation","country","banner"],char:"🇦🇩",fitzpatrick_scale:false,category:"flags"},angola:{keywords:["ao","flag","nation","country","banner"],char:"🇦🇴",fitzpatrick_scale:false,category:"flags"},anguilla:{keywords:["ai","flag","nation","country","banner"],char:"🇦🇮",fitzpatrick_scale:false,category:"flags"},antarctica:{keywords:["aq","flag","nation","country","banner"],char:"🇦🇶",fitzpatrick_scale:false,category:"flags"},antigua_barbuda:{keywords:["antigua","barbuda","flag","nation","country","banner"],char:"🇦🇬",fitzpatrick_scale:false,category:"flags"},argentina:{keywords:["ar","flag","nation","country","banner"],char:"🇦🇷",fitzpatrick_scale:false,category:"flags"},armenia:{keywords:["am","flag","nation","country","banner"],char:"🇦🇲",fitzpatrick_scale:false,category:"flags"},aruba:{keywords:["aw","flag","nation","country","banner"],char:"🇦🇼",fitzpatrick_scale:false,category:"flags"},australia:{keywords:["au","flag","nation","country","banner"],char:"🇦🇺",fitzpatrick_scale:false,category:"flags"},austria:{keywords:["at","flag","nation","country","banner"],char:"🇦🇹",fitzpatrick_scale:false,category:"flags"},azerbaijan:{keywords:["az","flag","nation","country","banner"],char:"🇦🇿",fitzpatrick_scale:false,category:"flags"},bahamas:{keywords:["bs","flag","nation","country","banner"],char:"🇧🇸",fitzpatrick_scale:false,category:"flags"},bahrain:{keywords:["bh","flag","nation","country","banner"],char:"🇧🇭",fitzpatrick_scale:false,category:"flags"},bangladesh:{keywords:["bd","flag","nation","country","banner"],char:"🇧🇩",fitzpatrick_scale:false,category:"flags"},barbados:{keywords:["bb","flag","nation","country","banner"],char:"🇧🇧",fitzpatrick_scale:false,category:"flags"},belarus:{keywords:["by","flag","nation","country","banner"],char:"🇧🇾",fitzpatrick_scale:false,category:"flags"},belgium:{keywords:["be","flag","nation","country","banner"],char:"🇧🇪",fitzpatrick_scale:false,category:"flags"},belize:{keywords:["bz","flag","nation","country","banner"],char:"🇧🇿",fitzpatrick_scale:false,category:"flags"},benin:{keywords:["bj","flag","nation","country","banner"],char:"🇧🇯",fitzpatrick_scale:false,category:"flags"},bermuda:{keywords:["bm","flag","nation","country","banner"],char:"🇧🇲",fitzpatrick_scale:false,category:"flags"},bhutan:{keywords:["bt","flag","nation","country","banner"],char:"🇧🇹",fitzpatrick_scale:false,category:"flags"},bolivia:{keywords:["bo","flag","nation","country","banner"],char:"🇧🇴",fitzpatrick_scale:false,category:"flags"},caribbean_netherlands:{keywords:["bonaire","flag","nation","country","banner"],char:"🇧🇶",fitzpatrick_scale:false,category:"flags"},bosnia_herzegovina:{keywords:["bosnia","herzegovina","flag","nation","country","banner"],char:"🇧🇦",fitzpatrick_scale:false,category:"flags"},botswana:{keywords:["bw","flag","nation","country","banner"],char:"🇧🇼",fitzpatrick_scale:false,category:"flags"},brazil:{keywords:["br","flag","nation","country","banner"],char:"🇧🇷",fitzpatrick_scale:false,category:"flags"},british_indian_ocean_territory:{keywords:["british","indian","ocean","territory","flag","nation","country","banner"],char:"🇮🇴",fitzpatrick_scale:false,category:"flags"},british_virgin_islands:{keywords:["british","virgin","islands","bvi","flag","nation","country","banner"],char:"🇻🇬",fitzpatrick_scale:false,category:"flags"},brunei:{keywords:["bn","darussalam","flag","nation","country","banner"],char:"🇧🇳",fitzpatrick_scale:false,category:"flags"},bulgaria:{keywords:["bg","flag","nation","country","banner"],char:"🇧🇬",fitzpatrick_scale:false,category:"flags"},burkina_faso:{keywords:["burkina","faso","flag","nation","country","banner"],char:"🇧🇫",fitzpatrick_scale:false,category:"flags"},burundi:{keywords:["bi","flag","nation","country","banner"],char:"🇧🇮",fitzpatrick_scale:false,category:"flags"},cape_verde:{keywords:["cabo","verde","flag","nation","country","banner"],char:"🇨🇻",fitzpatrick_scale:false,category:"flags"},cambodia:{keywords:["kh","flag","nation","country","banner"],char:"🇰🇭",fitzpatrick_scale:false,category:"flags"},cameroon:{keywords:["cm","flag","nation","country","banner"],char:"🇨🇲",fitzpatrick_scale:false,category:"flags"},canada:{keywords:["ca","flag","nation","country","banner"],char:"🇨🇦",fitzpatrick_scale:false,category:"flags"},canary_islands:{keywords:["canary","islands","flag","nation","country","banner"],char:"🇮🇨",fitzpatrick_scale:false,category:"flags"},cayman_islands:{keywords:["cayman","islands","flag","nation","country","banner"],char:"🇰🇾",fitzpatrick_scale:false,category:"flags"},central_african_republic:{keywords:["central","african","republic","flag","nation","country","banner"],char:"🇨🇫",fitzpatrick_scale:false,category:"flags"},chad:{keywords:["td","flag","nation","country","banner"],char:"🇹🇩",fitzpatrick_scale:false,category:"flags"},chile:{keywords:["flag","nation","country","banner"],char:"🇨🇱",fitzpatrick_scale:false,category:"flags"},cn:{keywords:["china","chinese","prc","flag","country","nation","banner"],char:"🇨🇳",fitzpatrick_scale:false,category:"flags"},christmas_island:{keywords:["christmas","island","flag","nation","country","banner"],char:"🇨🇽",fitzpatrick_scale:false,category:"flags"},cocos_islands:{keywords:["cocos","keeling","islands","flag","nation","country","banner"],char:"🇨🇨",fitzpatrick_scale:false,category:"flags"},colombia:{keywords:["co","flag","nation","country","banner"],char:"🇨🇴",fitzpatrick_scale:false,category:"flags"},comoros:{keywords:["km","flag","nation","country","banner"],char:"🇰🇲",fitzpatrick_scale:false,category:"flags"},congo_brazzaville:{keywords:["congo","flag","nation","country","banner"],char:"🇨🇬",fitzpatrick_scale:false,category:"flags"},congo_kinshasa:{keywords:["congo","democratic","republic","flag","nation","country","banner"],char:"🇨🇩",fitzpatrick_scale:false,category:"flags"},cook_islands:{keywords:["cook","islands","flag","nation","country","banner"],char:"🇨🇰",fitzpatrick_scale:false,category:"flags"},costa_rica:{keywords:["costa","rica","flag","nation","country","banner"],char:"🇨🇷",fitzpatrick_scale:false,category:"flags"},croatia:{keywords:["hr","flag","nation","country","banner"],char:"🇭🇷",fitzpatrick_scale:false,category:"flags"},cuba:{keywords:["cu","flag","nation","country","banner"],char:"🇨🇺",fitzpatrick_scale:false,category:"flags"},curacao:{keywords:["curaçao","flag","nation","country","banner"],char:"🇨🇼",fitzpatrick_scale:false,category:"flags"},cyprus:{keywords:["cy","flag","nation","country","banner"],char:"🇨🇾",fitzpatrick_scale:false,category:"flags"},czech_republic:{keywords:["cz","flag","nation","country","banner"],char:"🇨🇿",fitzpatrick_scale:false,category:"flags"},denmark:{keywords:["dk","flag","nation","country","banner"],char:"🇩🇰",fitzpatrick_scale:false,category:"flags"},djibouti:{keywords:["dj","flag","nation","country","banner"],char:"🇩🇯",fitzpatrick_scale:false,category:"flags"},dominica:{keywords:["dm","flag","nation","country","banner"],char:"🇩🇲",fitzpatrick_scale:false,category:"flags"},dominican_republic:{keywords:["dominican","republic","flag","nation","country","banner"],char:"🇩🇴",fitzpatrick_scale:false,category:"flags"},ecuador:{keywords:["ec","flag","nation","country","banner"],char:"🇪🇨",fitzpatrick_scale:false,category:"flags"},egypt:{keywords:["eg","flag","nation","country","banner"],char:"🇪🇬",fitzpatrick_scale:false,category:"flags"},el_salvador:{keywords:["el","salvador","flag","nation","country","banner"],char:"🇸🇻",fitzpatrick_scale:false,category:"flags"},equatorial_guinea:{keywords:["equatorial","gn","flag","nation","country","banner"],char:"🇬🇶",fitzpatrick_scale:false,category:"flags"},eritrea:{keywords:["er","flag","nation","country","banner"],char:"🇪🇷",fitzpatrick_scale:false,category:"flags"},estonia:{keywords:["ee","flag","nation","country","banner"],char:"🇪🇪",fitzpatrick_scale:false,category:"flags"},ethiopia:{keywords:["et","flag","nation","country","banner"],char:"🇪🇹",fitzpatrick_scale:false,category:"flags"},eu:{keywords:["european","union","flag","banner"],char:"🇪🇺",fitzpatrick_scale:false,category:"flags"},falkland_islands:{keywords:["falkland","islands","malvinas","flag","nation","country","banner"],char:"🇫🇰",fitzpatrick_scale:false,category:"flags"},faroe_islands:{keywords:["faroe","islands","flag","nation","country","banner"],char:"🇫🇴",fitzpatrick_scale:false,category:"flags"},fiji:{keywords:["fj","flag","nation","country","banner"],char:"🇫🇯",fitzpatrick_scale:false,category:"flags"},finland:{keywords:["fi","flag","nation","country","banner"],char:"🇫🇮",fitzpatrick_scale:false,category:"flags"},fr:{keywords:["banner","flag","nation","france","french","country"],char:"🇫🇷",fitzpatrick_scale:false,category:"flags"},french_guiana:{keywords:["french","guiana","flag","nation","country","banner"],char:"🇬🇫",fitzpatrick_scale:false,category:"flags"},french_polynesia:{keywords:["french","polynesia","flag","nation","country","banner"],char:"🇵🇫",fitzpatrick_scale:false,category:"flags"},french_southern_territories:{keywords:["french","southern","territories","flag","nation","country","banner"],char:"🇹🇫",fitzpatrick_scale:false,category:"flags"},gabon:{keywords:["ga","flag","nation","country","banner"],char:"🇬🇦",fitzpatrick_scale:false,category:"flags"},gambia:{keywords:["gm","flag","nation","country","banner"],char:"🇬🇲",fitzpatrick_scale:false,category:"flags"},georgia:{keywords:["ge","flag","nation","country","banner"],char:"🇬🇪",fitzpatrick_scale:false,category:"flags"},de:{keywords:["german","nation","flag","country","banner"],char:"🇩🇪",fitzpatrick_scale:false,category:"flags"},ghana:{keywords:["gh","flag","nation","country","banner"],char:"🇬🇭",fitzpatrick_scale:false,category:"flags"},gibraltar:{keywords:["gi","flag","nation","country","banner"],char:"🇬🇮",fitzpatrick_scale:false,category:"flags"},greece:{keywords:["gr","flag","nation","country","banner"],char:"🇬🇷",fitzpatrick_scale:false,category:"flags"},greenland:{keywords:["gl","flag","nation","country","banner"],char:"🇬🇱",fitzpatrick_scale:false,category:"flags"},grenada:{keywords:["gd","flag","nation","country","banner"],char:"🇬🇩",fitzpatrick_scale:false,category:"flags"},guadeloupe:{keywords:["gp","flag","nation","country","banner"],char:"🇬🇵",fitzpatrick_scale:false,category:"flags"},guam:{keywords:["gu","flag","nation","country","banner"],char:"🇬🇺",fitzpatrick_scale:false,category:"flags"},guatemala:{keywords:["gt","flag","nation","country","banner"],char:"🇬🇹",fitzpatrick_scale:false,category:"flags"},guernsey:{keywords:["gg","flag","nation","country","banner"],char:"🇬🇬",fitzpatrick_scale:false,category:"flags"},guinea:{keywords:["gn","flag","nation","country","banner"],char:"🇬🇳",fitzpatrick_scale:false,category:"flags"},guinea_bissau:{keywords:["gw","bissau","flag","nation","country","banner"],char:"🇬🇼",fitzpatrick_scale:false,category:"flags"},guyana:{keywords:["gy","flag","nation","country","banner"],char:"🇬🇾",fitzpatrick_scale:false,category:"flags"},haiti:{keywords:["ht","flag","nation","country","banner"],char:"🇭🇹",fitzpatrick_scale:false,category:"flags"},honduras:{keywords:["hn","flag","nation","country","banner"],char:"🇭🇳",fitzpatrick_scale:false,category:"flags"},hong_kong:{keywords:["hong","kong","flag","nation","country","banner"],char:"🇭🇰",fitzpatrick_scale:false,category:"flags"},hungary:{keywords:["hu","flag","nation","country","banner"],char:"🇭🇺",fitzpatrick_scale:false,category:"flags"},iceland:{keywords:["is","flag","nation","country","banner"],char:"🇮🇸",fitzpatrick_scale:false,category:"flags"},india:{keywords:["in","flag","nation","country","banner"],char:"🇮🇳",fitzpatrick_scale:false,category:"flags"},indonesia:{keywords:["flag","nation","country","banner"],char:"🇮🇩",fitzpatrick_scale:false,category:"flags"},iran:{keywords:["iran,","islamic","republic","flag","nation","country","banner"],char:"🇮🇷",fitzpatrick_scale:false,category:"flags"},iraq:{keywords:["iq","flag","nation","country","banner"],char:"🇮🇶",fitzpatrick_scale:false,category:"flags"},ireland:{keywords:["ie","flag","nation","country","banner"],char:"🇮🇪",fitzpatrick_scale:false,category:"flags"},isle_of_man:{keywords:["isle","man","flag","nation","country","banner"],char:"🇮🇲",fitzpatrick_scale:false,category:"flags"},israel:{keywords:["il","flag","nation","country","banner"],char:"🇮🇱",fitzpatrick_scale:false,category:"flags"},it:{keywords:["italy","flag","nation","country","banner"],char:"🇮🇹",fitzpatrick_scale:false,category:"flags"},cote_divoire:{keywords:["ivory","coast","flag","nation","country","banner"],char:"🇨🇮",fitzpatrick_scale:false,category:"flags"},jamaica:{keywords:["jm","flag","nation","country","banner"],char:"🇯🇲",fitzpatrick_scale:false,category:"flags"},jp:{keywords:["japanese","nation","flag","country","banner"],char:"🇯🇵",fitzpatrick_scale:false,category:"flags"},jersey:{keywords:["je","flag","nation","country","banner"],char:"🇯🇪",fitzpatrick_scale:false,category:"flags"},jordan:{keywords:["jo","flag","nation","country","banner"],char:"🇯🇴",fitzpatrick_scale:false,category:"flags"},kazakhstan:{keywords:["kz","flag","nation","country","banner"],char:"🇰🇿",fitzpatrick_scale:false,category:"flags"},kenya:{keywords:["ke","flag","nation","country","banner"],char:"🇰🇪",fitzpatrick_scale:false,category:"flags"},kiribati:{keywords:["ki","flag","nation","country","banner"],char:"🇰🇮",fitzpatrick_scale:false,category:"flags"},kosovo:{keywords:["xk","flag","nation","country","banner"],char:"🇽🇰",fitzpatrick_scale:false,category:"flags"},kuwait:{keywords:["kw","flag","nation","country","banner"],char:"🇰🇼",fitzpatrick_scale:false,category:"flags"},kyrgyzstan:{keywords:["kg","flag","nation","country","banner"],char:"🇰🇬",fitzpatrick_scale:false,category:"flags"},laos:{keywords:["lao","democratic","republic","flag","nation","country","banner"],char:"🇱🇦",fitzpatrick_scale:false,category:"flags"},latvia:{keywords:["lv","flag","nation","country","banner"],char:"🇱🇻",fitzpatrick_scale:false,category:"flags"},lebanon:{keywords:["lb","flag","nation","country","banner"],char:"🇱🇧",fitzpatrick_scale:false,category:"flags"},lesotho:{keywords:["ls","flag","nation","country","banner"],char:"🇱🇸",fitzpatrick_scale:false,category:"flags"},liberia:{keywords:["lr","flag","nation","country","banner"],char:"🇱🇷",fitzpatrick_scale:false,category:"flags"},libya:{keywords:["ly","flag","nation","country","banner"],char:"🇱🇾",fitzpatrick_scale:false,category:"flags"},liechtenstein:{keywords:["li","flag","nation","country","banner"],char:"🇱🇮",fitzpatrick_scale:false,category:"flags"},lithuania:{keywords:["lt","flag","nation","country","banner"],char:"🇱🇹",fitzpatrick_scale:false,category:"flags"},luxembourg:{keywords:["lu","flag","nation","country","banner"],char:"🇱🇺",fitzpatrick_scale:false,category:"flags"},macau:{keywords:["macao","flag","nation","country","banner"],char:"🇲🇴",fitzpatrick_scale:false,category:"flags"},macedonia:{keywords:["macedonia,","flag","nation","country","banner"],char:"🇲🇰",fitzpatrick_scale:false,category:"flags"},madagascar:{keywords:["mg","flag","nation","country","banner"],char:"🇲🇬",fitzpatrick_scale:false,category:"flags"},malawi:{keywords:["mw","flag","nation","country","banner"],char:"🇲🇼",fitzpatrick_scale:false,category:"flags"},malaysia:{keywords:["my","flag","nation","country","banner"],char:"🇲🇾",fitzpatrick_scale:false,category:"flags"},maldives:{keywords:["mv","flag","nation","country","banner"],char:"🇲🇻",fitzpatrick_scale:false,category:"flags"},mali:{keywords:["ml","flag","nation","country","banner"],char:"🇲🇱",fitzpatrick_scale:false,category:"flags"},malta:{keywords:["mt","flag","nation","country","banner"],char:"🇲🇹",fitzpatrick_scale:false,category:"flags"},marshall_islands:{keywords:["marshall","islands","flag","nation","country","banner"],char:"🇲🇭",fitzpatrick_scale:false,category:"flags"},martinique:{keywords:["mq","flag","nation","country","banner"],char:"🇲🇶",fitzpatrick_scale:false,category:"flags"},mauritania:{keywords:["mr","flag","nation","country","banner"],char:"🇲🇷",fitzpatrick_scale:false,category:"flags"},mauritius:{keywords:["mu","flag","nation","country","banner"],char:"🇲🇺",fitzpatrick_scale:false,category:"flags"},mayotte:{keywords:["yt","flag","nation","country","banner"],char:"🇾🇹",fitzpatrick_scale:false,category:"flags"},mexico:{keywords:["mx","flag","nation","country","banner"],char:"🇲🇽",fitzpatrick_scale:false,category:"flags"},micronesia:{keywords:["micronesia,","federated","states","flag","nation","country","banner"],char:"🇫🇲",fitzpatrick_scale:false,category:"flags"},moldova:{keywords:["moldova,","republic","flag","nation","country","banner"],char:"🇲🇩",fitzpatrick_scale:false,category:"flags"},monaco:{keywords:["mc","flag","nation","country","banner"],char:"🇲🇨",fitzpatrick_scale:false,category:"flags"},mongolia:{keywords:["mn","flag","nation","country","banner"],char:"🇲🇳",fitzpatrick_scale:false,category:"flags"},montenegro:{keywords:["me","flag","nation","country","banner"],char:"🇲🇪",fitzpatrick_scale:false,category:"flags"},montserrat:{keywords:["ms","flag","nation","country","banner"],char:"🇲🇸",fitzpatrick_scale:false,category:"flags"},morocco:{keywords:["ma","flag","nation","country","banner"],char:"🇲🇦",fitzpatrick_scale:false,category:"flags"},mozambique:{keywords:["mz","flag","nation","country","banner"],char:"🇲🇿",fitzpatrick_scale:false,category:"flags"},myanmar:{keywords:["mm","flag","nation","country","banner"],char:"🇲🇲",fitzpatrick_scale:false,category:"flags"},namibia:{keywords:["na","flag","nation","country","banner"],char:"🇳🇦",fitzpatrick_scale:false,category:"flags"},nauru:{keywords:["nr","flag","nation","country","banner"],char:"🇳🇷",fitzpatrick_scale:false,category:"flags"},nepal:{keywords:["np","flag","nation","country","banner"],char:"🇳🇵",fitzpatrick_scale:false,category:"flags"},netherlands:{keywords:["nl","flag","nation","country","banner"],char:"🇳🇱",fitzpatrick_scale:false,category:"flags"},new_caledonia:{keywords:["new","caledonia","flag","nation","country","banner"],char:"🇳🇨",fitzpatrick_scale:false,category:"flags"},new_zealand:{keywords:["new","zealand","flag","nation","country","banner"],char:"🇳🇿",fitzpatrick_scale:false,category:"flags"},nicaragua:{keywords:["ni","flag","nation","country","banner"],char:"🇳🇮",fitzpatrick_scale:false,category:"flags"},niger:{keywords:["ne","flag","nation","country","banner"],char:"🇳🇪",fitzpatrick_scale:false,category:"flags"},nigeria:{keywords:["flag","nation","country","banner"],char:"🇳🇬",fitzpatrick_scale:false,category:"flags"},niue:{keywords:["nu","flag","nation","country","banner"],char:"🇳🇺",fitzpatrick_scale:false,category:"flags"},norfolk_island:{keywords:["norfolk","island","flag","nation","country","banner"],char:"🇳🇫",fitzpatrick_scale:false,category:"flags"},northern_mariana_islands:{keywords:["northern","mariana","islands","flag","nation","country","banner"],char:"🇲🇵",fitzpatrick_scale:false,category:"flags"},north_korea:{keywords:["north","korea","nation","flag","country","banner"],char:"🇰🇵",fitzpatrick_scale:false,category:"flags"},norway:{keywords:["no","flag","nation","country","banner"],char:"🇳🇴",fitzpatrick_scale:false,category:"flags"},oman:{keywords:["om_symbol","flag","nation","country","banner"],char:"🇴🇲",fitzpatrick_scale:false,category:"flags"},pakistan:{keywords:["pk","flag","nation","country","banner"],char:"🇵🇰",fitzpatrick_scale:false,category:"flags"},palau:{keywords:["pw","flag","nation","country","banner"],char:"🇵🇼",fitzpatrick_scale:false,category:"flags"},palestinian_territories:{keywords:["palestine","palestinian","territories","flag","nation","country","banner"],char:"🇵🇸",fitzpatrick_scale:false,category:"flags"},panama:{keywords:["pa","flag","nation","country","banner"],char:"🇵🇦",fitzpatrick_scale:false,category:"flags"},papua_new_guinea:{keywords:["papua","new","guinea","flag","nation","country","banner"],char:"🇵🇬",fitzpatrick_scale:false,category:"flags"},paraguay:{keywords:["py","flag","nation","country","banner"],char:"🇵🇾",fitzpatrick_scale:false,category:"flags"},peru:{keywords:["pe","flag","nation","country","banner"],char:"🇵🇪",fitzpatrick_scale:false,category:"flags"},philippines:{keywords:["ph","flag","nation","country","banner"],char:"🇵🇭",fitzpatrick_scale:false,category:"flags"},pitcairn_islands:{keywords:["pitcairn","flag","nation","country","banner"],char:"🇵🇳",fitzpatrick_scale:false,category:"flags"},poland:{keywords:["pl","flag","nation","country","banner"],char:"🇵🇱",fitzpatrick_scale:false,category:"flags"},portugal:{keywords:["pt","flag","nation","country","banner"],char:"🇵🇹",fitzpatrick_scale:false,category:"flags"},puerto_rico:{keywords:["puerto","rico","flag","nation","country","banner"],char:"🇵🇷",fitzpatrick_scale:false,category:"flags"},qatar:{keywords:["qa","flag","nation","country","banner"],char:"🇶🇦",fitzpatrick_scale:false,category:"flags"},reunion:{keywords:["réunion","flag","nation","country","banner"],char:"🇷🇪",fitzpatrick_scale:false,category:"flags"},romania:{keywords:["ro","flag","nation","country","banner"],char:"🇷🇴",fitzpatrick_scale:false,category:"flags"},ru:{keywords:["russian","federation","flag","nation","country","banner"],char:"🇷🇺",fitzpatrick_scale:false,category:"flags"},rwanda:{keywords:["rw","flag","nation","country","banner"],char:"🇷🇼",fitzpatrick_scale:false,category:"flags"},st_barthelemy:{keywords:["saint","barthélemy","flag","nation","country","banner"],char:"🇧🇱",fitzpatrick_scale:false,category:"flags"},st_helena:{keywords:["saint","helena","ascension","tristan","cunha","flag","nation","country","banner"],char:"🇸🇭",fitzpatrick_scale:false,category:"flags"},st_kitts_nevis:{keywords:["saint","kitts","nevis","flag","nation","country","banner"],char:"🇰🇳",fitzpatrick_scale:false,category:"flags"},st_lucia:{keywords:["saint","lucia","flag","nation","country","banner"],char:"🇱🇨",fitzpatrick_scale:false,category:"flags"},st_pierre_miquelon:{keywords:["saint","pierre","miquelon","flag","nation","country","banner"],char:"🇵🇲",fitzpatrick_scale:false,category:"flags"},st_vincent_grenadines:{keywords:["saint","vincent","grenadines","flag","nation","country","banner"],char:"🇻🇨",fitzpatrick_scale:false,category:"flags"},samoa:{keywords:["ws","flag","nation","country","banner"],char:"🇼🇸",fitzpatrick_scale:false,category:"flags"},san_marino:{keywords:["san","marino","flag","nation","country","banner"],char:"🇸🇲",fitzpatrick_scale:false,category:"flags"},sao_tome_principe:{keywords:["sao","tome","principe","flag","nation","country","banner"],char:"🇸🇹",fitzpatrick_scale:false,category:"flags"},saudi_arabia:{keywords:["flag","nation","country","banner"],char:"🇸🇦",fitzpatrick_scale:false,category:"flags"},senegal:{keywords:["sn","flag","nation","country","banner"],char:"🇸🇳",fitzpatrick_scale:false,category:"flags"},serbia:{keywords:["rs","flag","nation","country","banner"],char:"🇷🇸",fitzpatrick_scale:false,category:"flags"},seychelles:{keywords:["sc","flag","nation","country","banner"],char:"🇸🇨",fitzpatrick_scale:false,category:"flags"},sierra_leone:{keywords:["sierra","leone","flag","nation","country","banner"],char:"🇸🇱",fitzpatrick_scale:false,category:"flags"},singapore:{keywords:["sg","flag","nation","country","banner"],char:"🇸🇬",fitzpatrick_scale:false,category:"flags"},sint_maarten:{keywords:["sint","maarten","dutch","flag","nation","country","banner"],char:"🇸🇽",fitzpatrick_scale:false,category:"flags"},slovakia:{keywords:["sk","flag","nation","country","banner"],char:"🇸🇰",fitzpatrick_scale:false,category:"flags"},slovenia:{keywords:["si","flag","nation","country","banner"],char:"🇸🇮",fitzpatrick_scale:false,category:"flags"},solomon_islands:{keywords:["solomon","islands","flag","nation","country","banner"],char:"🇸🇧",fitzpatrick_scale:false,category:"flags"},somalia:{keywords:["so","flag","nation","country","banner"],char:"🇸🇴",fitzpatrick_scale:false,category:"flags"},south_africa:{keywords:["south","africa","flag","nation","country","banner"],char:"🇿🇦",fitzpatrick_scale:false,category:"flags"},south_georgia_south_sandwich_islands:{keywords:["south","georgia","sandwich","islands","flag","nation","country","banner"],char:"🇬🇸",fitzpatrick_scale:false,category:"flags"},kr:{keywords:["south","korea","nation","flag","country","banner"],char:"🇰🇷",fitzpatrick_scale:false,category:"flags"},south_sudan:{keywords:["south","sd","flag","nation","country","banner"],char:"🇸🇸",fitzpatrick_scale:false,category:"flags"},es:{keywords:["spain","flag","nation","country","banner"],char:"🇪🇸",fitzpatrick_scale:false,category:"flags"},sri_lanka:{keywords:["sri","lanka","flag","nation","country","banner"],char:"🇱🇰",fitzpatrick_scale:false,category:"flags"},sudan:{keywords:["sd","flag","nation","country","banner"],char:"🇸🇩",fitzpatrick_scale:false,category:"flags"},suriname:{keywords:["sr","flag","nation","country","banner"],char:"🇸🇷",fitzpatrick_scale:false,category:"flags"},swaziland:{keywords:["sz","flag","nation","country","banner"],char:"🇸🇿",fitzpatrick_scale:false,category:"flags"},sweden:{keywords:["se","flag","nation","country","banner"],char:"🇸🇪",fitzpatrick_scale:false,category:"flags"},switzerland:{keywords:["ch","flag","nation","country","banner"],char:"🇨🇭",fitzpatrick_scale:false,category:"flags"},syria:{keywords:["syrian","arab","republic","flag","nation","country","banner"],char:"🇸🇾",fitzpatrick_scale:false,category:"flags"},taiwan:{keywords:["tw","flag","nation","country","banner"],char:"🇹🇼",fitzpatrick_scale:false,category:"flags"},tajikistan:{keywords:["tj","flag","nation","country","banner"],char:"🇹🇯",fitzpatrick_scale:false,category:"flags"},tanzania:{keywords:["tanzania,","united","republic","flag","nation","country","banner"],char:"🇹🇿",fitzpatrick_scale:false,category:"flags"},thailand:{keywords:["th","flag","nation","country","banner"],char:"🇹🇭",fitzpatrick_scale:false,category:"flags"},timor_leste:{keywords:["timor","leste","flag","nation","country","banner"],char:"🇹🇱",fitzpatrick_scale:false,category:"flags"},togo:{keywords:["tg","flag","nation","country","banner"],char:"🇹🇬",fitzpatrick_scale:false,category:"flags"},tokelau:{keywords:["tk","flag","nation","country","banner"],char:"🇹🇰",fitzpatrick_scale:false,category:"flags"},tonga:{keywords:["to","flag","nation","country","banner"],char:"🇹🇴",fitzpatrick_scale:false,category:"flags"},trinidad_tobago:{keywords:["trinidad","tobago","flag","nation","country","banner"],char:"🇹🇹",fitzpatrick_scale:false,category:"flags"},tunisia:{keywords:["tn","flag","nation","country","banner"],char:"🇹🇳",fitzpatrick_scale:false,category:"flags"},tr:{keywords:["turkey","flag","nation","country","banner"],char:"🇹🇷",fitzpatrick_scale:false,category:"flags"},turkmenistan:{keywords:["flag","nation","country","banner"],char:"🇹🇲",fitzpatrick_scale:false,category:"flags"},turks_caicos_islands:{keywords:["turks","caicos","islands","flag","nation","country","banner"],char:"🇹🇨",fitzpatrick_scale:false,category:"flags"},tuvalu:{keywords:["flag","nation","country","banner"],char:"🇹🇻",fitzpatrick_scale:false,category:"flags"},uganda:{keywords:["ug","flag","nation","country","banner"],char:"🇺🇬",fitzpatrick_scale:false,category:"flags"},ukraine:{keywords:["ua","flag","nation","country","banner"],char:"🇺🇦",fitzpatrick_scale:false,category:"flags"},united_arab_emirates:{keywords:["united","arab","emirates","flag","nation","country","banner"],char:"🇦🇪",fitzpatrick_scale:false,category:"flags"},uk:{keywords:["united","kingdom","great","britain","northern","ireland","flag","nation","country","banner","british","UK","english","england","union jack"],char:"🇬🇧",fitzpatrick_scale:false,category:"flags"},england:{keywords:["flag","english"],char:"🏴󠁧󠁢󠁥󠁮󠁧󠁿",fitzpatrick_scale:false,category:"flags"},scotland:{keywords:["flag","scottish"],char:"🏴󠁧󠁢󠁳󠁣󠁴󠁿",fitzpatrick_scale:false,category:"flags"},wales:{keywords:["flag","welsh"],char:"🏴󠁧󠁢󠁷󠁬󠁳󠁿",fitzpatrick_scale:false,category:"flags"},us:{keywords:["united","states","america","flag","nation","country","banner"],char:"🇺🇸",fitzpatrick_scale:false,category:"flags"},us_virgin_islands:{keywords:["virgin","islands","us","flag","nation","country","banner"],char:"🇻🇮",fitzpatrick_scale:false,category:"flags"},uruguay:{keywords:["uy","flag","nation","country","banner"],char:"🇺🇾",fitzpatrick_scale:false,category:"flags"},uzbekistan:{keywords:["uz","flag","nation","country","banner"],char:"🇺🇿",fitzpatrick_scale:false,category:"flags"},vanuatu:{keywords:["vu","flag","nation","country","banner"],char:"🇻🇺",fitzpatrick_scale:false,category:"flags"},vatican_city:{keywords:["vatican","city","flag","nation","country","banner"],char:"🇻🇦",fitzpatrick_scale:false,category:"flags"},venezuela:{keywords:["ve","bolivarian","republic","flag","nation","country","banner"],char:"🇻🇪",fitzpatrick_scale:false,category:"flags"},vietnam:{keywords:["viet","nam","flag","nation","country","banner"],char:"🇻🇳",fitzpatrick_scale:false,category:"flags"},wallis_futuna:{keywords:["wallis","futuna","flag","nation","country","banner"],char:"🇼🇫",fitzpatrick_scale:false,category:"flags"},western_sahara:{keywords:["western","sahara","flag","nation","country","banner"],char:"🇪🇭",fitzpatrick_scale:false,category:"flags"},yemen:{keywords:["ye","flag","nation","country","banner"],char:"🇾🇪",fitzpatrick_scale:false,category:"flags"},zambia:{keywords:["zm","flag","nation","country","banner"],char:"🇿🇲",fitzpatrick_scale:false,category:"flags"},zimbabwe:{keywords:["zw","flag","nation","country","banner"],char:"🇿🇼",fitzpatrick_scale:false,category:"flags"},united_nations:{keywords:["un","flag","banner"],char:"🇺🇳",fitzpatrick_scale:false,category:"flags"},pirate_flag:{keywords:["skull","crossbones","flag","banner"],char:"🏴‍☠️",fitzpatrick_scale:false,category:"flags"}}); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/emoticons/js/emojis.min.js b/public/resource/tinymce/plugins/emoticons/js/emojis.min.js new file mode 100644 index 0000000..5a1c491 --- /dev/null +++ b/public/resource/tinymce/plugins/emoticons/js/emojis.min.js @@ -0,0 +1,2 @@ +// Source: npm package: emojilib, file:emojis.json +window.tinymce.Resource.add("tinymce.plugins.emoticons",{grinning:{keywords:["face","smile","happy","joy",":D","grin"],char:"\u{1f600}",fitzpatrick_scale:!1,category:"people"},grimacing:{keywords:["face","grimace","teeth"],char:"\u{1f62c}",fitzpatrick_scale:!1,category:"people"},grin:{keywords:["face","happy","smile","joy","kawaii"],char:"\u{1f601}",fitzpatrick_scale:!1,category:"people"},joy:{keywords:["face","cry","tears","weep","happy","happytears","haha"],char:"\u{1f602}",fitzpatrick_scale:!1,category:"people"},rofl:{keywords:["face","rolling","floor","laughing","lol","haha"],char:"\u{1f923}",fitzpatrick_scale:!1,category:"people"},partying:{keywords:["face","celebration","woohoo"],char:"\u{1f973}",fitzpatrick_scale:!1,category:"people"},smiley:{keywords:["face","happy","joy","haha",":D",":)","smile","funny"],char:"\u{1f603}",fitzpatrick_scale:!1,category:"people"},smile:{keywords:["face","happy","joy","funny","haha","laugh","like",":D",":)"],char:"\u{1f604}",fitzpatrick_scale:!1,category:"people"},sweat_smile:{keywords:["face","hot","happy","laugh","sweat","smile","relief"],char:"\u{1f605}",fitzpatrick_scale:!1,category:"people"},laughing:{keywords:["happy","joy","lol","satisfied","haha","face","glad","XD","laugh"],char:"\u{1f606}",fitzpatrick_scale:!1,category:"people"},innocent:{keywords:["face","angel","heaven","halo"],char:"\u{1f607}",fitzpatrick_scale:!1,category:"people"},wink:{keywords:["face","happy","mischievous","secret",";)","smile","eye"],char:"\u{1f609}",fitzpatrick_scale:!1,category:"people"},blush:{keywords:["face","smile","happy","flushed","crush","embarrassed","shy","joy"],char:"\u{1f60a}",fitzpatrick_scale:!1,category:"people"},slightly_smiling_face:{keywords:["face","smile"],char:"\u{1f642}",fitzpatrick_scale:!1,category:"people"},upside_down_face:{keywords:["face","flipped","silly","smile"],char:"\u{1f643}",fitzpatrick_scale:!1,category:"people"},relaxed:{keywords:["face","blush","massage","happiness"],char:"\u263a\ufe0f",fitzpatrick_scale:!1,category:"people"},yum:{keywords:["happy","joy","tongue","smile","face","silly","yummy","nom","delicious","savouring"],char:"\u{1f60b}",fitzpatrick_scale:!1,category:"people"},relieved:{keywords:["face","relaxed","phew","massage","happiness"],char:"\u{1f60c}",fitzpatrick_scale:!1,category:"people"},heart_eyes:{keywords:["face","love","like","affection","valentines","infatuation","crush","heart"],char:"\u{1f60d}",fitzpatrick_scale:!1,category:"people"},smiling_face_with_three_hearts:{keywords:["face","love","like","affection","valentines","infatuation","crush","hearts","adore"],char:"\u{1f970}",fitzpatrick_scale:!1,category:"people"},kissing_heart:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:"\u{1f618}",fitzpatrick_scale:!1,category:"people"},kissing:{keywords:["love","like","face","3","valentines","infatuation","kiss"],char:"\u{1f617}",fitzpatrick_scale:!1,category:"people"},kissing_smiling_eyes:{keywords:["face","affection","valentines","infatuation","kiss"],char:"\u{1f619}",fitzpatrick_scale:!1,category:"people"},kissing_closed_eyes:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:"\u{1f61a}",fitzpatrick_scale:!1,category:"people"},stuck_out_tongue_winking_eye:{keywords:["face","prank","childish","playful","mischievous","smile","wink","tongue"],char:"\u{1f61c}",fitzpatrick_scale:!1,category:"people"},zany:{keywords:["face","goofy","crazy"],char:"\u{1f92a}",fitzpatrick_scale:!1,category:"people"},raised_eyebrow:{keywords:["face","distrust","scepticism","disapproval","disbelief","surprise"],char:"\u{1f928}",fitzpatrick_scale:!1,category:"people"},monocle:{keywords:["face","stuffy","wealthy"],char:"\u{1f9d0}",fitzpatrick_scale:!1,category:"people"},stuck_out_tongue_closed_eyes:{keywords:["face","prank","playful","mischievous","smile","tongue"],char:"\u{1f61d}",fitzpatrick_scale:!1,category:"people"},stuck_out_tongue:{keywords:["face","prank","childish","playful","mischievous","smile","tongue"],char:"\u{1f61b}",fitzpatrick_scale:!1,category:"people"},money_mouth_face:{keywords:["face","rich","dollar","money"],char:"\u{1f911}",fitzpatrick_scale:!1,category:"people"},nerd_face:{keywords:["face","nerdy","geek","dork"],char:"\u{1f913}",fitzpatrick_scale:!1,category:"people"},sunglasses:{keywords:["face","cool","smile","summer","beach","sunglass"],char:"\u{1f60e}",fitzpatrick_scale:!1,category:"people"},star_struck:{keywords:["face","smile","starry","eyes","grinning"],char:"\u{1f929}",fitzpatrick_scale:!1,category:"people"},clown_face:{keywords:["face"],char:"\u{1f921}",fitzpatrick_scale:!1,category:"people"},cowboy_hat_face:{keywords:["face","cowgirl","hat"],char:"\u{1f920}",fitzpatrick_scale:!1,category:"people"},hugs:{keywords:["face","smile","hug"],char:"\u{1f917}",fitzpatrick_scale:!1,category:"people"},smirk:{keywords:["face","smile","mean","prank","smug","sarcasm"],char:"\u{1f60f}",fitzpatrick_scale:!1,category:"people"},no_mouth:{keywords:["face","hellokitty"],char:"\u{1f636}",fitzpatrick_scale:!1,category:"people"},neutral_face:{keywords:["indifference","meh",":|","neutral"],char:"\u{1f610}",fitzpatrick_scale:!1,category:"people"},expressionless:{keywords:["face","indifferent","-_-","meh","deadpan"],char:"\u{1f611}",fitzpatrick_scale:!1,category:"people"},unamused:{keywords:["indifference","bored","straight face","serious","sarcasm","unimpressed","skeptical","dubious","side_eye"],char:"\u{1f612}",fitzpatrick_scale:!1,category:"people"},roll_eyes:{keywords:["face","eyeroll","frustrated"],char:"\u{1f644}",fitzpatrick_scale:!1,category:"people"},thinking:{keywords:["face","hmmm","think","consider"],char:"\u{1f914}",fitzpatrick_scale:!1,category:"people"},lying_face:{keywords:["face","lie","pinocchio"],char:"\u{1f925}",fitzpatrick_scale:!1,category:"people"},hand_over_mouth:{keywords:["face","whoops","shock","surprise"],char:"\u{1f92d}",fitzpatrick_scale:!1,category:"people"},shushing:{keywords:["face","quiet","shhh"],char:"\u{1f92b}",fitzpatrick_scale:!1,category:"people"},symbols_over_mouth:{keywords:["face","swearing","cursing","cussing","profanity","expletive"],char:"\u{1f92c}",fitzpatrick_scale:!1,category:"people"},exploding_head:{keywords:["face","shocked","mind","blown"],char:"\u{1f92f}",fitzpatrick_scale:!1,category:"people"},flushed:{keywords:["face","blush","shy","flattered"],char:"\u{1f633}",fitzpatrick_scale:!1,category:"people"},disappointed:{keywords:["face","sad","upset","depressed",":("],char:"\u{1f61e}",fitzpatrick_scale:!1,category:"people"},worried:{keywords:["face","concern","nervous",":("],char:"\u{1f61f}",fitzpatrick_scale:!1,category:"people"},angry:{keywords:["mad","face","annoyed","frustrated"],char:"\u{1f620}",fitzpatrick_scale:!1,category:"people"},rage:{keywords:["angry","mad","hate","despise"],char:"\u{1f621}",fitzpatrick_scale:!1,category:"people"},pensive:{keywords:["face","sad","depressed","upset"],char:"\u{1f614}",fitzpatrick_scale:!1,category:"people"},confused:{keywords:["face","indifference","huh","weird","hmmm",":/"],char:"\u{1f615}",fitzpatrick_scale:!1,category:"people"},slightly_frowning_face:{keywords:["face","frowning","disappointed","sad","upset"],char:"\u{1f641}",fitzpatrick_scale:!1,category:"people"},frowning_face:{keywords:["face","sad","upset","frown"],char:"\u2639",fitzpatrick_scale:!1,category:"people"},persevere:{keywords:["face","sick","no","upset","oops"],char:"\u{1f623}",fitzpatrick_scale:!1,category:"people"},confounded:{keywords:["face","confused","sick","unwell","oops",":S"],char:"\u{1f616}",fitzpatrick_scale:!1,category:"people"},tired_face:{keywords:["sick","whine","upset","frustrated"],char:"\u{1f62b}",fitzpatrick_scale:!1,category:"people"},weary:{keywords:["face","tired","sleepy","sad","frustrated","upset"],char:"\u{1f629}",fitzpatrick_scale:!1,category:"people"},pleading:{keywords:["face","begging","mercy"],char:"\u{1f97a}",fitzpatrick_scale:!1,category:"people"},triumph:{keywords:["face","gas","phew","proud","pride"],char:"\u{1f624}",fitzpatrick_scale:!1,category:"people"},open_mouth:{keywords:["face","surprise","impressed","wow","whoa",":O"],char:"\u{1f62e}",fitzpatrick_scale:!1,category:"people"},scream:{keywords:["face","munch","scared","omg"],char:"\u{1f631}",fitzpatrick_scale:!1,category:"people"},fearful:{keywords:["face","scared","terrified","nervous","oops","huh"],char:"\u{1f628}",fitzpatrick_scale:!1,category:"people"},cold_sweat:{keywords:["face","nervous","sweat"],char:"\u{1f630}",fitzpatrick_scale:!1,category:"people"},hushed:{keywords:["face","woo","shh"],char:"\u{1f62f}",fitzpatrick_scale:!1,category:"people"},frowning:{keywords:["face","aw","what"],char:"\u{1f626}",fitzpatrick_scale:!1,category:"people"},anguished:{keywords:["face","stunned","nervous"],char:"\u{1f627}",fitzpatrick_scale:!1,category:"people"},cry:{keywords:["face","tears","sad","depressed","upset",":'("],char:"\u{1f622}",fitzpatrick_scale:!1,category:"people"},disappointed_relieved:{keywords:["face","phew","sweat","nervous"],char:"\u{1f625}",fitzpatrick_scale:!1,category:"people"},drooling_face:{keywords:["face"],char:"\u{1f924}",fitzpatrick_scale:!1,category:"people"},sleepy:{keywords:["face","tired","rest","nap"],char:"\u{1f62a}",fitzpatrick_scale:!1,category:"people"},sweat:{keywords:["face","hot","sad","tired","exercise"],char:"\u{1f613}",fitzpatrick_scale:!1,category:"people"},hot:{keywords:["face","feverish","heat","red","sweating"],char:"\u{1f975}",fitzpatrick_scale:!1,category:"people"},cold:{keywords:["face","blue","freezing","frozen","frostbite","icicles"],char:"\u{1f976}",fitzpatrick_scale:!1,category:"people"},sob:{keywords:["face","cry","tears","sad","upset","depressed"],char:"\u{1f62d}",fitzpatrick_scale:!1,category:"people"},dizzy_face:{keywords:["spent","unconscious","xox","dizzy"],char:"\u{1f635}",fitzpatrick_scale:!1,category:"people"},astonished:{keywords:["face","xox","surprised","poisoned"],char:"\u{1f632}",fitzpatrick_scale:!1,category:"people"},zipper_mouth_face:{keywords:["face","sealed","zipper","secret"],char:"\u{1f910}",fitzpatrick_scale:!1,category:"people"},nauseated_face:{keywords:["face","vomit","gross","green","sick","throw up","ill"],char:"\u{1f922}",fitzpatrick_scale:!1,category:"people"},sneezing_face:{keywords:["face","gesundheit","sneeze","sick","allergy"],char:"\u{1f927}",fitzpatrick_scale:!1,category:"people"},vomiting:{keywords:["face","sick"],char:"\u{1f92e}",fitzpatrick_scale:!1,category:"people"},mask:{keywords:["face","sick","ill","disease"],char:"\u{1f637}",fitzpatrick_scale:!1,category:"people"},face_with_thermometer:{keywords:["sick","temperature","thermometer","cold","fever"],char:"\u{1f912}",fitzpatrick_scale:!1,category:"people"},face_with_head_bandage:{keywords:["injured","clumsy","bandage","hurt"],char:"\u{1f915}",fitzpatrick_scale:!1,category:"people"},woozy:{keywords:["face","dizzy","intoxicated","tipsy","wavy"],char:"\u{1f974}",fitzpatrick_scale:!1,category:"people"},sleeping:{keywords:["face","tired","sleepy","night","zzz"],char:"\u{1f634}",fitzpatrick_scale:!1,category:"people"},zzz:{keywords:["sleepy","tired","dream"],char:"\u{1f4a4}",fitzpatrick_scale:!1,category:"people"},poop:{keywords:["hankey","shitface","fail","turd","shit"],char:"\u{1f4a9}",fitzpatrick_scale:!1,category:"people"},smiling_imp:{keywords:["devil","horns"],char:"\u{1f608}",fitzpatrick_scale:!1,category:"people"},imp:{keywords:["devil","angry","horns"],char:"\u{1f47f}",fitzpatrick_scale:!1,category:"people"},japanese_ogre:{keywords:["monster","red","mask","halloween","scary","creepy","devil","demon","japanese","ogre"],char:"\u{1f479}",fitzpatrick_scale:!1,category:"people"},japanese_goblin:{keywords:["red","evil","mask","monster","scary","creepy","japanese","goblin"],char:"\u{1f47a}",fitzpatrick_scale:!1,category:"people"},skull:{keywords:["dead","skeleton","creepy","death"],char:"\u{1f480}",fitzpatrick_scale:!1,category:"people"},ghost:{keywords:["halloween","spooky","scary"],char:"\u{1f47b}",fitzpatrick_scale:!1,category:"people"},alien:{keywords:["UFO","paul","weird","outer_space"],char:"\u{1f47d}",fitzpatrick_scale:!1,category:"people"},robot:{keywords:["computer","machine","bot"],char:"\u{1f916}",fitzpatrick_scale:!1,category:"people"},smiley_cat:{keywords:["animal","cats","happy","smile"],char:"\u{1f63a}",fitzpatrick_scale:!1,category:"people"},smile_cat:{keywords:["animal","cats","smile"],char:"\u{1f638}",fitzpatrick_scale:!1,category:"people"},joy_cat:{keywords:["animal","cats","haha","happy","tears"],char:"\u{1f639}",fitzpatrick_scale:!1,category:"people"},heart_eyes_cat:{keywords:["animal","love","like","affection","cats","valentines","heart"],char:"\u{1f63b}",fitzpatrick_scale:!1,category:"people"},smirk_cat:{keywords:["animal","cats","smirk"],char:"\u{1f63c}",fitzpatrick_scale:!1,category:"people"},kissing_cat:{keywords:["animal","cats","kiss"],char:"\u{1f63d}",fitzpatrick_scale:!1,category:"people"},scream_cat:{keywords:["animal","cats","munch","scared","scream"],char:"\u{1f640}",fitzpatrick_scale:!1,category:"people"},crying_cat_face:{keywords:["animal","tears","weep","sad","cats","upset","cry"],char:"\u{1f63f}",fitzpatrick_scale:!1,category:"people"},pouting_cat:{keywords:["animal","cats"],char:"\u{1f63e}",fitzpatrick_scale:!1,category:"people"},palms_up:{keywords:["hands","gesture","cupped","prayer"],char:"\u{1f932}",fitzpatrick_scale:!0,category:"people"},raised_hands:{keywords:["gesture","hooray","yea","celebration","hands"],char:"\u{1f64c}",fitzpatrick_scale:!0,category:"people"},clap:{keywords:["hands","praise","applause","congrats","yay"],char:"\u{1f44f}",fitzpatrick_scale:!0,category:"people"},wave:{keywords:["hands","gesture","goodbye","solong","farewell","hello","hi","palm"],char:"\u{1f44b}",fitzpatrick_scale:!0,category:"people"},call_me_hand:{keywords:["hands","gesture"],char:"\u{1f919}",fitzpatrick_scale:!0,category:"people"},"+1":{keywords:["thumbsup","yes","awesome","good","agree","accept","cool","hand","like"],char:"\u{1f44d}",fitzpatrick_scale:!0,category:"people"},"-1":{keywords:["thumbsdown","no","dislike","hand"],char:"\u{1f44e}",fitzpatrick_scale:!0,category:"people"},facepunch:{keywords:["angry","violence","fist","hit","attack","hand"],char:"\u{1f44a}",fitzpatrick_scale:!0,category:"people"},fist:{keywords:["fingers","hand","grasp"],char:"\u270a",fitzpatrick_scale:!0,category:"people"},fist_left:{keywords:["hand","fistbump"],char:"\u{1f91b}",fitzpatrick_scale:!0,category:"people"},fist_right:{keywords:["hand","fistbump"],char:"\u{1f91c}",fitzpatrick_scale:!0,category:"people"},v:{keywords:["fingers","ohyeah","hand","peace","victory","two"],char:"\u270c",fitzpatrick_scale:!0,category:"people"},ok_hand:{keywords:["fingers","limbs","perfect","ok","okay"],char:"\u{1f44c}",fitzpatrick_scale:!0,category:"people"},raised_hand:{keywords:["fingers","stop","highfive","palm","ban"],char:"\u270b",fitzpatrick_scale:!0,category:"people"},raised_back_of_hand:{keywords:["fingers","raised","backhand"],char:"\u{1f91a}",fitzpatrick_scale:!0,category:"people"},open_hands:{keywords:["fingers","butterfly","hands","open"],char:"\u{1f450}",fitzpatrick_scale:!0,category:"people"},muscle:{keywords:["arm","flex","hand","summer","strong","biceps"],char:"\u{1f4aa}",fitzpatrick_scale:!0,category:"people"},pray:{keywords:["please","hope","wish","namaste","highfive"],char:"\u{1f64f}",fitzpatrick_scale:!0,category:"people"},foot:{keywords:["kick","stomp"],char:"\u{1f9b6}",fitzpatrick_scale:!0,category:"people"},leg:{keywords:["kick","limb"],char:"\u{1f9b5}",fitzpatrick_scale:!0,category:"people"},handshake:{keywords:["agreement","shake"],char:"\u{1f91d}",fitzpatrick_scale:!1,category:"people"},point_up:{keywords:["hand","fingers","direction","up"],char:"\u261d",fitzpatrick_scale:!0,category:"people"},point_up_2:{keywords:["fingers","hand","direction","up"],char:"\u{1f446}",fitzpatrick_scale:!0,category:"people"},point_down:{keywords:["fingers","hand","direction","down"],char:"\u{1f447}",fitzpatrick_scale:!0,category:"people"},point_left:{keywords:["direction","fingers","hand","left"],char:"\u{1f448}",fitzpatrick_scale:!0,category:"people"},point_right:{keywords:["fingers","hand","direction","right"],char:"\u{1f449}",fitzpatrick_scale:!0,category:"people"},fu:{keywords:["hand","fingers","rude","middle","flipping"],char:"\u{1f595}",fitzpatrick_scale:!0,category:"people"},raised_hand_with_fingers_splayed:{keywords:["hand","fingers","palm"],char:"\u{1f590}",fitzpatrick_scale:!0,category:"people"},love_you:{keywords:["hand","fingers","gesture"],char:"\u{1f91f}",fitzpatrick_scale:!0,category:"people"},metal:{keywords:["hand","fingers","evil_eye","sign_of_horns","rock_on"],char:"\u{1f918}",fitzpatrick_scale:!0,category:"people"},crossed_fingers:{keywords:["good","lucky"],char:"\u{1f91e}",fitzpatrick_scale:!0,category:"people"},vulcan_salute:{keywords:["hand","fingers","spock","star trek"],char:"\u{1f596}",fitzpatrick_scale:!0,category:"people"},writing_hand:{keywords:["lower_left_ballpoint_pen","stationery","write","compose"],char:"\u270d",fitzpatrick_scale:!0,category:"people"},selfie:{keywords:["camera","phone"],char:"\u{1f933}",fitzpatrick_scale:!0,category:"people"},nail_care:{keywords:["beauty","manicure","finger","fashion","nail"],char:"\u{1f485}",fitzpatrick_scale:!0,category:"people"},lips:{keywords:["mouth","kiss"],char:"\u{1f444}",fitzpatrick_scale:!1,category:"people"},tooth:{keywords:["teeth","dentist"],char:"\u{1f9b7}",fitzpatrick_scale:!1,category:"people"},tongue:{keywords:["mouth","playful"],char:"\u{1f445}",fitzpatrick_scale:!1,category:"people"},ear:{keywords:["face","hear","sound","listen"],char:"\u{1f442}",fitzpatrick_scale:!0,category:"people"},nose:{keywords:["smell","sniff"],char:"\u{1f443}",fitzpatrick_scale:!0,category:"people"},eye:{keywords:["face","look","see","watch","stare"],char:"\u{1f441}",fitzpatrick_scale:!1,category:"people"},eyes:{keywords:["look","watch","stalk","peek","see"],char:"\u{1f440}",fitzpatrick_scale:!1,category:"people"},brain:{keywords:["smart","intelligent"],char:"\u{1f9e0}",fitzpatrick_scale:!1,category:"people"},bust_in_silhouette:{keywords:["user","person","human"],char:"\u{1f464}",fitzpatrick_scale:!1,category:"people"},busts_in_silhouette:{keywords:["user","person","human","group","team"],char:"\u{1f465}",fitzpatrick_scale:!1,category:"people"},speaking_head:{keywords:["user","person","human","sing","say","talk"],char:"\u{1f5e3}",fitzpatrick_scale:!1,category:"people"},baby:{keywords:["child","boy","girl","toddler"],char:"\u{1f476}",fitzpatrick_scale:!0,category:"people"},child:{keywords:["gender-neutral","young"],char:"\u{1f9d2}",fitzpatrick_scale:!0,category:"people"},boy:{keywords:["man","male","guy","teenager"],char:"\u{1f466}",fitzpatrick_scale:!0,category:"people"},girl:{keywords:["female","woman","teenager"],char:"\u{1f467}",fitzpatrick_scale:!0,category:"people"},adult:{keywords:["gender-neutral","person"],char:"\u{1f9d1}",fitzpatrick_scale:!0,category:"people"},man:{keywords:["mustache","father","dad","guy","classy","sir","moustache"],char:"\u{1f468}",fitzpatrick_scale:!0,category:"people"},woman:{keywords:["female","girls","lady"],char:"\u{1f469}",fitzpatrick_scale:!0,category:"people"},blonde_woman:{keywords:["woman","female","girl","blonde","person"],char:"\u{1f471}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},blonde_man:{keywords:["man","male","boy","blonde","guy","person"],char:"\u{1f471}",fitzpatrick_scale:!0,category:"people"},bearded_person:{keywords:["person","bewhiskered"],char:"\u{1f9d4}",fitzpatrick_scale:!0,category:"people"},older_adult:{keywords:["human","elder","senior","gender-neutral"],char:"\u{1f9d3}",fitzpatrick_scale:!0,category:"people"},older_man:{keywords:["human","male","men","old","elder","senior"],char:"\u{1f474}",fitzpatrick_scale:!0,category:"people"},older_woman:{keywords:["human","female","women","lady","old","elder","senior"],char:"\u{1f475}",fitzpatrick_scale:!0,category:"people"},man_with_gua_pi_mao:{keywords:["male","boy","chinese"],char:"\u{1f472}",fitzpatrick_scale:!0,category:"people"},woman_with_headscarf:{keywords:["female","hijab","mantilla","tichel"],char:"\u{1f9d5}",fitzpatrick_scale:!0,category:"people"},woman_with_turban:{keywords:["female","indian","hinduism","arabs","woman"],char:"\u{1f473}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_with_turban:{keywords:["male","indian","hinduism","arabs"],char:"\u{1f473}",fitzpatrick_scale:!0,category:"people"},policewoman:{keywords:["woman","police","law","legal","enforcement","arrest","911","female"],char:"\u{1f46e}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},policeman:{keywords:["man","police","law","legal","enforcement","arrest","911"],char:"\u{1f46e}",fitzpatrick_scale:!0,category:"people"},construction_worker_woman:{keywords:["female","human","wip","build","construction","worker","labor","woman"],char:"\u{1f477}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},construction_worker_man:{keywords:["male","human","wip","guy","build","construction","worker","labor"],char:"\u{1f477}",fitzpatrick_scale:!0,category:"people"},guardswoman:{keywords:["uk","gb","british","female","royal","woman"],char:"\u{1f482}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},guardsman:{keywords:["uk","gb","british","male","guy","royal"],char:"\u{1f482}",fitzpatrick_scale:!0,category:"people"},female_detective:{keywords:["human","spy","detective","female","woman"],char:"\u{1f575}\ufe0f\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},male_detective:{keywords:["human","spy","detective"],char:"\u{1f575}",fitzpatrick_scale:!0,category:"people"},woman_health_worker:{keywords:["doctor","nurse","therapist","healthcare","woman","human"],char:"\u{1f469}\u200d\u2695\ufe0f",fitzpatrick_scale:!0,category:"people"},man_health_worker:{keywords:["doctor","nurse","therapist","healthcare","man","human"],char:"\u{1f468}\u200d\u2695\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_farmer:{keywords:["rancher","gardener","woman","human"],char:"\u{1f469}\u200d\u{1f33e}",fitzpatrick_scale:!0,category:"people"},man_farmer:{keywords:["rancher","gardener","man","human"],char:"\u{1f468}\u200d\u{1f33e}",fitzpatrick_scale:!0,category:"people"},woman_cook:{keywords:["chef","woman","human"],char:"\u{1f469}\u200d\u{1f373}",fitzpatrick_scale:!0,category:"people"},man_cook:{keywords:["chef","man","human"],char:"\u{1f468}\u200d\u{1f373}",fitzpatrick_scale:!0,category:"people"},woman_student:{keywords:["graduate","woman","human"],char:"\u{1f469}\u200d\u{1f393}",fitzpatrick_scale:!0,category:"people"},man_student:{keywords:["graduate","man","human"],char:"\u{1f468}\u200d\u{1f393}",fitzpatrick_scale:!0,category:"people"},woman_singer:{keywords:["rockstar","entertainer","woman","human"],char:"\u{1f469}\u200d\u{1f3a4}",fitzpatrick_scale:!0,category:"people"},man_singer:{keywords:["rockstar","entertainer","man","human"],char:"\u{1f468}\u200d\u{1f3a4}",fitzpatrick_scale:!0,category:"people"},woman_teacher:{keywords:["instructor","professor","woman","human"],char:"\u{1f469}\u200d\u{1f3eb}",fitzpatrick_scale:!0,category:"people"},man_teacher:{keywords:["instructor","professor","man","human"],char:"\u{1f468}\u200d\u{1f3eb}",fitzpatrick_scale:!0,category:"people"},woman_factory_worker:{keywords:["assembly","industrial","woman","human"],char:"\u{1f469}\u200d\u{1f3ed}",fitzpatrick_scale:!0,category:"people"},man_factory_worker:{keywords:["assembly","industrial","man","human"],char:"\u{1f468}\u200d\u{1f3ed}",fitzpatrick_scale:!0,category:"people"},woman_technologist:{keywords:["coder","developer","engineer","programmer","software","woman","human","laptop","computer"],char:"\u{1f469}\u200d\u{1f4bb}",fitzpatrick_scale:!0,category:"people"},man_technologist:{keywords:["coder","developer","engineer","programmer","software","man","human","laptop","computer"],char:"\u{1f468}\u200d\u{1f4bb}",fitzpatrick_scale:!0,category:"people"},woman_office_worker:{keywords:["business","manager","woman","human"],char:"\u{1f469}\u200d\u{1f4bc}",fitzpatrick_scale:!0,category:"people"},man_office_worker:{keywords:["business","manager","man","human"],char:"\u{1f468}\u200d\u{1f4bc}",fitzpatrick_scale:!0,category:"people"},woman_mechanic:{keywords:["plumber","woman","human","wrench"],char:"\u{1f469}\u200d\u{1f527}",fitzpatrick_scale:!0,category:"people"},man_mechanic:{keywords:["plumber","man","human","wrench"],char:"\u{1f468}\u200d\u{1f527}",fitzpatrick_scale:!0,category:"people"},woman_scientist:{keywords:["biologist","chemist","engineer","physicist","woman","human"],char:"\u{1f469}\u200d\u{1f52c}",fitzpatrick_scale:!0,category:"people"},man_scientist:{keywords:["biologist","chemist","engineer","physicist","man","human"],char:"\u{1f468}\u200d\u{1f52c}",fitzpatrick_scale:!0,category:"people"},woman_artist:{keywords:["painter","woman","human"],char:"\u{1f469}\u200d\u{1f3a8}",fitzpatrick_scale:!0,category:"people"},man_artist:{keywords:["painter","man","human"],char:"\u{1f468}\u200d\u{1f3a8}",fitzpatrick_scale:!0,category:"people"},woman_firefighter:{keywords:["fireman","woman","human"],char:"\u{1f469}\u200d\u{1f692}",fitzpatrick_scale:!0,category:"people"},man_firefighter:{keywords:["fireman","man","human"],char:"\u{1f468}\u200d\u{1f692}",fitzpatrick_scale:!0,category:"people"},woman_pilot:{keywords:["aviator","plane","woman","human"],char:"\u{1f469}\u200d\u2708\ufe0f",fitzpatrick_scale:!0,category:"people"},man_pilot:{keywords:["aviator","plane","man","human"],char:"\u{1f468}\u200d\u2708\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_astronaut:{keywords:["space","rocket","woman","human"],char:"\u{1f469}\u200d\u{1f680}",fitzpatrick_scale:!0,category:"people"},man_astronaut:{keywords:["space","rocket","man","human"],char:"\u{1f468}\u200d\u{1f680}",fitzpatrick_scale:!0,category:"people"},woman_judge:{keywords:["justice","court","woman","human"],char:"\u{1f469}\u200d\u2696\ufe0f",fitzpatrick_scale:!0,category:"people"},man_judge:{keywords:["justice","court","man","human"],char:"\u{1f468}\u200d\u2696\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_superhero:{keywords:["woman","female","good","heroine","superpowers"],char:"\u{1f9b8}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_superhero:{keywords:["man","male","good","hero","superpowers"],char:"\u{1f9b8}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_supervillain:{keywords:["woman","female","evil","bad","criminal","heroine","superpowers"],char:"\u{1f9b9}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_supervillain:{keywords:["man","male","evil","bad","criminal","hero","superpowers"],char:"\u{1f9b9}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},mrs_claus:{keywords:["woman","female","xmas","mother christmas"],char:"\u{1f936}",fitzpatrick_scale:!0,category:"people"},santa:{keywords:["festival","man","male","xmas","father christmas"],char:"\u{1f385}",fitzpatrick_scale:!0,category:"people"},sorceress:{keywords:["woman","female","mage","witch"],char:"\u{1f9d9}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},wizard:{keywords:["man","male","mage","sorcerer"],char:"\u{1f9d9}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_elf:{keywords:["woman","female"],char:"\u{1f9dd}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_elf:{keywords:["man","male"],char:"\u{1f9dd}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_vampire:{keywords:["woman","female"],char:"\u{1f9db}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_vampire:{keywords:["man","male","dracula"],char:"\u{1f9db}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_zombie:{keywords:["woman","female","undead","walking dead"],char:"\u{1f9df}\u200d\u2640\ufe0f",fitzpatrick_scale:!1,category:"people"},man_zombie:{keywords:["man","male","dracula","undead","walking dead"],char:"\u{1f9df}\u200d\u2642\ufe0f",fitzpatrick_scale:!1,category:"people"},woman_genie:{keywords:["woman","female"],char:"\u{1f9de}\u200d\u2640\ufe0f",fitzpatrick_scale:!1,category:"people"},man_genie:{keywords:["man","male"],char:"\u{1f9de}\u200d\u2642\ufe0f",fitzpatrick_scale:!1,category:"people"},mermaid:{keywords:["woman","female","merwoman","ariel"],char:"\u{1f9dc}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},merman:{keywords:["man","male","triton"],char:"\u{1f9dc}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_fairy:{keywords:["woman","female"],char:"\u{1f9da}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_fairy:{keywords:["man","male"],char:"\u{1f9da}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},angel:{keywords:["heaven","wings","halo"],char:"\u{1f47c}",fitzpatrick_scale:!0,category:"people"},pregnant_woman:{keywords:["baby"],char:"\u{1f930}",fitzpatrick_scale:!0,category:"people"},breastfeeding:{keywords:["nursing","baby"],char:"\u{1f931}",fitzpatrick_scale:!0,category:"people"},princess:{keywords:["girl","woman","female","blond","crown","royal","queen"],char:"\u{1f478}",fitzpatrick_scale:!0,category:"people"},prince:{keywords:["boy","man","male","crown","royal","king"],char:"\u{1f934}",fitzpatrick_scale:!0,category:"people"},bride_with_veil:{keywords:["couple","marriage","wedding","woman","bride"],char:"\u{1f470}",fitzpatrick_scale:!0,category:"people"},man_in_tuxedo:{keywords:["couple","marriage","wedding","groom"],char:"\u{1f935}",fitzpatrick_scale:!0,category:"people"},running_woman:{keywords:["woman","walking","exercise","race","running","female"],char:"\u{1f3c3}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},running_man:{keywords:["man","walking","exercise","race","running"],char:"\u{1f3c3}",fitzpatrick_scale:!0,category:"people"},walking_woman:{keywords:["human","feet","steps","woman","female"],char:"\u{1f6b6}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},walking_man:{keywords:["human","feet","steps"],char:"\u{1f6b6}",fitzpatrick_scale:!0,category:"people"},dancer:{keywords:["female","girl","woman","fun"],char:"\u{1f483}",fitzpatrick_scale:!0,category:"people"},man_dancing:{keywords:["male","boy","fun","dancer"],char:"\u{1f57a}",fitzpatrick_scale:!0,category:"people"},dancing_women:{keywords:["female","bunny","women","girls"],char:"\u{1f46f}",fitzpatrick_scale:!1,category:"people"},dancing_men:{keywords:["male","bunny","men","boys"],char:"\u{1f46f}\u200d\u2642\ufe0f",fitzpatrick_scale:!1,category:"people"},couple:{keywords:["pair","people","human","love","date","dating","like","affection","valentines","marriage"],char:"\u{1f46b}",fitzpatrick_scale:!1,category:"people"},two_men_holding_hands:{keywords:["pair","couple","love","like","bromance","friendship","people","human"],char:"\u{1f46c}",fitzpatrick_scale:!1,category:"people"},two_women_holding_hands:{keywords:["pair","friendship","couple","love","like","female","people","human"],char:"\u{1f46d}",fitzpatrick_scale:!1,category:"people"},bowing_woman:{keywords:["woman","female","girl"],char:"\u{1f647}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},bowing_man:{keywords:["man","male","boy"],char:"\u{1f647}",fitzpatrick_scale:!0,category:"people"},man_facepalming:{keywords:["man","male","boy","disbelief"],char:"\u{1f926}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_facepalming:{keywords:["woman","female","girl","disbelief"],char:"\u{1f926}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_shrugging:{keywords:["woman","female","girl","confused","indifferent","doubt"],char:"\u{1f937}",fitzpatrick_scale:!0,category:"people"},man_shrugging:{keywords:["man","male","boy","confused","indifferent","doubt"],char:"\u{1f937}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},tipping_hand_woman:{keywords:["female","girl","woman","human","information"],char:"\u{1f481}",fitzpatrick_scale:!0,category:"people"},tipping_hand_man:{keywords:["male","boy","man","human","information"],char:"\u{1f481}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},no_good_woman:{keywords:["female","girl","woman","nope"],char:"\u{1f645}",fitzpatrick_scale:!0,category:"people"},no_good_man:{keywords:["male","boy","man","nope"],char:"\u{1f645}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},ok_woman:{keywords:["women","girl","female","pink","human","woman"],char:"\u{1f646}",fitzpatrick_scale:!0,category:"people"},ok_man:{keywords:["men","boy","male","blue","human","man"],char:"\u{1f646}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},raising_hand_woman:{keywords:["female","girl","woman"],char:"\u{1f64b}",fitzpatrick_scale:!0,category:"people"},raising_hand_man:{keywords:["male","boy","man"],char:"\u{1f64b}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},pouting_woman:{keywords:["female","girl","woman"],char:"\u{1f64e}",fitzpatrick_scale:!0,category:"people"},pouting_man:{keywords:["male","boy","man"],char:"\u{1f64e}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},frowning_woman:{keywords:["female","girl","woman","sad","depressed","discouraged","unhappy"],char:"\u{1f64d}",fitzpatrick_scale:!0,category:"people"},frowning_man:{keywords:["male","boy","man","sad","depressed","discouraged","unhappy"],char:"\u{1f64d}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},haircut_woman:{keywords:["female","girl","woman"],char:"\u{1f487}",fitzpatrick_scale:!0,category:"people"},haircut_man:{keywords:["male","boy","man"],char:"\u{1f487}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},massage_woman:{keywords:["female","girl","woman","head"],char:"\u{1f486}",fitzpatrick_scale:!0,category:"people"},massage_man:{keywords:["male","boy","man","head"],char:"\u{1f486}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_in_steamy_room:{keywords:["female","woman","spa","steamroom","sauna"],char:"\u{1f9d6}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_in_steamy_room:{keywords:["male","man","spa","steamroom","sauna"],char:"\u{1f9d6}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},couple_with_heart_woman_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:"\u{1f491}",fitzpatrick_scale:!1,category:"people"},couple_with_heart_woman_woman:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:"\u{1f469}\u200d\u2764\ufe0f\u200d\u{1f469}",fitzpatrick_scale:!1,category:"people"},couple_with_heart_man_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:"\u{1f468}\u200d\u2764\ufe0f\u200d\u{1f468}",fitzpatrick_scale:!1,category:"people"},couplekiss_man_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:"\u{1f48f}",fitzpatrick_scale:!1,category:"people"},couplekiss_woman_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:"\u{1f469}\u200d\u2764\ufe0f\u200d\u{1f48b}\u200d\u{1f469}",fitzpatrick_scale:!1,category:"people"},couplekiss_man_man:{keywords:["pair","valentines","love","like","dating","marriage"],char:"\u{1f468}\u200d\u2764\ufe0f\u200d\u{1f48b}\u200d\u{1f468}",fitzpatrick_scale:!1,category:"people"},family_man_woman_boy:{keywords:["home","parents","child","mom","dad","father","mother","people","human"],char:"\u{1f46a}",fitzpatrick_scale:!1,category:"people"},family_man_woman_girl:{keywords:["home","parents","people","human","child"],char:"\u{1f468}\u200d\u{1f469}\u200d\u{1f467}",fitzpatrick_scale:!1,category:"people"},family_man_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:"\u{1f468}\u200d\u{1f469}\u200d\u{1f467}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_man_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:"\u{1f468}\u200d\u{1f469}\u200d\u{1f466}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_man_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:"\u{1f468}\u200d\u{1f469}\u200d\u{1f467}\u200d\u{1f467}",fitzpatrick_scale:!1,category:"people"},family_woman_woman_boy:{keywords:["home","parents","people","human","children"],char:"\u{1f469}\u200d\u{1f469}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl:{keywords:["home","parents","people","human","children"],char:"\u{1f469}\u200d\u{1f469}\u200d\u{1f467}",fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:"\u{1f469}\u200d\u{1f469}\u200d\u{1f467}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_woman_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:"\u{1f469}\u200d\u{1f469}\u200d\u{1f466}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:"\u{1f469}\u200d\u{1f469}\u200d\u{1f467}\u200d\u{1f467}",fitzpatrick_scale:!1,category:"people"},family_man_man_boy:{keywords:["home","parents","people","human","children"],char:"\u{1f468}\u200d\u{1f468}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_man_man_girl:{keywords:["home","parents","people","human","children"],char:"\u{1f468}\u200d\u{1f468}\u200d\u{1f467}",fitzpatrick_scale:!1,category:"people"},family_man_man_girl_boy:{keywords:["home","parents","people","human","children"],char:"\u{1f468}\u200d\u{1f468}\u200d\u{1f467}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_man_man_boy_boy:{keywords:["home","parents","people","human","children"],char:"\u{1f468}\u200d\u{1f468}\u200d\u{1f466}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_man_man_girl_girl:{keywords:["home","parents","people","human","children"],char:"\u{1f468}\u200d\u{1f468}\u200d\u{1f467}\u200d\u{1f467}",fitzpatrick_scale:!1,category:"people"},family_woman_boy:{keywords:["home","parent","people","human","child"],char:"\u{1f469}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_woman_girl:{keywords:["home","parent","people","human","child"],char:"\u{1f469}\u200d\u{1f467}",fitzpatrick_scale:!1,category:"people"},family_woman_girl_boy:{keywords:["home","parent","people","human","children"],char:"\u{1f469}\u200d\u{1f467}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_woman_boy_boy:{keywords:["home","parent","people","human","children"],char:"\u{1f469}\u200d\u{1f466}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_woman_girl_girl:{keywords:["home","parent","people","human","children"],char:"\u{1f469}\u200d\u{1f467}\u200d\u{1f467}",fitzpatrick_scale:!1,category:"people"},family_man_boy:{keywords:["home","parent","people","human","child"],char:"\u{1f468}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_man_girl:{keywords:["home","parent","people","human","child"],char:"\u{1f468}\u200d\u{1f467}",fitzpatrick_scale:!1,category:"people"},family_man_girl_boy:{keywords:["home","parent","people","human","children"],char:"\u{1f468}\u200d\u{1f467}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_man_boy_boy:{keywords:["home","parent","people","human","children"],char:"\u{1f468}\u200d\u{1f466}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_man_girl_girl:{keywords:["home","parent","people","human","children"],char:"\u{1f468}\u200d\u{1f467}\u200d\u{1f467}",fitzpatrick_scale:!1,category:"people"},yarn:{keywords:["ball","crochet","knit"],char:"\u{1f9f6}",fitzpatrick_scale:!1,category:"people"},thread:{keywords:["needle","sewing","spool","string"],char:"\u{1f9f5}",fitzpatrick_scale:!1,category:"people"},coat:{keywords:["jacket"],char:"\u{1f9e5}",fitzpatrick_scale:!1,category:"people"},labcoat:{keywords:["doctor","experiment","scientist","chemist"],char:"\u{1f97c}",fitzpatrick_scale:!1,category:"people"},womans_clothes:{keywords:["fashion","shopping_bags","female"],char:"\u{1f45a}",fitzpatrick_scale:!1,category:"people"},tshirt:{keywords:["fashion","cloth","casual","shirt","tee"],char:"\u{1f455}",fitzpatrick_scale:!1,category:"people"},jeans:{keywords:["fashion","shopping"],char:"\u{1f456}",fitzpatrick_scale:!1,category:"people"},necktie:{keywords:["shirt","suitup","formal","fashion","cloth","business"],char:"\u{1f454}",fitzpatrick_scale:!1,category:"people"},dress:{keywords:["clothes","fashion","shopping"],char:"\u{1f457}",fitzpatrick_scale:!1,category:"people"},bikini:{keywords:["swimming","female","woman","girl","fashion","beach","summer"],char:"\u{1f459}",fitzpatrick_scale:!1,category:"people"},kimono:{keywords:["dress","fashion","women","female","japanese"],char:"\u{1f458}",fitzpatrick_scale:!1,category:"people"},lipstick:{keywords:["female","girl","fashion","woman"],char:"\u{1f484}",fitzpatrick_scale:!1,category:"people"},kiss:{keywords:["face","lips","love","like","affection","valentines"],char:"\u{1f48b}",fitzpatrick_scale:!1,category:"people"},footprints:{keywords:["feet","tracking","walking","beach"],char:"\u{1f463}",fitzpatrick_scale:!1,category:"people"},flat_shoe:{keywords:["ballet","slip-on","slipper"],char:"\u{1f97f}",fitzpatrick_scale:!1,category:"people"},high_heel:{keywords:["fashion","shoes","female","pumps","stiletto"],char:"\u{1f460}",fitzpatrick_scale:!1,category:"people"},sandal:{keywords:["shoes","fashion","flip flops"],char:"\u{1f461}",fitzpatrick_scale:!1,category:"people"},boot:{keywords:["shoes","fashion"],char:"\u{1f462}",fitzpatrick_scale:!1,category:"people"},mans_shoe:{keywords:["fashion","male"],char:"\u{1f45e}",fitzpatrick_scale:!1,category:"people"},athletic_shoe:{keywords:["shoes","sports","sneakers"],char:"\u{1f45f}",fitzpatrick_scale:!1,category:"people"},hiking_boot:{keywords:["backpacking","camping","hiking"],char:"\u{1f97e}",fitzpatrick_scale:!1,category:"people"},socks:{keywords:["stockings","clothes"],char:"\u{1f9e6}",fitzpatrick_scale:!1,category:"people"},gloves:{keywords:["hands","winter","clothes"],char:"\u{1f9e4}",fitzpatrick_scale:!1,category:"people"},scarf:{keywords:["neck","winter","clothes"],char:"\u{1f9e3}",fitzpatrick_scale:!1,category:"people"},womans_hat:{keywords:["fashion","accessories","female","lady","spring"],char:"\u{1f452}",fitzpatrick_scale:!1,category:"people"},tophat:{keywords:["magic","gentleman","classy","circus"],char:"\u{1f3a9}",fitzpatrick_scale:!1,category:"people"},billed_hat:{keywords:["cap","baseball"],char:"\u{1f9e2}",fitzpatrick_scale:!1,category:"people"},rescue_worker_helmet:{keywords:["construction","build"],char:"\u26d1",fitzpatrick_scale:!1,category:"people"},mortar_board:{keywords:["school","college","degree","university","graduation","cap","hat","legal","learn","education"],char:"\u{1f393}",fitzpatrick_scale:!1,category:"people"},crown:{keywords:["king","kod","leader","royalty","lord"],char:"\u{1f451}",fitzpatrick_scale:!1,category:"people"},school_satchel:{keywords:["student","education","bag","backpack"],char:"\u{1f392}",fitzpatrick_scale:!1,category:"people"},luggage:{keywords:["packing","travel"],char:"\u{1f9f3}",fitzpatrick_scale:!1,category:"people"},pouch:{keywords:["bag","accessories","shopping"],char:"\u{1f45d}",fitzpatrick_scale:!1,category:"people"},purse:{keywords:["fashion","accessories","money","sales","shopping"],char:"\u{1f45b}",fitzpatrick_scale:!1,category:"people"},handbag:{keywords:["fashion","accessory","accessories","shopping"],char:"\u{1f45c}",fitzpatrick_scale:!1,category:"people"},briefcase:{keywords:["business","documents","work","law","legal","job","career"],char:"\u{1f4bc}",fitzpatrick_scale:!1,category:"people"},eyeglasses:{keywords:["fashion","accessories","eyesight","nerdy","dork","geek"],char:"\u{1f453}",fitzpatrick_scale:!1,category:"people"},dark_sunglasses:{keywords:["face","cool","accessories"],char:"\u{1f576}",fitzpatrick_scale:!1,category:"people"},goggles:{keywords:["eyes","protection","safety"],char:"\u{1f97d}",fitzpatrick_scale:!1,category:"people"},ring:{keywords:["wedding","propose","marriage","valentines","diamond","fashion","jewelry","gem","engagement"],char:"\u{1f48d}",fitzpatrick_scale:!1,category:"people"},closed_umbrella:{keywords:["weather","rain","drizzle"],char:"\u{1f302}",fitzpatrick_scale:!1,category:"people"},dog:{keywords:["animal","friend","nature","woof","puppy","pet","faithful"],char:"\u{1f436}",fitzpatrick_scale:!1,category:"animals_and_nature"},cat:{keywords:["animal","meow","nature","pet","kitten"],char:"\u{1f431}",fitzpatrick_scale:!1,category:"animals_and_nature"},mouse:{keywords:["animal","nature","cheese_wedge","rodent"],char:"\u{1f42d}",fitzpatrick_scale:!1,category:"animals_and_nature"},hamster:{keywords:["animal","nature"],char:"\u{1f439}",fitzpatrick_scale:!1,category:"animals_and_nature"},rabbit:{keywords:["animal","nature","pet","spring","magic","bunny"],char:"\u{1f430}",fitzpatrick_scale:!1,category:"animals_and_nature"},fox_face:{keywords:["animal","nature","face"],char:"\u{1f98a}",fitzpatrick_scale:!1,category:"animals_and_nature"},bear:{keywords:["animal","nature","wild"],char:"\u{1f43b}",fitzpatrick_scale:!1,category:"animals_and_nature"},panda_face:{keywords:["animal","nature","panda"],char:"\u{1f43c}",fitzpatrick_scale:!1,category:"animals_and_nature"},koala:{keywords:["animal","nature"],char:"\u{1f428}",fitzpatrick_scale:!1,category:"animals_and_nature"},tiger:{keywords:["animal","cat","danger","wild","nature","roar"],char:"\u{1f42f}",fitzpatrick_scale:!1,category:"animals_and_nature"},lion:{keywords:["animal","nature"],char:"\u{1f981}",fitzpatrick_scale:!1,category:"animals_and_nature"},cow:{keywords:["beef","ox","animal","nature","moo","milk"],char:"\u{1f42e}",fitzpatrick_scale:!1,category:"animals_and_nature"},pig:{keywords:["animal","oink","nature"],char:"\u{1f437}",fitzpatrick_scale:!1,category:"animals_and_nature"},pig_nose:{keywords:["animal","oink"],char:"\u{1f43d}",fitzpatrick_scale:!1,category:"animals_and_nature"},frog:{keywords:["animal","nature","croak","toad"],char:"\u{1f438}",fitzpatrick_scale:!1,category:"animals_and_nature"},squid:{keywords:["animal","nature","ocean","sea"],char:"\u{1f991}",fitzpatrick_scale:!1,category:"animals_and_nature"},octopus:{keywords:["animal","creature","ocean","sea","nature","beach"],char:"\u{1f419}",fitzpatrick_scale:!1,category:"animals_and_nature"},shrimp:{keywords:["animal","ocean","nature","seafood"],char:"\u{1f990}",fitzpatrick_scale:!1,category:"animals_and_nature"},monkey_face:{keywords:["animal","nature","circus"],char:"\u{1f435}",fitzpatrick_scale:!1,category:"animals_and_nature"},gorilla:{keywords:["animal","nature","circus"],char:"\u{1f98d}",fitzpatrick_scale:!1,category:"animals_and_nature"},see_no_evil:{keywords:["monkey","animal","nature","haha"],char:"\u{1f648}",fitzpatrick_scale:!1,category:"animals_and_nature"},hear_no_evil:{keywords:["animal","monkey","nature"],char:"\u{1f649}",fitzpatrick_scale:!1,category:"animals_and_nature"},speak_no_evil:{keywords:["monkey","animal","nature","omg"],char:"\u{1f64a}",fitzpatrick_scale:!1,category:"animals_and_nature"},monkey:{keywords:["animal","nature","banana","circus"],char:"\u{1f412}",fitzpatrick_scale:!1,category:"animals_and_nature"},chicken:{keywords:["animal","cluck","nature","bird"],char:"\u{1f414}",fitzpatrick_scale:!1,category:"animals_and_nature"},penguin:{keywords:["animal","nature"],char:"\u{1f427}",fitzpatrick_scale:!1,category:"animals_and_nature"},bird:{keywords:["animal","nature","fly","tweet","spring"],char:"\u{1f426}",fitzpatrick_scale:!1,category:"animals_and_nature"},baby_chick:{keywords:["animal","chicken","bird"],char:"\u{1f424}",fitzpatrick_scale:!1,category:"animals_and_nature"},hatching_chick:{keywords:["animal","chicken","egg","born","baby","bird"],char:"\u{1f423}",fitzpatrick_scale:!1,category:"animals_and_nature"},hatched_chick:{keywords:["animal","chicken","baby","bird"],char:"\u{1f425}",fitzpatrick_scale:!1,category:"animals_and_nature"},duck:{keywords:["animal","nature","bird","mallard"],char:"\u{1f986}",fitzpatrick_scale:!1,category:"animals_and_nature"},eagle:{keywords:["animal","nature","bird"],char:"\u{1f985}",fitzpatrick_scale:!1,category:"animals_and_nature"},owl:{keywords:["animal","nature","bird","hoot"],char:"\u{1f989}",fitzpatrick_scale:!1,category:"animals_and_nature"},bat:{keywords:["animal","nature","blind","vampire"],char:"\u{1f987}",fitzpatrick_scale:!1,category:"animals_and_nature"},wolf:{keywords:["animal","nature","wild"],char:"\u{1f43a}",fitzpatrick_scale:!1,category:"animals_and_nature"},boar:{keywords:["animal","nature"],char:"\u{1f417}",fitzpatrick_scale:!1,category:"animals_and_nature"},horse:{keywords:["animal","brown","nature"],char:"\u{1f434}",fitzpatrick_scale:!1,category:"animals_and_nature"},unicorn:{keywords:["animal","nature","mystical"],char:"\u{1f984}",fitzpatrick_scale:!1,category:"animals_and_nature"},honeybee:{keywords:["animal","insect","nature","bug","spring","honey"],char:"\u{1f41d}",fitzpatrick_scale:!1,category:"animals_and_nature"},bug:{keywords:["animal","insect","nature","worm"],char:"\u{1f41b}",fitzpatrick_scale:!1,category:"animals_and_nature"},butterfly:{keywords:["animal","insect","nature","caterpillar"],char:"\u{1f98b}",fitzpatrick_scale:!1,category:"animals_and_nature"},snail:{keywords:["slow","animal","shell"],char:"\u{1f40c}",fitzpatrick_scale:!1,category:"animals_and_nature"},beetle:{keywords:["animal","insect","nature","ladybug"],char:"\u{1f41e}",fitzpatrick_scale:!1,category:"animals_and_nature"},ant:{keywords:["animal","insect","nature","bug"],char:"\u{1f41c}",fitzpatrick_scale:!1,category:"animals_and_nature"},grasshopper:{keywords:["animal","cricket","chirp"],char:"\u{1f997}",fitzpatrick_scale:!1,category:"animals_and_nature"},spider:{keywords:["animal","arachnid"],char:"\u{1f577}",fitzpatrick_scale:!1,category:"animals_and_nature"},scorpion:{keywords:["animal","arachnid"],char:"\u{1f982}",fitzpatrick_scale:!1,category:"animals_and_nature"},crab:{keywords:["animal","crustacean"],char:"\u{1f980}",fitzpatrick_scale:!1,category:"animals_and_nature"},snake:{keywords:["animal","evil","nature","hiss","python"],char:"\u{1f40d}",fitzpatrick_scale:!1,category:"animals_and_nature"},lizard:{keywords:["animal","nature","reptile"],char:"\u{1f98e}",fitzpatrick_scale:!1,category:"animals_and_nature"},"t-rex":{keywords:["animal","nature","dinosaur","tyrannosaurus","extinct"],char:"\u{1f996}",fitzpatrick_scale:!1,category:"animals_and_nature"},sauropod:{keywords:["animal","nature","dinosaur","brachiosaurus","brontosaurus","diplodocus","extinct"],char:"\u{1f995}",fitzpatrick_scale:!1,category:"animals_and_nature"},turtle:{keywords:["animal","slow","nature","tortoise"],char:"\u{1f422}",fitzpatrick_scale:!1,category:"animals_and_nature"},tropical_fish:{keywords:["animal","swim","ocean","beach","nemo"],char:"\u{1f420}",fitzpatrick_scale:!1,category:"animals_and_nature"},fish:{keywords:["animal","food","nature"],char:"\u{1f41f}",fitzpatrick_scale:!1,category:"animals_and_nature"},blowfish:{keywords:["animal","nature","food","sea","ocean"],char:"\u{1f421}",fitzpatrick_scale:!1,category:"animals_and_nature"},dolphin:{keywords:["animal","nature","fish","sea","ocean","flipper","fins","beach"],char:"\u{1f42c}",fitzpatrick_scale:!1,category:"animals_and_nature"},shark:{keywords:["animal","nature","fish","sea","ocean","jaws","fins","beach"],char:"\u{1f988}",fitzpatrick_scale:!1,category:"animals_and_nature"},whale:{keywords:["animal","nature","sea","ocean"],char:"\u{1f433}",fitzpatrick_scale:!1,category:"animals_and_nature"},whale2:{keywords:["animal","nature","sea","ocean"],char:"\u{1f40b}",fitzpatrick_scale:!1,category:"animals_and_nature"},crocodile:{keywords:["animal","nature","reptile","lizard","alligator"],char:"\u{1f40a}",fitzpatrick_scale:!1,category:"animals_and_nature"},leopard:{keywords:["animal","nature"],char:"\u{1f406}",fitzpatrick_scale:!1,category:"animals_and_nature"},zebra:{keywords:["animal","nature","stripes","safari"],char:"\u{1f993}",fitzpatrick_scale:!1,category:"animals_and_nature"},tiger2:{keywords:["animal","nature","roar"],char:"\u{1f405}",fitzpatrick_scale:!1,category:"animals_and_nature"},water_buffalo:{keywords:["animal","nature","ox","cow"],char:"\u{1f403}",fitzpatrick_scale:!1,category:"animals_and_nature"},ox:{keywords:["animal","cow","beef"],char:"\u{1f402}",fitzpatrick_scale:!1,category:"animals_and_nature"},cow2:{keywords:["beef","ox","animal","nature","moo","milk"],char:"\u{1f404}",fitzpatrick_scale:!1,category:"animals_and_nature"},deer:{keywords:["animal","nature","horns","venison"],char:"\u{1f98c}",fitzpatrick_scale:!1,category:"animals_and_nature"},dromedary_camel:{keywords:["animal","hot","desert","hump"],char:"\u{1f42a}",fitzpatrick_scale:!1,category:"animals_and_nature"},camel:{keywords:["animal","nature","hot","desert","hump"],char:"\u{1f42b}",fitzpatrick_scale:!1,category:"animals_and_nature"},giraffe:{keywords:["animal","nature","spots","safari"],char:"\u{1f992}",fitzpatrick_scale:!1,category:"animals_and_nature"},elephant:{keywords:["animal","nature","nose","th","circus"],char:"\u{1f418}",fitzpatrick_scale:!1,category:"animals_and_nature"},rhinoceros:{keywords:["animal","nature","horn"],char:"\u{1f98f}",fitzpatrick_scale:!1,category:"animals_and_nature"},goat:{keywords:["animal","nature"],char:"\u{1f410}",fitzpatrick_scale:!1,category:"animals_and_nature"},ram:{keywords:["animal","sheep","nature"],char:"\u{1f40f}",fitzpatrick_scale:!1,category:"animals_and_nature"},sheep:{keywords:["animal","nature","wool","shipit"],char:"\u{1f411}",fitzpatrick_scale:!1,category:"animals_and_nature"},racehorse:{keywords:["animal","gamble","luck"],char:"\u{1f40e}",fitzpatrick_scale:!1,category:"animals_and_nature"},pig2:{keywords:["animal","nature"],char:"\u{1f416}",fitzpatrick_scale:!1,category:"animals_and_nature"},rat:{keywords:["animal","mouse","rodent"],char:"\u{1f400}",fitzpatrick_scale:!1,category:"animals_and_nature"},mouse2:{keywords:["animal","nature","rodent"],char:"\u{1f401}",fitzpatrick_scale:!1,category:"animals_and_nature"},rooster:{keywords:["animal","nature","chicken"],char:"\u{1f413}",fitzpatrick_scale:!1,category:"animals_and_nature"},turkey:{keywords:["animal","bird"],char:"\u{1f983}",fitzpatrick_scale:!1,category:"animals_and_nature"},dove:{keywords:["animal","bird"],char:"\u{1f54a}",fitzpatrick_scale:!1,category:"animals_and_nature"},dog2:{keywords:["animal","nature","friend","doge","pet","faithful"],char:"\u{1f415}",fitzpatrick_scale:!1,category:"animals_and_nature"},poodle:{keywords:["dog","animal","101","nature","pet"],char:"\u{1f429}",fitzpatrick_scale:!1,category:"animals_and_nature"},cat2:{keywords:["animal","meow","pet","cats"],char:"\u{1f408}",fitzpatrick_scale:!1,category:"animals_and_nature"},rabbit2:{keywords:["animal","nature","pet","magic","spring"],char:"\u{1f407}",fitzpatrick_scale:!1,category:"animals_and_nature"},chipmunk:{keywords:["animal","nature","rodent","squirrel"],char:"\u{1f43f}",fitzpatrick_scale:!1,category:"animals_and_nature"},hedgehog:{keywords:["animal","nature","spiny"],char:"\u{1f994}",fitzpatrick_scale:!1,category:"animals_and_nature"},raccoon:{keywords:["animal","nature"],char:"\u{1f99d}",fitzpatrick_scale:!1,category:"animals_and_nature"},llama:{keywords:["animal","nature","alpaca"],char:"\u{1f999}",fitzpatrick_scale:!1,category:"animals_and_nature"},hippopotamus:{keywords:["animal","nature"],char:"\u{1f99b}",fitzpatrick_scale:!1,category:"animals_and_nature"},kangaroo:{keywords:["animal","nature","australia","joey","hop","marsupial"],char:"\u{1f998}",fitzpatrick_scale:!1,category:"animals_and_nature"},badger:{keywords:["animal","nature","honey"],char:"\u{1f9a1}",fitzpatrick_scale:!1,category:"animals_and_nature"},swan:{keywords:["animal","nature","bird"],char:"\u{1f9a2}",fitzpatrick_scale:!1,category:"animals_and_nature"},peacock:{keywords:["animal","nature","peahen","bird"],char:"\u{1f99a}",fitzpatrick_scale:!1,category:"animals_and_nature"},parrot:{keywords:["animal","nature","bird","pirate","talk"],char:"\u{1f99c}",fitzpatrick_scale:!1,category:"animals_and_nature"},lobster:{keywords:["animal","nature","bisque","claws","seafood"],char:"\u{1f99e}",fitzpatrick_scale:!1,category:"animals_and_nature"},mosquito:{keywords:["animal","nature","insect","malaria"],char:"\u{1f99f}",fitzpatrick_scale:!1,category:"animals_and_nature"},paw_prints:{keywords:["animal","tracking","footprints","dog","cat","pet","feet"],char:"\u{1f43e}",fitzpatrick_scale:!1,category:"animals_and_nature"},dragon:{keywords:["animal","myth","nature","chinese","green"],char:"\u{1f409}",fitzpatrick_scale:!1,category:"animals_and_nature"},dragon_face:{keywords:["animal","myth","nature","chinese","green"],char:"\u{1f432}",fitzpatrick_scale:!1,category:"animals_and_nature"},cactus:{keywords:["vegetable","plant","nature"],char:"\u{1f335}",fitzpatrick_scale:!1,category:"animals_and_nature"},christmas_tree:{keywords:["festival","vacation","december","xmas","celebration"],char:"\u{1f384}",fitzpatrick_scale:!1,category:"animals_and_nature"},evergreen_tree:{keywords:["plant","nature"],char:"\u{1f332}",fitzpatrick_scale:!1,category:"animals_and_nature"},deciduous_tree:{keywords:["plant","nature"],char:"\u{1f333}",fitzpatrick_scale:!1,category:"animals_and_nature"},palm_tree:{keywords:["plant","vegetable","nature","summer","beach","mojito","tropical"],char:"\u{1f334}",fitzpatrick_scale:!1,category:"animals_and_nature"},seedling:{keywords:["plant","nature","grass","lawn","spring"],char:"\u{1f331}",fitzpatrick_scale:!1,category:"animals_and_nature"},herb:{keywords:["vegetable","plant","medicine","weed","grass","lawn"],char:"\u{1f33f}",fitzpatrick_scale:!1,category:"animals_and_nature"},shamrock:{keywords:["vegetable","plant","nature","irish","clover"],char:"\u2618",fitzpatrick_scale:!1,category:"animals_and_nature"},four_leaf_clover:{keywords:["vegetable","plant","nature","lucky","irish"],char:"\u{1f340}",fitzpatrick_scale:!1,category:"animals_and_nature"},bamboo:{keywords:["plant","nature","vegetable","panda","pine_decoration"],char:"\u{1f38d}",fitzpatrick_scale:!1,category:"animals_and_nature"},tanabata_tree:{keywords:["plant","nature","branch","summer"],char:"\u{1f38b}",fitzpatrick_scale:!1,category:"animals_and_nature"},leaves:{keywords:["nature","plant","tree","vegetable","grass","lawn","spring"],char:"\u{1f343}",fitzpatrick_scale:!1,category:"animals_and_nature"},fallen_leaf:{keywords:["nature","plant","vegetable","leaves"],char:"\u{1f342}",fitzpatrick_scale:!1,category:"animals_and_nature"},maple_leaf:{keywords:["nature","plant","vegetable","ca","fall"],char:"\u{1f341}",fitzpatrick_scale:!1,category:"animals_and_nature"},ear_of_rice:{keywords:["nature","plant"],char:"\u{1f33e}",fitzpatrick_scale:!1,category:"animals_and_nature"},hibiscus:{keywords:["plant","vegetable","flowers","beach"],char:"\u{1f33a}",fitzpatrick_scale:!1,category:"animals_and_nature"},sunflower:{keywords:["nature","plant","fall"],char:"\u{1f33b}",fitzpatrick_scale:!1,category:"animals_and_nature"},rose:{keywords:["flowers","valentines","love","spring"],char:"\u{1f339}",fitzpatrick_scale:!1,category:"animals_and_nature"},wilted_flower:{keywords:["plant","nature","flower"],char:"\u{1f940}",fitzpatrick_scale:!1,category:"animals_and_nature"},tulip:{keywords:["flowers","plant","nature","summer","spring"],char:"\u{1f337}",fitzpatrick_scale:!1,category:"animals_and_nature"},blossom:{keywords:["nature","flowers","yellow"],char:"\u{1f33c}",fitzpatrick_scale:!1,category:"animals_and_nature"},cherry_blossom:{keywords:["nature","plant","spring","flower"],char:"\u{1f338}",fitzpatrick_scale:!1,category:"animals_and_nature"},bouquet:{keywords:["flowers","nature","spring"],char:"\u{1f490}",fitzpatrick_scale:!1,category:"animals_and_nature"},mushroom:{keywords:["plant","vegetable"],char:"\u{1f344}",fitzpatrick_scale:!1,category:"animals_and_nature"},chestnut:{keywords:["food","squirrel"],char:"\u{1f330}",fitzpatrick_scale:!1,category:"animals_and_nature"},jack_o_lantern:{keywords:["halloween","light","pumpkin","creepy","fall"],char:"\u{1f383}",fitzpatrick_scale:!1,category:"animals_and_nature"},shell:{keywords:["nature","sea","beach"],char:"\u{1f41a}",fitzpatrick_scale:!1,category:"animals_and_nature"},spider_web:{keywords:["animal","insect","arachnid","silk"],char:"\u{1f578}",fitzpatrick_scale:!1,category:"animals_and_nature"},earth_americas:{keywords:["globe","world","USA","international"],char:"\u{1f30e}",fitzpatrick_scale:!1,category:"animals_and_nature"},earth_africa:{keywords:["globe","world","international"],char:"\u{1f30d}",fitzpatrick_scale:!1,category:"animals_and_nature"},earth_asia:{keywords:["globe","world","east","international"],char:"\u{1f30f}",fitzpatrick_scale:!1,category:"animals_and_nature"},full_moon:{keywords:["nature","yellow","twilight","planet","space","night","evening","sleep"],char:"\u{1f315}",fitzpatrick_scale:!1,category:"animals_and_nature"},waning_gibbous_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep","waxing_gibbous_moon"],char:"\u{1f316}",fitzpatrick_scale:!1,category:"animals_and_nature"},last_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\u{1f317}",fitzpatrick_scale:!1,category:"animals_and_nature"},waning_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\u{1f318}",fitzpatrick_scale:!1,category:"animals_and_nature"},new_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\u{1f311}",fitzpatrick_scale:!1,category:"animals_and_nature"},waxing_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\u{1f312}",fitzpatrick_scale:!1,category:"animals_and_nature"},first_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\u{1f313}",fitzpatrick_scale:!1,category:"animals_and_nature"},waxing_gibbous_moon:{keywords:["nature","night","sky","gray","twilight","planet","space","evening","sleep"],char:"\u{1f314}",fitzpatrick_scale:!1,category:"animals_and_nature"},new_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\u{1f31a}",fitzpatrick_scale:!1,category:"animals_and_nature"},full_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\u{1f31d}",fitzpatrick_scale:!1,category:"animals_and_nature"},first_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\u{1f31b}",fitzpatrick_scale:!1,category:"animals_and_nature"},last_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\u{1f31c}",fitzpatrick_scale:!1,category:"animals_and_nature"},sun_with_face:{keywords:["nature","morning","sky"],char:"\u{1f31e}",fitzpatrick_scale:!1,category:"animals_and_nature"},crescent_moon:{keywords:["night","sleep","sky","evening","magic"],char:"\u{1f319}",fitzpatrick_scale:!1,category:"animals_and_nature"},star:{keywords:["night","yellow"],char:"\u2b50",fitzpatrick_scale:!1,category:"animals_and_nature"},star2:{keywords:["night","sparkle","awesome","good","magic"],char:"\u{1f31f}",fitzpatrick_scale:!1,category:"animals_and_nature"},dizzy:{keywords:["star","sparkle","shoot","magic"],char:"\u{1f4ab}",fitzpatrick_scale:!1,category:"animals_and_nature"},sparkles:{keywords:["stars","shine","shiny","cool","awesome","good","magic"],char:"\u2728",fitzpatrick_scale:!1,category:"animals_and_nature"},comet:{keywords:["space"],char:"\u2604",fitzpatrick_scale:!1,category:"animals_and_nature"},sunny:{keywords:["weather","nature","brightness","summer","beach","spring"],char:"\u2600\ufe0f",fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_small_cloud:{keywords:["weather"],char:"\u{1f324}",fitzpatrick_scale:!1,category:"animals_and_nature"},partly_sunny:{keywords:["weather","nature","cloudy","morning","fall","spring"],char:"\u26c5",fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_large_cloud:{keywords:["weather"],char:"\u{1f325}",fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_rain_cloud:{keywords:["weather"],char:"\u{1f326}",fitzpatrick_scale:!1,category:"animals_and_nature"},cloud:{keywords:["weather","sky"],char:"\u2601\ufe0f",fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_rain:{keywords:["weather"],char:"\u{1f327}",fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_lightning_and_rain:{keywords:["weather","lightning"],char:"\u26c8",fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_lightning:{keywords:["weather","thunder"],char:"\u{1f329}",fitzpatrick_scale:!1,category:"animals_and_nature"},zap:{keywords:["thunder","weather","lightning bolt","fast"],char:"\u26a1",fitzpatrick_scale:!1,category:"animals_and_nature"},fire:{keywords:["hot","cook","flame"],char:"\u{1f525}",fitzpatrick_scale:!1,category:"animals_and_nature"},boom:{keywords:["bomb","explode","explosion","collision","blown"],char:"\u{1f4a5}",fitzpatrick_scale:!1,category:"animals_and_nature"},snowflake:{keywords:["winter","season","cold","weather","christmas","xmas"],char:"\u2744\ufe0f",fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_snow:{keywords:["weather"],char:"\u{1f328}",fitzpatrick_scale:!1,category:"animals_and_nature"},snowman:{keywords:["winter","season","cold","weather","christmas","xmas","frozen","without_snow"],char:"\u26c4",fitzpatrick_scale:!1,category:"animals_and_nature"},snowman_with_snow:{keywords:["winter","season","cold","weather","christmas","xmas","frozen"],char:"\u2603",fitzpatrick_scale:!1,category:"animals_and_nature"},wind_face:{keywords:["gust","air"],char:"\u{1f32c}",fitzpatrick_scale:!1,category:"animals_and_nature"},dash:{keywords:["wind","air","fast","shoo","fart","smoke","puff"],char:"\u{1f4a8}",fitzpatrick_scale:!1,category:"animals_and_nature"},tornado:{keywords:["weather","cyclone","twister"],char:"\u{1f32a}",fitzpatrick_scale:!1,category:"animals_and_nature"},fog:{keywords:["weather"],char:"\u{1f32b}",fitzpatrick_scale:!1,category:"animals_and_nature"},open_umbrella:{keywords:["weather","spring"],char:"\u2602",fitzpatrick_scale:!1,category:"animals_and_nature"},umbrella:{keywords:["rainy","weather","spring"],char:"\u2614",fitzpatrick_scale:!1,category:"animals_and_nature"},droplet:{keywords:["water","drip","faucet","spring"],char:"\u{1f4a7}",fitzpatrick_scale:!1,category:"animals_and_nature"},sweat_drops:{keywords:["water","drip","oops"],char:"\u{1f4a6}",fitzpatrick_scale:!1,category:"animals_and_nature"},ocean:{keywords:["sea","water","wave","nature","tsunami","disaster"],char:"\u{1f30a}",fitzpatrick_scale:!1,category:"animals_and_nature"},green_apple:{keywords:["fruit","nature"],char:"\u{1f34f}",fitzpatrick_scale:!1,category:"food_and_drink"},apple:{keywords:["fruit","mac","school"],char:"\u{1f34e}",fitzpatrick_scale:!1,category:"food_and_drink"},pear:{keywords:["fruit","nature","food"],char:"\u{1f350}",fitzpatrick_scale:!1,category:"food_and_drink"},tangerine:{keywords:["food","fruit","nature","orange"],char:"\u{1f34a}",fitzpatrick_scale:!1,category:"food_and_drink"},lemon:{keywords:["fruit","nature"],char:"\u{1f34b}",fitzpatrick_scale:!1,category:"food_and_drink"},banana:{keywords:["fruit","food","monkey"],char:"\u{1f34c}",fitzpatrick_scale:!1,category:"food_and_drink"},watermelon:{keywords:["fruit","food","picnic","summer"],char:"\u{1f349}",fitzpatrick_scale:!1,category:"food_and_drink"},grapes:{keywords:["fruit","food","wine"],char:"\u{1f347}",fitzpatrick_scale:!1,category:"food_and_drink"},strawberry:{keywords:["fruit","food","nature"],char:"\u{1f353}",fitzpatrick_scale:!1,category:"food_and_drink"},melon:{keywords:["fruit","nature","food"],char:"\u{1f348}",fitzpatrick_scale:!1,category:"food_and_drink"},cherries:{keywords:["food","fruit"],char:"\u{1f352}",fitzpatrick_scale:!1,category:"food_and_drink"},peach:{keywords:["fruit","nature","food"],char:"\u{1f351}",fitzpatrick_scale:!1,category:"food_and_drink"},pineapple:{keywords:["fruit","nature","food"],char:"\u{1f34d}",fitzpatrick_scale:!1,category:"food_and_drink"},coconut:{keywords:["fruit","nature","food","palm"],char:"\u{1f965}",fitzpatrick_scale:!1,category:"food_and_drink"},kiwi_fruit:{keywords:["fruit","food"],char:"\u{1f95d}",fitzpatrick_scale:!1,category:"food_and_drink"},mango:{keywords:["fruit","food","tropical"],char:"\u{1f96d}",fitzpatrick_scale:!1,category:"food_and_drink"},avocado:{keywords:["fruit","food"],char:"\u{1f951}",fitzpatrick_scale:!1,category:"food_and_drink"},broccoli:{keywords:["fruit","food","vegetable"],char:"\u{1f966}",fitzpatrick_scale:!1,category:"food_and_drink"},tomato:{keywords:["fruit","vegetable","nature","food"],char:"\u{1f345}",fitzpatrick_scale:!1,category:"food_and_drink"},eggplant:{keywords:["vegetable","nature","food","aubergine"],char:"\u{1f346}",fitzpatrick_scale:!1,category:"food_and_drink"},cucumber:{keywords:["fruit","food","pickle"],char:"\u{1f952}",fitzpatrick_scale:!1,category:"food_and_drink"},carrot:{keywords:["vegetable","food","orange"],char:"\u{1f955}",fitzpatrick_scale:!1,category:"food_and_drink"},hot_pepper:{keywords:["food","spicy","chilli","chili"],char:"\u{1f336}",fitzpatrick_scale:!1,category:"food_and_drink"},potato:{keywords:["food","tuber","vegatable","starch"],char:"\u{1f954}",fitzpatrick_scale:!1,category:"food_and_drink"},corn:{keywords:["food","vegetable","plant"],char:"\u{1f33d}",fitzpatrick_scale:!1,category:"food_and_drink"},leafy_greens:{keywords:["food","vegetable","plant","bok choy","cabbage","kale","lettuce"],char:"\u{1f96c}",fitzpatrick_scale:!1,category:"food_and_drink"},sweet_potato:{keywords:["food","nature"],char:"\u{1f360}",fitzpatrick_scale:!1,category:"food_and_drink"},peanuts:{keywords:["food","nut"],char:"\u{1f95c}",fitzpatrick_scale:!1,category:"food_and_drink"},honey_pot:{keywords:["bees","sweet","kitchen"],char:"\u{1f36f}",fitzpatrick_scale:!1,category:"food_and_drink"},croissant:{keywords:["food","bread","french"],char:"\u{1f950}",fitzpatrick_scale:!1,category:"food_and_drink"},bread:{keywords:["food","wheat","breakfast","toast"],char:"\u{1f35e}",fitzpatrick_scale:!1,category:"food_and_drink"},baguette_bread:{keywords:["food","bread","french"],char:"\u{1f956}",fitzpatrick_scale:!1,category:"food_and_drink"},bagel:{keywords:["food","bread","bakery","schmear"],char:"\u{1f96f}",fitzpatrick_scale:!1,category:"food_and_drink"},pretzel:{keywords:["food","bread","twisted"],char:"\u{1f968}",fitzpatrick_scale:!1,category:"food_and_drink"},cheese:{keywords:["food","chadder"],char:"\u{1f9c0}",fitzpatrick_scale:!1,category:"food_and_drink"},egg:{keywords:["food","chicken","breakfast"],char:"\u{1f95a}",fitzpatrick_scale:!1,category:"food_and_drink"},bacon:{keywords:["food","breakfast","pork","pig","meat"],char:"\u{1f953}",fitzpatrick_scale:!1,category:"food_and_drink"},steak:{keywords:["food","cow","meat","cut","chop","lambchop","porkchop"],char:"\u{1f969}",fitzpatrick_scale:!1,category:"food_and_drink"},pancakes:{keywords:["food","breakfast","flapjacks","hotcakes"],char:"\u{1f95e}",fitzpatrick_scale:!1,category:"food_and_drink"},poultry_leg:{keywords:["food","meat","drumstick","bird","chicken","turkey"],char:"\u{1f357}",fitzpatrick_scale:!1,category:"food_and_drink"},meat_on_bone:{keywords:["good","food","drumstick"],char:"\u{1f356}",fitzpatrick_scale:!1,category:"food_and_drink"},bone:{keywords:["skeleton"],char:"\u{1f9b4}",fitzpatrick_scale:!1,category:"food_and_drink"},fried_shrimp:{keywords:["food","animal","appetizer","summer"],char:"\u{1f364}",fitzpatrick_scale:!1,category:"food_and_drink"},fried_egg:{keywords:["food","breakfast","kitchen","egg"],char:"\u{1f373}",fitzpatrick_scale:!1,category:"food_and_drink"},hamburger:{keywords:["meat","fast food","beef","cheeseburger","mcdonalds","burger king"],char:"\u{1f354}",fitzpatrick_scale:!1,category:"food_and_drink"},fries:{keywords:["chips","snack","fast food"],char:"\u{1f35f}",fitzpatrick_scale:!1,category:"food_and_drink"},stuffed_flatbread:{keywords:["food","flatbread","stuffed","gyro"],char:"\u{1f959}",fitzpatrick_scale:!1,category:"food_and_drink"},hotdog:{keywords:["food","frankfurter"],char:"\u{1f32d}",fitzpatrick_scale:!1,category:"food_and_drink"},pizza:{keywords:["food","party"],char:"\u{1f355}",fitzpatrick_scale:!1,category:"food_and_drink"},sandwich:{keywords:["food","lunch","bread"],char:"\u{1f96a}",fitzpatrick_scale:!1,category:"food_and_drink"},canned_food:{keywords:["food","soup"],char:"\u{1f96b}",fitzpatrick_scale:!1,category:"food_and_drink"},spaghetti:{keywords:["food","italian","noodle"],char:"\u{1f35d}",fitzpatrick_scale:!1,category:"food_and_drink"},taco:{keywords:["food","mexican"],char:"\u{1f32e}",fitzpatrick_scale:!1,category:"food_and_drink"},burrito:{keywords:["food","mexican"],char:"\u{1f32f}",fitzpatrick_scale:!1,category:"food_and_drink"},green_salad:{keywords:["food","healthy","lettuce"],char:"\u{1f957}",fitzpatrick_scale:!1,category:"food_and_drink"},shallow_pan_of_food:{keywords:["food","cooking","casserole","paella"],char:"\u{1f958}",fitzpatrick_scale:!1,category:"food_and_drink"},ramen:{keywords:["food","japanese","noodle","chopsticks"],char:"\u{1f35c}",fitzpatrick_scale:!1,category:"food_and_drink"},stew:{keywords:["food","meat","soup"],char:"\u{1f372}",fitzpatrick_scale:!1,category:"food_and_drink"},fish_cake:{keywords:["food","japan","sea","beach","narutomaki","pink","swirl","kamaboko","surimi","ramen"],char:"\u{1f365}",fitzpatrick_scale:!1,category:"food_and_drink"},fortune_cookie:{keywords:["food","prophecy"],char:"\u{1f960}",fitzpatrick_scale:!1,category:"food_and_drink"},sushi:{keywords:["food","fish","japanese","rice"],char:"\u{1f363}",fitzpatrick_scale:!1,category:"food_and_drink"},bento:{keywords:["food","japanese","box"],char:"\u{1f371}",fitzpatrick_scale:!1,category:"food_and_drink"},curry:{keywords:["food","spicy","hot","indian"],char:"\u{1f35b}",fitzpatrick_scale:!1,category:"food_and_drink"},rice_ball:{keywords:["food","japanese"],char:"\u{1f359}",fitzpatrick_scale:!1,category:"food_and_drink"},rice:{keywords:["food","china","asian"],char:"\u{1f35a}",fitzpatrick_scale:!1,category:"food_and_drink"},rice_cracker:{keywords:["food","japanese"],char:"\u{1f358}",fitzpatrick_scale:!1,category:"food_and_drink"},oden:{keywords:["food","japanese"],char:"\u{1f362}",fitzpatrick_scale:!1,category:"food_and_drink"},dango:{keywords:["food","dessert","sweet","japanese","barbecue","meat"],char:"\u{1f361}",fitzpatrick_scale:!1,category:"food_and_drink"},shaved_ice:{keywords:["hot","dessert","summer"],char:"\u{1f367}",fitzpatrick_scale:!1,category:"food_and_drink"},ice_cream:{keywords:["food","hot","dessert"],char:"\u{1f368}",fitzpatrick_scale:!1,category:"food_and_drink"},icecream:{keywords:["food","hot","dessert","summer"],char:"\u{1f366}",fitzpatrick_scale:!1,category:"food_and_drink"},pie:{keywords:["food","dessert","pastry"],char:"\u{1f967}",fitzpatrick_scale:!1,category:"food_and_drink"},cake:{keywords:["food","dessert"],char:"\u{1f370}",fitzpatrick_scale:!1,category:"food_and_drink"},cupcake:{keywords:["food","dessert","bakery","sweet"],char:"\u{1f9c1}",fitzpatrick_scale:!1,category:"food_and_drink"},moon_cake:{keywords:["food","autumn"],char:"\u{1f96e}",fitzpatrick_scale:!1,category:"food_and_drink"},birthday:{keywords:["food","dessert","cake"],char:"\u{1f382}",fitzpatrick_scale:!1,category:"food_and_drink"},custard:{keywords:["dessert","food"],char:"\u{1f36e}",fitzpatrick_scale:!1,category:"food_and_drink"},candy:{keywords:["snack","dessert","sweet","lolly"],char:"\u{1f36c}",fitzpatrick_scale:!1,category:"food_and_drink"},lollipop:{keywords:["food","snack","candy","sweet"],char:"\u{1f36d}",fitzpatrick_scale:!1,category:"food_and_drink"},chocolate_bar:{keywords:["food","snack","dessert","sweet"],char:"\u{1f36b}",fitzpatrick_scale:!1,category:"food_and_drink"},popcorn:{keywords:["food","movie theater","films","snack"],char:"\u{1f37f}",fitzpatrick_scale:!1,category:"food_and_drink"},dumpling:{keywords:["food","empanada","pierogi","potsticker"],char:"\u{1f95f}",fitzpatrick_scale:!1,category:"food_and_drink"},doughnut:{keywords:["food","dessert","snack","sweet","donut"],char:"\u{1f369}",fitzpatrick_scale:!1,category:"food_and_drink"},cookie:{keywords:["food","snack","oreo","chocolate","sweet","dessert"],char:"\u{1f36a}",fitzpatrick_scale:!1,category:"food_and_drink"},milk_glass:{keywords:["beverage","drink","cow"],char:"\u{1f95b}",fitzpatrick_scale:!1,category:"food_and_drink"},beer:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:"\u{1f37a}",fitzpatrick_scale:!1,category:"food_and_drink"},beers:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:"\u{1f37b}",fitzpatrick_scale:!1,category:"food_and_drink"},clinking_glasses:{keywords:["beverage","drink","party","alcohol","celebrate","cheers","wine","champagne","toast"],char:"\u{1f942}",fitzpatrick_scale:!1,category:"food_and_drink"},wine_glass:{keywords:["drink","beverage","drunk","alcohol","booze"],char:"\u{1f377}",fitzpatrick_scale:!1,category:"food_and_drink"},tumbler_glass:{keywords:["drink","beverage","drunk","alcohol","liquor","booze","bourbon","scotch","whisky","glass","shot"],char:"\u{1f943}",fitzpatrick_scale:!1,category:"food_and_drink"},cocktail:{keywords:["drink","drunk","alcohol","beverage","booze","mojito"],char:"\u{1f378}",fitzpatrick_scale:!1,category:"food_and_drink"},tropical_drink:{keywords:["beverage","cocktail","summer","beach","alcohol","booze","mojito"],char:"\u{1f379}",fitzpatrick_scale:!1,category:"food_and_drink"},champagne:{keywords:["drink","wine","bottle","celebration"],char:"\u{1f37e}",fitzpatrick_scale:!1,category:"food_and_drink"},sake:{keywords:["wine","drink","drunk","beverage","japanese","alcohol","booze"],char:"\u{1f376}",fitzpatrick_scale:!1,category:"food_and_drink"},tea:{keywords:["drink","bowl","breakfast","green","british"],char:"\u{1f375}",fitzpatrick_scale:!1,category:"food_and_drink"},cup_with_straw:{keywords:["drink","soda"],char:"\u{1f964}",fitzpatrick_scale:!1,category:"food_and_drink"},coffee:{keywords:["beverage","caffeine","latte","espresso"],char:"\u2615",fitzpatrick_scale:!1,category:"food_and_drink"},baby_bottle:{keywords:["food","container","milk"],char:"\u{1f37c}",fitzpatrick_scale:!1,category:"food_and_drink"},salt:{keywords:["condiment","shaker"],char:"\u{1f9c2}",fitzpatrick_scale:!1,category:"food_and_drink"},spoon:{keywords:["cutlery","kitchen","tableware"],char:"\u{1f944}",fitzpatrick_scale:!1,category:"food_and_drink"},fork_and_knife:{keywords:["cutlery","kitchen"],char:"\u{1f374}",fitzpatrick_scale:!1,category:"food_and_drink"},plate_with_cutlery:{keywords:["food","eat","meal","lunch","dinner","restaurant"],char:"\u{1f37d}",fitzpatrick_scale:!1,category:"food_and_drink"},bowl_with_spoon:{keywords:["food","breakfast","cereal","oatmeal","porridge"],char:"\u{1f963}",fitzpatrick_scale:!1,category:"food_and_drink"},takeout_box:{keywords:["food","leftovers"],char:"\u{1f961}",fitzpatrick_scale:!1,category:"food_and_drink"},chopsticks:{keywords:["food"],char:"\u{1f962}",fitzpatrick_scale:!1,category:"food_and_drink"},soccer:{keywords:["sports","football"],char:"\u26bd",fitzpatrick_scale:!1,category:"activity"},basketball:{keywords:["sports","balls","NBA"],char:"\u{1f3c0}",fitzpatrick_scale:!1,category:"activity"},football:{keywords:["sports","balls","NFL"],char:"\u{1f3c8}",fitzpatrick_scale:!1,category:"activity"},baseball:{keywords:["sports","balls"],char:"\u26be",fitzpatrick_scale:!1,category:"activity"},softball:{keywords:["sports","balls"],char:"\u{1f94e}",fitzpatrick_scale:!1,category:"activity"},tennis:{keywords:["sports","balls","green"],char:"\u{1f3be}",fitzpatrick_scale:!1,category:"activity"},volleyball:{keywords:["sports","balls"],char:"\u{1f3d0}",fitzpatrick_scale:!1,category:"activity"},rugby_football:{keywords:["sports","team"],char:"\u{1f3c9}",fitzpatrick_scale:!1,category:"activity"},flying_disc:{keywords:["sports","frisbee","ultimate"],char:"\u{1f94f}",fitzpatrick_scale:!1,category:"activity"},"8ball":{keywords:["pool","hobby","game","luck","magic"],char:"\u{1f3b1}",fitzpatrick_scale:!1,category:"activity"},golf:{keywords:["sports","business","flag","hole","summer"],char:"\u26f3",fitzpatrick_scale:!1,category:"activity"},golfing_woman:{keywords:["sports","business","woman","female"],char:"\u{1f3cc}\ufe0f\u200d\u2640\ufe0f",fitzpatrick_scale:!1,category:"activity"},golfing_man:{keywords:["sports","business"],char:"\u{1f3cc}",fitzpatrick_scale:!0,category:"activity"},ping_pong:{keywords:["sports","pingpong"],char:"\u{1f3d3}",fitzpatrick_scale:!1,category:"activity"},badminton:{keywords:["sports"],char:"\u{1f3f8}",fitzpatrick_scale:!1,category:"activity"},goal_net:{keywords:["sports"],char:"\u{1f945}",fitzpatrick_scale:!1,category:"activity"},ice_hockey:{keywords:["sports"],char:"\u{1f3d2}",fitzpatrick_scale:!1,category:"activity"},field_hockey:{keywords:["sports"],char:"\u{1f3d1}",fitzpatrick_scale:!1,category:"activity"},lacrosse:{keywords:["sports","ball","stick"],char:"\u{1f94d}",fitzpatrick_scale:!1,category:"activity"},cricket:{keywords:["sports"],char:"\u{1f3cf}",fitzpatrick_scale:!1,category:"activity"},ski:{keywords:["sports","winter","cold","snow"],char:"\u{1f3bf}",fitzpatrick_scale:!1,category:"activity"},skier:{keywords:["sports","winter","snow"],char:"\u26f7",fitzpatrick_scale:!1,category:"activity"},snowboarder:{keywords:["sports","winter"],char:"\u{1f3c2}",fitzpatrick_scale:!0,category:"activity"},person_fencing:{keywords:["sports","fencing","sword"],char:"\u{1f93a}",fitzpatrick_scale:!1,category:"activity"},women_wrestling:{keywords:["sports","wrestlers"],char:"\u{1f93c}\u200d\u2640\ufe0f",fitzpatrick_scale:!1,category:"activity"},men_wrestling:{keywords:["sports","wrestlers"],char:"\u{1f93c}\u200d\u2642\ufe0f",fitzpatrick_scale:!1,category:"activity"},woman_cartwheeling:{keywords:["gymnastics"],char:"\u{1f938}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},man_cartwheeling:{keywords:["gymnastics"],char:"\u{1f938}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},woman_playing_handball:{keywords:["sports"],char:"\u{1f93e}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},man_playing_handball:{keywords:["sports"],char:"\u{1f93e}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},ice_skate:{keywords:["sports"],char:"\u26f8",fitzpatrick_scale:!1,category:"activity"},curling_stone:{keywords:["sports"],char:"\u{1f94c}",fitzpatrick_scale:!1,category:"activity"},skateboard:{keywords:["board"],char:"\u{1f6f9}",fitzpatrick_scale:!1,category:"activity"},sled:{keywords:["sleigh","luge","toboggan"],char:"\u{1f6f7}",fitzpatrick_scale:!1,category:"activity"},bow_and_arrow:{keywords:["sports"],char:"\u{1f3f9}",fitzpatrick_scale:!1,category:"activity"},fishing_pole_and_fish:{keywords:["food","hobby","summer"],char:"\u{1f3a3}",fitzpatrick_scale:!1,category:"activity"},boxing_glove:{keywords:["sports","fighting"],char:"\u{1f94a}",fitzpatrick_scale:!1,category:"activity"},martial_arts_uniform:{keywords:["judo","karate","taekwondo"],char:"\u{1f94b}",fitzpatrick_scale:!1,category:"activity"},rowing_woman:{keywords:["sports","hobby","water","ship","woman","female"],char:"\u{1f6a3}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},rowing_man:{keywords:["sports","hobby","water","ship"],char:"\u{1f6a3}",fitzpatrick_scale:!0,category:"activity"},climbing_woman:{keywords:["sports","hobby","woman","female","rock"],char:"\u{1f9d7}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},climbing_man:{keywords:["sports","hobby","man","male","rock"],char:"\u{1f9d7}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},swimming_woman:{keywords:["sports","exercise","human","athlete","water","summer","woman","female"],char:"\u{1f3ca}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},swimming_man:{keywords:["sports","exercise","human","athlete","water","summer"],char:"\u{1f3ca}",fitzpatrick_scale:!0,category:"activity"},woman_playing_water_polo:{keywords:["sports","pool"],char:"\u{1f93d}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},man_playing_water_polo:{keywords:["sports","pool"],char:"\u{1f93d}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},woman_in_lotus_position:{keywords:["woman","female","meditation","yoga","serenity","zen","mindfulness"],char:"\u{1f9d8}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},man_in_lotus_position:{keywords:["man","male","meditation","yoga","serenity","zen","mindfulness"],char:"\u{1f9d8}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},surfing_woman:{keywords:["sports","ocean","sea","summer","beach","woman","female"],char:"\u{1f3c4}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},surfing_man:{keywords:["sports","ocean","sea","summer","beach"],char:"\u{1f3c4}",fitzpatrick_scale:!0,category:"activity"},bath:{keywords:["clean","shower","bathroom"],char:"\u{1f6c0}",fitzpatrick_scale:!0,category:"activity"},basketball_woman:{keywords:["sports","human","woman","female"],char:"\u26f9\ufe0f\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},basketball_man:{keywords:["sports","human"],char:"\u26f9",fitzpatrick_scale:!0,category:"activity"},weight_lifting_woman:{keywords:["sports","training","exercise","woman","female"],char:"\u{1f3cb}\ufe0f\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},weight_lifting_man:{keywords:["sports","training","exercise"],char:"\u{1f3cb}",fitzpatrick_scale:!0,category:"activity"},biking_woman:{keywords:["sports","bike","exercise","hipster","woman","female"],char:"\u{1f6b4}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},biking_man:{keywords:["sports","bike","exercise","hipster"],char:"\u{1f6b4}",fitzpatrick_scale:!0,category:"activity"},mountain_biking_woman:{keywords:["transportation","sports","human","race","bike","woman","female"],char:"\u{1f6b5}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},mountain_biking_man:{keywords:["transportation","sports","human","race","bike"],char:"\u{1f6b5}",fitzpatrick_scale:!0,category:"activity"},horse_racing:{keywords:["animal","betting","competition","gambling","luck"],char:"\u{1f3c7}",fitzpatrick_scale:!0,category:"activity"},business_suit_levitating:{keywords:["suit","business","levitate","hover","jump"],char:"\u{1f574}",fitzpatrick_scale:!0,category:"activity"},trophy:{keywords:["win","award","contest","place","ftw","ceremony"],char:"\u{1f3c6}",fitzpatrick_scale:!1,category:"activity"},running_shirt_with_sash:{keywords:["play","pageant"],char:"\u{1f3bd}",fitzpatrick_scale:!1,category:"activity"},medal_sports:{keywords:["award","winning"],char:"\u{1f3c5}",fitzpatrick_scale:!1,category:"activity"},medal_military:{keywords:["award","winning","army"],char:"\u{1f396}",fitzpatrick_scale:!1,category:"activity"},"1st_place_medal":{keywords:["award","winning","first"],char:"\u{1f947}",fitzpatrick_scale:!1,category:"activity"},"2nd_place_medal":{keywords:["award","second"],char:"\u{1f948}",fitzpatrick_scale:!1,category:"activity"},"3rd_place_medal":{keywords:["award","third"],char:"\u{1f949}",fitzpatrick_scale:!1,category:"activity"},reminder_ribbon:{keywords:["sports","cause","support","awareness"],char:"\u{1f397}",fitzpatrick_scale:!1,category:"activity"},rosette:{keywords:["flower","decoration","military"],char:"\u{1f3f5}",fitzpatrick_scale:!1,category:"activity"},ticket:{keywords:["event","concert","pass"],char:"\u{1f3ab}",fitzpatrick_scale:!1,category:"activity"},tickets:{keywords:["sports","concert","entrance"],char:"\u{1f39f}",fitzpatrick_scale:!1,category:"activity"},performing_arts:{keywords:["acting","theater","drama"],char:"\u{1f3ad}",fitzpatrick_scale:!1,category:"activity"},art:{keywords:["design","paint","draw","colors"],char:"\u{1f3a8}",fitzpatrick_scale:!1,category:"activity"},circus_tent:{keywords:["festival","carnival","party"],char:"\u{1f3aa}",fitzpatrick_scale:!1,category:"activity"},woman_juggling:{keywords:["juggle","balance","skill","multitask"],char:"\u{1f939}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},man_juggling:{keywords:["juggle","balance","skill","multitask"],char:"\u{1f939}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},microphone:{keywords:["sound","music","PA","sing","talkshow"],char:"\u{1f3a4}",fitzpatrick_scale:!1,category:"activity"},headphones:{keywords:["music","score","gadgets"],char:"\u{1f3a7}",fitzpatrick_scale:!1,category:"activity"},musical_score:{keywords:["treble","clef","compose"],char:"\u{1f3bc}",fitzpatrick_scale:!1,category:"activity"},musical_keyboard:{keywords:["piano","instrument","compose"],char:"\u{1f3b9}",fitzpatrick_scale:!1,category:"activity"},drum:{keywords:["music","instrument","drumsticks","snare"],char:"\u{1f941}",fitzpatrick_scale:!1,category:"activity"},saxophone:{keywords:["music","instrument","jazz","blues"],char:"\u{1f3b7}",fitzpatrick_scale:!1,category:"activity"},trumpet:{keywords:["music","brass"],char:"\u{1f3ba}",fitzpatrick_scale:!1,category:"activity"},guitar:{keywords:["music","instrument"],char:"\u{1f3b8}",fitzpatrick_scale:!1,category:"activity"},violin:{keywords:["music","instrument","orchestra","symphony"],char:"\u{1f3bb}",fitzpatrick_scale:!1,category:"activity"},clapper:{keywords:["movie","film","record"],char:"\u{1f3ac}",fitzpatrick_scale:!1,category:"activity"},video_game:{keywords:["play","console","PS4","controller"],char:"\u{1f3ae}",fitzpatrick_scale:!1,category:"activity"},space_invader:{keywords:["game","arcade","play"],char:"\u{1f47e}",fitzpatrick_scale:!1,category:"activity"},dart:{keywords:["game","play","bar","target","bullseye"],char:"\u{1f3af}",fitzpatrick_scale:!1,category:"activity"},game_die:{keywords:["dice","random","tabletop","play","luck"],char:"\u{1f3b2}",fitzpatrick_scale:!1,category:"activity"},chess_pawn:{keywords:["expendable"],char:"\u265f",fitzpatrick_scale:!1,category:"activity"},slot_machine:{keywords:["bet","gamble","vegas","fruit machine","luck","casino"],char:"\u{1f3b0}",fitzpatrick_scale:!1,category:"activity"},jigsaw:{keywords:["interlocking","puzzle","piece"],char:"\u{1f9e9}",fitzpatrick_scale:!1,category:"activity"},bowling:{keywords:["sports","fun","play"],char:"\u{1f3b3}",fitzpatrick_scale:!1,category:"activity"},red_car:{keywords:["red","transportation","vehicle"],char:"\u{1f697}",fitzpatrick_scale:!1,category:"travel_and_places"},taxi:{keywords:["uber","vehicle","cars","transportation"],char:"\u{1f695}",fitzpatrick_scale:!1,category:"travel_and_places"},blue_car:{keywords:["transportation","vehicle"],char:"\u{1f699}",fitzpatrick_scale:!1,category:"travel_and_places"},bus:{keywords:["car","vehicle","transportation"],char:"\u{1f68c}",fitzpatrick_scale:!1,category:"travel_and_places"},trolleybus:{keywords:["bart","transportation","vehicle"],char:"\u{1f68e}",fitzpatrick_scale:!1,category:"travel_and_places"},racing_car:{keywords:["sports","race","fast","formula","f1"],char:"\u{1f3ce}",fitzpatrick_scale:!1,category:"travel_and_places"},police_car:{keywords:["vehicle","cars","transportation","law","legal","enforcement"],char:"\u{1f693}",fitzpatrick_scale:!1,category:"travel_and_places"},ambulance:{keywords:["health","911","hospital"],char:"\u{1f691}",fitzpatrick_scale:!1,category:"travel_and_places"},fire_engine:{keywords:["transportation","cars","vehicle"],char:"\u{1f692}",fitzpatrick_scale:!1,category:"travel_and_places"},minibus:{keywords:["vehicle","car","transportation"],char:"\u{1f690}",fitzpatrick_scale:!1,category:"travel_and_places"},truck:{keywords:["cars","transportation"],char:"\u{1f69a}",fitzpatrick_scale:!1,category:"travel_and_places"},articulated_lorry:{keywords:["vehicle","cars","transportation","express"],char:"\u{1f69b}",fitzpatrick_scale:!1,category:"travel_and_places"},tractor:{keywords:["vehicle","car","farming","agriculture"],char:"\u{1f69c}",fitzpatrick_scale:!1,category:"travel_and_places"},kick_scooter:{keywords:["vehicle","kick","razor"],char:"\u{1f6f4}",fitzpatrick_scale:!1,category:"travel_and_places"},motorcycle:{keywords:["race","sports","fast"],char:"\u{1f3cd}",fitzpatrick_scale:!1,category:"travel_and_places"},bike:{keywords:["sports","bicycle","exercise","hipster"],char:"\u{1f6b2}",fitzpatrick_scale:!1,category:"travel_and_places"},motor_scooter:{keywords:["vehicle","vespa","sasha"],char:"\u{1f6f5}",fitzpatrick_scale:!1,category:"travel_and_places"},rotating_light:{keywords:["police","ambulance","911","emergency","alert","error","pinged","law","legal"],char:"\u{1f6a8}",fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_police_car:{keywords:["vehicle","law","legal","enforcement","911"],char:"\u{1f694}",fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_bus:{keywords:["vehicle","transportation"],char:"\u{1f68d}",fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_automobile:{keywords:["car","vehicle","transportation"],char:"\u{1f698}",fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_taxi:{keywords:["vehicle","cars","uber"],char:"\u{1f696}",fitzpatrick_scale:!1,category:"travel_and_places"},aerial_tramway:{keywords:["transportation","vehicle","ski"],char:"\u{1f6a1}",fitzpatrick_scale:!1,category:"travel_and_places"},mountain_cableway:{keywords:["transportation","vehicle","ski"],char:"\u{1f6a0}",fitzpatrick_scale:!1,category:"travel_and_places"},suspension_railway:{keywords:["vehicle","transportation"],char:"\u{1f69f}",fitzpatrick_scale:!1,category:"travel_and_places"},railway_car:{keywords:["transportation","vehicle"],char:"\u{1f683}",fitzpatrick_scale:!1,category:"travel_and_places"},train:{keywords:["transportation","vehicle","carriage","public","travel"],char:"\u{1f68b}",fitzpatrick_scale:!1,category:"travel_and_places"},monorail:{keywords:["transportation","vehicle"],char:"\u{1f69d}",fitzpatrick_scale:!1,category:"travel_and_places"},bullettrain_side:{keywords:["transportation","vehicle"],char:"\u{1f684}",fitzpatrick_scale:!1,category:"travel_and_places"},bullettrain_front:{keywords:["transportation","vehicle","speed","fast","public","travel"],char:"\u{1f685}",fitzpatrick_scale:!1,category:"travel_and_places"},light_rail:{keywords:["transportation","vehicle"],char:"\u{1f688}",fitzpatrick_scale:!1,category:"travel_and_places"},mountain_railway:{keywords:["transportation","vehicle"],char:"\u{1f69e}",fitzpatrick_scale:!1,category:"travel_and_places"},steam_locomotive:{keywords:["transportation","vehicle","train"],char:"\u{1f682}",fitzpatrick_scale:!1,category:"travel_and_places"},train2:{keywords:["transportation","vehicle"],char:"\u{1f686}",fitzpatrick_scale:!1,category:"travel_and_places"},metro:{keywords:["transportation","blue-square","mrt","underground","tube"],char:"\u{1f687}",fitzpatrick_scale:!1,category:"travel_and_places"},tram:{keywords:["transportation","vehicle"],char:"\u{1f68a}",fitzpatrick_scale:!1,category:"travel_and_places"},station:{keywords:["transportation","vehicle","public"],char:"\u{1f689}",fitzpatrick_scale:!1,category:"travel_and_places"},flying_saucer:{keywords:["transportation","vehicle","ufo"],char:"\u{1f6f8}",fitzpatrick_scale:!1,category:"travel_and_places"},helicopter:{keywords:["transportation","vehicle","fly"],char:"\u{1f681}",fitzpatrick_scale:!1,category:"travel_and_places"},small_airplane:{keywords:["flight","transportation","fly","vehicle"],char:"\u{1f6e9}",fitzpatrick_scale:!1,category:"travel_and_places"},airplane:{keywords:["vehicle","transportation","flight","fly"],char:"\u2708\ufe0f",fitzpatrick_scale:!1,category:"travel_and_places"},flight_departure:{keywords:["airport","flight","landing"],char:"\u{1f6eb}",fitzpatrick_scale:!1,category:"travel_and_places"},flight_arrival:{keywords:["airport","flight","boarding"],char:"\u{1f6ec}",fitzpatrick_scale:!1,category:"travel_and_places"},sailboat:{keywords:["ship","summer","transportation","water","sailing"],char:"\u26f5",fitzpatrick_scale:!1,category:"travel_and_places"},motor_boat:{keywords:["ship"],char:"\u{1f6e5}",fitzpatrick_scale:!1,category:"travel_and_places"},speedboat:{keywords:["ship","transportation","vehicle","summer"],char:"\u{1f6a4}",fitzpatrick_scale:!1,category:"travel_and_places"},ferry:{keywords:["boat","ship","yacht"],char:"\u26f4",fitzpatrick_scale:!1,category:"travel_and_places"},passenger_ship:{keywords:["yacht","cruise","ferry"],char:"\u{1f6f3}",fitzpatrick_scale:!1,category:"travel_and_places"},rocket:{keywords:["launch","ship","staffmode","NASA","outer space","outer_space","fly"],char:"\u{1f680}",fitzpatrick_scale:!1,category:"travel_and_places"},artificial_satellite:{keywords:["communication","gps","orbit","spaceflight","NASA","ISS"],char:"\u{1f6f0}",fitzpatrick_scale:!1,category:"travel_and_places"},seat:{keywords:["sit","airplane","transport","bus","flight","fly"],char:"\u{1f4ba}",fitzpatrick_scale:!1,category:"travel_and_places"},canoe:{keywords:["boat","paddle","water","ship"],char:"\u{1f6f6}",fitzpatrick_scale:!1,category:"travel_and_places"},anchor:{keywords:["ship","ferry","sea","boat"],char:"\u2693",fitzpatrick_scale:!1,category:"travel_and_places"},construction:{keywords:["wip","progress","caution","warning"],char:"\u{1f6a7}",fitzpatrick_scale:!1,category:"travel_and_places"},fuelpump:{keywords:["gas station","petroleum"],char:"\u26fd",fitzpatrick_scale:!1,category:"travel_and_places"},busstop:{keywords:["transportation","wait"],char:"\u{1f68f}",fitzpatrick_scale:!1,category:"travel_and_places"},vertical_traffic_light:{keywords:["transportation","driving"],char:"\u{1f6a6}",fitzpatrick_scale:!1,category:"travel_and_places"},traffic_light:{keywords:["transportation","signal"],char:"\u{1f6a5}",fitzpatrick_scale:!1,category:"travel_and_places"},checkered_flag:{keywords:["contest","finishline","race","gokart"],char:"\u{1f3c1}",fitzpatrick_scale:!1,category:"travel_and_places"},ship:{keywords:["transportation","titanic","deploy"],char:"\u{1f6a2}",fitzpatrick_scale:!1,category:"travel_and_places"},ferris_wheel:{keywords:["photo","carnival","londoneye"],char:"\u{1f3a1}",fitzpatrick_scale:!1,category:"travel_and_places"},roller_coaster:{keywords:["carnival","playground","photo","fun"],char:"\u{1f3a2}",fitzpatrick_scale:!1,category:"travel_and_places"},carousel_horse:{keywords:["photo","carnival"],char:"\u{1f3a0}",fitzpatrick_scale:!1,category:"travel_and_places"},building_construction:{keywords:["wip","working","progress"],char:"\u{1f3d7}",fitzpatrick_scale:!1,category:"travel_and_places"},foggy:{keywords:["photo","mountain"],char:"\u{1f301}",fitzpatrick_scale:!1,category:"travel_and_places"},tokyo_tower:{keywords:["photo","japanese"],char:"\u{1f5fc}",fitzpatrick_scale:!1,category:"travel_and_places"},factory:{keywords:["building","industry","pollution","smoke"],char:"\u{1f3ed}",fitzpatrick_scale:!1,category:"travel_and_places"},fountain:{keywords:["photo","summer","water","fresh"],char:"\u26f2",fitzpatrick_scale:!1,category:"travel_and_places"},rice_scene:{keywords:["photo","japan","asia","tsukimi"],char:"\u{1f391}",fitzpatrick_scale:!1,category:"travel_and_places"},mountain:{keywords:["photo","nature","environment"],char:"\u26f0",fitzpatrick_scale:!1,category:"travel_and_places"},mountain_snow:{keywords:["photo","nature","environment","winter","cold"],char:"\u{1f3d4}",fitzpatrick_scale:!1,category:"travel_and_places"},mount_fuji:{keywords:["photo","mountain","nature","japanese"],char:"\u{1f5fb}",fitzpatrick_scale:!1,category:"travel_and_places"},volcano:{keywords:["photo","nature","disaster"],char:"\u{1f30b}",fitzpatrick_scale:!1,category:"travel_and_places"},japan:{keywords:["nation","country","japanese","asia"],char:"\u{1f5fe}",fitzpatrick_scale:!1,category:"travel_and_places"},camping:{keywords:["photo","outdoors","tent"],char:"\u{1f3d5}",fitzpatrick_scale:!1,category:"travel_and_places"},tent:{keywords:["photo","camping","outdoors"],char:"\u26fa",fitzpatrick_scale:!1,category:"travel_and_places"},national_park:{keywords:["photo","environment","nature"],char:"\u{1f3de}",fitzpatrick_scale:!1,category:"travel_and_places"},motorway:{keywords:["road","cupertino","interstate","highway"],char:"\u{1f6e3}",fitzpatrick_scale:!1,category:"travel_and_places"},railway_track:{keywords:["train","transportation"],char:"\u{1f6e4}",fitzpatrick_scale:!1,category:"travel_and_places"},sunrise:{keywords:["morning","view","vacation","photo"],char:"\u{1f305}",fitzpatrick_scale:!1,category:"travel_and_places"},sunrise_over_mountains:{keywords:["view","vacation","photo"],char:"\u{1f304}",fitzpatrick_scale:!1,category:"travel_and_places"},desert:{keywords:["photo","warm","saharah"],char:"\u{1f3dc}",fitzpatrick_scale:!1,category:"travel_and_places"},beach_umbrella:{keywords:["weather","summer","sunny","sand","mojito"],char:"\u{1f3d6}",fitzpatrick_scale:!1,category:"travel_and_places"},desert_island:{keywords:["photo","tropical","mojito"],char:"\u{1f3dd}",fitzpatrick_scale:!1,category:"travel_and_places"},city_sunrise:{keywords:["photo","good morning","dawn"],char:"\u{1f307}",fitzpatrick_scale:!1,category:"travel_and_places"},city_sunset:{keywords:["photo","evening","sky","buildings"],char:"\u{1f306}",fitzpatrick_scale:!1,category:"travel_and_places"},cityscape:{keywords:["photo","night life","urban"],char:"\u{1f3d9}",fitzpatrick_scale:!1,category:"travel_and_places"},night_with_stars:{keywords:["evening","city","downtown"],char:"\u{1f303}",fitzpatrick_scale:!1,category:"travel_and_places"},bridge_at_night:{keywords:["photo","sanfrancisco"],char:"\u{1f309}",fitzpatrick_scale:!1,category:"travel_and_places"},milky_way:{keywords:["photo","space","stars"],char:"\u{1f30c}",fitzpatrick_scale:!1,category:"travel_and_places"},stars:{keywords:["night","photo"],char:"\u{1f320}",fitzpatrick_scale:!1,category:"travel_and_places"},sparkler:{keywords:["stars","night","shine"],char:"\u{1f387}",fitzpatrick_scale:!1,category:"travel_and_places"},fireworks:{keywords:["photo","festival","carnival","congratulations"],char:"\u{1f386}",fitzpatrick_scale:!1,category:"travel_and_places"},rainbow:{keywords:["nature","happy","unicorn_face","photo","sky","spring"],char:"\u{1f308}",fitzpatrick_scale:!1,category:"travel_and_places"},houses:{keywords:["buildings","photo"],char:"\u{1f3d8}",fitzpatrick_scale:!1,category:"travel_and_places"},european_castle:{keywords:["building","royalty","history"],char:"\u{1f3f0}",fitzpatrick_scale:!1,category:"travel_and_places"},japanese_castle:{keywords:["photo","building"],char:"\u{1f3ef}",fitzpatrick_scale:!1,category:"travel_and_places"},stadium:{keywords:["photo","place","sports","concert","venue"],char:"\u{1f3df}",fitzpatrick_scale:!1,category:"travel_and_places"},statue_of_liberty:{keywords:["american","newyork"],char:"\u{1f5fd}",fitzpatrick_scale:!1,category:"travel_and_places"},house:{keywords:["building","home"],char:"\u{1f3e0}",fitzpatrick_scale:!1,category:"travel_and_places"},house_with_garden:{keywords:["home","plant","nature"],char:"\u{1f3e1}",fitzpatrick_scale:!1,category:"travel_and_places"},derelict_house:{keywords:["abandon","evict","broken","building"],char:"\u{1f3da}",fitzpatrick_scale:!1,category:"travel_and_places"},office:{keywords:["building","bureau","work"],char:"\u{1f3e2}",fitzpatrick_scale:!1,category:"travel_and_places"},department_store:{keywords:["building","shopping","mall"],char:"\u{1f3ec}",fitzpatrick_scale:!1,category:"travel_and_places"},post_office:{keywords:["building","envelope","communication"],char:"\u{1f3e3}",fitzpatrick_scale:!1,category:"travel_and_places"},european_post_office:{keywords:["building","email"],char:"\u{1f3e4}",fitzpatrick_scale:!1,category:"travel_and_places"},hospital:{keywords:["building","health","surgery","doctor"],char:"\u{1f3e5}",fitzpatrick_scale:!1,category:"travel_and_places"},bank:{keywords:["building","money","sales","cash","business","enterprise"],char:"\u{1f3e6}",fitzpatrick_scale:!1,category:"travel_and_places"},hotel:{keywords:["building","accomodation","checkin"],char:"\u{1f3e8}",fitzpatrick_scale:!1,category:"travel_and_places"},convenience_store:{keywords:["building","shopping","groceries"],char:"\u{1f3ea}",fitzpatrick_scale:!1,category:"travel_and_places"},school:{keywords:["building","student","education","learn","teach"],char:"\u{1f3eb}",fitzpatrick_scale:!1,category:"travel_and_places"},love_hotel:{keywords:["like","affection","dating"],char:"\u{1f3e9}",fitzpatrick_scale:!1,category:"travel_and_places"},wedding:{keywords:["love","like","affection","couple","marriage","bride","groom"],char:"\u{1f492}",fitzpatrick_scale:!1,category:"travel_and_places"},classical_building:{keywords:["art","culture","history"],char:"\u{1f3db}",fitzpatrick_scale:!1,category:"travel_and_places"},church:{keywords:["building","religion","christ"],char:"\u26ea",fitzpatrick_scale:!1,category:"travel_and_places"},mosque:{keywords:["islam","worship","minaret"],char:"\u{1f54c}",fitzpatrick_scale:!1,category:"travel_and_places"},synagogue:{keywords:["judaism","worship","temple","jewish"],char:"\u{1f54d}",fitzpatrick_scale:!1,category:"travel_and_places"},kaaba:{keywords:["mecca","mosque","islam"],char:"\u{1f54b}",fitzpatrick_scale:!1,category:"travel_and_places"},shinto_shrine:{keywords:["temple","japan","kyoto"],char:"\u26e9",fitzpatrick_scale:!1,category:"travel_and_places"},watch:{keywords:["time","accessories"],char:"\u231a",fitzpatrick_scale:!1,category:"objects"},iphone:{keywords:["technology","apple","gadgets","dial"],char:"\u{1f4f1}",fitzpatrick_scale:!1,category:"objects"},calling:{keywords:["iphone","incoming"],char:"\u{1f4f2}",fitzpatrick_scale:!1,category:"objects"},computer:{keywords:["technology","laptop","screen","display","monitor"],char:"\u{1f4bb}",fitzpatrick_scale:!1,category:"objects"},keyboard:{keywords:["technology","computer","type","input","text"],char:"\u2328",fitzpatrick_scale:!1,category:"objects"},desktop_computer:{keywords:["technology","computing","screen"],char:"\u{1f5a5}",fitzpatrick_scale:!1,category:"objects"},printer:{keywords:["paper","ink"],char:"\u{1f5a8}",fitzpatrick_scale:!1,category:"objects"},computer_mouse:{keywords:["click"],char:"\u{1f5b1}",fitzpatrick_scale:!1,category:"objects"},trackball:{keywords:["technology","trackpad"],char:"\u{1f5b2}",fitzpatrick_scale:!1,category:"objects"},joystick:{keywords:["game","play"],char:"\u{1f579}",fitzpatrick_scale:!1,category:"objects"},clamp:{keywords:["tool"],char:"\u{1f5dc}",fitzpatrick_scale:!1,category:"objects"},minidisc:{keywords:["technology","record","data","disk","90s"],char:"\u{1f4bd}",fitzpatrick_scale:!1,category:"objects"},floppy_disk:{keywords:["oldschool","technology","save","90s","80s"],char:"\u{1f4be}",fitzpatrick_scale:!1,category:"objects"},cd:{keywords:["technology","dvd","disk","disc","90s"],char:"\u{1f4bf}",fitzpatrick_scale:!1,category:"objects"},dvd:{keywords:["cd","disk","disc"],char:"\u{1f4c0}",fitzpatrick_scale:!1,category:"objects"},vhs:{keywords:["record","video","oldschool","90s","80s"],char:"\u{1f4fc}",fitzpatrick_scale:!1,category:"objects"},camera:{keywords:["gadgets","photography"],char:"\u{1f4f7}",fitzpatrick_scale:!1,category:"objects"},camera_flash:{keywords:["photography","gadgets"],char:"\u{1f4f8}",fitzpatrick_scale:!1,category:"objects"},video_camera:{keywords:["film","record"],char:"\u{1f4f9}",fitzpatrick_scale:!1,category:"objects"},movie_camera:{keywords:["film","record"],char:"\u{1f3a5}",fitzpatrick_scale:!1,category:"objects"},film_projector:{keywords:["video","tape","record","movie"],char:"\u{1f4fd}",fitzpatrick_scale:!1,category:"objects"},film_strip:{keywords:["movie"],char:"\u{1f39e}",fitzpatrick_scale:!1,category:"objects"},telephone_receiver:{keywords:["technology","communication","dial"],char:"\u{1f4de}",fitzpatrick_scale:!1,category:"objects"},phone:{keywords:["technology","communication","dial","telephone"],char:"\u260e\ufe0f",fitzpatrick_scale:!1,category:"objects"},pager:{keywords:["bbcall","oldschool","90s"],char:"\u{1f4df}",fitzpatrick_scale:!1,category:"objects"},fax:{keywords:["communication","technology"],char:"\u{1f4e0}",fitzpatrick_scale:!1,category:"objects"},tv:{keywords:["technology","program","oldschool","show","television"],char:"\u{1f4fa}",fitzpatrick_scale:!1,category:"objects"},radio:{keywords:["communication","music","podcast","program"],char:"\u{1f4fb}",fitzpatrick_scale:!1,category:"objects"},studio_microphone:{keywords:["sing","recording","artist","talkshow"],char:"\u{1f399}",fitzpatrick_scale:!1,category:"objects"},level_slider:{keywords:["scale"],char:"\u{1f39a}",fitzpatrick_scale:!1,category:"objects"},control_knobs:{keywords:["dial"],char:"\u{1f39b}",fitzpatrick_scale:!1,category:"objects"},compass:{keywords:["magnetic","navigation","orienteering"],char:"\u{1f9ed}",fitzpatrick_scale:!1,category:"objects"},stopwatch:{keywords:["time","deadline"],char:"\u23f1",fitzpatrick_scale:!1,category:"objects"},timer_clock:{keywords:["alarm"],char:"\u23f2",fitzpatrick_scale:!1,category:"objects"},alarm_clock:{keywords:["time","wake"],char:"\u23f0",fitzpatrick_scale:!1,category:"objects"},mantelpiece_clock:{keywords:["time"],char:"\u{1f570}",fitzpatrick_scale:!1,category:"objects"},hourglass_flowing_sand:{keywords:["oldschool","time","countdown"],char:"\u23f3",fitzpatrick_scale:!1,category:"objects"},hourglass:{keywords:["time","clock","oldschool","limit","exam","quiz","test"],char:"\u231b",fitzpatrick_scale:!1,category:"objects"},satellite:{keywords:["communication","future","radio","space"],char:"\u{1f4e1}",fitzpatrick_scale:!1,category:"objects"},battery:{keywords:["power","energy","sustain"],char:"\u{1f50b}",fitzpatrick_scale:!1,category:"objects"},electric_plug:{keywords:["charger","power"],char:"\u{1f50c}",fitzpatrick_scale:!1,category:"objects"},bulb:{keywords:["light","electricity","idea"],char:"\u{1f4a1}",fitzpatrick_scale:!1,category:"objects"},flashlight:{keywords:["dark","camping","sight","night"],char:"\u{1f526}",fitzpatrick_scale:!1,category:"objects"},candle:{keywords:["fire","wax"],char:"\u{1f56f}",fitzpatrick_scale:!1,category:"objects"},fire_extinguisher:{keywords:["quench"],char:"\u{1f9ef}",fitzpatrick_scale:!1,category:"objects"},wastebasket:{keywords:["bin","trash","rubbish","garbage","toss"],char:"\u{1f5d1}",fitzpatrick_scale:!1,category:"objects"},oil_drum:{keywords:["barrell"],char:"\u{1f6e2}",fitzpatrick_scale:!1,category:"objects"},money_with_wings:{keywords:["dollar","bills","payment","sale"],char:"\u{1f4b8}",fitzpatrick_scale:!1,category:"objects"},dollar:{keywords:["money","sales","bill","currency"],char:"\u{1f4b5}",fitzpatrick_scale:!1,category:"objects"},yen:{keywords:["money","sales","japanese","dollar","currency"],char:"\u{1f4b4}",fitzpatrick_scale:!1,category:"objects"},euro:{keywords:["money","sales","dollar","currency"],char:"\u{1f4b6}",fitzpatrick_scale:!1,category:"objects"},pound:{keywords:["british","sterling","money","sales","bills","uk","england","currency"],char:"\u{1f4b7}",fitzpatrick_scale:!1,category:"objects"},moneybag:{keywords:["dollar","payment","coins","sale"],char:"\u{1f4b0}",fitzpatrick_scale:!1,category:"objects"},credit_card:{keywords:["money","sales","dollar","bill","payment","shopping"],char:"\u{1f4b3}",fitzpatrick_scale:!1,category:"objects"},gem:{keywords:["blue","ruby","diamond","jewelry"],char:"\u{1f48e}",fitzpatrick_scale:!1,category:"objects"},balance_scale:{keywords:["law","fairness","weight"],char:"\u2696",fitzpatrick_scale:!1,category:"objects"},toolbox:{keywords:["tools","diy","fix","maintainer","mechanic"],char:"\u{1f9f0}",fitzpatrick_scale:!1,category:"objects"},wrench:{keywords:["tools","diy","ikea","fix","maintainer"],char:"\u{1f527}",fitzpatrick_scale:!1,category:"objects"},hammer:{keywords:["tools","build","create"],char:"\u{1f528}",fitzpatrick_scale:!1,category:"objects"},hammer_and_pick:{keywords:["tools","build","create"],char:"\u2692",fitzpatrick_scale:!1,category:"objects"},hammer_and_wrench:{keywords:["tools","build","create"],char:"\u{1f6e0}",fitzpatrick_scale:!1,category:"objects"},pick:{keywords:["tools","dig"],char:"\u26cf",fitzpatrick_scale:!1,category:"objects"},nut_and_bolt:{keywords:["handy","tools","fix"],char:"\u{1f529}",fitzpatrick_scale:!1,category:"objects"},gear:{keywords:["cog"],char:"\u2699",fitzpatrick_scale:!1,category:"objects"},brick:{keywords:["bricks"],char:"\u{1f9f1}",fitzpatrick_scale:!1,category:"objects"},chains:{keywords:["lock","arrest"],char:"\u26d3",fitzpatrick_scale:!1,category:"objects"},magnet:{keywords:["attraction","magnetic"],char:"\u{1f9f2}",fitzpatrick_scale:!1,category:"objects"},gun:{keywords:["violence","weapon","pistol","revolver"],char:"\u{1f52b}",fitzpatrick_scale:!1,category:"objects"},bomb:{keywords:["boom","explode","explosion","terrorism"],char:"\u{1f4a3}",fitzpatrick_scale:!1,category:"objects"},firecracker:{keywords:["dynamite","boom","explode","explosion","explosive"],char:"\u{1f9e8}",fitzpatrick_scale:!1,category:"objects"},hocho:{keywords:["knife","blade","cutlery","kitchen","weapon"],char:"\u{1f52a}",fitzpatrick_scale:!1,category:"objects"},dagger:{keywords:["weapon"],char:"\u{1f5e1}",fitzpatrick_scale:!1,category:"objects"},crossed_swords:{keywords:["weapon"],char:"\u2694",fitzpatrick_scale:!1,category:"objects"},shield:{keywords:["protection","security"],char:"\u{1f6e1}",fitzpatrick_scale:!1,category:"objects"},smoking:{keywords:["kills","tobacco","cigarette","joint","smoke"],char:"\u{1f6ac}",fitzpatrick_scale:!1,category:"objects"},skull_and_crossbones:{keywords:["poison","danger","deadly","scary","death","pirate","evil"],char:"\u2620",fitzpatrick_scale:!1,category:"objects"},coffin:{keywords:["vampire","dead","die","death","rip","graveyard","cemetery","casket","funeral","box"],char:"\u26b0",fitzpatrick_scale:!1,category:"objects"},funeral_urn:{keywords:["dead","die","death","rip","ashes"],char:"\u26b1",fitzpatrick_scale:!1,category:"objects"},amphora:{keywords:["vase","jar"],char:"\u{1f3fa}",fitzpatrick_scale:!1,category:"objects"},crystal_ball:{keywords:["disco","party","magic","circus","fortune_teller"],char:"\u{1f52e}",fitzpatrick_scale:!1,category:"objects"},prayer_beads:{keywords:["dhikr","religious"],char:"\u{1f4ff}",fitzpatrick_scale:!1,category:"objects"},nazar_amulet:{keywords:["bead","charm"],char:"\u{1f9ff}",fitzpatrick_scale:!1,category:"objects"},barber:{keywords:["hair","salon","style"],char:"\u{1f488}",fitzpatrick_scale:!1,category:"objects"},alembic:{keywords:["distilling","science","experiment","chemistry"],char:"\u2697",fitzpatrick_scale:!1,category:"objects"},telescope:{keywords:["stars","space","zoom","science","astronomy"],char:"\u{1f52d}",fitzpatrick_scale:!1,category:"objects"},microscope:{keywords:["laboratory","experiment","zoomin","science","study"],char:"\u{1f52c}",fitzpatrick_scale:!1,category:"objects"},hole:{keywords:["embarrassing"],char:"\u{1f573}",fitzpatrick_scale:!1,category:"objects"},pill:{keywords:["health","medicine","doctor","pharmacy","drug"],char:"\u{1f48a}",fitzpatrick_scale:!1,category:"objects"},syringe:{keywords:["health","hospital","drugs","blood","medicine","needle","doctor","nurse"],char:"\u{1f489}",fitzpatrick_scale:!1,category:"objects"},dna:{keywords:["biologist","genetics","life"],char:"\u{1f9ec}",fitzpatrick_scale:!1,category:"objects"},microbe:{keywords:["amoeba","bacteria","germs"],char:"\u{1f9a0}",fitzpatrick_scale:!1,category:"objects"},petri_dish:{keywords:["bacteria","biology","culture","lab"],char:"\u{1f9eb}",fitzpatrick_scale:!1,category:"objects"},test_tube:{keywords:["chemistry","experiment","lab","science"],char:"\u{1f9ea}",fitzpatrick_scale:!1,category:"objects"},thermometer:{keywords:["weather","temperature","hot","cold"],char:"\u{1f321}",fitzpatrick_scale:!1,category:"objects"},broom:{keywords:["cleaning","sweeping","witch"],char:"\u{1f9f9}",fitzpatrick_scale:!1,category:"objects"},basket:{keywords:["laundry"],char:"\u{1f9fa}",fitzpatrick_scale:!1,category:"objects"},toilet_paper:{keywords:["roll"],char:"\u{1f9fb}",fitzpatrick_scale:!1,category:"objects"},label:{keywords:["sale","tag"],char:"\u{1f3f7}",fitzpatrick_scale:!1,category:"objects"},bookmark:{keywords:["favorite","label","save"],char:"\u{1f516}",fitzpatrick_scale:!1,category:"objects"},toilet:{keywords:["restroom","wc","washroom","bathroom","potty"],char:"\u{1f6bd}",fitzpatrick_scale:!1,category:"objects"},shower:{keywords:["clean","water","bathroom"],char:"\u{1f6bf}",fitzpatrick_scale:!1,category:"objects"},bathtub:{keywords:["clean","shower","bathroom"],char:"\u{1f6c1}",fitzpatrick_scale:!1,category:"objects"},soap:{keywords:["bar","bathing","cleaning","lather"],char:"\u{1f9fc}",fitzpatrick_scale:!1,category:"objects"},sponge:{keywords:["absorbing","cleaning","porous"],char:"\u{1f9fd}",fitzpatrick_scale:!1,category:"objects"},lotion_bottle:{keywords:["moisturizer","sunscreen"],char:"\u{1f9f4}",fitzpatrick_scale:!1,category:"objects"},key:{keywords:["lock","door","password"],char:"\u{1f511}",fitzpatrick_scale:!1,category:"objects"},old_key:{keywords:["lock","door","password"],char:"\u{1f5dd}",fitzpatrick_scale:!1,category:"objects"},couch_and_lamp:{keywords:["read","chill"],char:"\u{1f6cb}",fitzpatrick_scale:!1,category:"objects"},sleeping_bed:{keywords:["bed","rest"],char:"\u{1f6cc}",fitzpatrick_scale:!0,category:"objects"},bed:{keywords:["sleep","rest"],char:"\u{1f6cf}",fitzpatrick_scale:!1,category:"objects"},door:{keywords:["house","entry","exit"],char:"\u{1f6aa}",fitzpatrick_scale:!1,category:"objects"},bellhop_bell:{keywords:["service"],char:"\u{1f6ce}",fitzpatrick_scale:!1,category:"objects"},teddy_bear:{keywords:["plush","stuffed"],char:"\u{1f9f8}",fitzpatrick_scale:!1,category:"objects"},framed_picture:{keywords:["photography"],char:"\u{1f5bc}",fitzpatrick_scale:!1,category:"objects"},world_map:{keywords:["location","direction"],char:"\u{1f5fa}",fitzpatrick_scale:!1,category:"objects"},parasol_on_ground:{keywords:["weather","summer"],char:"\u26f1",fitzpatrick_scale:!1,category:"objects"},moyai:{keywords:["rock","easter island","moai"],char:"\u{1f5ff}",fitzpatrick_scale:!1,category:"objects"},shopping:{keywords:["mall","buy","purchase"],char:"\u{1f6cd}",fitzpatrick_scale:!1,category:"objects"},shopping_cart:{keywords:["trolley"],char:"\u{1f6d2}",fitzpatrick_scale:!1,category:"objects"},balloon:{keywords:["party","celebration","birthday","circus"],char:"\u{1f388}",fitzpatrick_scale:!1,category:"objects"},flags:{keywords:["fish","japanese","koinobori","carp","banner"],char:"\u{1f38f}",fitzpatrick_scale:!1,category:"objects"},ribbon:{keywords:["decoration","pink","girl","bowtie"],char:"\u{1f380}",fitzpatrick_scale:!1,category:"objects"},gift:{keywords:["present","birthday","christmas","xmas"],char:"\u{1f381}",fitzpatrick_scale:!1,category:"objects"},confetti_ball:{keywords:["festival","party","birthday","circus"],char:"\u{1f38a}",fitzpatrick_scale:!1,category:"objects"},tada:{keywords:["party","congratulations","birthday","magic","circus","celebration"],char:"\u{1f389}",fitzpatrick_scale:!1,category:"objects"},dolls:{keywords:["japanese","toy","kimono"],char:"\u{1f38e}",fitzpatrick_scale:!1,category:"objects"},wind_chime:{keywords:["nature","ding","spring","bell"],char:"\u{1f390}",fitzpatrick_scale:!1,category:"objects"},crossed_flags:{keywords:["japanese","nation","country","border"],char:"\u{1f38c}",fitzpatrick_scale:!1,category:"objects"},izakaya_lantern:{keywords:["light","paper","halloween","spooky"],char:"\u{1f3ee}",fitzpatrick_scale:!1,category:"objects"},red_envelope:{keywords:["gift"],char:"\u{1f9e7}",fitzpatrick_scale:!1,category:"objects"},email:{keywords:["letter","postal","inbox","communication"],char:"\u2709\ufe0f",fitzpatrick_scale:!1,category:"objects"},envelope_with_arrow:{keywords:["email","communication"],char:"\u{1f4e9}",fitzpatrick_scale:!1,category:"objects"},incoming_envelope:{keywords:["email","inbox"],char:"\u{1f4e8}",fitzpatrick_scale:!1,category:"objects"},"e-mail":{keywords:["communication","inbox"],char:"\u{1f4e7}",fitzpatrick_scale:!1,category:"objects"},love_letter:{keywords:["email","like","affection","envelope","valentines"],char:"\u{1f48c}",fitzpatrick_scale:!1,category:"objects"},postbox:{keywords:["email","letter","envelope"],char:"\u{1f4ee}",fitzpatrick_scale:!1,category:"objects"},mailbox_closed:{keywords:["email","communication","inbox"],char:"\u{1f4ea}",fitzpatrick_scale:!1,category:"objects"},mailbox:{keywords:["email","inbox","communication"],char:"\u{1f4eb}",fitzpatrick_scale:!1,category:"objects"},mailbox_with_mail:{keywords:["email","inbox","communication"],char:"\u{1f4ec}",fitzpatrick_scale:!1,category:"objects"},mailbox_with_no_mail:{keywords:["email","inbox"],char:"\u{1f4ed}",fitzpatrick_scale:!1,category:"objects"},package:{keywords:["mail","gift","cardboard","box","moving"],char:"\u{1f4e6}",fitzpatrick_scale:!1,category:"objects"},postal_horn:{keywords:["instrument","music"],char:"\u{1f4ef}",fitzpatrick_scale:!1,category:"objects"},inbox_tray:{keywords:["email","documents"],char:"\u{1f4e5}",fitzpatrick_scale:!1,category:"objects"},outbox_tray:{keywords:["inbox","email"],char:"\u{1f4e4}",fitzpatrick_scale:!1,category:"objects"},scroll:{keywords:["documents","ancient","history","paper"],char:"\u{1f4dc}",fitzpatrick_scale:!1,category:"objects"},page_with_curl:{keywords:["documents","office","paper"],char:"\u{1f4c3}",fitzpatrick_scale:!1,category:"objects"},bookmark_tabs:{keywords:["favorite","save","order","tidy"],char:"\u{1f4d1}",fitzpatrick_scale:!1,category:"objects"},receipt:{keywords:["accounting","expenses"],char:"\u{1f9fe}",fitzpatrick_scale:!1,category:"objects"},bar_chart:{keywords:["graph","presentation","stats"],char:"\u{1f4ca}",fitzpatrick_scale:!1,category:"objects"},chart_with_upwards_trend:{keywords:["graph","presentation","stats","recovery","business","economics","money","sales","good","success"],char:"\u{1f4c8}",fitzpatrick_scale:!1,category:"objects"},chart_with_downwards_trend:{keywords:["graph","presentation","stats","recession","business","economics","money","sales","bad","failure"],char:"\u{1f4c9}",fitzpatrick_scale:!1,category:"objects"},page_facing_up:{keywords:["documents","office","paper","information"],char:"\u{1f4c4}",fitzpatrick_scale:!1,category:"objects"},date:{keywords:["calendar","schedule"],char:"\u{1f4c5}",fitzpatrick_scale:!1,category:"objects"},calendar:{keywords:["schedule","date","planning"],char:"\u{1f4c6}",fitzpatrick_scale:!1,category:"objects"},spiral_calendar:{keywords:["date","schedule","planning"],char:"\u{1f5d3}",fitzpatrick_scale:!1,category:"objects"},card_index:{keywords:["business","stationery"],char:"\u{1f4c7}",fitzpatrick_scale:!1,category:"objects"},card_file_box:{keywords:["business","stationery"],char:"\u{1f5c3}",fitzpatrick_scale:!1,category:"objects"},ballot_box:{keywords:["election","vote"],char:"\u{1f5f3}",fitzpatrick_scale:!1,category:"objects"},file_cabinet:{keywords:["filing","organizing"],char:"\u{1f5c4}",fitzpatrick_scale:!1,category:"objects"},clipboard:{keywords:["stationery","documents"],char:"\u{1f4cb}",fitzpatrick_scale:!1,category:"objects"},spiral_notepad:{keywords:["memo","stationery"],char:"\u{1f5d2}",fitzpatrick_scale:!1,category:"objects"},file_folder:{keywords:["documents","business","office"],char:"\u{1f4c1}",fitzpatrick_scale:!1,category:"objects"},open_file_folder:{keywords:["documents","load"],char:"\u{1f4c2}",fitzpatrick_scale:!1,category:"objects"},card_index_dividers:{keywords:["organizing","business","stationery"],char:"\u{1f5c2}",fitzpatrick_scale:!1,category:"objects"},newspaper_roll:{keywords:["press","headline"],char:"\u{1f5de}",fitzpatrick_scale:!1,category:"objects"},newspaper:{keywords:["press","headline"],char:"\u{1f4f0}",fitzpatrick_scale:!1,category:"objects"},notebook:{keywords:["stationery","record","notes","paper","study"],char:"\u{1f4d3}",fitzpatrick_scale:!1,category:"objects"},closed_book:{keywords:["read","library","knowledge","textbook","learn"],char:"\u{1f4d5}",fitzpatrick_scale:!1,category:"objects"},green_book:{keywords:["read","library","knowledge","study"],char:"\u{1f4d7}",fitzpatrick_scale:!1,category:"objects"},blue_book:{keywords:["read","library","knowledge","learn","study"],char:"\u{1f4d8}",fitzpatrick_scale:!1,category:"objects"},orange_book:{keywords:["read","library","knowledge","textbook","study"],char:"\u{1f4d9}",fitzpatrick_scale:!1,category:"objects"},notebook_with_decorative_cover:{keywords:["classroom","notes","record","paper","study"],char:"\u{1f4d4}",fitzpatrick_scale:!1,category:"objects"},ledger:{keywords:["notes","paper"],char:"\u{1f4d2}",fitzpatrick_scale:!1,category:"objects"},books:{keywords:["literature","library","study"],char:"\u{1f4da}",fitzpatrick_scale:!1,category:"objects"},open_book:{keywords:["book","read","library","knowledge","literature","learn","study"],char:"\u{1f4d6}",fitzpatrick_scale:!1,category:"objects"},safety_pin:{keywords:["diaper"],char:"\u{1f9f7}",fitzpatrick_scale:!1,category:"objects"},link:{keywords:["rings","url"],char:"\u{1f517}",fitzpatrick_scale:!1,category:"objects"},paperclip:{keywords:["documents","stationery"],char:"\u{1f4ce}",fitzpatrick_scale:!1,category:"objects"},paperclips:{keywords:["documents","stationery"],char:"\u{1f587}",fitzpatrick_scale:!1,category:"objects"},scissors:{keywords:["stationery","cut"],char:"\u2702\ufe0f",fitzpatrick_scale:!1,category:"objects"},triangular_ruler:{keywords:["stationery","math","architect","sketch"],char:"\u{1f4d0}",fitzpatrick_scale:!1,category:"objects"},straight_ruler:{keywords:["stationery","calculate","length","math","school","drawing","architect","sketch"],char:"\u{1f4cf}",fitzpatrick_scale:!1,category:"objects"},abacus:{keywords:["calculation"],char:"\u{1f9ee}",fitzpatrick_scale:!1,category:"objects"},pushpin:{keywords:["stationery","mark","here"],char:"\u{1f4cc}",fitzpatrick_scale:!1,category:"objects"},round_pushpin:{keywords:["stationery","location","map","here"],char:"\u{1f4cd}",fitzpatrick_scale:!1,category:"objects"},triangular_flag_on_post:{keywords:["mark","milestone","place"],char:"\u{1f6a9}",fitzpatrick_scale:!1,category:"objects"},white_flag:{keywords:["losing","loser","lost","surrender","give up","fail"],char:"\u{1f3f3}",fitzpatrick_scale:!1,category:"objects"},black_flag:{keywords:["pirate"],char:"\u{1f3f4}",fitzpatrick_scale:!1,category:"objects"},rainbow_flag:{keywords:["flag","rainbow","pride","gay","lgbt","glbt","queer","homosexual","lesbian","bisexual","transgender"],char:"\u{1f3f3}\ufe0f\u200d\u{1f308}",fitzpatrick_scale:!1,category:"objects"},closed_lock_with_key:{keywords:["security","privacy"],char:"\u{1f510}",fitzpatrick_scale:!1,category:"objects"},lock:{keywords:["security","password","padlock"],char:"\u{1f512}",fitzpatrick_scale:!1,category:"objects"},unlock:{keywords:["privacy","security"],char:"\u{1f513}",fitzpatrick_scale:!1,category:"objects"},lock_with_ink_pen:{keywords:["security","secret"],char:"\u{1f50f}",fitzpatrick_scale:!1,category:"objects"},pen:{keywords:["stationery","writing","write"],char:"\u{1f58a}",fitzpatrick_scale:!1,category:"objects"},fountain_pen:{keywords:["stationery","writing","write"],char:"\u{1f58b}",fitzpatrick_scale:!1,category:"objects"},black_nib:{keywords:["pen","stationery","writing","write"],char:"\u2712\ufe0f",fitzpatrick_scale:!1,category:"objects"},memo:{keywords:["write","documents","stationery","pencil","paper","writing","legal","exam","quiz","test","study","compose"],char:"\u{1f4dd}",fitzpatrick_scale:!1,category:"objects"},pencil2:{keywords:["stationery","write","paper","writing","school","study"],char:"\u270f\ufe0f",fitzpatrick_scale:!1,category:"objects"},crayon:{keywords:["drawing","creativity"],char:"\u{1f58d}",fitzpatrick_scale:!1,category:"objects"},paintbrush:{keywords:["drawing","creativity","art"],char:"\u{1f58c}",fitzpatrick_scale:!1,category:"objects"},mag:{keywords:["search","zoom","find","detective"],char:"\u{1f50d}",fitzpatrick_scale:!1,category:"objects"},mag_right:{keywords:["search","zoom","find","detective"],char:"\u{1f50e}",fitzpatrick_scale:!1,category:"objects"},heart:{keywords:["love","like","valentines"],char:"\u2764\ufe0f",fitzpatrick_scale:!1,category:"symbols"},orange_heart:{keywords:["love","like","affection","valentines"],char:"\u{1f9e1}",fitzpatrick_scale:!1,category:"symbols"},yellow_heart:{keywords:["love","like","affection","valentines"],char:"\u{1f49b}",fitzpatrick_scale:!1,category:"symbols"},green_heart:{keywords:["love","like","affection","valentines"],char:"\u{1f49a}",fitzpatrick_scale:!1,category:"symbols"},blue_heart:{keywords:["love","like","affection","valentines"],char:"\u{1f499}",fitzpatrick_scale:!1,category:"symbols"},purple_heart:{keywords:["love","like","affection","valentines"],char:"\u{1f49c}",fitzpatrick_scale:!1,category:"symbols"},black_heart:{keywords:["evil"],char:"\u{1f5a4}",fitzpatrick_scale:!1,category:"symbols"},broken_heart:{keywords:["sad","sorry","break","heart","heartbreak"],char:"\u{1f494}",fitzpatrick_scale:!1,category:"symbols"},heavy_heart_exclamation:{keywords:["decoration","love"],char:"\u2763",fitzpatrick_scale:!1,category:"symbols"},two_hearts:{keywords:["love","like","affection","valentines","heart"],char:"\u{1f495}",fitzpatrick_scale:!1,category:"symbols"},revolving_hearts:{keywords:["love","like","affection","valentines"],char:"\u{1f49e}",fitzpatrick_scale:!1,category:"symbols"},heartbeat:{keywords:["love","like","affection","valentines","pink","heart"],char:"\u{1f493}",fitzpatrick_scale:!1,category:"symbols"},heartpulse:{keywords:["like","love","affection","valentines","pink"],char:"\u{1f497}",fitzpatrick_scale:!1,category:"symbols"},sparkling_heart:{keywords:["love","like","affection","valentines"],char:"\u{1f496}",fitzpatrick_scale:!1,category:"symbols"},cupid:{keywords:["love","like","heart","affection","valentines"],char:"\u{1f498}",fitzpatrick_scale:!1,category:"symbols"},gift_heart:{keywords:["love","valentines"],char:"\u{1f49d}",fitzpatrick_scale:!1,category:"symbols"},heart_decoration:{keywords:["purple-square","love","like"],char:"\u{1f49f}",fitzpatrick_scale:!1,category:"symbols"},peace_symbol:{keywords:["hippie"],char:"\u262e",fitzpatrick_scale:!1,category:"symbols"},latin_cross:{keywords:["christianity"],char:"\u271d",fitzpatrick_scale:!1,category:"symbols"},star_and_crescent:{keywords:["islam"],char:"\u262a",fitzpatrick_scale:!1,category:"symbols"},om:{keywords:["hinduism","buddhism","sikhism","jainism"],char:"\u{1f549}",fitzpatrick_scale:!1,category:"symbols"},wheel_of_dharma:{keywords:["hinduism","buddhism","sikhism","jainism"],char:"\u2638",fitzpatrick_scale:!1,category:"symbols"},star_of_david:{keywords:["judaism"],char:"\u2721",fitzpatrick_scale:!1,category:"symbols"},six_pointed_star:{keywords:["purple-square","religion","jewish","hexagram"],char:"\u{1f52f}",fitzpatrick_scale:!1,category:"symbols"},menorah:{keywords:["hanukkah","candles","jewish"],char:"\u{1f54e}",fitzpatrick_scale:!1,category:"symbols"},yin_yang:{keywords:["balance"],char:"\u262f",fitzpatrick_scale:!1,category:"symbols"},orthodox_cross:{keywords:["suppedaneum","religion"],char:"\u2626",fitzpatrick_scale:!1,category:"symbols"},place_of_worship:{keywords:["religion","church","temple","prayer"],char:"\u{1f6d0}",fitzpatrick_scale:!1,category:"symbols"},ophiuchus:{keywords:["sign","purple-square","constellation","astrology"],char:"\u26ce",fitzpatrick_scale:!1,category:"symbols"},aries:{keywords:["sign","purple-square","zodiac","astrology"],char:"\u2648",fitzpatrick_scale:!1,category:"symbols"},taurus:{keywords:["purple-square","sign","zodiac","astrology"],char:"\u2649",fitzpatrick_scale:!1,category:"symbols"},gemini:{keywords:["sign","zodiac","purple-square","astrology"],char:"\u264a",fitzpatrick_scale:!1,category:"symbols"},cancer:{keywords:["sign","zodiac","purple-square","astrology"],char:"\u264b",fitzpatrick_scale:!1,category:"symbols"},leo:{keywords:["sign","purple-square","zodiac","astrology"],char:"\u264c",fitzpatrick_scale:!1,category:"symbols"},virgo:{keywords:["sign","zodiac","purple-square","astrology"],char:"\u264d",fitzpatrick_scale:!1,category:"symbols"},libra:{keywords:["sign","purple-square","zodiac","astrology"],char:"\u264e",fitzpatrick_scale:!1,category:"symbols"},scorpius:{keywords:["sign","zodiac","purple-square","astrology","scorpio"],char:"\u264f",fitzpatrick_scale:!1,category:"symbols"},sagittarius:{keywords:["sign","zodiac","purple-square","astrology"],char:"\u2650",fitzpatrick_scale:!1,category:"symbols"},capricorn:{keywords:["sign","zodiac","purple-square","astrology"],char:"\u2651",fitzpatrick_scale:!1,category:"symbols"},aquarius:{keywords:["sign","purple-square","zodiac","astrology"],char:"\u2652",fitzpatrick_scale:!1,category:"symbols"},pisces:{keywords:["purple-square","sign","zodiac","astrology"],char:"\u2653",fitzpatrick_scale:!1,category:"symbols"},id:{keywords:["purple-square","words"],char:"\u{1f194}",fitzpatrick_scale:!1,category:"symbols"},atom_symbol:{keywords:["science","physics","chemistry"],char:"\u269b",fitzpatrick_scale:!1,category:"symbols"},u7a7a:{keywords:["kanji","japanese","chinese","empty","sky","blue-square"],char:"\u{1f233}",fitzpatrick_scale:!1,category:"symbols"},u5272:{keywords:["cut","divide","chinese","kanji","pink-square"],char:"\u{1f239}",fitzpatrick_scale:!1,category:"symbols"},radioactive:{keywords:["nuclear","danger"],char:"\u2622",fitzpatrick_scale:!1,category:"symbols"},biohazard:{keywords:["danger"],char:"\u2623",fitzpatrick_scale:!1,category:"symbols"},mobile_phone_off:{keywords:["mute","orange-square","silence","quiet"],char:"\u{1f4f4}",fitzpatrick_scale:!1,category:"symbols"},vibration_mode:{keywords:["orange-square","phone"],char:"\u{1f4f3}",fitzpatrick_scale:!1,category:"symbols"},u6709:{keywords:["orange-square","chinese","have","kanji"],char:"\u{1f236}",fitzpatrick_scale:!1,category:"symbols"},u7121:{keywords:["nothing","chinese","kanji","japanese","orange-square"],char:"\u{1f21a}",fitzpatrick_scale:!1,category:"symbols"},u7533:{keywords:["chinese","japanese","kanji","orange-square"],char:"\u{1f238}",fitzpatrick_scale:!1,category:"symbols"},u55b6:{keywords:["japanese","opening hours","orange-square"],char:"\u{1f23a}",fitzpatrick_scale:!1,category:"symbols"},u6708:{keywords:["chinese","month","moon","japanese","orange-square","kanji"],char:"\u{1f237}\ufe0f",fitzpatrick_scale:!1,category:"symbols"},eight_pointed_black_star:{keywords:["orange-square","shape","polygon"],char:"\u2734\ufe0f",fitzpatrick_scale:!1,category:"symbols"},vs:{keywords:["words","orange-square"],char:"\u{1f19a}",fitzpatrick_scale:!1,category:"symbols"},accept:{keywords:["ok","good","chinese","kanji","agree","yes","orange-circle"],char:"\u{1f251}",fitzpatrick_scale:!1,category:"symbols"},white_flower:{keywords:["japanese","spring"],char:"\u{1f4ae}",fitzpatrick_scale:!1,category:"symbols"},ideograph_advantage:{keywords:["chinese","kanji","obtain","get","circle"],char:"\u{1f250}",fitzpatrick_scale:!1,category:"symbols"},secret:{keywords:["privacy","chinese","sshh","kanji","red-circle"],char:"\u3299\ufe0f",fitzpatrick_scale:!1,category:"symbols"},congratulations:{keywords:["chinese","kanji","japanese","red-circle"],char:"\u3297\ufe0f",fitzpatrick_scale:!1,category:"symbols"},u5408:{keywords:["japanese","chinese","join","kanji","red-square"],char:"\u{1f234}",fitzpatrick_scale:!1,category:"symbols"},u6e80:{keywords:["full","chinese","japanese","red-square","kanji"],char:"\u{1f235}",fitzpatrick_scale:!1,category:"symbols"},u7981:{keywords:["kanji","japanese","chinese","forbidden","limit","restricted","red-square"],char:"\u{1f232}",fitzpatrick_scale:!1,category:"symbols"},a:{keywords:["red-square","alphabet","letter"],char:"\u{1f170}\ufe0f",fitzpatrick_scale:!1,category:"symbols"},b:{keywords:["red-square","alphabet","letter"],char:"\u{1f171}\ufe0f",fitzpatrick_scale:!1,category:"symbols"},ab:{keywords:["red-square","alphabet"],char:"\u{1f18e}",fitzpatrick_scale:!1,category:"symbols"},cl:{keywords:["alphabet","words","red-square"],char:"\u{1f191}",fitzpatrick_scale:!1,category:"symbols"},o2:{keywords:["alphabet","red-square","letter"],char:"\u{1f17e}\ufe0f",fitzpatrick_scale:!1,category:"symbols"},sos:{keywords:["help","red-square","words","emergency","911"],char:"\u{1f198}",fitzpatrick_scale:!1,category:"symbols"},no_entry:{keywords:["limit","security","privacy","bad","denied","stop","circle"],char:"\u26d4",fitzpatrick_scale:!1,category:"symbols"},name_badge:{keywords:["fire","forbid"],char:"\u{1f4db}",fitzpatrick_scale:!1,category:"symbols"},no_entry_sign:{keywords:["forbid","stop","limit","denied","disallow","circle"],char:"\u{1f6ab}",fitzpatrick_scale:!1,category:"symbols"},x:{keywords:["no","delete","remove","cancel","red"],char:"\u274c",fitzpatrick_scale:!1,category:"symbols"},o:{keywords:["circle","round"],char:"\u2b55",fitzpatrick_scale:!1,category:"symbols"},stop_sign:{keywords:["stop"],char:"\u{1f6d1}",fitzpatrick_scale:!1,category:"symbols"},anger:{keywords:["angry","mad"],char:"\u{1f4a2}",fitzpatrick_scale:!1,category:"symbols"},hotsprings:{keywords:["bath","warm","relax"],char:"\u2668\ufe0f",fitzpatrick_scale:!1,category:"symbols"},no_pedestrians:{keywords:["rules","crossing","walking","circle"],char:"\u{1f6b7}",fitzpatrick_scale:!1,category:"symbols"},do_not_litter:{keywords:["trash","bin","garbage","circle"],char:"\u{1f6af}",fitzpatrick_scale:!1,category:"symbols"},no_bicycles:{keywords:["cyclist","prohibited","circle"],char:"\u{1f6b3}",fitzpatrick_scale:!1,category:"symbols"},"non-potable_water":{keywords:["drink","faucet","tap","circle"],char:"\u{1f6b1}",fitzpatrick_scale:!1,category:"symbols"},underage:{keywords:["18","drink","pub","night","minor","circle"],char:"\u{1f51e}",fitzpatrick_scale:!1,category:"symbols"},no_mobile_phones:{keywords:["iphone","mute","circle"],char:"\u{1f4f5}",fitzpatrick_scale:!1,category:"symbols"},exclamation:{keywords:["heavy_exclamation_mark","danger","surprise","punctuation","wow","warning"],char:"\u2757",fitzpatrick_scale:!1,category:"symbols"},grey_exclamation:{keywords:["surprise","punctuation","gray","wow","warning"],char:"\u2755",fitzpatrick_scale:!1,category:"symbols"},question:{keywords:["doubt","confused"],char:"\u2753",fitzpatrick_scale:!1,category:"symbols"},grey_question:{keywords:["doubts","gray","huh","confused"],char:"\u2754",fitzpatrick_scale:!1,category:"symbols"},bangbang:{keywords:["exclamation","surprise"],char:"\u203c\ufe0f",fitzpatrick_scale:!1,category:"symbols"},interrobang:{keywords:["wat","punctuation","surprise"],char:"\u2049\ufe0f",fitzpatrick_scale:!1,category:"symbols"},100:{keywords:["score","perfect","numbers","century","exam","quiz","test","pass","hundred"],char:"\u{1f4af}",fitzpatrick_scale:!1,category:"symbols"},low_brightness:{keywords:["sun","afternoon","warm","summer"],char:"\u{1f505}",fitzpatrick_scale:!1,category:"symbols"},high_brightness:{keywords:["sun","light"],char:"\u{1f506}",fitzpatrick_scale:!1,category:"symbols"},trident:{keywords:["weapon","spear"],char:"\u{1f531}",fitzpatrick_scale:!1,category:"symbols"},fleur_de_lis:{keywords:["decorative","scout"],char:"\u269c",fitzpatrick_scale:!1,category:"symbols"},part_alternation_mark:{keywords:["graph","presentation","stats","business","economics","bad"],char:"\u303d\ufe0f",fitzpatrick_scale:!1,category:"symbols"},warning:{keywords:["exclamation","wip","alert","error","problem","issue"],char:"\u26a0\ufe0f",fitzpatrick_scale:!1,category:"symbols"},children_crossing:{keywords:["school","warning","danger","sign","driving","yellow-diamond"],char:"\u{1f6b8}",fitzpatrick_scale:!1,category:"symbols"},beginner:{keywords:["badge","shield"],char:"\u{1f530}",fitzpatrick_scale:!1,category:"symbols"},recycle:{keywords:["arrow","environment","garbage","trash"],char:"\u267b\ufe0f",fitzpatrick_scale:!1,category:"symbols"},u6307:{keywords:["chinese","point","green-square","kanji"],char:"\u{1f22f}",fitzpatrick_scale:!1,category:"symbols"},chart:{keywords:["green-square","graph","presentation","stats"],char:"\u{1f4b9}",fitzpatrick_scale:!1,category:"symbols"},sparkle:{keywords:["stars","green-square","awesome","good","fireworks"],char:"\u2747\ufe0f",fitzpatrick_scale:!1,category:"symbols"},eight_spoked_asterisk:{keywords:["star","sparkle","green-square"],char:"\u2733\ufe0f",fitzpatrick_scale:!1,category:"symbols"},negative_squared_cross_mark:{keywords:["x","green-square","no","deny"],char:"\u274e",fitzpatrick_scale:!1,category:"symbols"},white_check_mark:{keywords:["green-square","ok","agree","vote","election","answer","tick"],char:"\u2705",fitzpatrick_scale:!1,category:"symbols"},diamond_shape_with_a_dot_inside:{keywords:["jewel","blue","gem","crystal","fancy"],char:"\u{1f4a0}",fitzpatrick_scale:!1,category:"symbols"},cyclone:{keywords:["weather","swirl","blue","cloud","vortex","spiral","whirlpool","spin","tornado","hurricane","typhoon"],char:"\u{1f300}",fitzpatrick_scale:!1,category:"symbols"},loop:{keywords:["tape","cassette"],char:"\u27bf",fitzpatrick_scale:!1,category:"symbols"},globe_with_meridians:{keywords:["earth","international","world","internet","interweb","i18n"],char:"\u{1f310}",fitzpatrick_scale:!1,category:"symbols"},m:{keywords:["alphabet","blue-circle","letter"],char:"\u24c2\ufe0f",fitzpatrick_scale:!1,category:"symbols"},atm:{keywords:["money","sales","cash","blue-square","payment","bank"],char:"\u{1f3e7}",fitzpatrick_scale:!1,category:"symbols"},sa:{keywords:["japanese","blue-square","katakana"],char:"\u{1f202}\ufe0f",fitzpatrick_scale:!1,category:"symbols"},passport_control:{keywords:["custom","blue-square"],char:"\u{1f6c2}",fitzpatrick_scale:!1,category:"symbols"},customs:{keywords:["passport","border","blue-square"],char:"\u{1f6c3}",fitzpatrick_scale:!1,category:"symbols"},baggage_claim:{keywords:["blue-square","airport","transport"],char:"\u{1f6c4}",fitzpatrick_scale:!1,category:"symbols"},left_luggage:{keywords:["blue-square","travel"],char:"\u{1f6c5}",fitzpatrick_scale:!1,category:"symbols"},wheelchair:{keywords:["blue-square","disabled","a11y","accessibility"],char:"\u267f",fitzpatrick_scale:!1,category:"symbols"},no_smoking:{keywords:["cigarette","blue-square","smell","smoke"],char:"\u{1f6ad}",fitzpatrick_scale:!1,category:"symbols"},wc:{keywords:["toilet","restroom","blue-square"],char:"\u{1f6be}",fitzpatrick_scale:!1,category:"symbols"},parking:{keywords:["cars","blue-square","alphabet","letter"],char:"\u{1f17f}\ufe0f",fitzpatrick_scale:!1,category:"symbols"},potable_water:{keywords:["blue-square","liquid","restroom","cleaning","faucet"],char:"\u{1f6b0}",fitzpatrick_scale:!1,category:"symbols"},mens:{keywords:["toilet","restroom","wc","blue-square","gender","male"],char:"\u{1f6b9}",fitzpatrick_scale:!1,category:"symbols"},womens:{keywords:["purple-square","woman","female","toilet","loo","restroom","gender"],char:"\u{1f6ba}",fitzpatrick_scale:!1,category:"symbols"},baby_symbol:{keywords:["orange-square","child"],char:"\u{1f6bc}",fitzpatrick_scale:!1,category:"symbols"},restroom:{keywords:["blue-square","toilet","refresh","wc","gender"],char:"\u{1f6bb}",fitzpatrick_scale:!1,category:"symbols"},put_litter_in_its_place:{keywords:["blue-square","sign","human","info"],char:"\u{1f6ae}",fitzpatrick_scale:!1,category:"symbols"},cinema:{keywords:["blue-square","record","film","movie","curtain","stage","theater"],char:"\u{1f3a6}",fitzpatrick_scale:!1,category:"symbols"},signal_strength:{keywords:["blue-square","reception","phone","internet","connection","wifi","bluetooth","bars"],char:"\u{1f4f6}",fitzpatrick_scale:!1,category:"symbols"},koko:{keywords:["blue-square","here","katakana","japanese","destination"],char:"\u{1f201}",fitzpatrick_scale:!1,category:"symbols"},ng:{keywords:["blue-square","words","shape","icon"],char:"\u{1f196}",fitzpatrick_scale:!1,category:"symbols"},ok:{keywords:["good","agree","yes","blue-square"],char:"\u{1f197}",fitzpatrick_scale:!1,category:"symbols"},up:{keywords:["blue-square","above","high"],char:"\u{1f199}",fitzpatrick_scale:!1,category:"symbols"},cool:{keywords:["words","blue-square"],char:"\u{1f192}",fitzpatrick_scale:!1,category:"symbols"},new:{keywords:["blue-square","words","start"],char:"\u{1f195}",fitzpatrick_scale:!1,category:"symbols"},free:{keywords:["blue-square","words"],char:"\u{1f193}",fitzpatrick_scale:!1,category:"symbols"},zero:{keywords:["0","numbers","blue-square","null"],char:"0\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},one:{keywords:["blue-square","numbers","1"],char:"1\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},two:{keywords:["numbers","2","prime","blue-square"],char:"2\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},three:{keywords:["3","numbers","prime","blue-square"],char:"3\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},four:{keywords:["4","numbers","blue-square"],char:"4\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},five:{keywords:["5","numbers","blue-square","prime"],char:"5\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},six:{keywords:["6","numbers","blue-square"],char:"6\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},seven:{keywords:["7","numbers","blue-square","prime"],char:"7\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},eight:{keywords:["8","blue-square","numbers"],char:"8\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},nine:{keywords:["blue-square","numbers","9"],char:"9\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},keycap_ten:{keywords:["numbers","10","blue-square"],char:"\u{1f51f}",fitzpatrick_scale:!1,category:"symbols"},asterisk:{keywords:["star","keycap"],char:"*\u20e3",fitzpatrick_scale:!1,category:"symbols"},1234:{keywords:["numbers","blue-square"],char:"\u{1f522}",fitzpatrick_scale:!1,category:"symbols"},eject_button:{keywords:["blue-square"],char:"\u23cf\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_forward:{keywords:["blue-square","right","direction","play"],char:"\u25b6\ufe0f",fitzpatrick_scale:!1,category:"symbols"},pause_button:{keywords:["pause","blue-square"],char:"\u23f8",fitzpatrick_scale:!1,category:"symbols"},next_track_button:{keywords:["forward","next","blue-square"],char:"\u23ed",fitzpatrick_scale:!1,category:"symbols"},stop_button:{keywords:["blue-square"],char:"\u23f9",fitzpatrick_scale:!1,category:"symbols"},record_button:{keywords:["blue-square"],char:"\u23fa",fitzpatrick_scale:!1,category:"symbols"},play_or_pause_button:{keywords:["blue-square","play","pause"],char:"\u23ef",fitzpatrick_scale:!1,category:"symbols"},previous_track_button:{keywords:["backward"],char:"\u23ee",fitzpatrick_scale:!1,category:"symbols"},fast_forward:{keywords:["blue-square","play","speed","continue"],char:"\u23e9",fitzpatrick_scale:!1,category:"symbols"},rewind:{keywords:["play","blue-square"],char:"\u23ea",fitzpatrick_scale:!1,category:"symbols"},twisted_rightwards_arrows:{keywords:["blue-square","shuffle","music","random"],char:"\u{1f500}",fitzpatrick_scale:!1,category:"symbols"},repeat:{keywords:["loop","record"],char:"\u{1f501}",fitzpatrick_scale:!1,category:"symbols"},repeat_one:{keywords:["blue-square","loop"],char:"\u{1f502}",fitzpatrick_scale:!1,category:"symbols"},arrow_backward:{keywords:["blue-square","left","direction"],char:"\u25c0\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_up_small:{keywords:["blue-square","triangle","direction","point","forward","top"],char:"\u{1f53c}",fitzpatrick_scale:!1,category:"symbols"},arrow_down_small:{keywords:["blue-square","direction","bottom"],char:"\u{1f53d}",fitzpatrick_scale:!1,category:"symbols"},arrow_double_up:{keywords:["blue-square","direction","top"],char:"\u23eb",fitzpatrick_scale:!1,category:"symbols"},arrow_double_down:{keywords:["blue-square","direction","bottom"],char:"\u23ec",fitzpatrick_scale:!1,category:"symbols"},arrow_right:{keywords:["blue-square","next"],char:"\u27a1\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_left:{keywords:["blue-square","previous","back"],char:"\u2b05\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_up:{keywords:["blue-square","continue","top","direction"],char:"\u2b06\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_down:{keywords:["blue-square","direction","bottom"],char:"\u2b07\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_upper_right:{keywords:["blue-square","point","direction","diagonal","northeast"],char:"\u2197\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_lower_right:{keywords:["blue-square","direction","diagonal","southeast"],char:"\u2198\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_lower_left:{keywords:["blue-square","direction","diagonal","southwest"],char:"\u2199\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_upper_left:{keywords:["blue-square","point","direction","diagonal","northwest"],char:"\u2196\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_up_down:{keywords:["blue-square","direction","way","vertical"],char:"\u2195\ufe0f",fitzpatrick_scale:!1,category:"symbols"},left_right_arrow:{keywords:["shape","direction","horizontal","sideways"],char:"\u2194\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrows_counterclockwise:{keywords:["blue-square","sync","cycle"],char:"\u{1f504}",fitzpatrick_scale:!1,category:"symbols"},arrow_right_hook:{keywords:["blue-square","return","rotate","direction"],char:"\u21aa\ufe0f",fitzpatrick_scale:!1,category:"symbols"},leftwards_arrow_with_hook:{keywords:["back","return","blue-square","undo","enter"],char:"\u21a9\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_heading_up:{keywords:["blue-square","direction","top"],char:"\u2934\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_heading_down:{keywords:["blue-square","direction","bottom"],char:"\u2935\ufe0f",fitzpatrick_scale:!1,category:"symbols"},hash:{keywords:["symbol","blue-square","twitter"],char:"#\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},information_source:{keywords:["blue-square","alphabet","letter"],char:"\u2139\ufe0f",fitzpatrick_scale:!1,category:"symbols"},abc:{keywords:["blue-square","alphabet"],char:"\u{1f524}",fitzpatrick_scale:!1,category:"symbols"},abcd:{keywords:["blue-square","alphabet"],char:"\u{1f521}",fitzpatrick_scale:!1,category:"symbols"},capital_abcd:{keywords:["alphabet","words","blue-square"],char:"\u{1f520}",fitzpatrick_scale:!1,category:"symbols"},symbols:{keywords:["blue-square","music","note","ampersand","percent","glyphs","characters"],char:"\u{1f523}",fitzpatrick_scale:!1,category:"symbols"},musical_note:{keywords:["score","tone","sound"],char:"\u{1f3b5}",fitzpatrick_scale:!1,category:"symbols"},notes:{keywords:["music","score"],char:"\u{1f3b6}",fitzpatrick_scale:!1,category:"symbols"},wavy_dash:{keywords:["draw","line","moustache","mustache","squiggle","scribble"],char:"\u3030\ufe0f",fitzpatrick_scale:!1,category:"symbols"},curly_loop:{keywords:["scribble","draw","shape","squiggle"],char:"\u27b0",fitzpatrick_scale:!1,category:"symbols"},heavy_check_mark:{keywords:["ok","nike","answer","yes","tick"],char:"\u2714\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrows_clockwise:{keywords:["sync","cycle","round","repeat"],char:"\u{1f503}",fitzpatrick_scale:!1,category:"symbols"},heavy_plus_sign:{keywords:["math","calculation","addition","more","increase"],char:"\u2795",fitzpatrick_scale:!1,category:"symbols"},heavy_minus_sign:{keywords:["math","calculation","subtract","less"],char:"\u2796",fitzpatrick_scale:!1,category:"symbols"},heavy_division_sign:{keywords:["divide","math","calculation"],char:"\u2797",fitzpatrick_scale:!1,category:"symbols"},heavy_multiplication_x:{keywords:["math","calculation"],char:"\u2716\ufe0f",fitzpatrick_scale:!1,category:"symbols"},infinity:{keywords:["forever"],char:"\u267e",fitzpatrick_scale:!1,category:"symbols"},heavy_dollar_sign:{keywords:["money","sales","payment","currency","buck"],char:"\u{1f4b2}",fitzpatrick_scale:!1,category:"symbols"},currency_exchange:{keywords:["money","sales","dollar","travel"],char:"\u{1f4b1}",fitzpatrick_scale:!1,category:"symbols"},copyright:{keywords:["ip","license","circle","law","legal"],char:"\xa9\ufe0f",fitzpatrick_scale:!1,category:"symbols"},registered:{keywords:["alphabet","circle"],char:"\xae\ufe0f",fitzpatrick_scale:!1,category:"symbols"},tm:{keywords:["trademark","brand","law","legal"],char:"\u2122\ufe0f",fitzpatrick_scale:!1,category:"symbols"},end:{keywords:["words","arrow"],char:"\u{1f51a}",fitzpatrick_scale:!1,category:"symbols"},back:{keywords:["arrow","words","return"],char:"\u{1f519}",fitzpatrick_scale:!1,category:"symbols"},on:{keywords:["arrow","words"],char:"\u{1f51b}",fitzpatrick_scale:!1,category:"symbols"},top:{keywords:["words","blue-square"],char:"\u{1f51d}",fitzpatrick_scale:!1,category:"symbols"},soon:{keywords:["arrow","words"],char:"\u{1f51c}",fitzpatrick_scale:!1,category:"symbols"},ballot_box_with_check:{keywords:["ok","agree","confirm","black-square","vote","election","yes","tick"],char:"\u2611\ufe0f",fitzpatrick_scale:!1,category:"symbols"},radio_button:{keywords:["input","old","music","circle"],char:"\u{1f518}",fitzpatrick_scale:!1,category:"symbols"},white_circle:{keywords:["shape","round"],char:"\u26aa",fitzpatrick_scale:!1,category:"symbols"},black_circle:{keywords:["shape","button","round"],char:"\u26ab",fitzpatrick_scale:!1,category:"symbols"},red_circle:{keywords:["shape","error","danger"],char:"\u{1f534}",fitzpatrick_scale:!1,category:"symbols"},large_blue_circle:{keywords:["shape","icon","button"],char:"\u{1f535}",fitzpatrick_scale:!1,category:"symbols"},small_orange_diamond:{keywords:["shape","jewel","gem"],char:"\u{1f538}",fitzpatrick_scale:!1,category:"symbols"},small_blue_diamond:{keywords:["shape","jewel","gem"],char:"\u{1f539}",fitzpatrick_scale:!1,category:"symbols"},large_orange_diamond:{keywords:["shape","jewel","gem"],char:"\u{1f536}",fitzpatrick_scale:!1,category:"symbols"},large_blue_diamond:{keywords:["shape","jewel","gem"],char:"\u{1f537}",fitzpatrick_scale:!1,category:"symbols"},small_red_triangle:{keywords:["shape","direction","up","top"],char:"\u{1f53a}",fitzpatrick_scale:!1,category:"symbols"},black_small_square:{keywords:["shape","icon"],char:"\u25aa\ufe0f",fitzpatrick_scale:!1,category:"symbols"},white_small_square:{keywords:["shape","icon"],char:"\u25ab\ufe0f",fitzpatrick_scale:!1,category:"symbols"},black_large_square:{keywords:["shape","icon","button"],char:"\u2b1b",fitzpatrick_scale:!1,category:"symbols"},white_large_square:{keywords:["shape","icon","stone","button"],char:"\u2b1c",fitzpatrick_scale:!1,category:"symbols"},small_red_triangle_down:{keywords:["shape","direction","bottom"],char:"\u{1f53b}",fitzpatrick_scale:!1,category:"symbols"},black_medium_square:{keywords:["shape","button","icon"],char:"\u25fc\ufe0f",fitzpatrick_scale:!1,category:"symbols"},white_medium_square:{keywords:["shape","stone","icon"],char:"\u25fb\ufe0f",fitzpatrick_scale:!1,category:"symbols"},black_medium_small_square:{keywords:["icon","shape","button"],char:"\u25fe",fitzpatrick_scale:!1,category:"symbols"},white_medium_small_square:{keywords:["shape","stone","icon","button"],char:"\u25fd",fitzpatrick_scale:!1,category:"symbols"},black_square_button:{keywords:["shape","input","frame"],char:"\u{1f532}",fitzpatrick_scale:!1,category:"symbols"},white_square_button:{keywords:["shape","input"],char:"\u{1f533}",fitzpatrick_scale:!1,category:"symbols"},speaker:{keywords:["sound","volume","silence","broadcast"],char:"\u{1f508}",fitzpatrick_scale:!1,category:"symbols"},sound:{keywords:["volume","speaker","broadcast"],char:"\u{1f509}",fitzpatrick_scale:!1,category:"symbols"},loud_sound:{keywords:["volume","noise","noisy","speaker","broadcast"],char:"\u{1f50a}",fitzpatrick_scale:!1,category:"symbols"},mute:{keywords:["sound","volume","silence","quiet"],char:"\u{1f507}",fitzpatrick_scale:!1,category:"symbols"},mega:{keywords:["sound","speaker","volume"],char:"\u{1f4e3}",fitzpatrick_scale:!1,category:"symbols"},loudspeaker:{keywords:["volume","sound"],char:"\u{1f4e2}",fitzpatrick_scale:!1,category:"symbols"},bell:{keywords:["sound","notification","christmas","xmas","chime"],char:"\u{1f514}",fitzpatrick_scale:!1,category:"symbols"},no_bell:{keywords:["sound","volume","mute","quiet","silent"],char:"\u{1f515}",fitzpatrick_scale:!1,category:"symbols"},black_joker:{keywords:["poker","cards","game","play","magic"],char:"\u{1f0cf}",fitzpatrick_scale:!1,category:"symbols"},mahjong:{keywords:["game","play","chinese","kanji"],char:"\u{1f004}",fitzpatrick_scale:!1,category:"symbols"},spades:{keywords:["poker","cards","suits","magic"],char:"\u2660\ufe0f",fitzpatrick_scale:!1,category:"symbols"},clubs:{keywords:["poker","cards","magic","suits"],char:"\u2663\ufe0f",fitzpatrick_scale:!1,category:"symbols"},hearts:{keywords:["poker","cards","magic","suits"],char:"\u2665\ufe0f",fitzpatrick_scale:!1,category:"symbols"},diamonds:{keywords:["poker","cards","magic","suits"],char:"\u2666\ufe0f",fitzpatrick_scale:!1,category:"symbols"},flower_playing_cards:{keywords:["game","sunset","red"],char:"\u{1f3b4}",fitzpatrick_scale:!1,category:"symbols"},thought_balloon:{keywords:["bubble","cloud","speech","thinking","dream"],char:"\u{1f4ad}",fitzpatrick_scale:!1,category:"symbols"},right_anger_bubble:{keywords:["caption","speech","thinking","mad"],char:"\u{1f5ef}",fitzpatrick_scale:!1,category:"symbols"},speech_balloon:{keywords:["bubble","words","message","talk","chatting"],char:"\u{1f4ac}",fitzpatrick_scale:!1,category:"symbols"},left_speech_bubble:{keywords:["words","message","talk","chatting"],char:"\u{1f5e8}",fitzpatrick_scale:!1,category:"symbols"},clock1:{keywords:["time","late","early","schedule"],char:"\u{1f550}",fitzpatrick_scale:!1,category:"symbols"},clock2:{keywords:["time","late","early","schedule"],char:"\u{1f551}",fitzpatrick_scale:!1,category:"symbols"},clock3:{keywords:["time","late","early","schedule"],char:"\u{1f552}",fitzpatrick_scale:!1,category:"symbols"},clock4:{keywords:["time","late","early","schedule"],char:"\u{1f553}",fitzpatrick_scale:!1,category:"symbols"},clock5:{keywords:["time","late","early","schedule"],char:"\u{1f554}",fitzpatrick_scale:!1,category:"symbols"},clock6:{keywords:["time","late","early","schedule","dawn","dusk"],char:"\u{1f555}",fitzpatrick_scale:!1,category:"symbols"},clock7:{keywords:["time","late","early","schedule"],char:"\u{1f556}",fitzpatrick_scale:!1,category:"symbols"},clock8:{keywords:["time","late","early","schedule"],char:"\u{1f557}",fitzpatrick_scale:!1,category:"symbols"},clock9:{keywords:["time","late","early","schedule"],char:"\u{1f558}",fitzpatrick_scale:!1,category:"symbols"},clock10:{keywords:["time","late","early","schedule"],char:"\u{1f559}",fitzpatrick_scale:!1,category:"symbols"},clock11:{keywords:["time","late","early","schedule"],char:"\u{1f55a}",fitzpatrick_scale:!1,category:"symbols"},clock12:{keywords:["time","noon","midnight","midday","late","early","schedule"],char:"\u{1f55b}",fitzpatrick_scale:!1,category:"symbols"},clock130:{keywords:["time","late","early","schedule"],char:"\u{1f55c}",fitzpatrick_scale:!1,category:"symbols"},clock230:{keywords:["time","late","early","schedule"],char:"\u{1f55d}",fitzpatrick_scale:!1,category:"symbols"},clock330:{keywords:["time","late","early","schedule"],char:"\u{1f55e}",fitzpatrick_scale:!1,category:"symbols"},clock430:{keywords:["time","late","early","schedule"],char:"\u{1f55f}",fitzpatrick_scale:!1,category:"symbols"},clock530:{keywords:["time","late","early","schedule"],char:"\u{1f560}",fitzpatrick_scale:!1,category:"symbols"},clock630:{keywords:["time","late","early","schedule"],char:"\u{1f561}",fitzpatrick_scale:!1,category:"symbols"},clock730:{keywords:["time","late","early","schedule"],char:"\u{1f562}",fitzpatrick_scale:!1,category:"symbols"},clock830:{keywords:["time","late","early","schedule"],char:"\u{1f563}",fitzpatrick_scale:!1,category:"symbols"},clock930:{keywords:["time","late","early","schedule"],char:"\u{1f564}",fitzpatrick_scale:!1,category:"symbols"},clock1030:{keywords:["time","late","early","schedule"],char:"\u{1f565}",fitzpatrick_scale:!1,category:"symbols"},clock1130:{keywords:["time","late","early","schedule"],char:"\u{1f566}",fitzpatrick_scale:!1,category:"symbols"},clock1230:{keywords:["time","late","early","schedule"],char:"\u{1f567}",fitzpatrick_scale:!1,category:"symbols"},afghanistan:{keywords:["af","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1eb}",fitzpatrick_scale:!1,category:"flags"},aland_islands:{keywords:["\xc5land","islands","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1fd}",fitzpatrick_scale:!1,category:"flags"},albania:{keywords:["al","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1f1}",fitzpatrick_scale:!1,category:"flags"},algeria:{keywords:["dz","flag","nation","country","banner"],char:"\u{1f1e9}\u{1f1ff}",fitzpatrick_scale:!1,category:"flags"},american_samoa:{keywords:["american","ws","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},andorra:{keywords:["ad","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1e9}",fitzpatrick_scale:!1,category:"flags"},angola:{keywords:["ao","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},anguilla:{keywords:["ai","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1ee}",fitzpatrick_scale:!1,category:"flags"},antarctica:{keywords:["aq","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1f6}",fitzpatrick_scale:!1,category:"flags"},antigua_barbuda:{keywords:["antigua","barbuda","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},argentina:{keywords:["ar","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},armenia:{keywords:["am","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},aruba:{keywords:["aw","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1fc}",fitzpatrick_scale:!1,category:"flags"},australia:{keywords:["au","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1fa}",fitzpatrick_scale:!1,category:"flags"},austria:{keywords:["at","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},azerbaijan:{keywords:["az","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1ff}",fitzpatrick_scale:!1,category:"flags"},bahamas:{keywords:["bs","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},bahrain:{keywords:["bh","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1ed}",fitzpatrick_scale:!1,category:"flags"},bangladesh:{keywords:["bd","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1e9}",fitzpatrick_scale:!1,category:"flags"},barbados:{keywords:["bb","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1e7}",fitzpatrick_scale:!1,category:"flags"},belarus:{keywords:["by","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1fe}",fitzpatrick_scale:!1,category:"flags"},belgium:{keywords:["be","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},belize:{keywords:["bz","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1ff}",fitzpatrick_scale:!1,category:"flags"},benin:{keywords:["bj","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1ef}",fitzpatrick_scale:!1,category:"flags"},bermuda:{keywords:["bm","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},bhutan:{keywords:["bt","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},bolivia:{keywords:["bo","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},caribbean_netherlands:{keywords:["bonaire","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1f6}",fitzpatrick_scale:!1,category:"flags"},bosnia_herzegovina:{keywords:["bosnia","herzegovina","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},botswana:{keywords:["bw","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1fc}",fitzpatrick_scale:!1,category:"flags"},brazil:{keywords:["br","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},british_indian_ocean_territory:{keywords:["british","indian","ocean","territory","flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},british_virgin_islands:{keywords:["british","virgin","islands","bvi","flag","nation","country","banner"],char:"\u{1f1fb}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},brunei:{keywords:["bn","darussalam","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},bulgaria:{keywords:["bg","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},burkina_faso:{keywords:["burkina","faso","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1eb}",fitzpatrick_scale:!1,category:"flags"},burundi:{keywords:["bi","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1ee}",fitzpatrick_scale:!1,category:"flags"},cape_verde:{keywords:["cabo","verde","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1fb}",fitzpatrick_scale:!1,category:"flags"},cambodia:{keywords:["kh","flag","nation","country","banner"],char:"\u{1f1f0}\u{1f1ed}",fitzpatrick_scale:!1,category:"flags"},cameroon:{keywords:["cm","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},canada:{keywords:["ca","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},canary_islands:{keywords:["canary","islands","flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1e8}",fitzpatrick_scale:!1,category:"flags"},cayman_islands:{keywords:["cayman","islands","flag","nation","country","banner"],char:"\u{1f1f0}\u{1f1fe}",fitzpatrick_scale:!1,category:"flags"},central_african_republic:{keywords:["central","african","republic","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1eb}",fitzpatrick_scale:!1,category:"flags"},chad:{keywords:["td","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1e9}",fitzpatrick_scale:!1,category:"flags"},chile:{keywords:["flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1f1}",fitzpatrick_scale:!1,category:"flags"},cn:{keywords:["china","chinese","prc","flag","country","nation","banner"],char:"\u{1f1e8}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},christmas_island:{keywords:["christmas","island","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1fd}",fitzpatrick_scale:!1,category:"flags"},cocos_islands:{keywords:["cocos","keeling","islands","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1e8}",fitzpatrick_scale:!1,category:"flags"},colombia:{keywords:["co","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},comoros:{keywords:["km","flag","nation","country","banner"],char:"\u{1f1f0}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},congo_brazzaville:{keywords:["congo","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},congo_kinshasa:{keywords:["congo","democratic","republic","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1e9}",fitzpatrick_scale:!1,category:"flags"},cook_islands:{keywords:["cook","islands","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1f0}",fitzpatrick_scale:!1,category:"flags"},costa_rica:{keywords:["costa","rica","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},croatia:{keywords:["hr","flag","nation","country","banner"],char:"\u{1f1ed}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},cuba:{keywords:["cu","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1fa}",fitzpatrick_scale:!1,category:"flags"},curacao:{keywords:["cura\xe7ao","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1fc}",fitzpatrick_scale:!1,category:"flags"},cyprus:{keywords:["cy","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1fe}",fitzpatrick_scale:!1,category:"flags"},czech_republic:{keywords:["cz","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1ff}",fitzpatrick_scale:!1,category:"flags"},denmark:{keywords:["dk","flag","nation","country","banner"],char:"\u{1f1e9}\u{1f1f0}",fitzpatrick_scale:!1,category:"flags"},djibouti:{keywords:["dj","flag","nation","country","banner"],char:"\u{1f1e9}\u{1f1ef}",fitzpatrick_scale:!1,category:"flags"},dominica:{keywords:["dm","flag","nation","country","banner"],char:"\u{1f1e9}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},dominican_republic:{keywords:["dominican","republic","flag","nation","country","banner"],char:"\u{1f1e9}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},ecuador:{keywords:["ec","flag","nation","country","banner"],char:"\u{1f1ea}\u{1f1e8}",fitzpatrick_scale:!1,category:"flags"},egypt:{keywords:["eg","flag","nation","country","banner"],char:"\u{1f1ea}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},el_salvador:{keywords:["el","salvador","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1fb}",fitzpatrick_scale:!1,category:"flags"},equatorial_guinea:{keywords:["equatorial","gn","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1f6}",fitzpatrick_scale:!1,category:"flags"},eritrea:{keywords:["er","flag","nation","country","banner"],char:"\u{1f1ea}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},estonia:{keywords:["ee","flag","nation","country","banner"],char:"\u{1f1ea}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},ethiopia:{keywords:["et","flag","nation","country","banner"],char:"\u{1f1ea}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},eu:{keywords:["european","union","flag","banner"],char:"\u{1f1ea}\u{1f1fa}",fitzpatrick_scale:!1,category:"flags"},falkland_islands:{keywords:["falkland","islands","malvinas","flag","nation","country","banner"],char:"\u{1f1eb}\u{1f1f0}",fitzpatrick_scale:!1,category:"flags"},faroe_islands:{keywords:["faroe","islands","flag","nation","country","banner"],char:"\u{1f1eb}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},fiji:{keywords:["fj","flag","nation","country","banner"],char:"\u{1f1eb}\u{1f1ef}",fitzpatrick_scale:!1,category:"flags"},finland:{keywords:["fi","flag","nation","country","banner"],char:"\u{1f1eb}\u{1f1ee}",fitzpatrick_scale:!1,category:"flags"},fr:{keywords:["banner","flag","nation","france","french","country"],char:"\u{1f1eb}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},french_guiana:{keywords:["french","guiana","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1eb}",fitzpatrick_scale:!1,category:"flags"},french_polynesia:{keywords:["french","polynesia","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1eb}",fitzpatrick_scale:!1,category:"flags"},french_southern_territories:{keywords:["french","southern","territories","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1eb}",fitzpatrick_scale:!1,category:"flags"},gabon:{keywords:["ga","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},gambia:{keywords:["gm","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},georgia:{keywords:["ge","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},de:{keywords:["german","nation","flag","country","banner"],char:"\u{1f1e9}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},ghana:{keywords:["gh","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1ed}",fitzpatrick_scale:!1,category:"flags"},gibraltar:{keywords:["gi","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1ee}",fitzpatrick_scale:!1,category:"flags"},greece:{keywords:["gr","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},greenland:{keywords:["gl","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1f1}",fitzpatrick_scale:!1,category:"flags"},grenada:{keywords:["gd","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1e9}",fitzpatrick_scale:!1,category:"flags"},guadeloupe:{keywords:["gp","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1f5}",fitzpatrick_scale:!1,category:"flags"},guam:{keywords:["gu","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1fa}",fitzpatrick_scale:!1,category:"flags"},guatemala:{keywords:["gt","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},guernsey:{keywords:["gg","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},guinea:{keywords:["gn","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},guinea_bissau:{keywords:["gw","bissau","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1fc}",fitzpatrick_scale:!1,category:"flags"},guyana:{keywords:["gy","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1fe}",fitzpatrick_scale:!1,category:"flags"},haiti:{keywords:["ht","flag","nation","country","banner"],char:"\u{1f1ed}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},honduras:{keywords:["hn","flag","nation","country","banner"],char:"\u{1f1ed}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},hong_kong:{keywords:["hong","kong","flag","nation","country","banner"],char:"\u{1f1ed}\u{1f1f0}",fitzpatrick_scale:!1,category:"flags"},hungary:{keywords:["hu","flag","nation","country","banner"],char:"\u{1f1ed}\u{1f1fa}",fitzpatrick_scale:!1,category:"flags"},iceland:{keywords:["is","flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},india:{keywords:["in","flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},indonesia:{keywords:["flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1e9}",fitzpatrick_scale:!1,category:"flags"},iran:{keywords:["iran,","islamic","republic","flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},iraq:{keywords:["iq","flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1f6}",fitzpatrick_scale:!1,category:"flags"},ireland:{keywords:["ie","flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},isle_of_man:{keywords:["isle","man","flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},israel:{keywords:["il","flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1f1}",fitzpatrick_scale:!1,category:"flags"},it:{keywords:["italy","flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},cote_divoire:{keywords:["ivory","coast","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1ee}",fitzpatrick_scale:!1,category:"flags"},jamaica:{keywords:["jm","flag","nation","country","banner"],char:"\u{1f1ef}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},jp:{keywords:["japanese","nation","flag","country","banner"],char:"\u{1f1ef}\u{1f1f5}",fitzpatrick_scale:!1,category:"flags"},jersey:{keywords:["je","flag","nation","country","banner"],char:"\u{1f1ef}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},jordan:{keywords:["jo","flag","nation","country","banner"],char:"\u{1f1ef}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},kazakhstan:{keywords:["kz","flag","nation","country","banner"],char:"\u{1f1f0}\u{1f1ff}",fitzpatrick_scale:!1,category:"flags"},kenya:{keywords:["ke","flag","nation","country","banner"],char:"\u{1f1f0}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},kiribati:{keywords:["ki","flag","nation","country","banner"],char:"\u{1f1f0}\u{1f1ee}",fitzpatrick_scale:!1,category:"flags"},kosovo:{keywords:["xk","flag","nation","country","banner"],char:"\u{1f1fd}\u{1f1f0}",fitzpatrick_scale:!1,category:"flags"},kuwait:{keywords:["kw","flag","nation","country","banner"],char:"\u{1f1f0}\u{1f1fc}",fitzpatrick_scale:!1,category:"flags"},kyrgyzstan:{keywords:["kg","flag","nation","country","banner"],char:"\u{1f1f0}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},laos:{keywords:["lao","democratic","republic","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},latvia:{keywords:["lv","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1fb}",fitzpatrick_scale:!1,category:"flags"},lebanon:{keywords:["lb","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1e7}",fitzpatrick_scale:!1,category:"flags"},lesotho:{keywords:["ls","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},liberia:{keywords:["lr","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},libya:{keywords:["ly","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1fe}",fitzpatrick_scale:!1,category:"flags"},liechtenstein:{keywords:["li","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1ee}",fitzpatrick_scale:!1,category:"flags"},lithuania:{keywords:["lt","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},luxembourg:{keywords:["lu","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1fa}",fitzpatrick_scale:!1,category:"flags"},macau:{keywords:["macao","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},macedonia:{keywords:["macedonia,","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1f0}",fitzpatrick_scale:!1,category:"flags"},madagascar:{keywords:["mg","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},malawi:{keywords:["mw","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1fc}",fitzpatrick_scale:!1,category:"flags"},malaysia:{keywords:["my","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1fe}",fitzpatrick_scale:!1,category:"flags"},maldives:{keywords:["mv","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1fb}",fitzpatrick_scale:!1,category:"flags"},mali:{keywords:["ml","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1f1}",fitzpatrick_scale:!1,category:"flags"},malta:{keywords:["mt","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},marshall_islands:{keywords:["marshall","islands","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1ed}",fitzpatrick_scale:!1,category:"flags"},martinique:{keywords:["mq","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1f6}",fitzpatrick_scale:!1,category:"flags"},mauritania:{keywords:["mr","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},mauritius:{keywords:["mu","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1fa}",fitzpatrick_scale:!1,category:"flags"},mayotte:{keywords:["yt","flag","nation","country","banner"],char:"\u{1f1fe}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},mexico:{keywords:["mx","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1fd}",fitzpatrick_scale:!1,category:"flags"},micronesia:{keywords:["micronesia,","federated","states","flag","nation","country","banner"],char:"\u{1f1eb}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},moldova:{keywords:["moldova,","republic","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1e9}",fitzpatrick_scale:!1,category:"flags"},monaco:{keywords:["mc","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1e8}",fitzpatrick_scale:!1,category:"flags"},mongolia:{keywords:["mn","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},montenegro:{keywords:["me","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},montserrat:{keywords:["ms","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},morocco:{keywords:["ma","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},mozambique:{keywords:["mz","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1ff}",fitzpatrick_scale:!1,category:"flags"},myanmar:{keywords:["mm","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},namibia:{keywords:["na","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},nauru:{keywords:["nr","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},nepal:{keywords:["np","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1f5}",fitzpatrick_scale:!1,category:"flags"},netherlands:{keywords:["nl","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1f1}",fitzpatrick_scale:!1,category:"flags"},new_caledonia:{keywords:["new","caledonia","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1e8}",fitzpatrick_scale:!1,category:"flags"},new_zealand:{keywords:["new","zealand","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1ff}",fitzpatrick_scale:!1,category:"flags"},nicaragua:{keywords:["ni","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1ee}",fitzpatrick_scale:!1,category:"flags"},niger:{keywords:["ne","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},nigeria:{keywords:["flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},niue:{keywords:["nu","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1fa}",fitzpatrick_scale:!1,category:"flags"},norfolk_island:{keywords:["norfolk","island","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1eb}",fitzpatrick_scale:!1,category:"flags"},northern_mariana_islands:{keywords:["northern","mariana","islands","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1f5}",fitzpatrick_scale:!1,category:"flags"},north_korea:{keywords:["north","korea","nation","flag","country","banner"],char:"\u{1f1f0}\u{1f1f5}",fitzpatrick_scale:!1,category:"flags"},norway:{keywords:["no","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},oman:{keywords:["om_symbol","flag","nation","country","banner"],char:"\u{1f1f4}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},pakistan:{keywords:["pk","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1f0}",fitzpatrick_scale:!1,category:"flags"},palau:{keywords:["pw","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1fc}",fitzpatrick_scale:!1,category:"flags"},palestinian_territories:{keywords:["palestine","palestinian","territories","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},panama:{keywords:["pa","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},papua_new_guinea:{keywords:["papua","new","guinea","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},paraguay:{keywords:["py","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1fe}",fitzpatrick_scale:!1,category:"flags"},peru:{keywords:["pe","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},philippines:{keywords:["ph","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1ed}",fitzpatrick_scale:!1,category:"flags"},pitcairn_islands:{keywords:["pitcairn","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},poland:{keywords:["pl","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1f1}",fitzpatrick_scale:!1,category:"flags"},portugal:{keywords:["pt","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},puerto_rico:{keywords:["puerto","rico","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},qatar:{keywords:["qa","flag","nation","country","banner"],char:"\u{1f1f6}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},reunion:{keywords:["r\xe9union","flag","nation","country","banner"],char:"\u{1f1f7}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},romania:{keywords:["ro","flag","nation","country","banner"],char:"\u{1f1f7}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},ru:{keywords:["russian","federation","flag","nation","country","banner"],char:"\u{1f1f7}\u{1f1fa}",fitzpatrick_scale:!1,category:"flags"},rwanda:{keywords:["rw","flag","nation","country","banner"],char:"\u{1f1f7}\u{1f1fc}",fitzpatrick_scale:!1,category:"flags"},st_barthelemy:{keywords:["saint","barth\xe9lemy","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1f1}",fitzpatrick_scale:!1,category:"flags"},st_helena:{keywords:["saint","helena","ascension","tristan","cunha","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1ed}",fitzpatrick_scale:!1,category:"flags"},st_kitts_nevis:{keywords:["saint","kitts","nevis","flag","nation","country","banner"],char:"\u{1f1f0}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},st_lucia:{keywords:["saint","lucia","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1e8}",fitzpatrick_scale:!1,category:"flags"},st_pierre_miquelon:{keywords:["saint","pierre","miquelon","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},st_vincent_grenadines:{keywords:["saint","vincent","grenadines","flag","nation","country","banner"],char:"\u{1f1fb}\u{1f1e8}",fitzpatrick_scale:!1,category:"flags"},samoa:{keywords:["ws","flag","nation","country","banner"],char:"\u{1f1fc}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},san_marino:{keywords:["san","marino","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},sao_tome_principe:{keywords:["sao","tome","principe","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},saudi_arabia:{keywords:["flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},senegal:{keywords:["sn","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},serbia:{keywords:["rs","flag","nation","country","banner"],char:"\u{1f1f7}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},seychelles:{keywords:["sc","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1e8}",fitzpatrick_scale:!1,category:"flags"},sierra_leone:{keywords:["sierra","leone","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1f1}",fitzpatrick_scale:!1,category:"flags"},singapore:{keywords:["sg","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},sint_maarten:{keywords:["sint","maarten","dutch","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1fd}",fitzpatrick_scale:!1,category:"flags"},slovakia:{keywords:["sk","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1f0}",fitzpatrick_scale:!1,category:"flags"},slovenia:{keywords:["si","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1ee}",fitzpatrick_scale:!1,category:"flags"},solomon_islands:{keywords:["solomon","islands","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1e7}",fitzpatrick_scale:!1,category:"flags"},somalia:{keywords:["so","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},south_africa:{keywords:["south","africa","flag","nation","country","banner"],char:"\u{1f1ff}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},south_georgia_south_sandwich_islands:{keywords:["south","georgia","sandwich","islands","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},kr:{keywords:["south","korea","nation","flag","country","banner"],char:"\u{1f1f0}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},south_sudan:{keywords:["south","sd","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},es:{keywords:["spain","flag","nation","country","banner"],char:"\u{1f1ea}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},sri_lanka:{keywords:["sri","lanka","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1f0}",fitzpatrick_scale:!1,category:"flags"},sudan:{keywords:["sd","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1e9}",fitzpatrick_scale:!1,category:"flags"},suriname:{keywords:["sr","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},swaziland:{keywords:["sz","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1ff}",fitzpatrick_scale:!1,category:"flags"},sweden:{keywords:["se","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},switzerland:{keywords:["ch","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1ed}",fitzpatrick_scale:!1,category:"flags"},syria:{keywords:["syrian","arab","republic","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1fe}",fitzpatrick_scale:!1,category:"flags"},taiwan:{keywords:["tw","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1fc}",fitzpatrick_scale:!1,category:"flags"},tajikistan:{keywords:["tj","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1ef}",fitzpatrick_scale:!1,category:"flags"},tanzania:{keywords:["tanzania,","united","republic","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1ff}",fitzpatrick_scale:!1,category:"flags"},thailand:{keywords:["th","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1ed}",fitzpatrick_scale:!1,category:"flags"},timor_leste:{keywords:["timor","leste","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1f1}",fitzpatrick_scale:!1,category:"flags"},togo:{keywords:["tg","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},tokelau:{keywords:["tk","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1f0}",fitzpatrick_scale:!1,category:"flags"},tonga:{keywords:["to","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},trinidad_tobago:{keywords:["trinidad","tobago","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},tunisia:{keywords:["tn","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},tr:{keywords:["turkey","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},turkmenistan:{keywords:["flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},turks_caicos_islands:{keywords:["turks","caicos","islands","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1e8}",fitzpatrick_scale:!1,category:"flags"},tuvalu:{keywords:["flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1fb}",fitzpatrick_scale:!1,category:"flags"},uganda:{keywords:["ug","flag","nation","country","banner"],char:"\u{1f1fa}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},ukraine:{keywords:["ua","flag","nation","country","banner"],char:"\u{1f1fa}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},united_arab_emirates:{keywords:["united","arab","emirates","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},uk:{keywords:["united","kingdom","great","britain","northern","ireland","flag","nation","country","banner","british","UK","english","england","union jack"],char:"\u{1f1ec}\u{1f1e7}",fitzpatrick_scale:!1,category:"flags"},england:{keywords:["flag","english"],char:"\u{1f3f4}\u{e0067}\u{e0062}\u{e0065}\u{e006e}\u{e0067}\u{e007f}",fitzpatrick_scale:!1,category:"flags"},scotland:{keywords:["flag","scottish"],char:"\u{1f3f4}\u{e0067}\u{e0062}\u{e0073}\u{e0063}\u{e0074}\u{e007f}",fitzpatrick_scale:!1,category:"flags"},wales:{keywords:["flag","welsh"],char:"\u{1f3f4}\u{e0067}\u{e0062}\u{e0077}\u{e006c}\u{e0073}\u{e007f}",fitzpatrick_scale:!1,category:"flags"},us:{keywords:["united","states","america","flag","nation","country","banner"],char:"\u{1f1fa}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},us_virgin_islands:{keywords:["virgin","islands","us","flag","nation","country","banner"],char:"\u{1f1fb}\u{1f1ee}",fitzpatrick_scale:!1,category:"flags"},uruguay:{keywords:["uy","flag","nation","country","banner"],char:"\u{1f1fa}\u{1f1fe}",fitzpatrick_scale:!1,category:"flags"},uzbekistan:{keywords:["uz","flag","nation","country","banner"],char:"\u{1f1fa}\u{1f1ff}",fitzpatrick_scale:!1,category:"flags"},vanuatu:{keywords:["vu","flag","nation","country","banner"],char:"\u{1f1fb}\u{1f1fa}",fitzpatrick_scale:!1,category:"flags"},vatican_city:{keywords:["vatican","city","flag","nation","country","banner"],char:"\u{1f1fb}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},venezuela:{keywords:["ve","bolivarian","republic","flag","nation","country","banner"],char:"\u{1f1fb}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},vietnam:{keywords:["viet","nam","flag","nation","country","banner"],char:"\u{1f1fb}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},wallis_futuna:{keywords:["wallis","futuna","flag","nation","country","banner"],char:"\u{1f1fc}\u{1f1eb}",fitzpatrick_scale:!1,category:"flags"},western_sahara:{keywords:["western","sahara","flag","nation","country","banner"],char:"\u{1f1ea}\u{1f1ed}",fitzpatrick_scale:!1,category:"flags"},yemen:{keywords:["ye","flag","nation","country","banner"],char:"\u{1f1fe}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},zambia:{keywords:["zm","flag","nation","country","banner"],char:"\u{1f1ff}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},zimbabwe:{keywords:["zw","flag","nation","country","banner"],char:"\u{1f1ff}\u{1f1fc}",fitzpatrick_scale:!1,category:"flags"},united_nations:{keywords:["un","flag","banner"],char:"\u{1f1fa}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},pirate_flag:{keywords:["skull","crossbones","flag","banner"],char:"\u{1f3f4}\u200d\u2620\ufe0f",fitzpatrick_scale:!1,category:"flags"}}); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/emoticons/plugin.min.js b/public/resource/tinymce/plugins/emoticons/plugin.min.js new file mode 100644 index 0000000..af3e1d7 --- /dev/null +++ b/public/resource/tinymce/plugins/emoticons/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.4.2 (2023-04-26) + */ +!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=t=>e=>t===e,o=e(null),n=e(void 0),s=()=>{},r=()=>!1;class a{constructor(t,e){this.tag=t,this.value=e}static some(t){return new a(!0,t)}static none(){return a.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?a.some(t(this.value)):a.none()}bind(t){return this.tag?t(this.value):a.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:a.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return null==t?a.none():a.some(t)}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}a.singletonNone=new a(!1);const i=(t,e)=>{const o=t.length,n=new Array(o);for(let s=0;s{let e=t;return{get:()=>e,set:t=>{e=t}}},c=Object.keys,u=Object.hasOwnProperty,g=(t,e)=>{const o=c(t);for(let n=0,s=o.length;nu.call(t,e),h=(d=(t,e)=>e,(...t)=>{if(0===t.length)throw new Error("Can't merge zero objects");const e={};for(let o=0;o{const t=(t=>{const e=l(a.none()),o=()=>e.get().each(t);return{clear:()=>{o(),e.set(a.none())},isSet:()=>e.get().isSome(),get:()=>e.get(),set:t=>{o(),e.set(a.some(t))}}})(s);return{...t,on:e=>t.get().each(e)}},v=(t,e,o=0,s)=>{const r=t.indexOf(e,o);return-1!==r&&(!!n(s)||r+e.length<=s)};var y=tinymce.util.Tools.resolve("tinymce.Resource");const f=t=>e=>e.options.get(t),b=f("emoticons_database"),w=f("emoticons_database_url"),_=f("emoticons_database_id"),j=f("emoticons_append"),C=f("emoticons_images_url"),k="All",A={symbols:"Symbols",people:"People",animals_and_nature:"Animals and Nature",food_and_drink:"Food and Drink",activity:"Activity",travel_and_places:"Travel and Places",objects:"Objects",flags:"Flags",user:"User Defined"},O=(t,e)=>m(t,e)?t[e]:e,x=t=>{const e=j(t);return o=t=>({keywords:[],category:"user",...t}),((t,e)=>{const o={};return g(t,((t,n)=>{const s=e(t,n);o[s.k]=s.v})),o})(e,((t,e)=>({k:e,v:o(t)})));var o},L=(t,e)=>v(t.title.toLowerCase(),e)||((t,o)=>{for(let o=0,s=t.length;o{const n=[],s=e.toLowerCase(),a=o.fold((()=>r),(t=>e=>e>=t));for(let o=0;o{const n={pattern:"",results:T(e.listAll(),"",a.some(300))},s=l(k),r=((t,e)=>{let n=null;const s=()=>{o(n)||(clearTimeout(n),n=null)};return{cancel:s,throttle:(...e)=>{s(),n=setTimeout((()=>{n=null,t.apply(null,e)}),200)}}})((t=>{(t=>{const o=t.getData(),n=s.get(),r=e.listCategory(n),i=T(r,o.pattern,n===k?a.some(300):a.none());t.setData({results:i})})(t)})),c={label:"Search",type:"input",name:D},u={type:"collection",name:"results"},g=()=>({title:"Emojis",size:"normal",body:{type:"tabpanel",tabs:i(e.listCategories(),(t=>({title:t,name:t,items:[c,u]})))},initialData:n,onTabChange:(t,e)=>{s.set(e.newTabName),r.throttle(t)},onChange:r.throttle,onAction:(e,o)=>{"results"===o.name&&(((t,e)=>{t.insertContent(e)})(t,o.value),e.close())},buttons:[{type:"cancel",text:"Close",primary:!0}]}),m=t.windowManager.open(g());m.focus(D),e.hasLoaded()||(m.block("Loading emojis..."),e.waitForLoad().then((()=>{m.redial(g()),r.throttle(m),m.focus(D),m.unblock()})).catch((t=>{m.redial({title:"Emojis",body:{type:"panel",items:[{type:"alertbanner",level:"error",icon:"warning",text:"Could not load emojis"}]},buttons:[{type:"cancel",text:"Close",primary:!0}],initialData:{pattern:"",results:[]}}),m.focus(D),m.unblock()})))};t.add("emoticons",((t,e)=>{((t,e)=>{const o=t.options.register;o("emoticons_database",{processor:"string",default:"emojis"}),o("emoticons_database_url",{processor:"string",default:`${e}/js/${b(t)}${t.suffix}.js`}),o("emoticons_database_id",{processor:"string",default:"tinymce.plugins.emoticons"}),o("emoticons_append",{processor:"object",default:{}}),o("emoticons_images_url",{processor:"string",default:"https://twemoji.maxcdn.com/v/13.0.1/72x72/"})})(t,e);const o=((t,e,o)=>{const n=p(),s=p(),r=C(t),i=t=>{return o="=o.length&&e.substr(0,0+o.length)===o?t.char.replace(/src="([^"]+)"/,((t,e)=>`src="${r}${e}"`)):t.char;var e,o};t.on("init",(()=>{y.load(o,e).then((e=>{const o=x(t);(t=>{const e={},o=[];g(t,((t,n)=>{const s={title:n,keywords:t.keywords,char:i(t),category:O(A,t.category)},r=void 0!==e[s.category]?e[s.category]:[];e[s.category]=r.concat([s]),o.push(s)})),n.set(e),s.set(o)})(h(e,o))}),(t=>{console.log(`Failed to load emojis: ${t}`),n.set({}),s.set([])}))}));const l=()=>s.get().getOr([]),u=()=>n.isSet()&&s.isSet();return{listCategories:()=>[k].concat(c(n.get().getOr({}))),hasLoaded:u,waitForLoad:()=>u()?Promise.resolve(!0):new Promise(((t,o)=>{let n=15;const s=setInterval((()=>{u()?(clearInterval(s),t(!0)):(n--,n<0&&(console.log("Could not load emojis from url: "+e),clearInterval(s),o(!1)))}),100)})),listAll:l,listCategory:t=>t===k?l():n.get().bind((e=>a.from(e[t]))).getOr([])}})(t,w(t),_(t));((t,e)=>{t.addCommand("mceEmoticons",(()=>E(t,e)))})(t,o),(t=>{const e=()=>t.execCommand("mceEmoticons");t.ui.registry.addButton("emoticons",{tooltip:"Emojis",icon:"emoji",onAction:e}),t.ui.registry.addMenuItem("emoticons",{text:"Emojis...",icon:"emoji",onAction:e})})(t),((t,e)=>{t.ui.registry.addAutocompleter("emoticons",{trigger:":",columns:"auto",minChars:2,fetch:(t,o)=>e.waitForLoad().then((()=>{const n=e.listAll();return T(n,t,a.some(o))})),onAction:(e,o,n)=>{t.selection.setRng(o),t.insertContent(n),e.hide()}})})(t,o),(t=>{t.on("PreInit",(()=>{t.parser.addAttributeFilter("data-emoticon",(t=>{((t,e)=>{for(let e=0,n=t.length;e{let t=e;return{get:()=>t,set:e=>{t=e}}};var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const n=e=>t=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(n=r=e,(o=String).prototype.isPrototypeOf(n)||(null===(s=r.constructor)||void 0===s?void 0:s.name)===o.name)?"string":t;var n,r,o,s})(t)===e,r=e=>t=>typeof t===e,o=e=>t=>e===t,s=n("string"),i=n("array"),l=o(null),a=r("boolean"),c=o(void 0),u=e=>!(e=>null==e)(e),d=r("function"),m=r("number"),h=()=>{},g=e=>()=>e;function p(e,...t){return(...n)=>{const r=t.concat(n);return e.apply(null,r)}}const f=g(!1),v=g(!0);class w{constructor(e,t){this.tag=e,this.value=t}static some(e){return new w(!0,e)}static none(){return w.singletonNone}fold(e,t){return this.tag?t(this.value):e()}isSome(){return this.tag}isNone(){return!this.tag}map(e){return this.tag?w.some(e(this.value)):w.none()}bind(e){return this.tag?e(this.value):w.none()}exists(e){return this.tag&&e(this.value)}forall(e){return!this.tag||e(this.value)}filter(e){return!this.tag||e(this.value)?this:w.none()}getOr(e){return this.tag?this.value:e}or(e){return this.tag?this:e}getOrThunk(e){return this.tag?this.value:e()}orThunk(e){return this.tag?this:e()}getOrDie(e){if(this.tag)return this.value;throw new Error(null!=e?e:"Called getOrDie on None")}static from(e){return u(e)?w.some(e):w.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(e){this.tag&&e(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}w.singletonNone=new w(!1);const y=t=>{const n=e(w.none()),r=()=>n.get().each(t);return{clear:()=>{r(),n.set(w.none())},isSet:()=>n.get().isSome(),get:()=>n.get(),set:e=>{r(),n.set(w.some(e))}}},b=()=>y((e=>e.unbind())),S=Array.prototype.push,x=(e,t)=>{const n=e.length,r=new Array(n);for(let o=0;o{for(let n=0,r=e.length;n{const n=[];for(let r=0,o=e.length;r((e,t,n)=>{for(let r=0,o=e.length;r{const o=e.indexOf(t,n);return-1!==o&&(!!c(r)||o+t.length<=r)},C=e=>void 0!==e.style&&d(e.style.getPropertyValue),A=e=>{if(null==e)throw new Error("Node cannot be null or undefined");return{dom:e}},R=A;"undefined"!=typeof window?window:Function("return this;")();const L=e=>t=>(e=>e.dom.nodeType)(t)===e,M=L(1),N=L(3),P=L(9),D=L(11),W=(e,t)=>{const n=e.dom;if(1!==n.nodeType)return!1;{const e=n;if(void 0!==e.matches)return e.matches(t);if(void 0!==e.msMatchesSelector)return e.msMatchesSelector(t);if(void 0!==e.webkitMatchesSelector)return e.webkitMatchesSelector(t);if(void 0!==e.mozMatchesSelector)return e.mozMatchesSelector(t);throw new Error("Browser lacks native selectors")}},q=e=>R(e.dom.ownerDocument),H=e=>x(e.dom.childNodes,R),I=d(Element.prototype.attachShadow)&&d(Node.prototype.getRootNode),B=g(I),V=I?e=>R(e.dom.getRootNode()):e=>P(e)?e:q(e),_=e=>{const t=V(e);return D(n=t)&&u(n.dom.host)?w.some(t):w.none();var n},j=e=>R(e.dom.host),z=e=>{const t=N(e)?e.dom.parentNode:e.dom;if(null==t||null===t.ownerDocument)return!1;const n=t.ownerDocument;return _(R(t)).fold((()=>n.body.contains(t)),(r=z,o=j,e=>r(o(e))));var r,o},$=(e,t)=>{const n=e.dom.getAttribute(t);return null===n?void 0:n},U=(e,t)=>{e.dom.removeAttribute(t)},K=(e,t)=>{const n=e.dom;((e,t)=>{const n=T(e);for(let r=0,o=n.length;r{((e,t,n)=>{if(!s(n))throw console.error("Invalid call to CSS.set. Property ",t,":: Value ",n,":: Element ",e),new Error("CSS value must be a string: "+n);C(e)&&e.style.setProperty(t,n)})(n,t,e)}))},X=e=>{const t=R((e=>{if(B()&&u(e.target)){const t=R(e.target);if(M(t)&&u(t.dom.shadowRoot)&&e.composed&&e.composedPath){const t=e.composedPath();if(t)return((e,t)=>0e.stopPropagation(),r=()=>e.preventDefault(),o=(s=r,i=n,(...e)=>s(i.apply(null,e)));var s,i;return((e,t,n,r,o,s,i)=>({target:e,x:t,y:n,stop:r,prevent:o,kill:s,raw:i}))(t,e.clientX,e.clientY,n,r,o,e)},Y=(e,t,n,r)=>{e.dom.removeEventListener(t,n,r)},G=v,J=(e,t,n)=>((e,t,n,r)=>((e,t,n,r,o)=>{const s=((e,t)=>n=>{e(n)&&t(X(n))})(n,r);return e.dom.addEventListener(t,s,o),{unbind:p(Y,e,t,s,o)}})(e,t,n,r,!1))(e,t,G,n),Q=()=>Z(0,0),Z=(e,t)=>({major:e,minor:t}),ee={nu:Z,detect:(e,t)=>{const n=String(t).toLowerCase();return 0===e.length?Q():((e,t)=>{const n=((e,t)=>{for(let n=0;nNumber(t.replace(n,"$"+e));return Z(r(1),r(2))})(e,n)},unknown:Q},te=(e,t)=>{const n=String(t).toLowerCase();return O(e,(e=>e.search(n)))},ne=/.*?version\/\ ?([0-9]+)\.([0-9]+).*/,re=e=>t=>k(t,e),oe=[{name:"Edge",versionRegexes:[/.*?edge\/ ?([0-9]+)\.([0-9]+)$/],search:e=>k(e,"edge/")&&k(e,"chrome")&&k(e,"safari")&&k(e,"applewebkit")},{name:"Chromium",brand:"Chromium",versionRegexes:[/.*?chrome\/([0-9]+)\.([0-9]+).*/,ne],search:e=>k(e,"chrome")&&!k(e,"chromeframe")},{name:"IE",versionRegexes:[/.*?msie\ ?([0-9]+)\.([0-9]+).*/,/.*?rv:([0-9]+)\.([0-9]+).*/],search:e=>k(e,"msie")||k(e,"trident")},{name:"Opera",versionRegexes:[ne,/.*?opera\/([0-9]+)\.([0-9]+).*/],search:re("opera")},{name:"Firefox",versionRegexes:[/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/],search:re("firefox")},{name:"Safari",versionRegexes:[ne,/.*?cpu os ([0-9]+)_([0-9]+).*/],search:e=>(k(e,"safari")||k(e,"mobile/"))&&k(e,"applewebkit")}],se=[{name:"Windows",search:re("win"),versionRegexes:[/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/]},{name:"iOS",search:e=>k(e,"iphone")||k(e,"ipad"),versionRegexes:[/.*?version\/\ ?([0-9]+)\.([0-9]+).*/,/.*cpu os ([0-9]+)_([0-9]+).*/,/.*cpu iphone os ([0-9]+)_([0-9]+).*/]},{name:"Android",search:re("android"),versionRegexes:[/.*?android\ ?([0-9]+)\.([0-9]+).*/]},{name:"macOS",search:re("mac os x"),versionRegexes:[/.*?mac\ os\ x\ ?([0-9]+)_([0-9]+).*/]},{name:"Linux",search:re("linux"),versionRegexes:[]},{name:"Solaris",search:re("sunos"),versionRegexes:[]},{name:"FreeBSD",search:re("freebsd"),versionRegexes:[]},{name:"ChromeOS",search:re("cros"),versionRegexes:[/.*?chrome\/([0-9]+)\.([0-9]+).*/]}],ie={browsers:g(oe),oses:g(se)},le="Edge",ae="Chromium",ce="Opera",ue="Firefox",de="Safari",me=e=>{const t=e.current,n=e.version,r=e=>()=>t===e;return{current:t,version:n,isEdge:r(le),isChromium:r(ae),isIE:r("IE"),isOpera:r(ce),isFirefox:r(ue),isSafari:r(de)}},he=()=>me({current:void 0,version:ee.unknown()}),ge=me,pe=(g(le),g(ae),g("IE"),g(ce),g(ue),g(de),"Windows"),fe="Android",ve="Linux",we="macOS",ye="Solaris",be="FreeBSD",Se="ChromeOS",xe=e=>{const t=e.current,n=e.version,r=e=>()=>t===e;return{current:t,version:n,isWindows:r(pe),isiOS:r("iOS"),isAndroid:r(fe),isMacOS:r(we),isLinux:r(ve),isSolaris:r(ye),isFreeBSD:r(be),isChromeOS:r(Se)}},Ee=()=>xe({current:void 0,version:ee.unknown()}),Fe=xe,Oe=(g(pe),g("iOS"),g(fe),g(ve),g(we),g(ye),g(be),g(Se),(e,t,n)=>{const r=ie.browsers(),o=ie.oses(),s=t.bind((e=>((e,t)=>((e,t)=>{for(let n=0;n{const n=t.brand.toLowerCase();return O(e,(e=>{var t;return n===(null===(t=e.brand)||void 0===t?void 0:t.toLowerCase())})).map((e=>({current:e.name,version:ee.nu(parseInt(t.version,10),0)})))})))(r,e))).orThunk((()=>((e,t)=>te(e,t).map((e=>{const n=ee.detect(e.versionRegexes,t);return{current:e.name,version:n}})))(r,e))).fold(he,ge),i=((e,t)=>te(e,t).map((e=>{const n=ee.detect(e.versionRegexes,t);return{current:e.name,version:n}})))(o,e).fold(Ee,Fe),l=((e,t,n,r)=>{const o=e.isiOS()&&!0===/ipad/i.test(n),s=e.isiOS()&&!o,i=e.isiOS()||e.isAndroid(),l=i||r("(pointer:coarse)"),a=o||!s&&i&&r("(min-device-width:768px)"),c=s||i&&!a,u=t.isSafari()&&e.isiOS()&&!1===/safari/i.test(n),d=!c&&!a&&!u;return{isiPad:g(o),isiPhone:g(s),isTablet:g(a),isPhone:g(c),isTouch:g(l),isAndroid:e.isAndroid,isiOS:e.isiOS,isWebView:g(u),isDesktop:g(d)}})(i,s,e,n);return{browser:s,os:i,deviceType:l}}),Te=e=>window.matchMedia(e).matches;let ke=(e=>{let t,n=!1;return(...r)=>(n||(n=!0,t=e.apply(null,r)),t)})((()=>Oe(navigator.userAgent,w.from(navigator.userAgentData),Te)));const Ce=(e,t)=>({left:e,top:t,translate:(n,r)=>Ce(e+n,t+r)}),Ae=Ce,Re=e=>{const t=void 0===e?window:e;return ke().browser.isFirefox()?w.none():w.from(t.visualViewport)},Le=(e,t,n,r)=>({x:e,y:t,width:n,height:r,right:e+n,bottom:t+r}),Me=e=>{const t=void 0===e?window:e,n=t.document,r=(e=>{const t=void 0!==e?e.dom:document,n=t.body.scrollLeft||t.documentElement.scrollLeft,r=t.body.scrollTop||t.documentElement.scrollTop;return Ae(n,r)})(R(n));return Re(t).fold((()=>{const e=t.document.documentElement,n=e.clientWidth,o=e.clientHeight;return Le(r.left,r.top,n,o)}),(e=>Le(Math.max(e.pageLeft,r.left),Math.max(e.pageTop,r.top),e.width,e.height)))},Ne=(e,t,n)=>Re(n).map((n=>{const r=e=>t(X(e));return n.addEventListener(e,r),{unbind:()=>n.removeEventListener(e,r)}})).getOrThunk((()=>({unbind:h})));var Pe=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),De=tinymce.util.Tools.resolve("tinymce.Env");const We=(e,t)=>{e.dispatch("FullscreenStateChanged",{state:t}),e.dispatch("ResizeEditor")},qe=("fullscreen_native",e=>e.options.get("fullscreen_native"));const He=e=>{return e.dom===(void 0!==(t=q(e).dom).fullscreenElement?t.fullscreenElement:void 0!==t.msFullscreenElement?t.msFullscreenElement:void 0!==t.webkitFullscreenElement?t.webkitFullscreenElement:null);var t},Ie=(e,t,n)=>((e,t,n)=>F(((e,t)=>{const n=d(t)?t:f;let r=e.dom;const o=[];for(;null!==r.parentNode&&void 0!==r.parentNode;){const e=r.parentNode,t=R(e);if(o.push(t),!0===n(t))break;r=e}return o})(e,n),t))(e,(e=>W(e,t)),n),Be=(e,t)=>((e,n)=>{return F((e=>w.from(e.dom.parentNode).map(R))(r=e).map(H).map((e=>F(e,(e=>{return t=e,!(r.dom===t.dom);var t})))).getOr([]),(e=>W(e,t)));var r})(e),Ve="data-ephox-mobile-fullscreen-style",_e="position:absolute!important;",je="top:0!important;left:0!important;margin:0!important;padding:0!important;width:100%!important;height:100%!important;overflow:visible!important;",ze=De.os.isAndroid(),$e=e=>{const t=((e,t)=>{const n=e.dom,r=window.getComputedStyle(n).getPropertyValue(t);return""!==r||z(e)?r:((e,t)=>C(e)?e.style.getPropertyValue(t):"")(n,t)})(e,"background-color");return void 0!==t&&""!==t?"background-color:"+t+"!important":"background-color:rgb(255,255,255)!important;"},Ue=Pe.DOM,Ke=Re().fold((()=>({bind:h,unbind:h})),(e=>{const t=(()=>{const e=y(h);return{...e,on:t=>e.get().each(t)}})(),n=b(),r=b(),o=((e,t)=>{let n=null;return{cancel:()=>{l(n)||(clearTimeout(n),n=null)},throttle:(...t)=>{l(n)&&(n=setTimeout((()=>{n=null,e.apply(null,t)}),50))}}})((()=>{document.body.scrollTop=0,document.documentElement.scrollTop=0,window.requestAnimationFrame((()=>{t.on((t=>K(t,{top:e.offsetTop+"px",left:e.offsetLeft+"px",height:e.height+"px",width:e.width+"px"})))}))}));return{bind:e=>{t.set(e),o.throttle(),n.set(Ne("resize",o.throttle)),r.set(Ne("scroll",o.throttle))},unbind:()=>{t.on((()=>{n.clear(),r.clear()})),t.clear()}}})),Xe=(e,t)=>{const n=document.body,r=document.documentElement,o=e.getContainer(),l=R(o),c=(e=>{const t=R(e.getElement());return _(t).map(j).getOrThunk((()=>(e=>{const t=e.dom.body;if(null==t)throw new Error("Body is not available yet");return R(t)})(q(t))))})(e),u=t.get(),d=R(e.getBody()),h=De.deviceType.isTouch(),g=o.style,p=e.iframeElement,f=null==p?void 0:p.style,v=e=>{e(n,"tox-fullscreen"),e(r,"tox-fullscreen"),e(o,"tox-fullscreen"),_(l).map((e=>j(e).dom)).each((t=>{e(t,"tox-fullscreen"),e(t,"tox-shadowhost")}))},y=()=>{h&&(e=>{const t=((e,t)=>{const n=document;return 1!==(r=n).nodeType&&9!==r.nodeType&&11!==r.nodeType||0===r.childElementCount?[]:x(n.querySelectorAll(e),R);var r})("["+Ve+"]");E(t,(t=>{const n=$(t,Ve);n&&"no-styles"!==n?K(t,e.parseStyle(n)):U(t,"style"),U(t,Ve)}))})(e.dom),v(Ue.removeClass),Ke.unbind(),w.from(t.get()).each((e=>e.fullscreenChangeHandler.unbind()))};if(u)u.fullscreenChangeHandler.unbind(),qe(e)&&He(c)&&(e=>{const t=e.dom;t.exitFullscreen?t.exitFullscreen():t.msExitFullscreen?t.msExitFullscreen():t.webkitCancelFullScreen&&t.webkitCancelFullScreen()})(q(c)),f.width=u.iframeWidth,f.height=u.iframeHeight,g.width=u.containerWidth,g.height=u.containerHeight,g.top=u.containerTop,g.left=u.containerLeft,y(),b=u.scrollPos,window.scrollTo(b.x,b.y),t.set(null),We(e,!1),e.off("remove",y);else{const n=J(q(c),void 0!==document.fullscreenElement?"fullscreenchange":void 0!==document.msFullscreenElement?"MSFullscreenChange":void 0!==document.webkitFullscreenElement?"webkitfullscreenchange":"fullscreenchange",(n=>{qe(e)&&(He(c)||null===t.get()||Xe(e,t))})),r={scrollPos:Me(window),containerWidth:g.width,containerHeight:g.height,containerTop:g.top,containerLeft:g.left,iframeWidth:f.width,iframeHeight:f.height,fullscreenChangeHandler:n};h&&((e,t,n)=>{const r=t=>n=>{const r=$(n,"style"),o=void 0===r?"no-styles":r.trim();o!==t&&(((e,t,n)=>{((e,t,n)=>{if(!(s(n)||a(n)||m(n)))throw console.error("Invalid call to Attribute.set. Key ",t,":: Value ",n,":: Element ",e),new Error("Attribute value was not simple");e.setAttribute(t,n+"")})(e.dom,t,n)})(n,Ve,o),K(n,e.parseStyle(t)))},o=Ie(t,"*"),l=(e=>{const t=[];for(let n=0,r=e.length;nBe(e,"*:not(.tox-silver-sink)")))),c=$e(n);E(l,r("display:none!important;")),E(o,r(_e+je+c)),r((!0===ze?"":_e)+je+c)(t)})(e.dom,l,d),f.width=f.height="100%",g.width=g.height="",v(Ue.addClass),Ke.bind(l),e.on("remove",y),t.set(r),qe(e)&&(e=>{const t=e.dom;t.requestFullscreen?t.requestFullscreen():t.msRequestFullscreen?t.msRequestFullscreen():t.webkitRequestFullScreen&&t.webkitRequestFullScreen()})(c),We(e,!0)}var b},Ye=(e,t)=>n=>{n.setActive(null!==t.get());const r=e=>n.setActive(e.state);return e.on("FullscreenStateChanged",r),()=>e.off("FullscreenStateChanged",r)};t.add("fullscreen",(t=>{const n=e(null);return t.inline||((e=>{(0,e.options.register)("fullscreen_native",{processor:"boolean",default:!1})})(t),((e,t)=>{e.addCommand("mceFullScreen",(()=>{Xe(e,t)}))})(t,n),((e,t)=>{const n=()=>e.execCommand("mceFullScreen");e.ui.registry.addToggleMenuItem("fullscreen",{text:"Fullscreen",icon:"fullscreen",shortcut:"Meta+Shift+F",onAction:n,onSetup:Ye(e,t)}),e.ui.registry.addToggleButton("fullscreen",{tooltip:"Fullscreen",icon:"fullscreen",onAction:n,onSetup:Ye(e,t)})})(t,n),t.addShortcut("Meta+Shift+F","","mceFullScreen")),(e=>({isFullscreen:()=>null!==e.get()}))(n)}))}(); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/help/plugin.min.js b/public/resource/tinymce/plugins/help/plugin.min.js new file mode 100644 index 0000000..7c330c7 --- /dev/null +++ b/public/resource/tinymce/plugins/help/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.4.2 (2023-04-26) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");let t=0;const n=e=>{const n=(new Date).getTime(),a=Math.floor(1e9*Math.random());return t++,e+"_"+a+t+String(n)},a=e=>t=>t.options.get(e),o=a("help_tabs"),i=a("forced_plugins"),r=("string",e=>"string"===(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(n=a=e,(o=String).prototype.isPrototypeOf(n)||(null===(i=a.constructor)||void 0===i?void 0:i.name)===o.name)?"string":t;var n,a,o,i})(e));const s=(void 0,e=>undefined===e);const l=e=>"function"==typeof e,c=(!1,()=>false);class u{constructor(e,t){this.tag=e,this.value=t}static some(e){return new u(!0,e)}static none(){return u.singletonNone}fold(e,t){return this.tag?t(this.value):e()}isSome(){return this.tag}isNone(){return!this.tag}map(e){return this.tag?u.some(e(this.value)):u.none()}bind(e){return this.tag?e(this.value):u.none()}exists(e){return this.tag&&e(this.value)}forall(e){return!this.tag||e(this.value)}filter(e){return!this.tag||e(this.value)?this:u.none()}getOr(e){return this.tag?this.value:e}or(e){return this.tag?this:e}getOrThunk(e){return this.tag?this.value:e()}orThunk(e){return this.tag?this:e()}getOrDie(e){if(this.tag)return this.value;throw new Error(null!=e?e:"Called getOrDie on None")}static from(e){return null==e?u.none():u.some(e)}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(e){this.tag&&e(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}u.singletonNone=new u(!1);const m=Array.prototype.slice,h=Array.prototype.indexOf,p=(e,t)=>{const n=e.length,a=new Array(n);for(let o=0;o{const n=[];for(let a=0,o=e.length;a{const n=m.call(e,0);return n.sort(t),n},y=Object.keys,b=Object.hasOwnProperty,k=(e,t)=>b.call(e,t);var v=tinymce.util.Tools.resolve("tinymce.Env");const f=e=>{const t=v.os.isMacOS()||v.os.isiOS(),n=t?{alt:"⌥",ctrl:"⌃",shift:"⇧",meta:"⌘",access:"⌃⌥"}:{meta:"Ctrl ",access:"Shift + Alt "},a=e.split("+"),o=p(a,(e=>{const t=e.toLowerCase().trim();return k(n,t)?n[t]:e}));return t?o.join("").replace(/\s/,""):o.join("+")},w=[{shortcuts:["Meta + B"],action:"Bold"},{shortcuts:["Meta + I"],action:"Italic"},{shortcuts:["Meta + U"],action:"Underline"},{shortcuts:["Meta + A"],action:"Select all"},{shortcuts:["Meta + Y","Meta + Shift + Z"],action:"Redo"},{shortcuts:["Meta + Z"],action:"Undo"},{shortcuts:["Access + 1"],action:"Heading 1"},{shortcuts:["Access + 2"],action:"Heading 2"},{shortcuts:["Access + 3"],action:"Heading 3"},{shortcuts:["Access + 4"],action:"Heading 4"},{shortcuts:["Access + 5"],action:"Heading 5"},{shortcuts:["Access + 6"],action:"Heading 6"},{shortcuts:["Access + 7"],action:"Paragraph"},{shortcuts:["Access + 8"],action:"Div"},{shortcuts:["Access + 9"],action:"Address"},{shortcuts:["Alt + 0"],action:"Open help dialog"},{shortcuts:["Alt + F9"],action:"Focus to menubar"},{shortcuts:["Alt + F10"],action:"Focus to toolbar"},{shortcuts:["Alt + F11"],action:"Focus to element path"},{shortcuts:["Ctrl + F9"],action:"Focus to contextual toolbar"},{shortcuts:["Shift + Enter"],action:"Open popup menu for split buttons"},{shortcuts:["Meta + K"],action:"Insert link (if link plugin activated)"},{shortcuts:["Meta + S"],action:"Save (if save plugin activated)"},{shortcuts:["Meta + F"],action:"Find (if searchreplace plugin activated)"},{shortcuts:["Meta + Shift + F"],action:"Switch to or from fullscreen mode"}],A=()=>({name:"shortcuts",title:"Handy Shortcuts",items:[{type:"table",header:["Action","Shortcut"],cells:p(w,(e=>{const t=p(e.shortcuts,f).join(" or ");return[e.action,t]}))}]});var T=tinymce.util.Tools.resolve("tinymce.util.I18n");const x=p([{key:"advlist",name:"Advanced List"},{key:"anchor",name:"Anchor"},{key:"autolink",name:"Autolink"},{key:"autoresize",name:"Autoresize"},{key:"autosave",name:"Autosave"},{key:"charmap",name:"Character Map"},{key:"code",name:"Code"},{key:"codesample",name:"Code Sample"},{key:"colorpicker",name:"Color Picker"},{key:"directionality",name:"Directionality"},{key:"emoticons",name:"Emoticons"},{key:"fullscreen",name:"Full Screen"},{key:"help",name:"Help"},{key:"image",name:"Image"},{key:"importcss",name:"Import CSS"},{key:"insertdatetime",name:"Insert Date/Time"},{key:"link",name:"Link"},{key:"lists",name:"Lists"},{key:"media",name:"Media"},{key:"nonbreaking",name:"Nonbreaking"},{key:"pagebreak",name:"Page Break"},{key:"preview",name:"Preview"},{key:"quickbars",name:"Quick Toolbars"},{key:"save",name:"Save"},{key:"searchreplace",name:"Search and Replace"},{key:"table",name:"Table"},{key:"template",name:"Template"},{key:"textcolor",name:"Text Color"},{key:"visualblocks",name:"Visual Blocks"},{key:"visualchars",name:"Visual Characters"},{key:"wordcount",name:"Word Count"},{key:"a11ychecker",name:"Accessibility Checker",type:"premium"},{key:"advcode",name:"Advanced Code Editor",type:"premium"},{key:"advtable",name:"Advanced Tables",type:"premium"},{key:"advtemplate",name:"Advanced Templates",type:"premium",slug:"advanced-templates"},{key:"casechange",name:"Case Change",type:"premium"},{key:"checklist",name:"Checklist",type:"premium"},{key:"editimage",name:"Enhanced Image Editing",type:"premium"},{key:"footnotes",name:"Footnotes",type:"premium"},{key:"typography",name:"Advanced Typography",type:"premium",slug:"advanced-typography"},{key:"mediaembed",name:"Enhanced Media Embed",type:"premium",slug:"introduction-to-mediaembed"},{key:"export",name:"Export",type:"premium"},{key:"formatpainter",name:"Format Painter",type:"premium"},{key:"inlinecss",name:"Inline CSS",type:"premium",slug:"inline-css"},{key:"linkchecker",name:"Link Checker",type:"premium"},{key:"mentions",name:"Mentions",type:"premium"},{key:"mergetags",name:"Merge Tags",type:"premium"},{key:"pageembed",name:"Page Embed",type:"premium"},{key:"permanentpen",name:"Permanent Pen",type:"premium"},{key:"powerpaste",name:"PowerPaste",type:"premium",slug:"introduction-to-powerpaste"},{key:"rtc",name:"Real-Time Collaboration",type:"premium",slug:"rtc-introduction"},{key:"tinymcespellchecker",name:"Spell Checker Pro",type:"premium",slug:"introduction-to-tiny-spellchecker"},{key:"autocorrect",name:"Spelling Autocorrect",type:"premium"},{key:"tableofcontents",name:"Table of Contents",type:"premium"},{key:"tinycomments",name:"Tiny Comments",type:"premium",slug:"introduction-to-tiny-comments"},{key:"tinydrive",name:"Tiny Drive",type:"premium",slug:"tinydrive-introduction"}],(e=>({...e,type:e.type||"opensource",slug:e.slug||e.key}))),C=e=>{const t=e=>`
    ${e.name}`,n=(e,n)=>{return(a=x,o=e=>e.key===n,((e,t,n)=>{for(let a=0,o=e.length;a((e,n)=>{const a=e.plugins[n].getMetadata;if(l(a)){const e=a();return{name:e.name,html:t(e)}}return{name:n,html:n}})(e,n)),(e=>{const n="premium"===e.type?`${e.name}*`:e.name;return{name:n,html:t({name:n,url:`https://www.tiny.cloud/docs/tinymce/6/${e.slug}/`})}}));var a,o},a=e=>{const t=(e=>{const t=y(e.plugins),n=i(e);return s(n)?t:d(t,(e=>!(((e,t)=>h.call(e,t))(n,e)>-1)))})(e),a=g(p(t,(t=>n(e,t))),((e,t)=>e.name.localeCompare(t.name))),o=p(a,(e=>"
  • "+e.html+"
  • ")),r=o.length,l=o.join("");return"

    "+T.translate(["Plugins installed ({0}):",r])+"

      "+l+"
    "},o={type:"htmlpanel",presets:"document",html:[(e=>null==e?"":'
    '+a(e)+"
    ")(e),(()=>{const e=d(x,(({type:e})=>"premium"===e)),t=g(p(e,(e=>e.name)),((e,t)=>e.localeCompare(t))),n=p(t,(e=>`
  • ${e}
  • `)).join("");return'

    '+T.translate("Premium plugins:")+"

    "})()].join("")};return{name:"plugins",title:"Plugins",items:[o]}};var M=tinymce.util.Tools.resolve("tinymce.EditorManager");const S=(e,t)=>()=>{const{tabs:a,names:i}=((e,t)=>{const a=A(),i={name:"keyboardnav",title:"Keyboard Navigation",items:[{type:"htmlpanel",presets:"document",html:"

    Editor UI keyboard navigation

    \n\n

    Activating keyboard navigation

    \n\n

    The sections of the outer UI of the editor - the menubar, toolbar, sidebar and footer - are all keyboard navigable. As such, there are multiple ways to activate keyboard navigation:

    \n
      \n
    • Focus the menubar: Alt + F9 (Windows) or ⌥F9 (MacOS)
    • \n
    • Focus the toolbar: Alt + F10 (Windows) or ⌥F10 (MacOS)
    • \n
    • Focus the footer: Alt + F11 (Windows) or ⌥F11 (MacOS)
    • \n
    \n\n

    Focusing the menubar or toolbar will start keyboard navigation at the first item in the menubar or toolbar, which will be highlighted with a gray background. Focusing the footer will start keyboard navigation at the first item in the element path, which will be highlighted with an underline.

    \n\n

    Moving between UI sections

    \n\n

    When keyboard navigation is active, pressing tab will move the focus to the next major section of the UI, where applicable. These sections are:

    \n
      \n
    • the menubar
    • \n
    • each group of the toolbar
    • \n
    • the sidebar
    • \n
    • the element path in the footer
    • \n
    • the wordcount toggle button in the footer
    • \n
    • the branding link in the footer
    • \n
    • the editor resize handle in the footer
    • \n
    \n\n

    Pressing shift + tab will move backwards through the same sections, except when moving from the footer to the toolbar. Focusing the element path then pressing shift + tab will move focus to the first toolbar group, not the last.

    \n\n

    Moving within UI sections

    \n\n

    Keyboard navigation within UI sections can usually be achieved using the left and right arrow keys. This includes:

    \n
      \n
    • moving between menus in the menubar
    • \n
    • moving between buttons in a toolbar group
    • \n
    • moving between items in the element path
    • \n
    \n\n

    In all these UI sections, keyboard navigation will cycle within the section. For example, focusing the last button in a toolbar group then pressing right arrow will move focus to the first item in the same toolbar group.

    \n\n

    Executing buttons

    \n\n

    To execute a button, navigate the selection to the desired button and hit space or enter.

    \n\n

    Opening, navigating and closing menus

    \n\n

    When focusing a menubar button or a toolbar button with a menu, pressing space, enter or down arrow will open the menu. When the menu opens the first item will be selected. To move up or down the menu, press the up or down arrow key respectively. This is the same for submenus, which can also be opened and closed using the left and right arrow keys.

    \n\n

    To close any active menu, hit the escape key. When a menu is closed the selection will be restored to its previous selection. This also works for closing submenus.

    \n\n

    Context toolbars and menus

    \n\n

    To focus an open context toolbar such as the table context toolbar, press Ctrl + F9 (Windows) or ⌃F9 (MacOS).

    \n\n

    Context toolbar navigation is the same as toolbar navigation, and context menu navigation is the same as standard menu navigation.

    \n\n

    Dialog navigation

    \n\n

    There are two types of dialog UIs in TinyMCE: tabbed dialogs and non-tabbed dialogs.

    \n\n

    When a non-tabbed dialog is opened, the first interactive component in the dialog will be focused. Users can navigate between interactive components by pressing tab. This includes any footer buttons. Navigation will cycle back to the first dialog component if tab is pressed while focusing the last component in the dialog. Pressing shift + tab will navigate backwards.

    \n\n

    When a tabbed dialog is opened, the first button in the tab menu is focused. Pressing tab will navigate to the first interactive component in that tab, and will cycle through the tab\u2019s components, the footer buttons, then back to the tab button. To switch to another tab, focus the tab button for the current tab, then use the arrow keys to cycle through the tab buttons.

    "}]},s=C(e),l=(()=>{var e,t;const n='TinyMCE '+(e=M.majorVersion,t=M.minorVersion,(0===e.indexOf("@")?"X.X.X":e+"."+t)+"");return{name:"versions",title:"Version",items:[{type:"htmlpanel",html:"

    "+T.translate(["You are using {0}",n])+"

    ",presets:"document"}]}})(),c={[a.name]:a,[i.name]:i,[s.name]:s,[l.name]:l,...t.get()};return u.from(o(e)).fold((()=>(e=>{const t=y(e),n=t.indexOf("versions");return-1!==n&&(t.splice(n,1),t.push("versions")),{tabs:e,names:t}})(c)),(e=>((e,t)=>{const a={},o=p(e,(e=>{var o;if(r(e))return k(t,e)&&(a[e]=t[e]),e;{const t=null!==(o=e.name)&&void 0!==o?o:n("tab-name");return a[t]=e,t}}));return{tabs:a,names:o}})(e,c)))})(e,t),s={type:"tabpanel",tabs:(e=>{const t=[],n=e=>{t.push(e)};for(let t=0;t{return k(t=a,n=e)?u.from(t[n]):u.none();var t,n})))};e.windowManager.open({title:"Help",size:"normal",body:s,buttons:[{type:"cancel",name:"close",text:"Close",primary:!0}],initialData:{}})};e.add("help",(e=>{const t=(e=>{let t={};return{get:()=>t,set:e=>{t=e}}})(),a=(e=>({addTab:t=>{var a;const o=null!==(a=t.name)&&void 0!==a?a:n("tab-name"),i=e.get();i[o]=t,e.set(i)}}))(t);(e=>{(0,e.options.register)("help_tabs",{processor:"array"})})(e);const o=S(e,t);return((e,t)=>{e.ui.registry.addButton("help",{icon:"help",tooltip:"Help",onAction:t}),e.ui.registry.addMenuItem("help",{text:"Help",icon:"help",shortcut:"Alt+0",onAction:t})})(e,o),((e,t)=>{e.addCommand("mceHelp",t)})(e,o),e.shortcuts.add("Alt+0","Open help dialog","mceHelp"),a}))}(); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/image/plugin.min.js b/public/resource/tinymce/plugins/image/plugin.min.js new file mode 100644 index 0000000..ceb4826 --- /dev/null +++ b/public/resource/tinymce/plugins/image/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.4.2 (2023-04-26) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=Object.getPrototypeOf,a=(e,t,a)=>{var i;return!!a(e,t.prototype)||(null===(i=e.constructor)||void 0===i?void 0:i.name)===t.name},i=e=>t=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&a(e,String,((e,t)=>t.isPrototypeOf(e)))?"string":t})(t)===e,s=e=>t=>typeof t===e,r=i("string"),o=i("object"),n=e=>((e,i)=>o(e)&&a(e,i,((e,a)=>t(e)===a)))(e,Object),l=i("array"),c=(null,e=>null===e);const m=s("boolean"),d=e=>!(e=>null==e)(e),g=s("function"),u=s("number"),p=()=>{};class h{constructor(e,t){this.tag=e,this.value=t}static some(e){return new h(!0,e)}static none(){return h.singletonNone}fold(e,t){return this.tag?t(this.value):e()}isSome(){return this.tag}isNone(){return!this.tag}map(e){return this.tag?h.some(e(this.value)):h.none()}bind(e){return this.tag?e(this.value):h.none()}exists(e){return this.tag&&e(this.value)}forall(e){return!this.tag||e(this.value)}filter(e){return!this.tag||e(this.value)?this:h.none()}getOr(e){return this.tag?this.value:e}or(e){return this.tag?this:e}getOrThunk(e){return this.tag?this.value:e()}orThunk(e){return this.tag?this:e()}getOrDie(e){if(this.tag)return this.value;throw new Error(null!=e?e:"Called getOrDie on None")}static from(e){return d(e)?h.some(e):h.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(e){this.tag&&e(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}h.singletonNone=new h(!1);const b=Object.keys,v=Object.hasOwnProperty,y=(e,t)=>v.call(e,t),f=Array.prototype.push,w=e=>{const t=[];for(let a=0,i=e.length;a{((e,t,a)=>{if(!(r(a)||m(a)||u(a)))throw console.error("Invalid call to Attribute.set. Key ",t,":: Value ",a,":: Element ",e),new Error("Attribute value was not simple");e.setAttribute(t,a+"")})(e.dom,t,a)},D=e=>{if(null==e)throw new Error("Node cannot be null or undefined");return{dom:e}},_=D;var C=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),I=tinymce.util.Tools.resolve("tinymce.util.URI");const U=e=>e.length>0,x=e=>t=>t.options.get(e),S=x("image_dimensions"),N=x("image_advtab"),T=x("image_uploadtab"),O=x("image_prepend_url"),L=x("image_class_list"),E=x("image_description"),j=x("image_title"),M=x("image_caption"),R=x("image_list"),k=x("a11y_advanced_options"),z=x("automatic_uploads"),P=(e,t)=>Math.max(parseInt(e,10),parseInt(t,10)),B=e=>(e&&(e=e.replace(/px$/,"")),e),F=e=>(e.length>0&&/^[0-9]+$/.test(e)&&(e+="px"),e),H=e=>"IMG"===e.nodeName&&(e.hasAttribute("data-mce-object")||e.hasAttribute("data-mce-placeholder")),G=(e,t)=>{const a=e.options.get;return I.isDomSafe(t,"img",{allow_html_data_urls:a("allow_html_data_urls"),allow_script_urls:a("allow_script_urls"),allow_svg_data_urls:a("allow_svg_data_urls")})},W=C.DOM,$=e=>e.style.marginLeft&&e.style.marginRight&&e.style.marginLeft===e.style.marginRight?B(e.style.marginLeft):"",V=e=>e.style.marginTop&&e.style.marginBottom&&e.style.marginTop===e.style.marginBottom?B(e.style.marginTop):"",K=e=>e.style.borderWidth?B(e.style.borderWidth):"",Z=(e,t)=>{var a;return e.hasAttribute(t)&&null!==(a=e.getAttribute(t))&&void 0!==a?a:""},q=e=>null!==e.parentNode&&"FIGURE"===e.parentNode.nodeName,J=(e,t,a)=>{""===a||null===a?e.removeAttribute(t):e.setAttribute(t,a)},Q=(e,t)=>{const a=e.getAttribute("style"),i=t(null!==a?a:"");i.length>0?(e.setAttribute("style",i),e.setAttribute("data-mce-style",i)):e.removeAttribute("style")},X=(e,t)=>(e,a,i)=>{const s=e.style;s[a]?(s[a]=F(i),Q(e,t)):J(e,a,i)},Y=(e,t)=>e.style[t]?B(e.style[t]):Z(e,t),ee=(e,t)=>{const a=F(t);e.style.marginLeft=a,e.style.marginRight=a},te=(e,t)=>{const a=F(t);e.style.marginTop=a,e.style.marginBottom=a},ae=(e,t)=>{const a=F(t);e.style.borderWidth=a},ie=(e,t)=>{e.style.borderStyle=t},se=e=>{var t;return null!==(t=e.style.borderStyle)&&void 0!==t?t:""},re=e=>d(e)&&"FIGURE"===e.nodeName,oe=e=>0===W.getAttrib(e,"alt").length&&"presentation"===W.getAttrib(e,"role"),ne=e=>oe(e)?"":Z(e,"alt"),le=(e,t)=>{var a;const i=document.createElement("img");return J(i,"style",t.style),($(i)||""!==t.hspace)&&ee(i,t.hspace),(V(i)||""!==t.vspace)&&te(i,t.vspace),(K(i)||""!==t.border)&&ae(i,t.border),(se(i)||""!==t.borderStyle)&&ie(i,t.borderStyle),e(null!==(a=i.getAttribute("style"))&&void 0!==a?a:"")},ce=(e,t)=>({src:Z(t,"src"),alt:ne(t),title:Z(t,"title"),width:Y(t,"width"),height:Y(t,"height"),class:Z(t,"class"),style:e(Z(t,"style")),caption:q(t),hspace:$(t),vspace:V(t),border:K(t),borderStyle:se(t),isDecorative:oe(t)}),me=(e,t,a,i,s)=>{a[i]!==t[i]&&s(e,i,String(a[i]))},de=(e,t,a)=>{if(a){W.setAttrib(e,"role","presentation");const t=_(e);A(t,"alt","")}else{if(c(t)){"alt",_(e).dom.removeAttribute("alt")}else{const a=_(e);A(a,"alt",t)}"presentation"===W.getAttrib(e,"role")&&W.setAttrib(e,"role","")}},ge=(e,t)=>(a,i,s)=>{e(a,s),Q(a,t)},ue=(e,t,a)=>{const i=ce(e,a);me(a,i,t,"caption",((e,t,a)=>(e=>{q(e)?(e=>{const t=e.parentNode;d(t)&&(W.insertAfter(e,t),W.remove(t))})(e):(e=>{const t=W.create("figure",{class:"image"});W.insertAfter(t,e),t.appendChild(e),t.appendChild(W.create("figcaption",{contentEditable:"true"},"Caption")),t.contentEditable="false"})(e)})(e))),me(a,i,t,"src",J),me(a,i,t,"title",J),me(a,i,t,"width",X(0,e)),me(a,i,t,"height",X(0,e)),me(a,i,t,"class",J),me(a,i,t,"style",ge(((e,t)=>J(e,"style",t)),e)),me(a,i,t,"hspace",ge(ee,e)),me(a,i,t,"vspace",ge(te,e)),me(a,i,t,"border",ge(ae,e)),me(a,i,t,"borderStyle",ge(ie,e)),((e,t,a)=>{a.alt===t.alt&&a.isDecorative===t.isDecorative||de(e,a.alt,a.isDecorative)})(a,i,t)},pe=(e,t)=>{const a=(e=>{if(e.margin){const t=String(e.margin).split(" ");switch(t.length){case 1:e["margin-top"]=e["margin-top"]||t[0],e["margin-right"]=e["margin-right"]||t[0],e["margin-bottom"]=e["margin-bottom"]||t[0],e["margin-left"]=e["margin-left"]||t[0];break;case 2:e["margin-top"]=e["margin-top"]||t[0],e["margin-right"]=e["margin-right"]||t[1],e["margin-bottom"]=e["margin-bottom"]||t[0],e["margin-left"]=e["margin-left"]||t[1];break;case 3:e["margin-top"]=e["margin-top"]||t[0],e["margin-right"]=e["margin-right"]||t[1],e["margin-bottom"]=e["margin-bottom"]||t[2],e["margin-left"]=e["margin-left"]||t[1];break;case 4:e["margin-top"]=e["margin-top"]||t[0],e["margin-right"]=e["margin-right"]||t[1],e["margin-bottom"]=e["margin-bottom"]||t[2],e["margin-left"]=e["margin-left"]||t[3]}delete e.margin}return e})(e.dom.styles.parse(t)),i=e.dom.styles.parse(e.dom.styles.serialize(a));return e.dom.styles.serialize(i)},he=e=>{const t=e.selection.getNode(),a=e.dom.getParent(t,"figure.image");return a?e.dom.select("img",a)[0]:t&&("IMG"!==t.nodeName||H(t))?null:t},be=(e,t)=>{var a;const i=e.dom,s=((t,a)=>{const i={};var s;return((e,t,a,i)=>{((e,t)=>{const a=b(e);for(let i=0,s=a.length;i{(t(e,s)?a:i)(e,s)}))})(t,((t,a)=>!e.schema.isValidChild(a,"figure")),(s=i,(e,t)=>{s[t]=e}),p),i})(e.schema.getTextBlockElements()),r=i.getParent(t.parentNode,(e=>{return t=s,a=e.nodeName,y(t,a)&&void 0!==t[a]&&null!==t[a];var t,a}),e.getBody());return r&&null!==(a=i.split(r,t))&&void 0!==a?a:t},ve=(e,t)=>{const a=((t,a)=>{const i=document.createElement("img");if(ue((t=>pe(e,t)),{...a,caption:!1},i),de(i,a.alt,a.isDecorative),a.caption){const e=W.create("figure",{class:"image"});return e.appendChild(i),e.appendChild(W.create("figcaption",{contentEditable:"true"},"Caption")),e.contentEditable="false",e}return i})(0,t);e.dom.setAttrib(a,"data-mce-id","__mcenew"),e.focus(),e.selection.setContent(a.outerHTML);const i=e.dom.select('*[data-mce-id="__mcenew"]')[0];if(e.dom.setAttrib(i,"data-mce-id",null),re(i)){const t=be(e,i);e.selection.select(t)}else e.selection.select(i)},ye=(e,t)=>{const a=he(e);if(a){const i={...ce((t=>pe(e,t)),a),...t},s=((e,t)=>{const a=t.src;return{...t,src:G(e,a)?a:""}})(e,i);i.src?((e,t)=>{const a=he(e);if(a)if(ue((t=>pe(e,t)),t,a),((e,t)=>{e.dom.setAttrib(t,"src",t.getAttribute("src"))})(e,a),re(a.parentNode)){const t=a.parentNode;be(e,t),e.selection.select(a.parentNode)}else e.selection.select(a),((e,t,a)=>{const i=()=>{a.onload=a.onerror=null,e.selection&&(e.selection.select(a),e.nodeChanged())};a.onload=()=>{t.width||t.height||!S(e)||e.dom.setAttribs(a,{width:String(a.clientWidth),height:String(a.clientHeight)}),i()},a.onerror=i})(e,t,a)})(e,s):((e,t)=>{if(t){const a=e.dom.is(t.parentNode,"figure.image")?t.parentNode:t;e.dom.remove(a),e.focus(),e.nodeChanged(),e.dom.isEmpty(e.getBody())&&(e.setContent(""),e.selection.setCursorLocation())}})(e,a)}else t.src&&ve(e,{src:"",alt:"",title:"",width:"",height:"",class:"",style:"",caption:!1,hspace:"",vspace:"",border:"",borderStyle:"",isDecorative:!1,...t})},fe=(we=(e,t)=>n(e)&&n(t)?fe(e,t):t,(...e)=>{if(0===e.length)throw new Error("Can't merge zero objects");const t={};for(let a=0;ar(e.value)?e.value:"",Ce=(e,t)=>{const a=[];return De.each(e,(e=>{const i=(e=>r(e.text)?e.text:r(e.title)?e.title:"")(e);if(void 0!==e.menu){const s=Ce(e.menu,t);a.push({text:i,items:s})}else{const s=t(e);a.push({text:i,value:s})}})),a},Ie=(e=_e)=>t=>t?h.from(t).map((t=>Ce(t,e))):h.none(),Ue=(e,t)=>((e,a)=>{for(let a=0;ay(e,"items"))(i=e[a])?Ue(i.items,t):i.value===t?h.some(i):h.none();if(s.isSome())return s}var i;return h.none()})(e),xe=Ie,Se=(e,t)=>e.bind((e=>Ue(e,t))),Ne=e=>{const t=xe((t=>e.convertURL(t.value||t.url||"","src"))),a=new Promise((a=>{((e,t)=>{const a=R(e);r(a)?fetch(a).then((e=>{e.ok&&e.json().then(t)})):g(a)?a(t):t(a)})(e,(e=>{a(t(e).map((e=>w([[{text:"None",value:""}],e]))))}))})),i=(A=L(e),Ie(_e)(A)),s=N(e),o=T(e),n=(e=>U(e.options.get("images_upload_url")))(e),l=(e=>d(e.options.get("images_upload_handler")))(e),c=(e=>{const t=he(e);return t?ce((t=>pe(e,t)),t):{src:"",alt:"",title:"",width:"",height:"",class:"",style:"",caption:!1,hspace:"",vspace:"",border:"",borderStyle:"",isDecorative:!1}})(e),m=E(e),u=j(e),p=S(e),b=M(e),v=k(e),y=z(e),f=h.some(O(e)).filter((e=>r(e)&&e.length>0));var A;return a.then((e=>({image:c,imageList:e,classList:i,hasAdvTab:s,hasUploadTab:o,hasUploadUrl:n,hasUploadHandler:l,hasDescription:m,hasImageTitle:u,hasDimensions:p,hasImageCaption:b,prependURL:f,hasAccessibilityOptions:v,automaticUploads:y})))},Te=e=>{const t=e.imageList.map((e=>({name:"images",type:"listbox",label:"Image list",items:e}))),a={name:"alt",type:"input",label:"Alternative description",enabled:!(e.hasAccessibilityOptions&&e.image.isDecorative)},i=e.classList.map((e=>({name:"classes",type:"listbox",label:"Class",items:e})));return w([[{name:"src",type:"urlinput",filetype:"image",label:"Source"}],t.toArray(),e.hasAccessibilityOptions&&e.hasDescription?[{type:"label",label:"Accessibility",items:[{name:"isDecorative",type:"checkbox",label:"Image is decorative"}]}]:[],e.hasDescription?[a]:[],e.hasImageTitle?[{name:"title",type:"input",label:"Image title"}]:[],e.hasDimensions?[{name:"dimensions",type:"sizeinput"}]:[],[{...(s=e.classList.isSome()&&e.hasImageCaption,s?{type:"grid",columns:2}:{type:"panel"}),items:w([i.toArray(),e.hasImageCaption?[{type:"label",label:"Caption",items:[{type:"checkbox",name:"caption",label:"Show caption"}]}]:[]])}]]);var s},Oe=e=>({title:"General",name:"general",items:Te(e)}),Le=Te,Ee=e=>({src:{value:e.src,meta:{}},images:e.src,alt:e.alt,title:e.title,dimensions:{width:e.width,height:e.height},classes:e.class,caption:e.caption,style:e.style,vspace:e.vspace,border:e.border,hspace:e.hspace,borderstyle:e.borderStyle,fileinput:[],isDecorative:e.isDecorative}),je=(e,t)=>({src:e.src.value,alt:null!==e.alt&&0!==e.alt.length||!t?e.alt:null,title:e.title,width:e.dimensions.width,height:e.dimensions.height,class:e.classes,style:e.style,caption:e.caption,hspace:e.hspace,vspace:e.vspace,border:e.border,borderStyle:e.borderstyle,isDecorative:e.isDecorative}),Me=(e,t,a,i)=>{((e,t)=>{const a=t.getData();((e,t)=>/^(?:[a-zA-Z]+:)?\/\//.test(t)?h.none():e.prependURL.bind((e=>t.substring(0,e.length)!==e?h.some(e+t):h.none())))(e,a.src.value).each((e=>{t.setData({src:{value:e,meta:a.src.meta}})}))})(t,i),((e,t)=>{const a=t.getData(),i=a.src.meta;if(void 0!==i){const s=fe({},a);((e,t,a)=>{e.hasDescription&&r(a.alt)&&(t.alt=a.alt),e.hasAccessibilityOptions&&(t.isDecorative=a.isDecorative||t.isDecorative||!1),e.hasImageTitle&&r(a.title)&&(t.title=a.title),e.hasDimensions&&(r(a.width)&&(t.dimensions.width=a.width),r(a.height)&&(t.dimensions.height=a.height)),r(a.class)&&Se(e.classList,a.class).each((e=>{t.classes=e.value})),e.hasImageCaption&&m(a.caption)&&(t.caption=a.caption),e.hasAdvTab&&(r(a.style)&&(t.style=a.style),r(a.vspace)&&(t.vspace=a.vspace),r(a.border)&&(t.border=a.border),r(a.hspace)&&(t.hspace=a.hspace),r(a.borderstyle)&&(t.borderstyle=a.borderstyle))})(e,s,i),t.setData(s)}})(t,i),((e,t,a,i)=>{const s=i.getData(),r=s.src.value,o=s.src.meta||{};o.width||o.height||!t.hasDimensions||(U(r)?e.imageSize(r).then((e=>{a.open&&i.setData({dimensions:e})})).catch((e=>console.error(e))):i.setData({dimensions:{width:"",height:""}}))})(e,t,a,i),((e,t,a)=>{const i=a.getData(),s=Se(e.imageList,i.src.value);t.prevImage=s,a.setData({images:s.map((e=>e.value)).getOr("")})})(t,a,i)},Re=(e,t,a,i)=>{const s=i.getData();var r;i.block("Uploading image"),(r=s.fileinput,((e,t)=>0{i.unblock()}),(s=>{const r=URL.createObjectURL(s),o=()=>{i.unblock(),URL.revokeObjectURL(r)},n=s=>{i.setData({src:{value:s,meta:{}}}),i.showTab("general"),Me(e,t,a,i)};var l;(l=s,new Promise(((e,t)=>{const a=new FileReader;a.onload=()=>{e(a.result)},a.onerror=()=>{var e;t(null===(e=a.error)||void 0===e?void 0:e.message)},a.readAsDataURL(l)}))).then((a=>{const l=e.createBlobCache(s,r,a);t.automaticUploads?e.uploadImage(l).then((e=>{n(e.url),o()})).catch((t=>{o(),e.alertErr(t)})):(e.addToBlobCache(l),n(l.blobUri()),i.unblock())}))}))},ke=(e,t,a)=>(i,s)=>{"src"===s.name?Me(e,t,a,i):"images"===s.name?((e,t,a,i)=>{const s=i.getData(),r=Se(t.imageList,s.images);r.each((e=>{const t=""===s.alt||a.prevImage.map((e=>e.text===s.alt)).getOr(!1);t?""===e.value?i.setData({src:e,alt:a.prevAlt}):i.setData({src:e,alt:e.text}):i.setData({src:e})})),a.prevImage=r,Me(e,t,a,i)})(e,t,a,i):"alt"===s.name?a.prevAlt=i.getData().alt:"fileinput"===s.name?Re(e,t,a,i):"isDecorative"===s.name&&i.setEnabled("alt",!i.getData().isDecorative)},ze=e=>()=>{e.open=!1},Pe=e=>e.hasAdvTab||e.hasUploadUrl||e.hasUploadHandler?{type:"tabpanel",tabs:w([[Oe(e)],e.hasAdvTab?[{title:"Advanced",name:"advanced",items:[{type:"grid",columns:2,items:[{type:"input",label:"Vertical space",name:"vspace",inputMode:"numeric"},{type:"input",label:"Horizontal space",name:"hspace",inputMode:"numeric"},{type:"input",label:"Border width",name:"border",inputMode:"numeric"},{type:"listbox",name:"borderstyle",label:"Border style",items:[{text:"Select...",value:""},{text:"Solid",value:"solid"},{text:"Dotted",value:"dotted"},{text:"Dashed",value:"dashed"},{text:"Double",value:"double"},{text:"Groove",value:"groove"},{text:"Ridge",value:"ridge"},{text:"Inset",value:"inset"},{text:"Outset",value:"outset"},{text:"None",value:"none"},{text:"Hidden",value:"hidden"}]}]}]}]:[],e.hasUploadTab&&(e.hasUploadUrl||e.hasUploadHandler)?[{title:"Upload",name:"upload",items:[{type:"dropzone",name:"fileinput"}]}]:[]])}:{type:"panel",items:Le(e)},Be=(e,t,a)=>i=>{const s=fe(Ee(t.image),i.getData()),r={...s,style:le(a.normalizeCss,je(s,!1))};e.execCommand("mceUpdateImage",!1,je(r,t.hasAccessibilityOptions)),e.editorUpload.uploadImagesAuto(),i.close()},Fe=e=>t=>G(e,t)?(e=>new Promise((t=>{const a=document.createElement("img"),i=e=>{a.onload=a.onerror=null,a.parentNode&&a.parentNode.removeChild(a),t(e)};a.onload=()=>{const e={width:P(a.width,a.clientWidth),height:P(a.height,a.clientHeight)};i(Promise.resolve(e))},a.onerror=()=>{i(Promise.reject(`Failed to get image dimensions for: ${e}`))};const s=a.style;s.visibility="hidden",s.position="fixed",s.bottom=s.left="0px",s.width=s.height="auto",document.body.appendChild(a),a.src=e})))(e.documentBaseURI.toAbsolute(t)).then((e=>({width:String(e.width),height:String(e.height)}))):Promise.resolve({width:"",height:""}),He=e=>(t,a,i)=>{var s;return e.editorUpload.blobCache.create({blob:t,blobUri:a,name:null===(s=t.name)||void 0===s?void 0:s.replace(/\.[^\.]+$/,""),filename:t.name,base64:i.split(",")[1]})},Ge=e=>t=>{e.editorUpload.blobCache.add(t)},We=e=>t=>{e.windowManager.alert(t)},$e=e=>t=>pe(e,t),Ve=e=>t=>e.dom.parseStyle(t),Ke=e=>(t,a)=>e.dom.serializeStyle(t,a),Ze=e=>t=>Ae(e).upload([t],!1).then((e=>{var t;return 0===e.length?Promise.reject("Failed to upload image"):!1===e[0].status?Promise.reject(null===(t=e[0].error)||void 0===t?void 0:t.message):e[0]})),qe=e=>{const t={imageSize:Fe(e),addToBlobCache:Ge(e),createBlobCache:He(e),alertErr:We(e),normalizeCss:$e(e),parseStyle:Ve(e),serializeStyle:Ke(e),uploadImage:Ze(e)};return{open:()=>{Ne(e).then((a=>{const i=(e=>({prevImage:Se(e.imageList,e.image.src),prevAlt:e.image.alt,open:!0}))(a);return{title:"Insert/Edit Image",size:"normal",body:Pe(a),buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:Ee(a.image),onSubmit:Be(e,a,t),onChange:ke(t,a,i),onClose:ze(i)}})).then(e.windowManager.open)}}},Je=e=>{const t=e.attr("class");return d(t)&&/\bimage\b/.test(t)},Qe=e=>t=>{let a=t.length;const i=t=>{t.attr("contenteditable",e?"true":null)};for(;a--;){const s=t[a];Je(s)&&(s.attr("contenteditable",e?"false":null),De.each(s.getAll("figcaption"),i))}};e.add("image",(e=>{(e=>{const t=e.options.register;t("image_dimensions",{processor:"boolean",default:!0}),t("image_advtab",{processor:"boolean",default:!1}),t("image_uploadtab",{processor:"boolean",default:!0}),t("image_prepend_url",{processor:"string",default:""}),t("image_class_list",{processor:"object[]"}),t("image_description",{processor:"boolean",default:!0}),t("image_title",{processor:"boolean",default:!1}),t("image_caption",{processor:"boolean",default:!1}),t("image_list",{processor:e=>{const t=!1===e||r(e)||((e,t)=>{if(l(e)){for(let a=0,i=e.length;a{e.on("PreInit",(()=>{e.parser.addNodeFilter("figure",Qe(!0)),e.serializer.addNodeFilter("figure",Qe(!1))}))})(e),(e=>{e.ui.registry.addToggleButton("image",{icon:"image",tooltip:"Insert/edit image",onAction:qe(e).open,onSetup:t=>(t.setActive(d(he(e))),e.selection.selectorChangedWithUnbind("img:not([data-mce-object]):not([data-mce-placeholder]),figure.image",t.setActive).unbind)}),e.ui.registry.addMenuItem("image",{icon:"image",text:"Image...",onAction:qe(e).open}),e.ui.registry.addContextMenu("image",{update:e=>re(e)||"IMG"===e.nodeName&&!H(e)?["image"]:[]})})(e),(e=>{e.addCommand("mceImage",qe(e).open),e.addCommand("mceUpdateImage",((t,a)=>{e.undoManager.transact((()=>ye(e,a)))}))})(e)}))}(); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/importcss/plugin.min.js b/public/resource/tinymce/plugins/importcss/plugin.min.js new file mode 100644 index 0000000..3bd9ba5 --- /dev/null +++ b/public/resource/tinymce/plugins/importcss/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.4.2 (2023-04-26) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(s=r=e,(o=String).prototype.isPrototypeOf(s)||(null===(n=r.constructor)||void 0===n?void 0:n.name)===o.name)?"string":t;var s,r,o,n})(t)===e,s=t("string"),r=t("object"),o=t("array"),n=("function",e=>"function"==typeof e);var c=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),i=tinymce.util.Tools.resolve("tinymce.EditorManager"),l=tinymce.util.Tools.resolve("tinymce.Env"),a=tinymce.util.Tools.resolve("tinymce.util.Tools");const p=e=>t=>t.options.get(e),u=p("importcss_merge_classes"),m=p("importcss_exclusive"),f=p("importcss_selector_converter"),y=p("importcss_selector_filter"),d=p("importcss_groups"),h=p("importcss_append"),_=p("importcss_file_filter"),g=p("skin"),v=p("skin_url"),b=Array.prototype.push,x=/^\.(?:ephox|tiny-pageembed|mce)(?:[.-]+\w+)+$/,T=e=>s(e)?t=>-1!==t.indexOf(e):e instanceof RegExp?t=>e.test(t):e,S=(e,t)=>{let s={};const r=/^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(t);if(!r)return;const o=r[1],n=r[2].substr(1).split(".").join(" "),c=a.makeMap("a,img");return r[1]?(s={title:t},e.schema.getTextBlockElements()[o]?s.block=o:e.schema.getBlockElements()[o]||c[o.toLowerCase()]?s.selector=o:s.inline=o):r[2]&&(s={inline:"span",title:t.substr(1),classes:n}),u(e)?s.classes=n:s.attributes={class:n},s},k=(e,t)=>null===t||m(e),w=e=>{e.on("init",(()=>{const t=(()=>{const e=[],t=[],s={};return{addItemToGroup:(e,r)=>{s[e]?s[e].push(r):(t.push(e),s[e]=[r])},addItem:t=>{e.push(t)},toFormats:()=>{return(r=t,n=e=>{const t=s[e];return 0===t.length?[]:[{title:e,items:t}]},(e=>{const t=[];for(let s=0,r=e.length;s{const s=e.length,r=new Array(s);for(let o=0;oa.map(e,(e=>a.extend({},e,{original:e,selectors:{},filter:T(e.filter)}))))(d(e)),u=(t,s)=>{if(((e,t,s,r)=>!(k(e,s)?t in r:t in s.selectors))(e,t,s,r)){((e,t,s,r)=>{k(e,s)?r[t]=!0:s.selectors[t]=!0})(e,t,s,r);const o=((e,t,s,r)=>{let o;const n=f(e);return o=r&&r.selector_converter?r.selector_converter:n||(()=>S(e,s)),o.call(t,s,r)})(e,e.plugins.importcss,t,s);if(o){const t=o.name||c.DOM.uniqueId();return e.formatter.register(t,o),{title:o.title,format:t}}}return null};a.each(((e,t,r)=>{const o=[],n={},c=(t,n)=>{let p,u=t.href;if(u=(e=>{const t=l.cacheSuffix;return s(e)&&(e=e.replace("?"+t,"").replace("&"+t,"")),e})(u),u&&(!r||r(u,n))&&!((e,t)=>{const s=g(e);if(s){const r=v(e),o=r?e.documentBaseURI.toAbsolute(r):i.baseURL+"/skins/ui/"+s,n=i.baseURL+"/skins/content/";return t===o+"/content"+(e.inline?".inline":"")+".min.css"||-1!==t.indexOf(n)}return!1})(e,u)){a.each(t.imports,(e=>{c(e,!0)}));try{p=t.cssRules||t.rules}catch(e){}a.each(p,(e=>{e.styleSheet?c(e.styleSheet,!0):e.selectorText&&a.each(e.selectorText.split(","),(e=>{o.push(a.trim(e))}))}))}};a.each(e.contentCSS,(e=>{n[e]=!0})),r||(r=(e,t)=>t||n[e]);try{a.each(t.styleSheets,(e=>{c(e)}))}catch(e){}return o})(e,e.getDoc(),T(_(e))),(e=>{if(!x.test(e)&&(!n||n(e))){const s=((e,t)=>a.grep(e,(e=>!e.filter||e.filter(t))))(p,e);if(s.length>0)a.each(s,(s=>{const r=u(e,s);r&&t.addItemToGroup(s.title,r)}));else{const s=u(e,null);s&&t.addItem(s)}}}));const m=t.toFormats();e.dispatch("addStyleModifications",{items:m,replace:!h(e)})}))};e.add("importcss",(e=>((e=>{const t=e.options.register,o=e=>s(e)||n(e)||r(e);t("importcss_merge_classes",{processor:"boolean",default:!0}),t("importcss_exclusive",{processor:"boolean",default:!0}),t("importcss_selector_converter",{processor:"function"}),t("importcss_selector_filter",{processor:o}),t("importcss_file_filter",{processor:o}),t("importcss_groups",{processor:"object[]"}),t("importcss_append",{processor:"boolean",default:!1})})(e),w(e),(e=>({convertSelectorToFormat:t=>S(e,t)}))(e))))}(); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/insertdatetime/plugin.min.js b/public/resource/tinymce/plugins/insertdatetime/plugin.min.js new file mode 100644 index 0000000..b0dae30 --- /dev/null +++ b/public/resource/tinymce/plugins/insertdatetime/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.4.2 (2023-04-26) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>t.options.get(e),a=t("insertdatetime_dateformat"),r=t("insertdatetime_timeformat"),n=t("insertdatetime_formats"),s=t("insertdatetime_element"),i="Sun Mon Tue Wed Thu Fri Sat Sun".split(" "),o="Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" "),l="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),m="January February March April May June July August September October November December".split(" "),c=(e,t)=>{if((e=""+e).length(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=t.replace("%D","%m/%d/%Y")).replace("%r","%I:%M:%S %p")).replace("%Y",""+a.getFullYear())).replace("%y",""+a.getYear())).replace("%m",c(a.getMonth()+1,2))).replace("%d",c(a.getDate(),2))).replace("%H",""+c(a.getHours(),2))).replace("%M",""+c(a.getMinutes(),2))).replace("%S",""+c(a.getSeconds(),2))).replace("%I",""+((a.getHours()+11)%12+1))).replace("%p",a.getHours()<12?"AM":"PM")).replace("%B",""+e.translate(m[a.getMonth()]))).replace("%b",""+e.translate(l[a.getMonth()]))).replace("%A",""+e.translate(o[a.getDay()]))).replace("%a",""+e.translate(i[a.getDay()]))).replace("%%","%"),u=(e,t)=>{if(s(e)){const a=d(e,t);let r;r=/%[HMSIp]/.test(t)?d(e,"%Y-%m-%dT%H:%M"):d(e,"%Y-%m-%d");const n=e.dom.getParent(e.selection.getStart(),"time");n?((e,t,a,r)=>{const n=e.dom.create("time",{datetime:a},r);e.dom.replace(n,t),e.selection.select(n,!0),e.selection.collapse(!1)})(e,n,r,a):e.insertContent('")}else e.insertContent(d(e,t))};var p=tinymce.util.Tools.resolve("tinymce.util.Tools");e.add("insertdatetime",(e=>{(e=>{const t=e.options.register;t("insertdatetime_dateformat",{processor:"string",default:e.translate("%Y-%m-%d")}),t("insertdatetime_timeformat",{processor:"string",default:e.translate("%H:%M:%S")}),t("insertdatetime_formats",{processor:"string[]",default:["%H:%M:%S","%Y-%m-%d","%I:%M:%S %p","%D"]}),t("insertdatetime_element",{processor:"boolean",default:!1})})(e),(e=>{e.addCommand("mceInsertDate",((t,r)=>{u(e,null!=r?r:a(e))})),e.addCommand("mceInsertTime",((t,a)=>{u(e,null!=a?a:r(e))}))})(e),(e=>{const t=n(e),a=(e=>{let t=e;return{get:()=>t,set:e=>{t=e}}})((e=>{const t=n(e);return t.length>0?t[0]:r(e)})(e)),s=t=>e.execCommand("mceInsertDate",!1,t);e.ui.registry.addSplitButton("insertdatetime",{icon:"insert-time",tooltip:"Insert date/time",select:e=>e===a.get(),fetch:a=>{a(p.map(t,(t=>({type:"choiceitem",text:d(e,t),value:t}))))},onAction:e=>{s(a.get())},onItemAction:(e,t)=>{a.set(t),s(t)}});const i=e=>()=>{a.set(e),s(e)};e.ui.registry.addNestedMenuItem("insertdatetime",{icon:"insert-time",text:"Date/time",getSubmenuItems:()=>p.map(t,(t=>({type:"menuitem",text:d(e,t),onAction:i(t)})))})})(e)}))}(); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/link/plugin.min.js b/public/resource/tinymce/plugins/link/plugin.min.js new file mode 100644 index 0000000..f9639d4 --- /dev/null +++ b/public/resource/tinymce/plugins/link/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.4.2 (2023-04-26) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(n=o=e,(r=String).prototype.isPrototypeOf(n)||(null===(l=o.constructor)||void 0===l?void 0:l.name)===r.name)?"string":t;var n,o,r,l})(t)===e,n=e=>t=>typeof t===e,o=t("string"),r=t("object"),l=t("array"),a=(null,e=>null===e);const i=n("boolean"),s=e=>!(e=>null==e)(e),c=n("function"),u=(e,t)=>{if(l(e)){for(let n=0,o=e.length;n{},d=(e,t)=>e===t;class m{constructor(e,t){this.tag=e,this.value=t}static some(e){return new m(!0,e)}static none(){return m.singletonNone}fold(e,t){return this.tag?t(this.value):e()}isSome(){return this.tag}isNone(){return!this.tag}map(e){return this.tag?m.some(e(this.value)):m.none()}bind(e){return this.tag?e(this.value):m.none()}exists(e){return this.tag&&e(this.value)}forall(e){return!this.tag||e(this.value)}filter(e){return!this.tag||e(this.value)?this:m.none()}getOr(e){return this.tag?this.value:e}or(e){return this.tag?this:e}getOrThunk(e){return this.tag?this.value:e()}orThunk(e){return this.tag?this:e()}getOrDie(e){if(this.tag)return this.value;throw new Error(null!=e?e:"Called getOrDie on None")}static from(e){return s(e)?m.some(e):m.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(e){this.tag&&e(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}m.singletonNone=new m(!1);const h=Array.prototype.indexOf,f=Array.prototype.push,p=e=>{const t=[];for(let n=0,o=e.length;n{for(let n=0;ne.exists((e=>n(e,t))),y=e=>{const t=[],n=e=>{t.push(e)};for(let t=0;te?m.some(t):m.none(),b=e=>t=>t.options.get(e),_=b("link_assume_external_targets"),w=b("link_context_toolbar"),C=b("link_list"),O=b("link_default_target"),N=b("link_default_protocol"),A=b("link_target_list"),S=b("link_rel_list"),T=b("link_class_list"),E=b("link_title"),R=b("allow_unsafe_link_target"),P=b("link_quicklink");var L=tinymce.util.Tools.resolve("tinymce.util.Tools");const M=e=>o(e.value)?e.value:"",D=(e,t)=>{const n=[];return L.each(e,(e=>{const r=(e=>o(e.text)?e.text:o(e.title)?e.title:"")(e);if(void 0!==e.menu){const o=D(e.menu,t);n.push({text:r,items:o})}else{const o=t(e);n.push({text:r,value:o})}})),n},B=(e=M)=>t=>m.from(t).map((t=>D(t,e))),I=e=>B(M)(e),j=B,K=(e,t)=>n=>({name:e,type:"listbox",label:t,items:n}),U=M,q=Object.keys,F=Object.hasOwnProperty,V=(e,t)=>F.call(e,t);var $=tinymce.util.Tools.resolve("tinymce.dom.TreeWalker"),z=tinymce.util.Tools.resolve("tinymce.util.URI");const G=e=>s(e)&&"a"===e.nodeName.toLowerCase(),H=e=>G(e)&&!!Q(e),J=(e,t)=>{if(e.collapsed)return[];{const n=e.cloneContents(),o=n.firstChild,r=new $(o,n),l=[];let a=o;do{t(a)&&l.push(a)}while(a=r.next());return l}},W=e=>/^\w+:/i.test(e),Q=e=>{var t,n;return null!==(n=null!==(t=e.getAttribute("data-mce-href"))&&void 0!==t?t:e.getAttribute("href"))&&void 0!==n?n:""},X=(e,t)=>{const n=["noopener"],o=e?e.split(/\s+/):[],r=e=>e.filter((e=>-1===L.inArray(n,e))),l=t?(e=>(e=r(e)).length>0?e.concat(n):n)(o):r(o);return l.length>0?(e=>L.trim(e.sort().join(" ")))(l):""},Y=(e,t)=>(t=t||te(e.selection.getRng())[0]||e.selection.getNode(),le(t)?m.from(e.dom.select("a[href]",t)[0]):m.from(e.dom.getParent(t,"a[href]"))),Z=(e,t)=>Y(e,t).isSome(),ee=(e,t)=>t.fold((()=>e.getContent({format:"text"})),(e=>e.innerText||e.textContent||"")).replace(/\uFEFF/g,""),te=e=>J(e,H),ne=e=>L.grep(e,H),oe=e=>ne(e).length>0,re=e=>{const t=e.schema.getTextInlineElements();if(Y(e).exists((e=>e.hasAttribute("data-mce-block"))))return!1;const n=e.selection.getRng();return!!n.collapsed||0===J(n,(e=>1===e.nodeType&&!G(e)&&!V(t,e.nodeName.toLowerCase()))).length},le=e=>s(e)&&"FIGURE"===e.nodeName&&/\bimage\b/i.test(e.className),ae=(e,t,n)=>{const o=e.selection.getNode(),r=Y(e,o),l=((e,t)=>{const n={...t};if(0===S(e).length&&!R(e)){const e=X(n.rel,"_blank"===n.target);n.rel=e||null}return m.from(n.target).isNone()&&!1===A(e)&&(n.target=O(e)),n.href=((e,t)=>"http"!==t&&"https"!==t||W(e)?e:t+"://"+e)(n.href,_(e)),n})(e,(e=>{return t=["title","rel","class","target"],n=(t,n)=>(e[n].each((e=>{t[n]=e.length>0?e:null})),t),o={href:e.href},((e,t)=>{for(let n=0,o=e.length;n{o=n(o,e)})),o;var t,n,o})(n));e.undoManager.transact((()=>{n.href===t.href&&t.attach(),r.fold((()=>{((e,t,n,o)=>{const r=e.dom;le(t)?ge(r,t,o):n.fold((()=>{e.execCommand("mceInsertLink",!1,o)}),(t=>{e.insertContent(r.createHTML("a",o,r.encode(t)))}))})(e,o,n.text,l)}),(t=>{e.focus(),((e,t,n,o)=>{n.each((e=>{V(t,"innerText")?t.innerText=e:t.textContent=e})),e.dom.setAttribs(t,o),e.selection.select(t)})(e,t,n.text,l)}))}))},ie=e=>{const{class:t,href:n,rel:o,target:r,text:l,title:i}=e;return((e,t)=>{const n={};var o;return((e,t,n,o)=>{((e,t)=>{const n=q(e);for(let o=0,r=n.length;o{(t(e,r)?n:o)(e,r)}))})(e,((e,t)=>!1===a(e)),(o=n,(e,t)=>{o[t]=e}),g),n})({class:t.getOrNull(),href:n,rel:o.getOrNull(),target:r.getOrNull(),text:l.getOrNull(),title:i.getOrNull()})},se=(e,t,n)=>{const o=((e,t)=>{const n=e.options.get,o={allow_html_data_urls:n("allow_html_data_urls"),allow_script_urls:n("allow_script_urls"),allow_svg_data_urls:n("allow_svg_data_urls")},r=t.href;return{...t,href:z.isDomSafe(r,"a",o)?r:""}})(e,n);e.hasPlugin("rtc",!0)?e.execCommand("createlink",!1,ie(o)):ae(e,t,o)},ce=e=>{e.hasPlugin("rtc",!0)?e.execCommand("unlink"):(e=>{e.undoManager.transact((()=>{const t=e.selection.getNode();le(t)?ue(e,t):(e=>{const t=e.dom,n=e.selection,o=n.getBookmark(),r=n.getRng().cloneRange(),l=t.getParent(r.startContainer,"a[href]",e.getBody()),a=t.getParent(r.endContainer,"a[href]",e.getBody());l&&r.setStartBefore(l),a&&r.setEndAfter(a),n.setRng(r),e.execCommand("unlink"),n.moveToBookmark(o)})(e),e.focus()}))})(e)},ue=(e,t)=>{var n;const o=e.dom.select("img",t)[0];if(o){const r=e.dom.getParents(o,"a[href]",t)[0];r&&(null===(n=r.parentNode)||void 0===n||n.insertBefore(o,r),e.dom.remove(r))}},ge=(e,t,n)=>{var o;const r=e.select("img",t)[0];if(r){const t=e.create("a",n);null===(o=r.parentNode)||void 0===o||o.insertBefore(t,r),t.appendChild(r)}},de=(e,t)=>k(t,(t=>(e=>{return V(t=e,n="items")&&void 0!==t[n]&&null!==t[n];var t,n})(t)?de(e,t.items):x(t.value===e,t))),me=(e,t)=>{const n={text:e.text,title:e.title},o=(e,o)=>{const r=(l=t,a=o,"link"===a?l.link:"anchor"===a?l.anchor:m.none()).getOr([]);var l,a;return((e,t,n,o)=>{const r=o[t],l=e.length>0;return void 0!==r?de(r,n).map((t=>({url:{value:t.value,meta:{text:l?e:t.text,attach:g}},text:l?e:t.text}))):m.none()})(n.text,o,r,e)};return{onChange:(e,t)=>{const r=t.name;return"url"===r?(e=>{const t=(o=e.url,x(n.text.length<=0,m.from(null===(r=o.meta)||void 0===r?void 0:r.text).getOr(o.value)));var o,r;const l=(e=>{var t;return x(n.title.length<=0,m.from(null===(t=e.meta)||void 0===t?void 0:t.title).getOr(""))})(e.url);return t.isSome()||l.isSome()?m.some({...t.map((e=>({text:e}))).getOr({}),...l.map((e=>({title:e}))).getOr({})}):m.none()})(e()):((e,t)=>h.call(e,t))(["anchor","link"],r)>-1?o(e(),r):"text"===r||"title"===r?(n[r]=e()[r],m.none()):m.none()}}};var he=tinymce.util.Tools.resolve("tinymce.util.Delay");const fe=e=>{const t=e.href;return t.indexOf("@")>0&&-1===t.indexOf("/")&&-1===t.indexOf("mailto:")?m.some({message:"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?",preprocess:e=>({...e,href:"mailto:"+t})}):m.none()},pe=(e,t)=>n=>{const o=n.href;return 1===e&&!W(o)||0===e&&/^\s*www(\.|\d\.)/i.test(o)?m.some({message:`The URL you entered seems to be an external link. Do you want to add the required ${t}:// prefix?`,preprocess:e=>({...e,href:t+"://"+o})}):m.none()},ke=e=>{const t=e.dom.select("a:not([href])"),n=p(((e,t)=>{const n=e.length,o=new Array(n);for(let r=0;r{const t=e.name||e.id;return t?[{text:t,value:"#"+t}]:[]})));return n.length>0?m.some([{text:"None",value:""}].concat(n)):m.none()},ve=e=>{const t=T(e);return t.length>0?I(t):m.none()},ye=e=>{try{return m.some(JSON.parse(e))}catch(e){return m.none()}},xe=(e,t)=>{const n=S(e);if(n.length>0){const o=v(t,"_blank"),r=e=>X(U(e),o);return(!1===R(e)?j(r):I)(n)}return m.none()},be=[{text:"Current window",value:""},{text:"New window",value:"_blank"}],_e=e=>{const t=A(e);return l(t)?I(t).orThunk((()=>m.some(be))):!1===t?m.none():m.some(be)},we=(e,t,n)=>{const o=e.getAttrib(t,n);return null!==o&&o.length>0?m.some(o):m.none()},Ce=(e,t)=>(e=>{const t=t=>e.convertURL(t.value||t.url||"","href"),n=C(e);return new Promise((e=>{o(n)?fetch(n).then((e=>e.ok?e.text().then(ye):Promise.reject())).then(e,(()=>e(m.none()))):c(n)?n((t=>e(m.some(t)))):e(m.from(n))})).then((e=>e.bind(j(t)).map((e=>e.length>0?[{text:"None",value:""}].concat(e):e))))})(e).then((n=>{const o=((e,t)=>{const n=e.dom,o=re(e)?m.some(ee(e.selection,t)):m.none(),r=t.bind((e=>m.from(n.getAttrib(e,"href")))),l=t.bind((e=>m.from(n.getAttrib(e,"target")))),a=t.bind((e=>we(n,e,"rel"))),i=t.bind((e=>we(n,e,"class")));return{url:r,text:o,title:t.bind((e=>we(n,e,"title"))),target:l,rel:a,linkClass:i}})(e,t);return{anchor:o,catalogs:{targets:_e(e),rels:xe(e,o.target),classes:ve(e),anchor:ke(e),link:n},optNode:t,flags:{titleEnabled:E(e)}}})),Oe=e=>{const t=(e=>{const t=Y(e);return Ce(e,t)})(e);t.then((t=>{const n=((e,t)=>n=>{const o=n.getData();if(!o.url.value)return ce(e),void n.close();const r=e=>m.from(o[e]).filter((n=>!v(t.anchor[e],n))),l={href:o.url.value,text:r("text"),target:r("target"),rel:r("rel"),class:r("linkClass"),title:r("title")},a={href:o.url.value,attach:void 0!==o.url.meta&&o.url.meta.attach?o.url.meta.attach:g};((e,t)=>k([fe,pe(_(e),N(e))],(e=>e(t))).fold((()=>Promise.resolve(t)),(n=>new Promise((o=>{((e,t,n)=>{const o=e.selection.getRng();he.setEditorTimeout(e,(()=>{e.windowManager.confirm(t,(t=>{e.selection.setRng(o),n(t)}))}))})(e,n.message,(e=>{o(e?n.preprocess(t):t)}))})))))(e,l).then((t=>{se(e,a,t)})),n.close()})(e,t);return((e,t,n)=>{const o=e.anchor.text.map((()=>({name:"text",type:"input",label:"Text to display"}))).toArray(),r=e.flags.titleEnabled?[{name:"title",type:"input",label:"Title"}]:[],l=((e,t)=>{const n=e.anchor,o=n.url.getOr("");return{url:{value:o,meta:{original:{value:o}}},text:n.text.getOr(""),title:n.title.getOr(""),anchor:o,link:o,rel:n.rel.getOr(""),target:n.target.or(t).getOr(""),linkClass:n.linkClass.getOr("")}})(e,m.from(O(n))),a=e.catalogs,i=me(l,a);return{title:"Insert/Edit Link",size:"normal",body:{type:"panel",items:p([[{name:"url",type:"urlinput",filetype:"file",label:"URL"}],o,r,y([a.anchor.map(K("anchor","Anchors")),a.rels.map(K("rel","Rel")),a.targets.map(K("target","Open link in...")),a.link.map(K("link","Link list")),a.classes.map(K("linkClass","Class"))])])},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:l,onChange:(e,{name:t})=>{i.onChange(e.getData,{name:t}).each((t=>{e.setData(t)}))},onSubmit:t}})(t,n,e)})).then((t=>{e.windowManager.open(t)}))};var Ne=tinymce.util.Tools.resolve("tinymce.util.VK");const Ae=(e,t)=>e.dom.getParent(t,"a[href]"),Se=e=>Ae(e,e.selection.getStart()),Te=(e,t)=>{if(t){const n=Q(t);if(/^#/.test(n)){const t=e.dom.select(n);t.length&&e.selection.scrollIntoView(t[0],!0)}else(e=>{const t=document.createElement("a");t.target="_blank",t.href=e,t.rel="noreferrer noopener";const n=document.createEvent("MouseEvents");n.initMouseEvent("click",!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),((e,t)=>{document.body.appendChild(e),e.dispatchEvent(t),document.body.removeChild(e)})(t,n)})(t.href)}},Ee=e=>()=>{e.execCommand("mceLink",!1,{dialog:!0})},Re=e=>()=>{Te(e,Se(e))},Pe=(e,t)=>(e.on("NodeChange",t),()=>e.off("NodeChange",t)),Le=e=>t=>{const n=()=>t.setActive(!e.mode.isReadOnly()&&Z(e,e.selection.getNode()));return n(),Pe(e,n)},Me=e=>t=>{const n=()=>t.setEnabled((e=>1===(e.selection.isCollapsed()?ne(e.dom.getParents(e.selection.getStart())):te(e.selection.getRng())).length)(e));return n(),Pe(e,n)},De=e=>t=>{const n=t=>{return oe(t)||(n=e.selection.getRng(),te(n).length>0);var n},o=e.dom.getParents(e.selection.getStart());return t.setEnabled(n(o)),Pe(e,(e=>t.setEnabled(n(e.parents))))};e.add("link",(e=>{(e=>{const t=e.options.register;t("link_assume_external_targets",{processor:e=>{const t=o(e)||i(e);return t?!0===e?{value:1,valid:t}:"http"===e||"https"===e?{value:e,valid:t}:{value:0,valid:t}:{valid:!1,message:"Must be a string or a boolean."}},default:!1}),t("link_context_toolbar",{processor:"boolean",default:!1}),t("link_list",{processor:e=>o(e)||c(e)||u(e,r)}),t("link_default_target",{processor:"string"}),t("link_default_protocol",{processor:"string",default:"https"}),t("link_target_list",{processor:e=>i(e)||u(e,r),default:!0}),t("link_rel_list",{processor:"object[]",default:[]}),t("link_class_list",{processor:"object[]",default:[]}),t("link_title",{processor:"boolean",default:!0}),t("allow_unsafe_link_target",{processor:"boolean",default:!1}),t("link_quicklink",{processor:"boolean",default:!1})})(e),(e=>{e.ui.registry.addToggleButton("link",{icon:"link",tooltip:"Insert/edit link",onAction:Ee(e),onSetup:Le(e)}),e.ui.registry.addButton("openlink",{icon:"new-tab",tooltip:"Open link",onAction:Re(e),onSetup:Me(e)}),e.ui.registry.addButton("unlink",{icon:"unlink",tooltip:"Remove link",onAction:()=>ce(e),onSetup:De(e)})})(e),(e=>{e.ui.registry.addMenuItem("openlink",{text:"Open link",icon:"new-tab",onAction:Re(e),onSetup:Me(e)}),e.ui.registry.addMenuItem("link",{icon:"link",text:"Link...",shortcut:"Meta+K",onAction:Ee(e)}),e.ui.registry.addMenuItem("unlink",{icon:"unlink",text:"Remove link",onAction:()=>ce(e),onSetup:De(e)})})(e),(e=>{e.ui.registry.addContextMenu("link",{update:t=>e.dom.isEditable(t)?oe(e.dom.getParents(t,"a"))?"link unlink openlink":"link":""})})(e),(e=>{const t=t=>{const n=e.selection.getNode();return t.setEnabled(Z(e,n)),g};e.ui.registry.addContextForm("quicklink",{launch:{type:"contextformtogglebutton",icon:"link",tooltip:"Link",onSetup:Le(e)},label:"Link",predicate:t=>w(e)&&Z(e,t),initValue:()=>Y(e).fold((()=>""),Q),commands:[{type:"contextformtogglebutton",icon:"link",tooltip:"Link",primary:!0,onSetup:t=>{const n=e.selection.getNode();return t.setActive(Z(e,n)),Le(e)(t)},onAction:t=>{const n=t.getValue(),o=(t=>{const n=Y(e),o=re(e);if(n.isNone()&&o){const o=ee(e.selection,n);return x(0===o.length,t)}return m.none()})(n);se(e,{href:n,attach:g},{href:n,text:o,title:m.none(),rel:m.none(),target:m.none(),class:m.none()}),(e=>{e.selection.collapse(!1)})(e),t.hide()}},{type:"contextformbutton",icon:"unlink",tooltip:"Remove link",onSetup:t,onAction:t=>{ce(e),t.hide()}},{type:"contextformbutton",icon:"new-tab",tooltip:"Open link",onSetup:t,onAction:t=>{Re(e)(),t.hide()}}]})})(e),(e=>{e.on("click",(t=>{const n=Ae(e,t.target);n&&Ne.metaKeyPressed(t)&&(t.preventDefault(),Te(e,n))})),e.on("keydown",(t=>{if(!t.isDefaultPrevented()&&13===t.keyCode&&(e=>!0===e.altKey&&!1===e.shiftKey&&!1===e.ctrlKey&&!1===e.metaKey)(t)){const n=Se(e);n&&(t.preventDefault(),Te(e,n))}}))})(e),(e=>{e.addCommand("mceLink",((t,n)=>{!0!==(null==n?void 0:n.dialog)&&P(e)?e.dispatch("contexttoolbar-show",{toolbarKey:"quicklink"}):Oe(e)}))})(e),(e=>{e.addShortcut("Meta+K","",(()=>{e.execCommand("mceLink")}))})(e)}))}(); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/lists/plugin.min.js b/public/resource/tinymce/plugins/lists/plugin.min.js new file mode 100644 index 0000000..6e811c2 --- /dev/null +++ b/public/resource/tinymce/plugins/lists/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.4.2 (2023-04-26) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(n=r=e,(o=String).prototype.isPrototypeOf(n)||(null===(s=r.constructor)||void 0===s?void 0:s.name)===o.name)?"string":t;var n,r,o,s})(t)===e,n=e=>t=>typeof t===e,r=t("string"),o=t("object"),s=t("array"),i=n("boolean"),l=e=>!(e=>null==e)(e),a=n("function"),d=n("number"),c=()=>{},u=(e,t)=>e===t,m=e=>t=>!e(t),p=(!1,()=>false);class g{constructor(e,t){this.tag=e,this.value=t}static some(e){return new g(!0,e)}static none(){return g.singletonNone}fold(e,t){return this.tag?t(this.value):e()}isSome(){return this.tag}isNone(){return!this.tag}map(e){return this.tag?g.some(e(this.value)):g.none()}bind(e){return this.tag?e(this.value):g.none()}exists(e){return this.tag&&e(this.value)}forall(e){return!this.tag||e(this.value)}filter(e){return!this.tag||e(this.value)?this:g.none()}getOr(e){return this.tag?this.value:e}or(e){return this.tag?this:e}getOrThunk(e){return this.tag?this.value:e()}orThunk(e){return this.tag?this:e()}getOrDie(e){if(this.tag)return this.value;throw new Error(null!=e?e:"Called getOrDie on None")}static from(e){return l(e)?g.some(e):g.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(e){this.tag&&e(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}g.singletonNone=new g(!1);const h=Array.prototype.slice,f=Array.prototype.indexOf,y=Array.prototype.push,v=(e,t)=>{return n=e,r=t,f.call(n,r)>-1;var n,r},C=(e,t)=>{for(let n=0,r=e.length;n{const n=e.length,r=new Array(n);for(let o=0;o{for(let n=0,r=e.length;n{const n=[];for(let r=0,o=e.length;r(S(e,((e,r)=>{n=t(n,e,r)})),n),O=(e,t,n)=>{for(let r=0,o=e.length;rO(e,t,p),T=(e,t)=>(e=>{const t=[];for(let n=0,r=e.length;n{const t=h.call(e,0);return t.reverse(),t},x=(e,t)=>t>=0&&tx(e,0),D=e=>x(e,e.length-1),E=(e,t)=>{const n=[],r=a(t)?e=>C(n,(n=>t(n,e))):e=>v(n,e);for(let t=0,o=e.length;te.exists((e=>n(e,t))),I=(e,t,n)=>e.isSome()&&t.isSome()?g.some(n(e.getOrDie(),t.getOrDie())):g.none(),P=e=>{if(null==e)throw new Error("Node cannot be null or undefined");return{dom:e}},M=(e,t)=>{const n=(t||document).createElement(e);return P(n)},R=P,U=(e,t)=>e.dom===t.dom;"undefined"!=typeof window?window:Function("return this;")();const $=e=>e.dom.nodeName.toLowerCase(),_=(1,e=>1===(e=>e.dom.nodeType)(e));const F=e=>t=>_(t)&&$(t)===e,H=e=>g.from(e.dom.parentNode).map(R),V=e=>b(e.dom.childNodes,R),j=(e,t)=>{const n=e.dom.childNodes;return g.from(n[t]).map(R)},K=e=>j(e,0),z=e=>j(e,e.dom.childNodes.length-1),Q=(e,t,n)=>{let r=e.dom;const o=a(n)?n:p;for(;r.parentNode;){r=r.parentNode;const e=R(r);if(t(e))return g.some(e);if(o(e))break}return g.none()},q=(e,t,n)=>((e,t,n,r,o)=>r(n)?g.some(n):a(o)&&o(n)?g.none():t(n,r,o))(0,Q,e,t,n),W=(e,t)=>{H(e).each((n=>{n.dom.insertBefore(t.dom,e.dom)}))},Z=(e,t)=>{e.dom.appendChild(t.dom)},G=(e,t)=>{S(t,(t=>{Z(e,t)}))},J=e=>{e.dom.textContent="",S(V(e),(e=>{X(e)}))},X=e=>{const t=e.dom;null!==t.parentNode&&t.parentNode.removeChild(t)};var Y=tinymce.util.Tools.resolve("tinymce.dom.RangeUtils"),ee=tinymce.util.Tools.resolve("tinymce.dom.TreeWalker"),te=tinymce.util.Tools.resolve("tinymce.util.VK");const ne=e=>b(e,R),re=Object.keys,oe=(e,t)=>{const n=re(e);for(let r=0,o=n.length;r{const n=e.dom;oe(t,((e,t)=>{((e,t,n)=>{if(!(r(n)||i(n)||d(n)))throw console.error("Invalid call to Attribute.set. Key ",t,":: Value ",n,":: Element ",e),new Error("Attribute value was not simple");e.setAttribute(t,n+"")})(n,t,e)}))},ie=e=>L(e.dom.attributes,((e,t)=>(e[t.name]=t.value,e)),{}),le=e=>((e,t)=>R(e.dom.cloneNode(!0)))(e),ae=(e,t)=>{const n=((e,t)=>{const n=M(t),r=ie(e);return se(n,r),n})(e,t);((e,t)=>{const n=(e=>g.from(e.dom.nextSibling).map(R))(e);n.fold((()=>{H(e).each((e=>{Z(e,t)}))}),(e=>{W(e,t)}))})(e,n);const r=V(e);return G(n,r),X(e),n};var de=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),ce=tinymce.util.Tools.resolve("tinymce.util.Tools");const ue=e=>t=>l(t)&&t.nodeName.toLowerCase()===e,me=e=>t=>l(t)&&e.test(t.nodeName),pe=e=>l(e)&&3===e.nodeType,ge=e=>l(e)&&1===e.nodeType,he=me(/^(OL|UL|DL)$/),fe=me(/^(OL|UL)$/),ye=ue("ol"),ve=me(/^(LI|DT|DD)$/),Ce=me(/^(DT|DD)$/),be=me(/^(TH|TD)$/),Se=ue("br"),Ne=(e,t)=>l(t)&&t.nodeName in e.schema.getTextBlockElements(),Le=(e,t)=>l(e)&&e.nodeName in t,Oe=(e,t)=>l(t)&&t.nodeName in e.schema.getVoidElements(),ke=(e,t,n)=>{const r=e.isEmpty(t);return!(n&&e.select("span[data-mce-type=bookmark]",t).length>0)&&r},Te=(e,t)=>e.isChildOf(t,e.getRoot()),Ae=e=>t=>t.options.get(e),xe=Ae("lists_indent_on_tab"),we=Ae("forced_root_block"),De=Ae("forced_root_block_attrs"),Ee=(e,t)=>{const n=e.dom,r=e.schema.getBlockElements(),o=n.createFragment(),s=we(e),i=De(e);let l,a,d=!1;for(a=n.create(s,i),Le(t.firstChild,r)||o.appendChild(a);l=t.firstChild;){const e=l.nodeName;d||"SPAN"===e&&"bookmark"===l.getAttribute("data-mce-type")||(d=!0),Le(l,r)?(o.appendChild(l),a=null):(a||(a=n.create(s,i),o.appendChild(a)),a.appendChild(l))}return!d&&a&&a.appendChild(n.create("br",{"data-mce-bogus":"1"})),o},Be=de.DOM,Ie=F("dd"),Pe=F("dt"),Me=(e,t)=>{var n;Ie(t)?ae(t,"dt"):Pe(t)&&(n=t,g.from(n.dom.parentElement).map(R)).each((n=>((e,t,n)=>{const r=Be.select('span[data-mce-type="bookmark"]',t),o=Ee(e,n),s=Be.createRng();s.setStartAfter(n),s.setEndAfter(t);const i=s.extractContents();for(let t=i.firstChild;t;t=t.firstChild)if("LI"===t.nodeName&&e.dom.isEmpty(t)){Be.remove(t);break}e.dom.isEmpty(i)||Be.insertAfter(i,t),Be.insertAfter(o,t);const l=n.parentElement;l&&ke(e.dom,l)&&(e=>{const t=e.parentNode;t&&ce.each(r,(e=>{t.insertBefore(e,n.parentNode)})),Be.remove(e)})(l),Be.remove(n),ke(e.dom,t)&&Be.remove(t)})(e,n.dom,t.dom)))},Re=e=>{Pe(e)&&ae(e,"dd")},Ue=(e,t)=>{if(pe(e))return{container:e,offset:t};const n=Y.getNode(e,t);return pe(n)?{container:n,offset:t>=e.childNodes.length?n.data.length:0}:n.previousSibling&&pe(n.previousSibling)?{container:n.previousSibling,offset:n.previousSibling.data.length}:n.nextSibling&&pe(n.nextSibling)?{container:n.nextSibling,offset:0}:{container:e,offset:t}},$e=e=>{const t=e.cloneRange(),n=Ue(e.startContainer,e.startOffset);t.setStart(n.container,n.offset);const r=Ue(e.endContainer,e.endOffset);return t.setEnd(r.container,r.offset),t},_e=["OL","UL","DL"],Fe=_e.join(","),He=(e,t)=>{const n=t||e.selection.getStart(!0);return e.dom.getParent(n,Fe,Ke(e,n))},Ve=e=>{const t=e.selection.getSelectedBlocks();return N(((e,t)=>{const n=ce.map(t,(t=>e.dom.getParent(t,"li,dd,dt",Ke(e,t))||t));return E(n)})(e,t),ve)},je=(e,t)=>{const n=e.dom.getParents(t,"TD,TH");return n.length>0?n[0]:e.getBody()},Ke=(e,t)=>{const n=e.dom.getParents(t,e.dom.isBlock),r=k(n,(t=>{return n=e.schema,!he(r=t)&&!ve(r)&&C(_e,(e=>n.isValidChild(r.nodeName,e)));var n,r}));return r.getOr(e.getBody())},ze=(e,t)=>{const n=e.dom.getParents(t,"ol,ul",Ke(e,t));return D(n)},Qe=(e,t)=>{const n=b(t,(t=>ze(e,t).getOr(t)));return E(n)},qe=e=>/\btox\-/.test(e.className),We=(e,t)=>O(e,he,be).exists((e=>e.nodeName===t&&!qe(e))),Ze=(e,t)=>null!==t&&!e.dom.isEditable(t),Ge=(e,t)=>{const n=e.dom.getParent(t,"ol,ul,dl");return Ze(e,n)},Je=(e,t)=>{const n=e.selection.getNode();return t({parents:e.dom.getParents(n),element:n}),e.on("NodeChange",t),()=>e.off("NodeChange",t)},Xe=(e,t,n)=>e.dispatch("ListMutation",{action:t,element:n}),Ye=(et=/^\s+|\s+$/g,e=>e.replace(et,""));var et;const tt=(e,t,n)=>{((e,t,n)=>{if(!r(n))throw console.error("Invalid call to CSS.set. Property ",t,":: Value ",n,":: Element ",e),new Error("CSS value must be a string: "+n);(e=>void 0!==e.style&&a(e.style.getPropertyValue))(e)&&e.style.setProperty(t,n)})(e.dom,t,n)},nt=(e,t)=>{Z(e.item,t.list)},rt=(e,t)=>{const n={list:M(t,e),item:M("li",e)};return Z(n.list,n.item),n},ot=e=>((e,t)=>{const n=e.dom;if(1!==n.nodeType)return!1;{const e=n;if(void 0!==e.matches)return e.matches(t);if(void 0!==e.msMatchesSelector)return e.msMatchesSelector(t);if(void 0!==e.webkitMatchesSelector)return e.webkitMatchesSelector(t);if(void 0!==e.mozMatchesSelector)return e.mozMatchesSelector(t);throw new Error("Browser lacks native selectors")}})(e,"OL,UL"),st=e=>K(e).exists(ot),it=e=>e.depth>0,lt=e=>e.isSelected,at=e=>{const t=V(e),n=z(e).exists(ot)?t.slice(0,-1):t;return b(n,le)},dt=e=>(S(e,((t,n)=>{((e,t)=>{const n=e[t].depth,r=e=>e.depth===n&&!e.dirty,o=e=>e.depthO(e.slice(t+1),r,o)))})(e,n).fold((()=>{t.dirty&&(e=>{e.listAttributes=((e,t)=>{const n={};var r;return((e,t,n,r)=>{oe(e,((e,o)=>{(t(e,o)?n:r)(e,o)}))})(e,t,(r=n,(e,t)=>{r[t]=e}),c),n})(e.listAttributes,((e,t)=>"start"!==t))})(t)}),(e=>{return r=e,(n=t).listType=r.listType,void(n.listAttributes={...r.listAttributes});var n,r}))})),e),ct=(e,t,n,r)=>K(r).filter(ot).fold((()=>{t.each((e=>{U(e.start,r)&&n.set(!0)}));const o=((e,t,n)=>H(e).filter(_).map((r=>({depth:t,dirty:!1,isSelected:n,content:at(e),itemAttributes:ie(e),listAttributes:ie(r),listType:$(r)}))))(r,e,n.get());t.each((e=>{U(e.end,r)&&n.set(!1)}));const s=z(r).filter(ot).map((r=>ut(e,t,n,r))).getOr([]);return o.toArray().concat(s)}),(r=>ut(e,t,n,r))),ut=(e,t,n,r)=>T(V(r),(r=>(ot(r)?ut:ct)(e+1,t,n,r))),mt=(e,t)=>{const n=dt(t);return((e,t)=>{const n=L(t,((t,n)=>n.depth>t.length?((e,t,n)=>{const r=((e,t,n)=>{const r=[];for(let o=0;o{for(let t=1;t{for(let t=0;t{se(e.list,t.listAttributes),se(e.item,t.itemAttributes),G(e.item,t.content)}))})(r,n),o=r,I(D(t),w(o),nt),t.concat(r)})(e,t,n):((e,t,n)=>{const r=t.slice(0,n.depth);return D(r).each((t=>{const r=((e,t,n)=>{const r=M("li",e);return se(r,t),G(r,n),r})(e,n.itemAttributes,n.content);((e,t)=>{Z(e.list,t),e.item=t})(t,r),((e,t)=>{$(e.list)!==t.listType&&(e.list=ae(e.list,t.listType)),se(e.list,t.listAttributes)})(t,n)})),r})(e,t,n)),[]);return w(n).map((e=>e.list))})(e.contentDocument,n).toArray()},pt=(e,t,n)=>{const r=((e,t)=>{const n=(e=>{let t=!1;return{get:()=>t,set:e=>{t=e}}})();return b(e,(e=>({sourceList:e,entries:ut(0,t,n,e)})))})(t,(e=>{const t=b(Ve(e),R);return I(k(t,m(st)),k(A(t),m(st)),((e,t)=>({start:e,end:t})))})(e));S(r,(t=>{((e,t)=>{S(N(e,lt),(e=>((e,t)=>{switch(e){case"Indent":t.depth++;break;case"Outdent":t.depth--;break;case"Flatten":t.depth=0}t.dirty=!0})(t,e)))})(t.entries,n);const r=((e,t)=>T(((e,t)=>{if(0===e.length)return[];{let n=t(e[0]);const r=[];let o=[];for(let s=0,i=e.length;sw(t).exists(it)?mt(e,t):((e,t)=>{const n=dt(t);return b(n,(t=>{const n=((e,t)=>{const n=document.createDocumentFragment();return S(e,(e=>{n.appendChild(e.dom)})),R(n)})(t.content);return R(Ee(e,n.dom))}))})(e,t))))(e,t.entries);var o;S(r,(t=>{Xe(e,"Indent"===n?"IndentList":"OutdentList",t.dom)})),o=t.sourceList,S(r,(e=>{W(o,e)})),X(t.sourceList)}))},gt=(e,t)=>{const n=ne((e=>{const t=(e=>{const t=ze(e,e.selection.getStart()),n=N(e.selection.getSelectedBlocks(),fe);return t.toArray().concat(n)})(e);return Qe(e,t)})(e)),r=ne((e=>N(Ve(e),Ce))(e));let o=!1;if(n.length||r.length){const s=e.selection.getBookmark();pt(e,n,t),((e,t,n)=>{S(n,"Indent"===t?Re:t=>Me(e,t))})(e,t,r),e.selection.moveToBookmark(s),e.selection.setRng($e(e.selection.getRng())),e.nodeChanged(),o=!0}return o},ht=(e,t)=>!(e=>{const t=He(e);return Ze(e,t)})(e)&>(e,t),ft=e=>ht(e,"Indent"),yt=e=>ht(e,"Outdent"),vt=e=>ht(e,"Flatten"),Ct=e=>"\ufeff"===e;var bt=tinymce.util.Tools.resolve("tinymce.dom.BookmarkManager");const St=de.DOM,Nt=e=>{const t={},n=n=>{let r=e[n?"startContainer":"endContainer"],o=e[n?"startOffset":"endOffset"];if(ge(r)){const e=St.create("span",{"data-mce-type":"bookmark"});r.hasChildNodes()?(o=Math.min(o,r.childNodes.length-1),n?r.insertBefore(e,r.childNodes[o]):St.insertAfter(e,r.childNodes[o])):r.appendChild(e),r=e,o=0}t[n?"startContainer":"endContainer"]=r,t[n?"startOffset":"endOffset"]=o};return n(!0),e.collapsed||n(),t},Lt=e=>{const t=t=>{let n=e[t?"startContainer":"endContainer"],r=e[t?"startOffset":"endOffset"];if(n){if(ge(n)&&n.parentNode){const e=n;r=(e=>{var t;let n=null===(t=e.parentNode)||void 0===t?void 0:t.firstChild,r=0;for(;n;){if(n===e)return r;ge(n)&&"bookmark"===n.getAttribute("data-mce-type")||r++,n=n.nextSibling}return-1})(n),n=n.parentNode,St.remove(e),!n.hasChildNodes()&&St.isBlock(n)&&n.appendChild(St.create("br"))}e[t?"startContainer":"endContainer"]=n,e[t?"startOffset":"endOffset"]=r}};t(!0),t();const n=St.createRng();return n.setStart(e.startContainer,e.startOffset),e.endContainer&&n.setEnd(e.endContainer,e.endOffset),$e(n)},Ot=e=>{switch(e){case"UL":return"ToggleUlList";case"OL":return"ToggleOlList";case"DL":return"ToggleDLList"}},kt=(e,t)=>{ce.each(t,((t,n)=>{e.setAttribute(n,t)}))},Tt=(e,t,n)=>{((e,t,n)=>{const r=n["list-style-type"]?n["list-style-type"]:null;e.setStyle(t,"list-style-type",r)})(e,t,n),((e,t,n)=>{kt(t,n["list-attributes"]),ce.each(e.select("li",t),(e=>{kt(e,n["list-item-attributes"])}))})(e,t,n)},At=(e,t)=>l(t)&&!Le(t,e.schema.getBlockElements()),xt=(e,t,n,r)=>{let o=t[n?"startContainer":"endContainer"];const s=t[n?"startOffset":"endOffset"];ge(o)&&(o=o.childNodes[Math.min(s,o.childNodes.length-1)]||o),!n&&Se(o.nextSibling)&&(o=o.nextSibling);const i=(t,n)=>{var o;const s=new ee(t,r),i=n?"next":"prev";let l;for(;l=s[i]();)if(!Oe(e,l)&&!Ct(l.textContent)&&0!==(null===(o=l.textContent)||void 0===o?void 0:o.length))return g.some(l);return g.none()};if(n&&pe(o))if(Ct(o.textContent))o=i(o,!1).getOr(o);else for(null!==o.parentNode&&At(e,o.parentNode)&&(o=o.parentNode);null!==o.previousSibling&&(At(e,o.previousSibling)||pe(o.previousSibling));)o=o.previousSibling;if(!n&&pe(o))if(Ct(o.textContent))o=i(o,!0).getOr(o);else for(null!==o.parentNode&&At(e,o.parentNode)&&(o=o.parentNode);null!==o.nextSibling&&(At(e,o.nextSibling)||pe(o.nextSibling));)o=o.nextSibling;for(;o.parentNode!==r;){const t=o.parentNode;if(Ne(e,o))return o;if(/^(TD|TH)$/.test(t.nodeName))return o;o=t}return o},wt=(e,t,n)=>{const r=e.selection.getRng();let o="LI";const s=Ke(e,e.selection.getStart(!0)),i=e.dom;if("false"===i.getContentEditable(e.selection.getNode()))return;"DL"===(t=t.toUpperCase())&&(o="DT");const l=Nt(r),a=((e,t,n)=>{const r=[],o=e.dom,s=xt(e,t,!0,n),i=xt(e,t,!1,n);let l;const a=[];for(let e=s;e&&(a.push(e),e!==i);e=e.nextSibling);return ce.each(a,(t=>{var s;if(Ne(e,t))return r.push(t),void(l=null);if(o.isBlock(t)||Se(t))return Se(t)&&o.remove(t),void(l=null);const i=t.nextSibling;bt.isBookmarkNode(t)&&(he(i)||Ne(e,i)||!i&&t.parentNode===n)?l=null:(l||(l=o.create("p"),null===(s=t.parentNode)||void 0===s||s.insertBefore(l,t),r.push(l)),l.appendChild(t))})),r})(e,r,s);ce.each(a,(r=>{let s;const l=r.previousSibling,a=r.parentNode;ve(a)||(l&&he(l)&&l.nodeName===t&&((e,t,n)=>{const r=e.getStyle(t,"list-style-type");let o=n?n["list-style-type"]:"";return o=null===o?"":o,r===o})(i,l,n)?(s=l,r=i.rename(r,o),l.appendChild(r)):(s=i.create(t),a.insertBefore(s,r),s.appendChild(r),r=i.rename(r,o)),((e,t,n)=>{ce.each(["margin","margin-right","margin-bottom","margin-left","margin-top","padding","padding-right","padding-bottom","padding-left","padding-top"],(n=>e.setStyle(t,n,"")))})(i,r),Tt(i,s,n),Et(e.dom,s))})),e.selection.setRng(Lt(l))},Dt=(e,t,n)=>{return((e,t)=>he(e)&&e.nodeName===(null==t?void 0:t.nodeName))(t,n)&&((e,t,n)=>e.getStyle(t,"list-style-type",!0)===e.getStyle(n,"list-style-type",!0))(e,t,n)&&(r=n,t.className===r.className);var r},Et=(e,t)=>{let n,r=t.nextSibling;if(Dt(e,t,r)){const o=r;for(;n=o.firstChild;)t.appendChild(n);e.remove(o)}if(r=t.previousSibling,Dt(e,t,r)){const o=r;for(;n=o.lastChild;)t.insertBefore(n,t.firstChild);e.remove(o)}},Bt=e=>"list-style-type"in e,It=(e,t,n)=>{const r=He(e);if(Ge(e,r)||(e=>C(e.selection.getSelectedBlocks(),m(e.dom.isEditable)))(e))return;const s=(e=>{const t=He(e),n=e.selection.getSelectedBlocks();return((e,t)=>l(e)&&1===t.length&&t[0]===e)(t,n)?(e=>N(e.querySelectorAll(Fe),he))(t):N(n,(e=>he(e)&&t!==e))})(e),i=o(n)?n:{};s.length>0?((e,t,n,r,o)=>{const s=he(t);if(s&&t.nodeName===r&&!Bt(o))vt(e);else{wt(e,r,o);const i=Nt(e.selection.getRng()),l=s?[t,...n]:n;ce.each(l,(t=>{((e,t,n,r)=>{if(t.nodeName!==n){const o=e.dom.rename(t,n);Tt(e.dom,o,r),Xe(e,Ot(n),o)}else Tt(e.dom,t,r),Xe(e,Ot(n),t)})(e,t,r,o)})),e.selection.setRng(Lt(i))}})(e,r,s,t,i):((e,t,n,r)=>{if(t!==e.getBody())if(t)if(t.nodeName!==n||Bt(r)||qe(t)){const o=Nt(e.selection.getRng());Tt(e.dom,t,r);const s=e.dom.rename(t,n);Et(e.dom,s),e.selection.setRng(Lt(o)),wt(e,n,r),Xe(e,Ot(n),s)}else vt(e);else wt(e,n,r),Xe(e,Ot(n),t)})(e,r,t,i)},Pt=de.DOM,Mt=(e,t)=>{const n=ce.grep(e.select("ol,ul",t));ce.each(n,(t=>{((e,t)=>{const n=t.parentElement;if(n&&"LI"===n.nodeName&&n.firstChild===t){const r=n.previousSibling;r&&"LI"===r.nodeName?(r.appendChild(t),ke(e,n)&&Pt.remove(n)):Pt.setStyle(n,"listStyleType","none")}if(he(n)){const e=n.previousSibling;e&&"LI"===e.nodeName&&e.appendChild(t)}})(e,t)}))},Rt=(e,t,n,r)=>{let o=t.startContainer;const s=t.startOffset;if(pe(o)&&(n?s0))return o;const i=e.schema.getNonEmptyElements();ge(o)&&(o=Y.getNode(o,s));const l=new ee(o,r);n&&((e,t)=>!!Se(t)&&e.isBlock(t.nextSibling)&&!Se(t.previousSibling))(e.dom,o)&&l.next();const a=n?l.next.bind(l):l.prev2.bind(l);for(;o=a();){if("LI"===o.nodeName&&!o.hasChildNodes())return o;if(i[o.nodeName])return o;if(pe(o)&&o.data.length>0)return o}return null},Ut=(e,t)=>{const n=t.childNodes;return 1===n.length&&!he(n[0])&&e.isBlock(n[0])},$t=(e,t,n)=>{let r;const o=t.parentNode;if(!Te(e,t)||!Te(e,n))return;he(n.lastChild)&&(r=n.lastChild),o===n.lastChild&&Se(o.previousSibling)&&e.remove(o.previousSibling);const s=n.lastChild;s&&Se(s)&&t.hasChildNodes()&&e.remove(s),ke(e,n,!0)&&J(R(n)),((e,t,n)=>{let r;const o=Ut(e,n)?n.firstChild:n;if(((e,t)=>{Ut(e,t)&&e.remove(t.firstChild,!0)})(e,t),!ke(e,t,!0))for(;r=t.firstChild;)o.appendChild(r)})(e,t,n),r&&n.appendChild(r);const i=((e,t)=>{const n=e.dom,r=t.dom;return n!==r&&n.contains(r)})(R(n),R(t))?e.getParents(t,he,n):[];e.remove(t),S(i,(t=>{ke(e,t)&&t!==e.getRoot()&&e.remove(t)}))},_t=(e,t)=>{const n=e.dom,r=e.selection,o=r.getStart(),s=je(e,o),i=n.getParent(r.getStart(),"LI",s);if(i){const o=i.parentElement;if(o===e.getBody()&&ke(n,o))return!0;const l=$e(r.getRng()),a=n.getParent(Rt(e,l,t,s),"LI",s);if(a&&a!==i)return e.undoManager.transact((()=>{var n,r;t?((e,t,n,r)=>{const o=e.dom;if(o.isEmpty(r))((e,t,n)=>{J(R(n)),$t(e.dom,t,n),e.selection.setCursorLocation(n,0)})(e,n,r);else{const s=Nt(t);$t(o,n,r),e.selection.setRng(Lt(s))}})(e,l,a,i):(null===(r=(n=i).parentNode)||void 0===r?void 0:r.firstChild)===n?yt(e):((e,t,n,r)=>{const o=Nt(t);$t(e.dom,n,r);const s=Lt(o);e.selection.setRng(s)})(e,l,i,a)})),!0;if(!a&&!t&&0===l.startOffset&&0===l.endOffset)return e.undoManager.transact((()=>{vt(e)})),!0}return!1},Ft=e=>{const t=e.selection.getStart(),n=je(e,t);return e.dom.getParent(t,"LI,DT,DD",n)||Ve(e).length>0},Ht=(e,t)=>{const n=e.selection;return!Ge(e,n.getNode())&&(n.isCollapsed()?((e,t)=>_t(e,t)||((e,t)=>{const n=e.dom,r=e.selection.getStart(),o=je(e,r),s=n.getParent(r,n.isBlock,o);if(s&&n.isEmpty(s)){const r=$e(e.selection.getRng()),i=n.getParent(Rt(e,r,t,o),"LI",o);if(i){const l=e=>v(["td","th","caption"],$(e)),a=e=>e.dom===o;return!!((e,t,n=u)=>I(e,t,n).getOr(e.isNone()&&t.isNone()))(q(R(i),l,a),q(R(r.startContainer),l,a),U)&&(e.undoManager.transact((()=>{((e,t,n)=>{const r=e.getParent(t.parentNode,e.isBlock,n);e.remove(t),r&&e.isEmpty(r)&&e.remove(r)})(n,s,o),Et(n,i.parentNode),e.selection.select(i,!0),e.selection.collapse(t)})),!0)}}return!1})(e,t))(e,t):(e=>!!Ft(e)&&(e.undoManager.transact((()=>{e.execCommand("Delete"),Mt(e.dom,e.getBody())})),!0))(e))},Vt=e=>{const t=A(Ye(e).split("")),n=b(t,((e,t)=>{const n=e.toUpperCase().charCodeAt(0)-"A".charCodeAt(0)+1;return Math.pow(26,t)*n}));return L(n,((e,t)=>e+t),0)},jt=e=>{if(--e<0)return"";{const t=e%26,n=Math.floor(e/26);return jt(n)+String.fromCharCode("A".charCodeAt(0)+t)}},Kt=e=>{const t=parseInt(e.start,10);return B(e.listStyleType,"upper-alpha")?jt(t):B(e.listStyleType,"lower-alpha")?jt(t).toLowerCase():e.start},zt=(e,t)=>()=>{const n=He(e);return l(n)&&n.nodeName===t},Qt=e=>{e.addCommand("mceListProps",(()=>{(e=>{const t=He(e);ye(t)&&!Ge(e,t)&&e.windowManager.open({title:"List Properties",body:{type:"panel",items:[{type:"input",name:"start",label:"Start list at number",inputMode:"numeric"}]},initialData:{start:Kt({start:e.dom.getAttrib(t,"start","1"),listStyleType:g.from(e.dom.getStyle(t,"list-style-type"))})},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],onSubmit:t=>{(e=>{switch((e=>/^[0-9]+$/.test(e)?2:/^[A-Z]+$/.test(e)?0:/^[a-z]+$/.test(e)?1:e.length>0?4:3)(e)){case 2:return g.some({listStyleType:g.none(),start:e});case 0:return g.some({listStyleType:g.some("upper-alpha"),start:Vt(e).toString()});case 1:return g.some({listStyleType:g.some("lower-alpha"),start:Vt(e).toString()});case 3:return g.some({listStyleType:g.none(),start:""});case 4:return g.none()}})(t.getData().start).each((t=>{e.execCommand("mceListUpdate",!1,{attrs:{start:"1"===t.start?"":t.start},styles:{"list-style-type":t.listStyleType.getOr("")}})})),t.close()}})})(e)}))};var qt=tinymce.util.Tools.resolve("tinymce.html.Node");const Wt=e=>3===e.type,Zt=e=>0===e.length,Gt=e=>{const t=(t,n)=>{const r=qt.create("li");S(t,(e=>r.append(e))),n?e.insert(r,n,!0):e.append(r)},n=L(e.children(),((e,n)=>Wt(n)?[...e,n]:Zt(e)||Wt(n)?e:(t(e,n),[])),[]);Zt(n)||t(n)},Jt=(e,t)=>n=>Je(e,(r=>{n.setActive(We(r.parents,t)),n.setEnabled(!Ge(e,r.element))})),Xt=(e,t)=>n=>Je(e,(r=>n.setEnabled(We(r.parents,t)&&!Ge(e,r.element))));e.add("lists",(e=>((e=>{(0,e.options.register)("lists_indent_on_tab",{processor:"boolean",default:!0})})(e),(e=>{e.on("PreInit",(()=>{const{parser:t}=e;t.addNodeFilter("ul,ol",(e=>S(e,Gt)))}))})(e),e.hasPlugin("rtc",!0)?Qt(e):((e=>{xe(e)&&(e=>{e.on("keydown",(t=>{t.keyCode!==te.TAB||te.metaKeyPressed(t)||e.undoManager.transact((()=>{(t.shiftKey?yt(e):ft(e))&&t.preventDefault()}))}))})(e),(e=>{e.on("ExecCommand",(t=>{const n=t.command.toLowerCase();"delete"!==n&&"forwarddelete"!==n||!Ft(e)||Mt(e.dom,e.getBody())})),e.on("keydown",(t=>{t.keyCode===te.BACKSPACE?Ht(e,!1)&&t.preventDefault():t.keyCode===te.DELETE&&Ht(e,!0)&&t.preventDefault()}))})(e)})(e),(e=>{e.on("BeforeExecCommand",(t=>{const n=t.command.toLowerCase();"indent"===n?ft(e):"outdent"===n&&yt(e)})),e.addCommand("InsertUnorderedList",((t,n)=>{It(e,"UL",n)})),e.addCommand("InsertOrderedList",((t,n)=>{It(e,"OL",n)})),e.addCommand("InsertDefinitionList",((t,n)=>{It(e,"DL",n)})),e.addCommand("RemoveList",(()=>{vt(e)})),Qt(e),e.addCommand("mceListUpdate",((t,n)=>{o(n)&&((e,t)=>{const n=He(e);null===n||Ge(e,n)||e.undoManager.transact((()=>{o(t.styles)&&e.dom.setStyles(n,t.styles),o(t.attrs)&&oe(t.attrs,((t,r)=>e.dom.setAttrib(n,r,t)))}))})(e,n)})),e.addQueryStateHandler("InsertUnorderedList",zt(e,"UL")),e.addQueryStateHandler("InsertOrderedList",zt(e,"OL")),e.addQueryStateHandler("InsertDefinitionList",zt(e,"DL"))})(e)),(e=>{const t=t=>()=>e.execCommand(t);e.hasPlugin("advlist")||(e.ui.registry.addToggleButton("numlist",{icon:"ordered-list",active:!1,tooltip:"Numbered list",onAction:t("InsertOrderedList"),onSetup:Jt(e,"OL")}),e.ui.registry.addToggleButton("bullist",{icon:"unordered-list",active:!1,tooltip:"Bullet list",onAction:t("InsertUnorderedList"),onSetup:Jt(e,"UL")}))})(e),(e=>{const t={text:"List properties...",icon:"ordered-list",onAction:()=>e.execCommand("mceListProps"),onSetup:Xt(e,"OL")};e.ui.registry.addMenuItem("listprops",t),e.ui.registry.addContextMenu("lists",{update:t=>{const n=He(e,t);return ye(n)?["listprops"]:[]}})})(e),(e=>({backspaceDelete:t=>{Ht(e,t)}}))(e))))}(); \ No newline at end of file diff --git a/public/resource/tinymce/plugins/media/plugin.min.js b/public/resource/tinymce/plugins/media/plugin.min.js new file mode 100644 index 0000000..340c0a3 --- /dev/null +++ b/public/resource/tinymce/plugins/media/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.4.2 (2023-04-26) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(r=a=e,(o=String).prototype.isPrototypeOf(r)||(null===(s=a.constructor)||void 0===s?void 0:s.name)===o.name)?"string":t;var r,a,o,s})(t)===e,r=t("string"),a=t("object"),o=t("array"),s=e=>!(e=>null==e)(e);class i{constructor(e,t){this.tag=e,this.value=t}static some(e){return new i(!0,e)}static none(){return i.singletonNone}fold(e,t){return this.tag?t(this.value):e()}isSome(){return this.tag}isNone(){return!this.tag}map(e){return this.tag?i.some(e(this.value)):i.none()}bind(e){return this.tag?e(this.value):i.none()}exists(e){return this.tag&&e(this.value)}forall(e){return!this.tag||e(this.value)}filter(e){return!this.tag||e(this.value)?this:i.none()}getOr(e){return this.tag?this.value:e}or(e){return this.tag?this:e}getOrThunk(e){return this.tag?this.value:e()}orThunk(e){return this.tag?this:e()}getOrDie(e){if(this.tag)return this.value;throw new Error(null!=e?e:"Called getOrDie on None")}static from(e){return s(e)?i.some(e):i.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(e){this.tag&&e(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}i.singletonNone=new i(!1);const n=Array.prototype.push,c=(e,t)=>{for(let r=0,a=e.length;r{const t=[];for(let r=0,a=e.length;rh(e,t)?i.from(e[t]):i.none(),h=(e,t)=>u.call(e,t),p=e=>t=>t.options.get(e),g=p("audio_template_callback"),b=p("video_template_callback"),w=p("iframe_template_callback"),v=p("media_live_embeds"),f=p("media_filter_html"),y=p("media_url_resolver"),x=p("media_alt_source"),_=p("media_poster"),j=p("media_dimensions");var k=tinymce.util.Tools.resolve("tinymce.util.Tools"),O=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),A=tinymce.util.Tools.resolve("tinymce.html.DomParser");const S=O.DOM,C=e=>e.replace(/px$/,""),D=e=>{const t=e.attr("style"),r=t?S.parseStyle(t):{};return{type:"ephox-embed-iri",source:e.attr("data-ephox-embed-iri"),altsource:"",poster:"",width:d(r,"max-width").map(C).getOr(""),height:d(r,"max-height").map(C).getOr("")}},T=(e,t)=>{let r={};for(let a=A({validate:!1,forced_root_block:!1},t).parse(e);a;a=a.walk())if(1===a.type){const e=a.name;if(a.attr("data-ephox-embed-iri")){r=D(a);break}r.source||"param"!==e||(r.source=a.attr("movie")),"iframe"!==e&&"object"!==e&&"embed"!==e&&"video"!==e&&"audio"!==e||(r.type||(r.type=e),r=k.extend(a.attributes.map,r)),"script"===e&&(r={type:"script",source:a.attr("src")}),"source"===e&&(r.source?r.altsource||(r.altsource=a.attr("src")):r.source=a.attr("src")),"img"!==e||r.poster||(r.poster=a.attr("src"))}return r.source=r.source||r.src||"",r.altsource=r.altsource||"",r.poster=r.poster||"",r},z=e=>{var t;const r=null!==(t=e.toLowerCase().split(".").pop())&&void 0!==t?t:"";return d({mp3:"audio/mpeg",m4a:"audio/x-m4a",wav:"audio/wav",mp4:"video/mp4",webm:"video/webm",ogg:"video/ogg",swf:"application/x-shockwave-flash"},r).getOr("")};var $=tinymce.util.Tools.resolve("tinymce.html.Node"),M=tinymce.util.Tools.resolve("tinymce.html.Serializer");const F=(e,t={})=>A({forced_root_block:!1,validate:!1,allow_conditional_comments:!0,...t},e),N=O.DOM,R=e=>/^[0-9.]+$/.test(e)?e+"px":e,U=(e,t)=>{const r=t.attr("style"),a=r?N.parseStyle(r):{};s(e.width)&&(a["max-width"]=R(e.width)),s(e.height)&&(a["max-height"]=R(e.height)),t.attr("style",N.serializeStyle(a))},P=["source","altsource"],E=(e,t,r,a)=>{let o=0,s=0;const i=F(a);i.addNodeFilter("source",(e=>o=e.length));const n=i.parse(e);for(let e=n;e;e=e.walk())if(1===e.type){const a=e.name;if(e.attr("data-ephox-embed-iri")){U(t,e);break}switch(a){case"video":case"object":case"embed":case"img":case"iframe":void 0!==t.height&&void 0!==t.width&&(e.attr("width",t.width),e.attr("height",t.height))}if(r)switch(a){case"video":e.attr("poster",t.poster),e.attr("src",null);for(let r=o;r<2;r++)if(t[P[r]]){const a=new $("source",1);a.attr("src",t[P[r]]),a.attr("type",t[P[r]+"mime"]||null),e.append(a)}break;case"iframe":e.attr("src",t.source);break;case"object":const r=e.getAll("img").length>0;if(t.poster&&!r){e.attr("src",t.poster);const r=new $("img",1);r.attr("src",t.poster),r.attr("width",t.width),r.attr("height",t.height),e.append(r)}break;case"source":if(s<2&&(e.attr("src",t[P[s]]),e.attr("type",t[P[s]+"mime"]||null),!t[P[s]])){e.remove();continue}s++;break;case"img":t.poster||e.remove()}}return M({},a).serialize(n)},L=[{regex:/youtu\.be\/([\w\-_\?&=.]+)/i,type:"iframe",w:560,h:314,url:"www.youtube.com/embed/$1",allowFullscreen:!0},{regex:/youtube\.com(.+)v=([^&]+)(&([a-z0-9&=\-_]+))?/i,type:"iframe",w:560,h:314,url:"www.youtube.com/embed/$2?$4",allowFullscreen:!0},{regex:/youtube.com\/embed\/([a-z0-9\?&=\-_]+)/i,type:"iframe",w:560,h:314,url:"www.youtube.com/embed/$1",allowFullscreen:!0},{regex:/vimeo\.com\/([0-9]+)/,type:"iframe",w:425,h:350,url:"player.vimeo.com/video/$1?title=0&byline=0&portrait=0&color=8dc7dc",allowFullscreen:!0},{regex:/vimeo\.com\/(.*)\/([0-9]+)/,type:"iframe",w:425,h:350,url:"player.vimeo.com/video/$2?title=0&byline=0",allowFullscreen:!0},{regex:/maps\.google\.([a-z]{2,3})\/maps\/(.+)msid=(.+)/,type:"iframe",w:425,h:350,url:'maps.google.com/maps/ms?msid=$2&output=embed"',allowFullscreen:!1},{regex:/dailymotion\.com\/video\/([^_]+)/,type:"iframe",w:480,h:270,url:"www.dailymotion.com/embed/video/$1",allowFullscreen:!0},{regex:/dai\.ly\/([^_]+)/,type:"iframe",w:480,h:270,url:"www.dailymotion.com/embed/video/$1",allowFullscreen:!0}],I=(e,t)=>{const r=(e=>{const t=e.match(/^(https?:\/\/|www\.)(.+)$/i);return t&&t.length>1?"www."===t[1]?"https://":t[1]:"https://"})(t),a=e.regex.exec(t);let o=r+e.url;if(s(a))for(let e=0;ea[e]?a[e]:""));return o.replace(/\?$/,"")},B=(e,t)=>{var r;const a=k.extend({},t);if(!a.source&&(k.extend(a,T(null!==(r=a.embed)&&void 0!==r?r:"",e.schema)),!a.source))return"";a.altsource||(a.altsource=""),a.poster||(a.poster=""),a.source=e.convertURL(a.source,"source"),a.altsource=e.convertURL(a.altsource,"source"),a.sourcemime=z(a.source),a.altsourcemime=z(a.altsource),a.poster=e.convertURL(a.poster,"poster");const o=(e=>{const t=L.filter((t=>t.regex.test(e)));return t.length>0?k.extend({},t[0],{url:I(t[0],e)}):null})(a.source);if(o&&(a.source=o.url,a.type=o.type,a.allowfullscreen=o.allowFullscreen,a.width=a.width||String(o.w),a.height=a.height||String(o.h)),a.embed)return E(a.embed,a,!0,e.schema);{const t=g(e),r=b(e),o=w(e);return a.width=a.width||"300",a.height=a.height||"150",k.each(a,((t,r)=>{a[r]=e.dom.encode(""+t)})),"iframe"===a.type?((e,t)=>{if(t)return t(e);{const t=e.allowfullscreen?' allowFullscreen="1"':"";return'"}})(a,o):"application/x-shockwave-flash"===a.sourcemime?(e=>{let t='';return e.poster&&(t+=''),t+="",t})(a):-1!==a.sourcemime.indexOf("audio")?((e,t)=>t?t(e):'")(a,t):"script"===a.type?(e=>' diff --git a/src/api/.DS_Store b/src/api/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..1c58bed1de5bf3406eb259ce40241cfd9ba3fd1b GIT binary patch literal 8196 zcmeHM!DF*Uj#ZZg3|vY_bGz^9f!&>!0M5 zlNUe1Pw*3b)!j_Cdb;CH#8g9f4PCFg-n{AUp=OE59Ia-1M7u;ZLTCGM2ScQ>pL?%8 z@H5X~4dRKWiw}Dz)4FPUSe;M>Q~^~$6;K6Kfqz2*ytBED67PNI)ln5t1@5H+d_H98 zY;$j0XYJ8}!Il8915De7Yt#WYCi6D;wsqEqVog^)7$0hUiD6tg{29Yxb8lN`T{syR zPR3_8zCtlJJK{16CzCs?qbi^Z^cCRReMl2Jr3*R>>-V?sq_?VzVzQ_wnB||__m5w1 zUWSO-9}vxa{R_blgwr;?NA7cQIHxJDPH7>(BP@q;RDw@ry{eA#iXbJwpUiJa71cDO zGUR1S=}quii%;-aL&*I0G~1$vmX^T^`dmtF4xWHRfJpG@p`w}uD9PtD>oEeK6&Ouv zZudp(fO6^Kl=M;1sNrU=*MvpN#ozT0RY) z+%jZSdODj&FHf;#r-AJNW5-$HV*YF?GzOHUPiJU$zkBYreMb z-6YrA8TuHV8{=AMZ3qTij>Fn=9Jc$z5Z4)?9Fu$7I*S>!zy2Yhv1v))|4s)T@23L4 E0bnSL?EnA( literal 0 HcmV?d00001 diff --git a/src/api/basic/common.ts b/src/api/basic/common.ts new file mode 100644 index 0000000..ff912da --- /dev/null +++ b/src/api/basic/common.ts @@ -0,0 +1,70 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import {ContentTypeEnum} from "@/enums/httpEnum"; + +enum Api { + UploadXlsx = '/v2/common/upload/excel', + ExportXlsx = '/v2/common/export/excel', + UploadOss = '/v2/common/uploadOss', + GenerateId = '/v2/common/nextId', +} + +export interface UploadFileParams { + // file name + file: File; +} + +export function uploadXlsx(params: UploadFileParams, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: Api.UploadXlsx, + params, + headers: { + 'Content-type': ContentTypeEnum.FORM_DATA, + // @ts-ignore + ignoreCancelToken: true, + }, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function exportXlsx(type: string, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.get>( + { + url: `${Api.ExportXlsx}?type=${type}`, + responseType: "blob" + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function uploadOss(params: UploadFileParams, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: Api.UploadOss, + params, + headers: { + 'Content-type': ContentTypeEnum.FORM_DATA, + // @ts-ignore + ignoreCancelToken: true, + }, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function generateId(type: string) { + return defHttp.get>( + { + url: `${Api.GenerateId}/${type}`, + } + ); +} \ No newline at end of file diff --git a/src/api/basic/customer.ts b/src/api/basic/customer.ts new file mode 100644 index 0000000..ca1b985 --- /dev/null +++ b/src/api/basic/customer.ts @@ -0,0 +1,82 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + CustomerResp, + AddOrUpdateCustomerReq, + QueryCustomerReq +} from "@/api/basic/model/customerModel"; + + +enum API { + PageList = '/basic/customer/pageList', + List = '/basic/customer/list', + AddOrUpdateCustomer = '/basic/customer/addOrUpdate', + DeleteBatch = '/basic/customer/deleteBatch', + UpdateStatus = '/basic/customer/updateStatus', + Export = '/basic/customer/export', +} + +export function getCustomerPageList(params: QueryCustomerReq) { + return defHttp.post>( + { + url: API.PageList, + params, + }, + ); +} + +export function getCustomerList() { + return defHttp.get>( + { + url: API.List + } + ); +} + +export function addOrUpdateCustomer(params: AddOrUpdateCustomerReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdateCustomer, + params, + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + }, + ); +} + +export function updateCustomerStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: `${API.UpdateStatus}?ids=${ids}&status=${status}` + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + }, + ); +} + +export function deleteBatchCustomer(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.delete( + { + url: `${API.DeleteBatch}?ids=${ids}` + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + }, + ); +} + +export function exportCustomer(params: QueryCustomerReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/basic/incomeExpense.ts b/src/api/basic/incomeExpense.ts new file mode 100644 index 0000000..3c43c2f --- /dev/null +++ b/src/api/basic/incomeExpense.ts @@ -0,0 +1,69 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + QueryIncomeExpenseReq, + AddOrUpdateIncomeExpenseReq, + IncomeExpenseResp, +} from "@/api/basic/model/incomeExpenseModel"; + +enum API { + PageList = '/basic/incomeExpense/pageList', + List = '/basic/incomeExpense/list', + AddOrUpdateIncomeExpense = '/basic/incomeExpense/addOrUpdate', + DeleteBatch = '/basic/incomeExpense/deleteBatch', + UpdateStatus = '/basic/incomeExpense/updateStatus', +} + +export function getIncomeExpensePageList(params: QueryIncomeExpenseReq) { + return defHttp.post>( + { + url: API.PageList, + params, + } + ); +} + +export function getIncomeExpenseList(type: string) { + return defHttp.get>( + { + url: `${API.List}/${type}` + } + ); +} + +export function addOrUpdateIncomeExpense(params: AddOrUpdateIncomeExpenseReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdateIncomeExpense, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteIncomeExpense(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.delete( + { + url: `${API.DeleteBatch}?ids=${ids}` + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + }, + ); +} + +export function updateIncomeExpenseStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: `${API.UpdateStatus}?ids=${ids}&status=${status}` + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + }, + ); +} diff --git a/src/api/basic/member.ts b/src/api/basic/member.ts new file mode 100644 index 0000000..a5cac99 --- /dev/null +++ b/src/api/basic/member.ts @@ -0,0 +1,79 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + MemberResp, + AddOrUpdateMemberReq, + QueryMemberReq +} from "@/api/basic/model/memberModel"; + + +enum API { + List = '/basic/member/list', + PageList = '/basic/member/pageList', + AddOrUpdateMember = '/basic/member/addOrUpdate', + DeleteBatch = '/basic/member/deleteBatch', + UpdateStatus = '/basic/member/updateStatus', + Export = '/basic/member/export', +} + +export function getMemberPageList(params: QueryMemberReq) { + return defHttp.post>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdateMember(params: AddOrUpdateMemberReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdateMember, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function updateMemberStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: `${API.UpdateStatus}?ids=${ids}&status=${status}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteBatchMember(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.delete( + { + url: `${API.DeleteBatch}?ids=${ids}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getMemberList() { + return defHttp.get>( + { + url: API.List + } + ); +} + +export function exportMember(params: QueryMemberReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/basic/model/customerModel.ts b/src/api/basic/model/customerModel.ts new file mode 100644 index 0000000..f6ac2da --- /dev/null +++ b/src/api/basic/model/customerModel.ts @@ -0,0 +1,49 @@ +export interface CustomerResp { + id: number | string; + customerName: string; + contact: string; + phoneNumber: string; + address: string; + email: string; + status: number; + firstQuarterAccountReceivable: number; + secondQuarterAccountReceivable: number; + thirdQuarterAccountReceivable: number; + fourthQuarterAccountReceivable: number; + totalAccountReceivable: number; + fax: string; + taxNumber: string; + bankName: string; + accountNumber: string; + taxRate: string; + sort: number; + remark: string; + createTime: string; +} + +export interface AddOrUpdateCustomerReq { + id: number | string | undefined; + customerName: string; + contact: string; + phoneNumber: string; + address: string; + email: string; + status: number; + firstQuarterAccountReceivable: number; + secondQuarterAccountReceivable: number; + thirdQuarterAccountReceivable: number; + fourthQuarterAccountReceivable: number; + fax: string; + taxNumber: string; + bankName: string; + accountNumber: string; + taxRate: string; + sort: number; + remark: string; +} + +export interface QueryCustomerReq { + customerName: string; + contact: string; + phoneNumber: string; +} \ No newline at end of file diff --git a/src/api/basic/model/incomeExpenseModel.ts b/src/api/basic/model/incomeExpenseModel.ts new file mode 100644 index 0000000..7c8ece7 --- /dev/null +++ b/src/api/basic/model/incomeExpenseModel.ts @@ -0,0 +1,24 @@ +export interface QueryIncomeExpenseReq { + name: string; + type: string; + remark: string; +} + +export interface AddOrUpdateIncomeExpenseReq { + id: number | string | undefined; + name: string; + type: string; + remark: string; + status: number; + sort: number; +} + +export interface IncomeExpenseResp { + id: string; + name: string; + type: string; + remark: string; + status: number; + sort: number; + createTime: string; +} \ No newline at end of file diff --git a/src/api/basic/model/memberModel.ts b/src/api/basic/model/memberModel.ts new file mode 100644 index 0000000..a63685c --- /dev/null +++ b/src/api/basic/model/memberModel.ts @@ -0,0 +1,29 @@ +export interface MemberResp { + id: number | string; + memberNumber: string; + memberName: string; + phoneNumber: string; + email: string; + advancePayment: number; + status: number; + remark: string; + sort: number; + createTime: string; +} + +export interface AddOrUpdateMemberReq { + id: number | string | undefined; + memberNumber: string; + memberName: string; + phoneNumber: string; + email: string; + advancePayment: number; + status: number; + remark: string; + sort: number; +} + +export interface QueryMemberReq { + memberNumber: string; + phoneNumber: string; +} \ No newline at end of file diff --git a/src/api/basic/model/operatorModel.ts b/src/api/basic/model/operatorModel.ts new file mode 100644 index 0000000..b832694 --- /dev/null +++ b/src/api/basic/model/operatorModel.ts @@ -0,0 +1,23 @@ +export interface OperatorResp { + id: number | string; + name: string; + type: string; + status: number; + sort: number; + remark: string; + createTime: string; +} + +export interface AddOrUpdateOperatorReq { + id: number | string | undefined; + name: string; + type: number; + status: number; + remark: string; + sort: number; +} + +export interface QueryOperatorReq { + name: string; + type: string; +} \ No newline at end of file diff --git a/src/api/basic/model/supplierModel.ts b/src/api/basic/model/supplierModel.ts new file mode 100644 index 0000000..dfb5283 --- /dev/null +++ b/src/api/basic/model/supplierModel.ts @@ -0,0 +1,88 @@ +export interface SupplierResp { + id: number | string; + supplierName: string; + contact: string; + contactNumber: string; + phoneNumber: string; + address: string; + email: string; + status: number; + firstQuarterAccountReceivable: number; + secondQuarterAccountReceivable: number; + thirdQuarterAccountReceivable: number; + fourthQuarterAccountReceivable: number; + totalAccountReceivable: number; + firstQuarterAccountPayment: number; + secondQuarterAccountPayment: number; + thirdQuarterAccountPayment: number; + fourthQuarterAccountPayment: number; + totalAccountPayment: number; + fax: string; + taxNumber: string; + bankName: string; + accountNumber: string; + taxRate: string; + sort: number; + remark: string; + createTime: string; +} + +export interface AddSupplierReq { + supplierName: string; + contact: string; + contactNumber: string; + phoneNumber: string; + address: string; + email: string; + status: number; + firstQuarterAccountReceivable: number; + secondQuarterAccountReceivable: number; + thirdQuarterAccountReceivable: number; + fourthQuarterAccountReceivable: number; + firstQuarterAccountPayment: number; + secondQuarterAccountPayment: number; + thirdQuarterAccountPayment: number; + fourthQuarterAccountPayment: number; + fax: string; + taxNumber: string; + bankName: string; + accountNumber: string; + taxRate: string; + sort: number; + remark: string; +} + +export interface UpdateSupplierReq { + id: number | string; + supplierName: string; + contact: string; + contactNumber: string; + phoneNumber: string; + address: string; + email: string; + status: number; + firstQuarterAccountReceivable: number; + secondQuarterAccountReceivable: number; + thirdQuarterAccountReceivable: number; + fourthQuarterAccountReceivable: number; + totalAccountReceivable: number; + firstQuarterAccountPayment: number; + secondQuarterAccountPayment: number; + thirdQuarterAccountPayment: number; + fourthQuarterAccountPayment: number; + totalAccountPayment: number; + fax: string; + taxNumber: string; + bankName: string; + accountNumber: string; + taxRate: string; + sort: number; + remark: string; +} + +export interface QuerySupplierReq { + supplierName: string; + contact: string; + contactNumber: string; + phoneNumber: string; +} \ No newline at end of file diff --git a/src/api/basic/model/warehouseModel.ts b/src/api/basic/model/warehouseModel.ts new file mode 100644 index 0000000..7224241 --- /dev/null +++ b/src/api/basic/model/warehouseModel.ts @@ -0,0 +1,33 @@ +export interface WarehouseResp { + id: number | string; + warehouseManager: string; + warehouseName: string; + address: string; + price: number; + truckage: number; + type: number; + status: number; + remark: string; + sort: number; + isDefault: number; + createTime: string; +} + +export interface AddOrUpdateWarehouseReq { + id: number | string | undefined; + warehouseName: string; + warehouseManager: number; + address: string; + price: number; + truckage: number; + type: number; + isDefault: number; + status: number; + remark: string; + sort: number; +} + +export interface QueryWarehouseReq { + warehouseName: string; + remark: string; +} \ No newline at end of file diff --git a/src/api/basic/operator.ts b/src/api/basic/operator.ts new file mode 100644 index 0000000..cbb9880 --- /dev/null +++ b/src/api/basic/operator.ts @@ -0,0 +1,68 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + OperatorResp, + AddOrUpdateOperatorReq, + QueryOperatorReq +} from "@/api/basic/model/operatorModel"; + + +enum API { + PageList = '/basic/operator/pageList', + AddOrUpdateOperator = '/basic/operator/addOrUpdate', + DeleteBatch = '/basic/operator/delete', + UpdateStatus = '/basic/operator/updateStatus', + List = '/basic/operator/list', +} + +export function getOperatorPageList(params: QueryOperatorReq) { + return defHttp.post>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdateOperator(params: AddOrUpdateOperatorReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdateOperator, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function updateOperatorStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: `${API.UpdateStatus}?ids=${ids}&status=${status}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteBatchOperator(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.delete( + { + url: `${API.DeleteBatch}?ids=${ids}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getOperatorList(type: string) { + return defHttp.get>( + { + url: `${API.List}/${type}`, + } + ); +} \ No newline at end of file diff --git a/src/api/basic/supplier.ts b/src/api/basic/supplier.ts new file mode 100644 index 0000000..3d26689 --- /dev/null +++ b/src/api/basic/supplier.ts @@ -0,0 +1,94 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + SupplierResp, + AddSupplierReq, + UpdateSupplierReq, + QuerySupplierReq +} from "@/api/basic/model/supplierModel"; + + +enum API { + PageList = '/basic/supplier/pageList', + List = '/basic/supplier/list', + AddSupplier = '/basic/supplier/add', + UpdateSupplier = '/basic/supplier/update', + DeleteBatch = '/basic/supplier/deleteBatch', + UpdateStatus = '/basic/supplier/updateStatus', + Export = '/basic/supplier/export', +} + +export function getSupplierPageList(params: QuerySupplierReq) { + return defHttp.post>( + { + url: API.PageList, + params, + } + ); +} + +export function getSupplierList() { + return defHttp.get>( + { + url: API.List + } + ); +} + +export function addSupplier(params: AddSupplierReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddSupplier, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function updateSupplier(params: UpdateSupplierReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.UpdateSupplier, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function updateSupplierStatus(params: { ids: number[], status: number }, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.UpdateStatus, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteBatchSuppliers(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.delete( + { + url: `${API.DeleteBatch}?ids=${ids}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function exportSupplier(params: QuerySupplierReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/basic/warehouse.ts b/src/api/basic/warehouse.ts new file mode 100644 index 0000000..c513998 --- /dev/null +++ b/src/api/basic/warehouse.ts @@ -0,0 +1,86 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + WarehouseResp, + AddOrUpdateWarehouseReq, + QueryWarehouseReq +} from "@/api/basic/model/warehouseModel"; + + +enum API { + PageList = '/basic/warehouse/pageList', + AddOrUpdateWarehouse = '/basic/warehouse/addOrUpdate', + DeleteBatch = '/basic/warehouse/delete', + UpdateStatus = '/basic/warehouse/updateStatus', + GetWarehouse = '/basic/warehouse/getWarehouse', + List = '/basic/warehouse/list', + GetDefaultWarehouse = '/basic/warehouse/getDefaultWarehouse', +} + +export function getWarehousePageList(params: QueryWarehouseReq) { + return defHttp.post>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdateWarehouse(params: AddOrUpdateWarehouseReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdateWarehouse, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function updateWarehouseStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: `${API.UpdateStatus}?ids=${ids}&status=${status}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteBatchWarehouse(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.delete( + { + url: `${API.DeleteBatch}?ids=${ids}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getWarehouse() { + return defHttp.get>( + { + url: API.GetWarehouse, + } + ); +} + +export function getWarehouseList() { + return defHttp.get>( + { + url: API.List, + } + ); +} + +export function getDefaultWarehouse() { + return defHttp.get>( + { + url: API.GetDefaultWarehouse, + } + ); +} \ No newline at end of file diff --git a/src/api/financial/account.ts b/src/api/financial/account.ts new file mode 100644 index 0000000..966e765 --- /dev/null +++ b/src/api/financial/account.ts @@ -0,0 +1,68 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + AccountResp, + AddOrUpdateAccountReq, + QueryAccountReq +} from "@/api/financial/model/accountModel"; + + +enum API { + PageList = '/financial/account/pageList', + AddOrUpdateAccount = '/financial/account/addOrUpdate', + DeleteBatch = '/financial/account/delete', + UpdateStatus = '/financial/account/updateStatus', + List = '/financial/account/list', +} + +export function getAccountPageList(params: QueryAccountReq) { + return defHttp.post>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdateAccount(params: AddOrUpdateAccountReq, mode: ErrorMessageMode = 'notice', successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdateAccount, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function updateAccountStatus(ids: number[], status: number, mode: ErrorMessageMode = 'notice', successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: `${API.UpdateStatus}?ids=${ids}&status=${status}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteBatchAccount(ids: number[], mode: ErrorMessageMode = 'notice', successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.delete( + { + url: `${API.DeleteBatch}?ids=${ids}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getAccountList() { + return defHttp.get>( + { + url: API.List, + } + ); +} \ No newline at end of file diff --git a/src/api/financial/advance.ts b/src/api/financial/advance.ts new file mode 100644 index 0000000..c340619 --- /dev/null +++ b/src/api/financial/advance.ts @@ -0,0 +1,96 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + AdvanceChargeResp, + AddOrUpdateAdvanceReq, + QueryAdvanceReq, AdvanceChargeDetailResp, +} from "@/api/financial/model/advanceModel"; + +enum API { + PageList = '/financial/advance-charge/pageList', + AddOrUpdateAccount = '/financial/advance-charge/addOrUpdate', + DeleteBatch = '/financial/advance-charge/deleteByIds', + UpdateStatus = '/financial/advance-charge/updateStatusByIds', + GetDetail = '/financial/advance-charge/getDetailById', + Export = '/financial/advance-charge/export', + ExportDetail = '/financial/advance-charge/exportDetail', +} + +export function getAdvancePageList(params: QueryAdvanceReq, errorMode: ErrorMessageMode = 'message') { + return defHttp.post>( + { + url: API.PageList, + params, + }, + { + errorMessageMode: errorMode, + }, + ); +} + +export function addOrUpdateAdvance(params: AddOrUpdateAdvanceReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdateAccount, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function updateAdvanceStatus(ids: number[] | string[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.UpdateStatus}?ids=${ids}&status=${status}` + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + }, + ); +} + +export function deleteBatchAdvance(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.DeleteBatch}?ids=${ids}` + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + }, + ); +} + +export function getAdvanceDetail(id: number | string, mode: ErrorMessageMode = 'notice') { + return defHttp.get>( + { + url: `${API.GetDetail}/${id}` + }, + { + errorMessageMode: mode, + }, + ); +} + +export function exportAdvance(params: QueryAdvanceReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} + +export function exportAdvanceDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.ExportDetail}/${receiptNumber}`, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/financial/collection.ts b/src/api/financial/collection.ts new file mode 100644 index 0000000..55c51a6 --- /dev/null +++ b/src/api/financial/collection.ts @@ -0,0 +1,99 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + AddOrUpdateCollectionReq, + QueryCollectionReq, + CollectionResp, + CollectionDetailResp, QuerySaleArrearsReq, SaleArrearsResp, +} from "@/api/financial/model/collectionModel"; + +enum API { + PageList = '/financial/collection/pageList', + AddOrUpdateAccount = '/financial/collection/addOrUpdate', + DeleteBatch = '/financial/collection/deleteByIds', + UpdateStatus = '/financial/collection/updateStatusByIds', + GetDetail = '/financial/collection/getDetailById', + GetArrearsPage = '/sale/arrears/pageList', + Export = '/financial/collection/export', + ExportDetail = '/financial/collection/exportDetail', +} + +export function getCollectionPageList(params: QueryCollectionReq) { + return defHttp.post>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdateCollection(params: AddOrUpdateCollectionReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdateAccount, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function updateCollectionStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.UpdateStatus}?ids=${ids}&status=${status}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteBatchCollection(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.DeleteBatch}?ids=${ids}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getCollectionDetailById(id: number) { + return defHttp.get>( + { + url: `${API.GetDetail}/${id}` + }, + ); +} + +export function getArrearsPageList(params: QuerySaleArrearsReq) { + return defHttp.post>( + { + url: API.GetArrearsPage, + params, + } + ); +} + +export function exportCollection(params: QueryCollectionReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} + +export function exportCollectionDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.ExportDetail}/${receiptNumber}`, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/financial/expense.ts b/src/api/financial/expense.ts new file mode 100644 index 0000000..95ecb90 --- /dev/null +++ b/src/api/financial/expense.ts @@ -0,0 +1,89 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + AddOrUpdateExpenseReq, + QueryExpenseReq, + ExpenseResp, + ExpenseDetailResp, +} from "@/api/financial/model/expenseModel"; + +enum API { + PageList = '/financial/expense/pageList', + AddOrUpdateAccount = '/financial/expense/addOrUpdate', + DeleteBatch = '/financial/expense/deleteByIds', + UpdateStatus = '/financial/expense/updateStatusByIds', + GetDetail = '/financial/expense/getDetailById', + Export = '/financial/expense/export', + ExportDetail = '/financial/expense/exportDetail', +} + +export function getExpensePageList(params: QueryExpenseReq) { + return defHttp.post>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdateExpense(params: AddOrUpdateExpenseReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdateAccount, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function updateExpenseStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.UpdateStatus}?ids=${ids}&status=${status}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteBatchExpense(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.DeleteBatch}?ids=${ids}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getExpenseDetailById(id: number) { + return defHttp.get>( + { + url: `${API.GetDetail}/${id}` + }, + ); +} + +export function exportExpense(params: QueryExpenseReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} + +export function exportExpenseDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.ExportDetail}/${receiptNumber}`, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/financial/income.ts b/src/api/financial/income.ts new file mode 100644 index 0000000..7566be0 --- /dev/null +++ b/src/api/financial/income.ts @@ -0,0 +1,88 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + IncomeDetailResp, + AddOrUpdateIncomeReq, + QueryIncomeReq, IncomeResp, +} from "@/api/financial/model/incomeModel"; + +enum API { + PageList = '/financial/income/pageList', + AddOrUpdateAccount = '/financial/income/addOrUpdate', + DeleteBatch = '/financial/income/deleteByIds', + UpdateStatus = '/financial/income/updateStatusByIds', + GetDetail = '/financial/income/getDetailById', + Export = '/financial/income/export', + ExportDetail = '/financial/income/exportDetail', +} + +export function getIncomePageList(params: QueryIncomeReq, mode: ErrorMessageMode = 'notice') { + return defHttp.post>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdateIncome(params: AddOrUpdateIncomeReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdateAccount, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function updateIncomeStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.UpdateStatus}?ids=${ids}&status=${status}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteBatchIncome(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.DeleteBatch}?ids=${ids}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getIncomeDetailById(id: number) { + return defHttp.get>( + { + url: `${API.GetDetail}/${id}` + }, + ); +} + +export function exportIncome(params: QueryIncomeReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} + +export function exportIncomeDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.ExportDetail}/${receiptNumber}`, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/financial/model/accountModel.ts b/src/api/financial/model/accountModel.ts new file mode 100644 index 0000000..08283a4 --- /dev/null +++ b/src/api/financial/model/accountModel.ts @@ -0,0 +1,29 @@ +export interface AccountResp { + id: number | string; + accountNumber: string; + accountName: string; + initialAmount: number; + currentAmount: number; + isDefault: number; + status: number; + sort: number; + remark: string; + createTime: string; +} + +export interface AddOrUpdateAccountReq { + id: number | string | undefined; + accountNumber: string; + accountName: string; + initialAmount: number; + currentAmount: number; + isDefault: number; + status: number; + sort: number; + remark: string; +} + +export interface QueryAccountReq { + accountNumber: string; + accountName: string; +} \ No newline at end of file diff --git a/src/api/financial/model/advanceModel.ts b/src/api/financial/model/advanceModel.ts new file mode 100644 index 0000000..871e641 --- /dev/null +++ b/src/api/financial/model/advanceModel.ts @@ -0,0 +1,65 @@ +export interface FileData { + id: number | string; + uid: number | string; + fileName: string; + fileUrl: string; + fileType: string; + fileSize: number; +} + +export interface AdvanceChargeData { + accountId: number | string; + accountName: string; + amount: number; + remark: string; +} + +export interface AddOrUpdateAdvanceReq { + id: number | string | undefined; + memberId: number | string; + receiptDate: string; + receiptNumber: string; + financialPersonnelId: number | string; + totalAmount: number; + collectedAmount: number; + remark: string; + tableData: AdvanceChargeData[]; + fileDataList: FileData[]; + review: number; +} + +export interface QueryAdvanceReq { + receiptNumber: string; + memberId: number | string; + operatorId: number | string; + financialPersonnelId: number | string; + status: number; + remark: string; +} + +export interface AdvanceChargeResp { + id: number | string; + memberName: string; + receiptNumber: string; + receiptDate: string; + operator: string; + financialPersonnel: string; + totalAmount: number; + collectedAmount: number; + status: number; + remark: string; +} + +export interface AdvanceChargeDetailResp { + memberId: string; + memberName: string; + receiptNumber: string; + receiptDate: string; + financialPersonnel: string; + financialPersonnelId: string; + remark: string; + totalAmount: number; + collectedAmount: number; + tableData: AdvanceChargeData[]; + files: FileData[]; +} \ No newline at end of file diff --git a/src/api/financial/model/collectionModel.ts b/src/api/financial/model/collectionModel.ts new file mode 100644 index 0000000..5921c43 --- /dev/null +++ b/src/api/financial/model/collectionModel.ts @@ -0,0 +1,86 @@ +import {FileData} from "@/api/financial/model/advanceModel"; + +export interface CollectionData { + collectionId: number | string; + saleReceiptNumber: string | undefined; + receivableArrears: number; + receivedArrears: number; + thisCollectionAmount: number; + remark: string; +} + +export interface AddOrUpdateCollectionReq { + id: number | undefined; + customerId: number; + receiptDate: string; + receiptNumber: string; + financialPersonId: number; + collectionAccountId: number; + totalCollectionAmount: number; + discountAmount: number; + actualCollectionAmount: number; + remark: string; + status: number; + files: FileData[]; + tableData: CollectionData[]; +} + +export interface QueryCollectionReq { + receiptNumber: string; + financialPersonId: number; + saleReceiptNumber: string; + customerId: number; + accountId: number; + status: number; + remark: string; +} + +export interface CollectionResp { + id: string | undefined; + customerName: string; + receiptNumber: string; + receiptDate: string; + financialPerson: string; + collectionAccountName: string; + totalCollectionAmount: number; + discountAmount: number; + actualCollectionAmount: number; + remark: string; + status: number; +} + +export interface CollectionDetailResp { + id: string; + customerId: number; + customerName: string; + receiptDate: string; + receiptNumber: string; + financialPersonId: number; + financialPersonName: string; + collectionAccountId: number; + collectionAccountName: string; + totalCollectionAmount: number; + discountAmount: number; + actualCollectionAmount: number; + remark: string; + status: number; + files: FileData[]; + tableData: CollectionData[]; +} + +export interface QuerySaleArrearsReq { + customerId: number; + receiptNumber: string; + productInfo: string; +} + +export interface SaleArrearsResp { + customerName: string; + receiptNumber: string; + receiptDate: string; + productInfo: string; + operatorName: string; + thisReceiptArrears: number; + receivedArrears: number; + receivableArrears: number; +} \ No newline at end of file diff --git a/src/api/financial/model/expenseModel.ts b/src/api/financial/model/expenseModel.ts new file mode 100644 index 0000000..f87d98d --- /dev/null +++ b/src/api/financial/model/expenseModel.ts @@ -0,0 +1,58 @@ +import {FileData} from "@/api/financial/model/advanceModel"; + +export interface ExpenseData { + accountId: number | string; + accountName: string | undefined; + amount: number; + remark: string; + incomeExpenseId: string | number; + incomeExpenseAmount: number; +} + +export interface AddOrUpdateExpenseReq { + id: number | undefined; + relatedPersonId: number; + receiptDate: string; + receiptNumber: string; + financialPersonId: number; + expenseAccountId: number; + expenseAmount: number; + remark: string; + status: number; + files: FileData[]; + tableData: ExpenseData[]; +} + +export interface QueryExpenseReq { + receiptNumber: string; + relatedPersonId: number; + financialPersonId: number; + accountId: number; + status: number; + remark: string; +} + +export interface ExpenseResp { + id: string | undefined; + name: string; + receiptNumber: string; + receiptDate: string; + financialPerson: string; + expenseAccountName: string; + expenseAmount: number; + remark: string; + status: number; +} + +export interface ExpenseDetailResp { + id: string | undefined; + relatedPersonId: number; + receiptDate: string; + receiptNumber: string; + financialPersonId: number; + expenseAccountId: number; + expenseAmount: number; + remark: string; + files: FileData[]; + tableData: ExpenseData[]; +} \ No newline at end of file diff --git a/src/api/financial/model/incomeModel.ts b/src/api/financial/model/incomeModel.ts new file mode 100644 index 0000000..215979e --- /dev/null +++ b/src/api/financial/model/incomeModel.ts @@ -0,0 +1,58 @@ +import {FileData} from "@/api/financial/model/advanceModel"; + +export interface IncomeData { + accountId: number | string; + accountName: string | undefined; + amount: number; + remark: string; + incomeExpenseId: string | number; + incomeExpenseAmount: number; +} + +export interface AddOrUpdateIncomeReq { + id: number | undefined; + relatedPersonId: number; + receiptDate: string; + receiptNumber: string; + financialPersonId: number; + incomeAccountId: number; + incomeAmount: number; + remark: string; + status: number; + files: FileData[]; + tableData: IncomeData[]; +} + +export interface QueryIncomeReq { + receiptNumber: string; + relatedPersonId: number; + financialPersonId: number; + accountId: number; + status: number; + remark: string; +} + +export interface IncomeResp { + id: string | undefined; + name: string; + receiptNumber: string; + receiptDate: string; + financialPerson: string; + incomeAccountName: string; + incomeAmount: number; + remark: string; + status: number; +} + +export interface IncomeDetailResp { + id: string | undefined; + relatedPersonId: number; + receiptDate: string; + receiptNumber: string; + financialPersonId: number; + incomeAccountId: number; + incomeAmount: number; + remark: string; + files: FileData[]; + tableData: IncomeData[]; +} \ No newline at end of file diff --git a/src/api/financial/model/paymentModel.ts b/src/api/financial/model/paymentModel.ts new file mode 100644 index 0000000..09162d5 --- /dev/null +++ b/src/api/financial/model/paymentModel.ts @@ -0,0 +1,87 @@ +import {FileData} from "@/api/financial/model/advanceModel"; + +export interface PaymentData { + paymentId: number | string; + purchaseReceiptNumber: string | undefined; + paymentArrears: number; + prepaidArrears: number; + thisPaymentAmount: number; + remark: string; +} + +export interface AddOrUpdatePaymentReq { + id: number | undefined; + supplierId: number; + receiptDate: string; + receiptNumber: string; + financialPersonId: number; + paymentAccountId: number; + totalPaymentAmount: number; + discountAmount: number; + actualPaymentAmount: number; + remark: string; + status: number; + files: FileData[]; + tableData: PaymentData[]; +} + +export interface QueryPaymentReq { + receiptNumber: string; + financialPersonId: number; + purchaseReceiptNumber: string; + supplierId: number; + accountId: number; + status: number; + remark: string; +} + +export interface PaymentResp { + id: string | undefined; + supplierName: string; + receiptNumber: string; + receiptDate: string; + financialPerson: string; + paymentAccountName: string; + totalPaymentAmount: number; + discountAmount: number; + actualPaymentAmount: number; + remark: string; + status: number; +} + +export interface PaymentDetailResp { + id: string; + supplierId: number; + supplierName: string; + receiptDate: string; + receiptNumber: string; + financialPersonId: number; + financialPersonName: string; + paymentAccountId: number; + paymentAccountName: string; + totalPaymentAmount: number; + discountAmount: number; + actualPaymentAmount: number; + remark: string; + status: number; + files: FileData[]; + tableData: PaymentData[]; +} + +export interface QueryPaymentArrearsReq { + supplierId: number; + receiptNumber: string; + productInfo: string; +} + +export interface PaymentArrearsResp { + id: string; + supplierName: string; + receiptNumber: string; + receiptDate: string; + productInfo: string; + operatorName: string; + thisReceiptArrears: number; + prepaidArrears: number; + paymentArrears: number; +} \ No newline at end of file diff --git a/src/api/financial/model/transferModel.ts b/src/api/financial/model/transferModel.ts new file mode 100644 index 0000000..77c0d26 --- /dev/null +++ b/src/api/financial/model/transferModel.ts @@ -0,0 +1,54 @@ +import {FileData} from "@/api/financial/model/advanceModel"; + +export interface TransferData { + accountId: number | string; + accountName: string | undefined; + transferAmount: number; + remark: string; +} + +export interface AddOrUpdateTransferReq { + id: number | undefined; + receiptDate: string; + receiptNumber: string; + financialPersonId: number; + paymentAccountId: number; + paymentAmount: number; + remark: string; + status: number; + files: FileData[]; + tableData: TransferData[]; +} + +export interface QueryTransferReq { + receiptNumber: string; + financialPersonId: number; + accountId: number; + status: number; + remark: string; +} + +export interface TransferResp { + id: string | undefined; + receiptNumber: string; + receiptDate: string; + financialPerson: string; + paymentAccountName: string; + paymentAmount: number; + remark: string; + status: number; +} + +export interface TransferDetailResp { + receiptDate: string; + receiptNumber: string; + financialPersonId: number; + financialPersonName: string; + paymentAccountId: number; + paymentAccountName: string; + paymentAmount: number; + remark: string; + status: number; + files: FileData[]; + tableData: TransferData[]; +} \ No newline at end of file diff --git a/src/api/financial/payment.ts b/src/api/financial/payment.ts new file mode 100644 index 0000000..92d592e --- /dev/null +++ b/src/api/financial/payment.ts @@ -0,0 +1,101 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + AddOrUpdatePaymentReq, + QueryPaymentReq, + PaymentResp, + PaymentDetailResp, + QueryPaymentArrearsReq, + PaymentArrearsResp, +} from "@/api/financial/model/paymentModel"; + +enum API { + PageList = '/financial/payment/pageList', + AddOrUpdateAccount = '/financial/payment/addOrUpdate', + DeleteBatch = '/financial/payment/deleteByIds', + UpdateStatus = '/financial/payment/updateStatusByIds', + GetDetail = '/financial/payment/getDetailById', + GetArrearsPage = '/purchase/arrears/pageList', + Export = '/financial/payment/export', + ExportDetail = '/financial/payment/exportDetail', +} + +export function getPaymentPageList(params: QueryPaymentReq) { + return defHttp.post>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdatePayment(params: AddOrUpdatePaymentReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdateAccount, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function updatePaymentStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.UpdateStatus}?ids=${ids}&status=${status}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteBatchPayment(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.DeleteBatch}?ids=${ids}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getPaymentDetailById(id: number) { + return defHttp.get>( + { + url: `${API.GetDetail}/${id}` + }, + ); +} + +export function getArrearsPageList(params: QueryPaymentArrearsReq) { + return defHttp.post>( + { + url: API.GetArrearsPage, + params, + } + ); +} + +export function exportPayment(params: QueryPaymentReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} + +export function exportPaymentDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.ExportDetail}/${receiptNumber}`, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/financial/transfer.ts b/src/api/financial/transfer.ts new file mode 100644 index 0000000..f7a0e9e --- /dev/null +++ b/src/api/financial/transfer.ts @@ -0,0 +1,89 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + TransferDetailResp, + AddOrUpdateTransferReq, + QueryTransferReq, + TransferResp, +} from "@/api/financial/model/transferModel"; + +enum API { + PageList = '/financial/transfer/pageList', + AddOrUpdateAccount = '/financial/transfer/addOrUpdate', + DeleteBatch = '/financial/transfer/deleteByIds', + UpdateStatus = '/financial/transfer/updateStatusByIds', + GetDetail = '/financial/transfer/getDetailById', + Export = '/financial/transfer/export', + ExportDetail = '/financial/transfer/exportDetail', +} + +export function getTransferPageList(params: QueryTransferReq, mode: ErrorMessageMode = 'notice') { + return defHttp.post>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdateTransfer(params: AddOrUpdateTransferReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdateAccount, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function updateTransferStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.UpdateStatus}?ids=${ids}&status=${status}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteBatchTransfer(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.DeleteBatch}?ids=${ids}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getTransferDetailById(id: number) { + return defHttp.get>( + { + url: `${API.GetDetail}/${id}` + }, + ); +} + +export function exportTransfer(params: QueryTransferReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} + +export function exportTransferDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.ExportDetail}/${receiptNumber}`, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/model/baseModel.ts b/src/api/model/baseModel.ts new file mode 100644 index 0000000..43a33ab --- /dev/null +++ b/src/api/model/baseModel.ts @@ -0,0 +1,25 @@ +export interface BasicPageParams { + page: number; + pageSize: number; +} + +export interface BasicFetchResult { + items: T[]; + total: number; +} + +export interface BaseDataResp { + code: string; + msg: string; + data: T; +} + +export interface BaseResp { + code?: string; + msg: string; +} + +export interface BaseListResp { + data: T[]; + total: number; +} diff --git a/src/api/product/model/productAttributeModel.ts b/src/api/product/model/productAttributeModel.ts new file mode 100644 index 0000000..0a82fac --- /dev/null +++ b/src/api/product/model/productAttributeModel.ts @@ -0,0 +1,30 @@ +/** + * Although it seems that the parameters of the two objects are very similar here, + * there is no guarantee that new fields will be added to the view object return in the future. For extension purposes, + * it is still necessary to distinguish between them + * + * @author James + * @since 2023-10-08 17:27 + */ + +export interface ProductAttributeResp { + id: number | string; + attributeName: string; + attributeValue: string; + remark: string; + sort: number; +} + +export interface AddOrUpdateProductAttributeReq { + id: number | string; + attributeName: string; + attributeValue: string; + remark: string; + sort: number; +} + +export interface ProductAttributeListReq { + attributeName: string | undefined; + page: number; + pageSize: number; +} \ No newline at end of file diff --git a/src/api/product/model/productCategoryModel.ts b/src/api/product/model/productCategoryModel.ts new file mode 100644 index 0000000..823488a --- /dev/null +++ b/src/api/product/model/productCategoryModel.ts @@ -0,0 +1,24 @@ +export interface ProductCategoryResp { + id: number | string; + parentId: number | string; + parentName: string; + categoryName: string; + categoryNumber: string; + remark: string; + sort: number; + createTime: string; + children?: ProductCategoryResp[]; +} + +export interface AddOrUpdateProductCategoryReq { + id: number | string; + parentId: number | string; + categoryName: string; + categoryNumber: number; + remark: string; + sort: number; +} + +export interface ProductCategoryListReq { + categoryName: string; +} \ No newline at end of file diff --git a/src/api/product/model/productModel.ts b/src/api/product/model/productModel.ts new file mode 100644 index 0000000..dd31e37 --- /dev/null +++ b/src/api/product/model/productModel.ts @@ -0,0 +1,183 @@ +export interface AddProductStockReq { + productStockId: number | string; + warehouseId: number | string; + warehouseName: string; + initStockQuantity: number; + lowStockQuantity: number; + highStockQuantity: number; +} + +export interface AddProductPriceReq { + productPriceId: number | string; + barCode: number; + productUnit: string; + multiAttribute: string; + purchasePrice: number; + retailPrice: number; + salesPrice: number; + lowSalesPrice: number; +} + +export interface AddProductImageReq { + productImageId: number | string | null; + uid: string | null; + type: string | null | undefined; + status: string | null | undefined; + imageName: string | null; + imageUrl: string | null; + imageSize: number | null | undefined; +} + +export interface AddProductReq { + productId: number | string; + productName: string; + productStandard: string; + productModel: string + productUnit: string + productUnitId: number | string; + productColor: string + productWeight: number | string; + productExpiryNum: number | string; + productCategoryId: number | string; + enableSerialNumber: number | string; + enableBatchNumber: number | string; + warehouseShelves: string + remark: string + productManufacturer: string + otherFieldOne: string + otherFieldTwo: string + otherFieldThree: string + priceList: AddProductPriceReq[]; + stockList: AddProductStockReq[]; + imageList: AddProductImageReq[]; +} + +export interface QueryProductReq { + productCategoryId: number | string + keywords: string + productColor: string + extendInfo: string + remark: string + warehouseShelves: string + status: number + enableSerialNumber: number + enableBatchNumber: number +} + +export interface ProductStockSkuReq { + warehouseId: number | string; + productInfo: string; + productCategoryId: number | string; + warehouseShelves: string; + isExportDetail: boolean; +} + +export interface ProductInfoDetailResp { + productId: string; + productCategoryId: string; + productUnitId: string; + productUnit: string; + productName: string; + productStandard: string; + productModel: string; + productColor: string; + productWeight: number; + productExpiryNum: number; + productCategoryName: string; + enableSerialNumber: number; + enableBatchNumber: number; + warehouseShelves: string; + productManufacturer: string; + otherFieldOne: string; + otherFieldTwo: string; + otherFieldThree: string; + remark: string; + priceList: ProductPriceResp[]; + imageList: ProductImageResp[]; +} + +export interface ProductImageResp { + productImageId: string; + imageName: string; + imageUrl: string; +} + +export interface ProductPriceResp { + productPriceId: string; + barCode: number; + productUnit: string; + multiAttribute: string; + purchasePrice: number; + retailPrice: number; + salesPrice: number; + lowSalesPrice: number; + stockList: ProductStockResp[]; +} + +export interface ProductStockSkuResp { + id: string; + productId: string; + warehouseId: string; + productBarcode: string; + warehouseName: string; + productName: string; + productCategoryName: string; + productStandard: string; + productModel: string; + productColor: string; + productUnit: string; + warehouseShelves: string; + productWeight: number; + unitPrice: number; + retailPrice: number; + salePrice: number; + purchasePrice: number; + initialStock: number; + currentStock: number; + stockAmount: number; +} + +export interface ProductStockResp { + productStockId: number | string; + warehouseId: number | string; + warehouseName: string; + initStockQuantity: number; + lowStockQuantity: number; + highStockQuantity: number; +} + +export interface UpdateBatchProductInfoReq { + productIds: number[]; + productCategoryId: number | string; + productColor: string; + productWeight: number; + productExpiryNum: number; + enableSerialNumber: string; + enableBatchNumber: string; + remark: string; +} + +export interface QueryProductExtendPriceReq { + productCategoryId: number | string; + warehouseId: number | string; + productName: string; + enableSerialNumber: number; + enableBatchNumber: number; +} + +export interface ProductExtendPriceResp { + id: number | string; + productId: number | string; + productCategoryId: number | string; + warehouseId: number | string; + barCode: string; + productName: string; + productStandard: string; + productModel: string; + productColor: string; + productUnit: string; + multiAttribute: string; + stock: number; + extendInfo: string; + retailPrice: number; +} \ No newline at end of file diff --git a/src/api/product/model/productUnitModel.ts b/src/api/product/model/productUnitModel.ts new file mode 100644 index 0000000..f23b9ed --- /dev/null +++ b/src/api/product/model/productUnitModel.ts @@ -0,0 +1,28 @@ +export interface ProductUnitResp { + id: number | string; + computeUnit: string; + basicUnit: string; + otherUnit: string; + otherUnitTwo: string; + otherUnitThree: number; + status: number; + createTime: string; +} + +export interface AddOrUpdateProductUnitReq { + id: number | string; + basicUnit: string; + otherUnit: string; + otherUnitTwo: string; + otherUnitThree: string; + ratio: number; + ratioTwo: number; + ratioThree: number; + status: number; +} + +export interface ProductUnitQueryReq { + computeUnit: string | undefined; + page: number; + pageSize: number; +} \ No newline at end of file diff --git a/src/api/product/product.ts b/src/api/product/product.ts new file mode 100644 index 0000000..a37bdb6 --- /dev/null +++ b/src/api/product/product.ts @@ -0,0 +1,125 @@ +import {defHttp} from '/@/utils/http/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + AddProductReq, + ProductInfoDetailResp, + QueryProductReq, + UpdateBatchProductInfoReq, + ProductExtendPriceResp, + QueryProductExtendPriceReq, ProductStockSkuReq, ProductStockSkuResp, +} from "@/api/product/model/productModel"; +import {ErrorMessageMode, SuccessMessageMode} from "#/axios"; + +enum Api { + getProductCode = '/product/getProductCode', + addProduct = '/product/addOrUpdateProduct', + getProductInfo = '/product/getProductInfo', + getProductInfoDetail = '/product/getProductInfoDetail', + deleteProduct = '/product/deleteProduct', + updateProductStatus = '/product/updateProductStatus', + updateBatchProductInfo = '/product/updateBatchProductInfo', + getProductSku = '/product/sku/pageList', + getProductSkuByBarCode = '/product/sku/getProduct', + getProductListInfo = '/product/sku/productStockSku' +} + +export function getProductCode() { + return defHttp.get>( + { + url: Api.getProductCode, + } + ); +} + +export function addOrUpdateProduct(params: AddProductReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: Api.addProduct, + params + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + }, + ); +} + +export function getProductInfo(params: QueryProductReq) { + return defHttp.post( + { + url: Api.getProductInfo, + params + }, + ); +} + +export function getProductInfoDetail(productId: number) { + return defHttp.get>( + { + url: `${Api.getProductInfoDetail}/${productId}`, + } + ); +} + +export function deleteProduct(productIds: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.delete( + { + url: `${Api.deleteProduct}/${productIds}`, + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + }, + ); +} + +export function updateProductStatus(productIds: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${Api.updateProductStatus}/${productIds}/${status}`, + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + }, + ); +} + +export function updateBatchProductInfo(params: UpdateBatchProductInfoReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: Api.updateBatchProductInfo, + params + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + }, + ); +} + +export function getProductSkuPage(params: QueryProductExtendPriceReq) { + return defHttp.post( + { + url: Api.getProductSku, + params + } + ); +} + +export function getProductSkuByBarCode(barCode: number | string, warehouseId: number | string) { + return defHttp.get>( + { + url: `${Api.getProductSkuByBarCode}/${barCode}/${warehouseId}`, + } + ); +} + +export function getProductStockSku(params: ProductStockSkuReq) { + return defHttp.post>( + { + url: Api.getProductListInfo, + params + } + ); +} \ No newline at end of file diff --git a/src/api/product/productAttribute.ts b/src/api/product/productAttribute.ts new file mode 100644 index 0000000..dc375a1 --- /dev/null +++ b/src/api/product/productAttribute.ts @@ -0,0 +1,52 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import {AddOrUpdateProductAttributeReq, ProductAttributeResp, ProductAttributeListReq} from "@/api/product/model/productAttributeModel"; + +enum Api { + List = '/product/attribute/list', + addOrUpdate = '/product/attribute/addOrUpdate', + deleteBatch = '/product/attribute/deleteBatch', + GetAttributeById = '/product/attribute/getValuesById', +} + +export function getAttributeList(params: ProductAttributeListReq) { + return defHttp.post>( + { + url: Api.List, + params, + } + ); +} + +export function addOrUpdateAttribute(params: AddOrUpdateProductAttributeReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: Api.addOrUpdate, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteBatchAttribute(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.delete( + { + url: `${Api.deleteBatch}?ids=${ids}` + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + }, + ); +} + +export function getAttributeById(id: number) { + return defHttp.get>( + { + url: `${Api.GetAttributeById}?id=${id}` + } + ); +} \ No newline at end of file diff --git a/src/api/product/productCategory.ts b/src/api/product/productCategory.ts new file mode 100644 index 0000000..790b7da --- /dev/null +++ b/src/api/product/productCategory.ts @@ -0,0 +1,43 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp} from "@/api/model/baseModel"; +import {AddOrUpdateProductCategoryReq, ProductCategoryResp} from "@/api/product/model/productCategoryModel"; + +enum Api { + List = '/product/category/list', + addOrUpdate = '/product/category/addOrUpdate', + deleteBatch = '/product/category/deleteBatch', +} + +export function getCategoryList() { + return defHttp.get>( + { + url: Api.List, + } + ); +} + +export function addOrUpdateCategory(params: AddOrUpdateProductCategoryReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post>( + { + url: Api.addOrUpdate, + params, + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + }, + ); +} + +export function deleteCategory(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post>( + { + url: `${Api.deleteBatch}?ids=${ids}`, + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + }, + ); +} \ No newline at end of file diff --git a/src/api/product/productUnit.ts b/src/api/product/productUnit.ts new file mode 100644 index 0000000..4808ee7 --- /dev/null +++ b/src/api/product/productUnit.ts @@ -0,0 +1,58 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import {AddOrUpdateProductUnitReq, ProductUnitResp, ProductUnitQueryReq} from "@/api/product/model/productUnitModel"; + +enum Api { + List = '/product/unit/list', + AddOrUpdate = '/product/unit/addOrUpdate', + DeleteBatch = '/product/unit/deleteBatch', + UpdateStatus = '/product/unit/updateUnitStatus', +} + +export function getUnitList(params: ProductUnitQueryReq) { + return defHttp.post>( + { + url: Api.List, + params, + } + ); +} + +export function addOrUpdateUnit(params: AddOrUpdateProductUnitReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: Api.AddOrUpdate, + params, + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteBatchUnits(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.delete( + { + url: `${Api.DeleteBatch}?ids=${ids}` + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function updateUnitStatus(params: {id: number, status: number}, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: Api.UpdateStatus, + params, + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} \ No newline at end of file diff --git a/src/api/purchase/model/orderModel.ts b/src/api/purchase/model/orderModel.ts new file mode 100644 index 0000000..0fd1f63 --- /dev/null +++ b/src/api/purchase/model/orderModel.ts @@ -0,0 +1,82 @@ +import {FileData} from '/@/api/retail/model/shipmentsModel'; + +export interface QueryPurchaseOrderReq { + receiptNumber: string; + productInfo: string; + supplierId: number | string; + operatorId: number | string; + status: number; + remark: string; +} + +export interface PurchaseData { + warehouseId: number | string; + productId: number | string; + barCode: number | string; + productName: string; + productUnit: string; + productStandard: string; + stock: number; + productNumber: number; + unitPrice: number; + purchasePrice: number; + amount: number; + taxRate: number; + taxAmount: number; + taxTotalPrice: number; + remark: string; +} + +export interface AddOrUpdateReceiptReq { + id: number | string | undefined; + supplierId: string; + receiptNumber: string; + receiptDate: string; + discountRate: number; + discountAmount: number; + discountLastAmount: number; + deposit: number; + accountId: number | string; + multipleAccountIds: number[]; + multipleAccountAmounts: number[]; + status: number; + remark: string; + tableData: PurchaseData[]; + files: FileData[]; +} + +export interface LinkReceiptDetailResp { + id: number | string | undefined; + supplierId: string; + supplierName: string; + receiptNumber: string; + receiptDate: string; + discountRate: number; + discountAmount: number; + discountLastAmount: number; + deposit: number; + accountId: number | string; + accountName: string; + multipleAccountIds: number[]; + multipleAccountAmounts: number[]; + status: number; + remark: string; + tableData: PurchaseData[]; + files: FileData[]; +} + +export interface PurchaseDetailData { + supplierId: number | string; + accountId: number; + receiptDate: string; + receiptNumber: string; + multipleAccountAmounts: number[]; + multipleAccountIds: number[]; + discountRate: number; + discountAmount: number; + discountLastAmount: number; + deposit: number; + remark: string; + tableData: PurchaseData[]; + files: FileData[]; +} \ No newline at end of file diff --git a/src/api/purchase/model/refundModel.ts b/src/api/purchase/model/refundModel.ts new file mode 100644 index 0000000..ade24d2 --- /dev/null +++ b/src/api/purchase/model/refundModel.ts @@ -0,0 +1,69 @@ +import {FileData} from '/@/api/retail/model/shipmentsModel'; + +export interface QueryPurchaseRefundReq { + receiptNumber: string; + productInfo: string; + supplierId: number | string; + operatorId: number | string; + status: number; + remark: string; +} + +export interface PurchaseRefundData { + warehouseId: number | string; + productId: number | string; + barCode: number | string; + productName: string; + productUnit: string; + productStandard: string; + stock: number; + productNumber: number; + unitPrice: number; + amount: number; + taxRate: number; + taxAmount: number; + taxTotalPrice: number; + remark: string; +} + +export interface AddOrUpdatePurchaseRefundReq { + id: number | string | undefined; + supplierId: string; + receiptNumber: string; + receiptDate: string; + refundOfferRate: number; + refundOfferAmount: number; + refundLastAmount: number; + otherAmount: number; + otherReceipt: string; + thisRefundAmount: number; + thisArrearsAmount: number; + accountId: number | string; + multipleAccountIds: number[]; + multipleAccountAmounts: number[]; + status: number; + remark: string; + tableData: PurchaseRefundData[]; + files: FileData[]; +} + +export interface PurchaseRefundDetailData { + supplierId: number | string; + supplierName: string; + accountId: number; + accountName: string; + otherReceipt: string; + receiptDate: string; + receiptNumber: string; + multipleAccountAmounts: number[]; + multipleAccountIds: number[]; + refundOfferRate: number; + refundOfferAmount: number; + refundLastAmount: number; + otherAmount: number; + thisRefundAmount: number; + thisArrearsAmount: number; + remark: string; + tableData: PurchaseRefundData[]; + files: FileData[]; +} \ No newline at end of file diff --git a/src/api/purchase/model/storageModel.ts b/src/api/purchase/model/storageModel.ts new file mode 100644 index 0000000..587be27 --- /dev/null +++ b/src/api/purchase/model/storageModel.ts @@ -0,0 +1,68 @@ +import {FileData} from '/@/api/retail/model/shipmentsModel'; + +export interface QueryPurchaseStorageReq { + receiptNumber: string; + productInfo: string; + supplierId: number | string; + operatorId: number | string; + status: number; + remark: string; +} + +export interface PurchaseData { + warehouseId: number | string; + productId: number | string; + barCode: number | string; + productName: string; + productUnit: string; + productStandard: string; + stock: number; + productNumber: number; + unitPrice: number; + amount: number; + taxRate: number; + taxAmount: number; + taxTotalPrice: number; + remark: string; +} + +export interface AddOrUpdatePurchaseStorageReq { + id: number | string | undefined; + supplierId: string; + receiptNumber: string; + receiptDate: string; + paymentRate: number; + paymentAmount: number; + paymentLastAmount: number; + otherAmount: number; + otherReceipt: string; + thisPaymentAmount: number; + thisArrearsAmount: number; + accountId: number | string; + multipleAccountIds: number[]; + multipleAccountAmounts: number[]; + status: number; + remark: string; + tableData: PurchaseData[]; + files: FileData[]; +} + +export interface PurchaseStorageDetailData { + supplierId: number | string; + supplierName: string; + accountId: number; + accountName: string; + receiptDate: string; + receiptNumber: string; + multipleAccountAmounts: number[]; + multipleAccountIds: number[]; + paymentRate: number; + paymentAmount: number; + paymentLastAmount: number; + otherAmount: number; + thisPaymentAmount: number; + thisArrearsAmount: number; + remark: string; + tableData: PurchaseData[]; + files: FileData[]; +} \ No newline at end of file diff --git a/src/api/purchase/order.ts b/src/api/purchase/order.ts new file mode 100644 index 0000000..4520c09 --- /dev/null +++ b/src/api/purchase/order.ts @@ -0,0 +1,97 @@ +import {defHttp} from '/@/utils/http/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + QueryPurchaseOrderReq, + AddOrUpdateReceiptReq, + PurchaseDetailData, LinkReceiptDetailResp +} from "@/api/purchase/model/orderModel" +import {ErrorMessageMode, SuccessMessageMode} from "#/axios"; + +enum API { + PageList = '/purchase/order/pageList', + AddOrUpdate = '/purchase/order/addOrUpdate', + GetDetail = '/purchase/order/detail', + UpdateStatus = '/purchase/order/updateStatus', + Delete = '/purchase/order/delete', + GetLinkOrderDetail = '/purchase/order/getLinkOrderDetail', + Export = '/purchase/order/export', + ExportDetail = '/purchase/order/exportDetail', +} + +export function getPurchaseOrderPageList(params: QueryPurchaseOrderReq) { + return defHttp.get>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdatePurchaseOrder(params: AddOrUpdateReceiptReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdate, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getPurchaseOrderDetail(id: string) { + return defHttp.get>( + { + url: `${API.GetDetail}/${id}`, + } + ); +} + +export function getLinkOrderDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.GetLinkOrderDetail}/${receiptNumber}`, + } + ); +} + +export function updatePurchaseOrderStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.UpdateStatus}/${ids}/${status}`, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deletePurchaseOrder(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.Delete}/${ids}`, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function exportOrder(params: QueryPurchaseOrderReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} + +export function exportOrderDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.ExportDetail}/${receiptNumber}`, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/purchase/refund.ts b/src/api/purchase/refund.ts new file mode 100644 index 0000000..0e62740 --- /dev/null +++ b/src/api/purchase/refund.ts @@ -0,0 +1,97 @@ +import {defHttp} from '/@/utils/http/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + QueryPurchaseRefundReq, + AddOrUpdatePurchaseRefundReq, + PurchaseRefundDetailData +} from "@/api/purchase/model/refundModel" +import {ErrorMessageMode, SuccessMessageMode} from "#/axios"; + +enum API { + PageList = '/purchase/refund/pageList', + AddOrUpdate = '/purchase/refund/addOrUpdate', + GetDetail = '/purchase/refund/detail', + UpdateStatus = '/purchase/refund/updateStatus', + Delete = '/purchase/refund/delete', + GetLinkRefundDetail = '/purchase/refund/getLinkRefundDetail', + Export = '/purchase/refund/export', + ExportDetail = '/purchase/order/exportDetail', +} + +export function getPurchaseRefundPageList(params: QueryPurchaseRefundReq) { + return defHttp.get>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdatePurchaseRefund(params: AddOrUpdatePurchaseRefundReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdate, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getPurchaseRefundDetail(id: string) { + return defHttp.get>( + { + url: `${API.GetDetail}/${id}`, + } + ); +} + +export function updatePurchaseRefundStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.UpdateStatus}/${ids}/${status}`, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deletePurchaseRefund(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.Delete}/${ids}`, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getLinkRefundDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.GetLinkRefundDetail}/${receiptNumber}`, + } + ); +} + +export function exportRefund(params: QueryPurchaseRefundReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} + +export function exportRefundDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.ExportDetail}/${receiptNumber}`, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/purchase/storage.ts b/src/api/purchase/storage.ts new file mode 100644 index 0000000..56c3f0d --- /dev/null +++ b/src/api/purchase/storage.ts @@ -0,0 +1,97 @@ +import {defHttp} from '/@/utils/http/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + QueryPurchaseStorageReq, + AddOrUpdatePurchaseStorageReq, + PurchaseStorageDetailData +} from "@/api/purchase/model/storageModel" +import {ErrorMessageMode, SuccessMessageMode} from "#/axios"; + +enum API { + PageList = '/purchase/storage/pageList', + AddOrUpdate = '/purchase/storage/addOrUpdate', + GetDetail = '/purchase/storage/detail', + UpdateStatus = '/purchase/storage/updateStatus', + Delete = '/purchase/storage/delete', + GetLinkStorageDetail = '/purchase/storage/getLinkStorageDetail', + Export = '/purchase/storage/export', + ExportDetail = '/purchase/order/exportDetail', +} + +export function getPurchaseStoragePageList(params: QueryPurchaseStorageReq) { + return defHttp.get>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdatePurchaseStorage(params: AddOrUpdatePurchaseStorageReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdate, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getPurchaseStorageDetail(id: string) { + return defHttp.get>( + { + url: `${API.GetDetail}/${id}`, + } + ); +} + +export function updatePurchaseStorageStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.UpdateStatus}/${ids}/${status}`, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deletePurchaseStorage(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.Delete}/${ids}`, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getLinkStorageDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.GetLinkStorageDetail}/${receiptNumber}`, + } + ); +} + +export function exportStorage(params: QueryPurchaseStorageReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} + +export function exportStorageDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.ExportDetail}/${receiptNumber}`, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/receipt/model/receiptModel.ts b/src/api/receipt/model/receiptModel.ts new file mode 100644 index 0000000..ae4cca9 --- /dev/null +++ b/src/api/receipt/model/receiptModel.ts @@ -0,0 +1,36 @@ +export interface ReceiptDetailResp { + id: string; + productBarcode : string | number; + warehouseId: string; + productId: string; + productName : string; + productStandard : string; + productModel : string; + unit : string; + productNumber : number; + amount : number; + taxRate : number; + taxAmount : number; + taxIncludedAmount : number; + remark : string; +} + +export interface ReceiptResp { + id: string; + name : string; + receiptNumber : string; + productInfo : string; + receiptDate : string; + operator : string; + productNumber : number; + totalAmount : number; + taxRateTotalAmount : number | undefined; +} + +export interface queryReceipt { + id: string | number; + type: string; + subType: string; + receiptNumber: string; + productInfo: string; +} \ No newline at end of file diff --git a/src/api/receipt/receipt.ts b/src/api/receipt/receipt.ts new file mode 100644 index 0000000..0009af1 --- /dev/null +++ b/src/api/receipt/receipt.ts @@ -0,0 +1,26 @@ +import {defHttp} from '/@/utils/http/axios'; +import {BaseDataResp} from "@/api/model/baseModel"; +import {queryReceipt, ReceiptDetailResp, ReceiptResp} from "@/api/receipt/model/receiptModel" + +enum API { + GetOtherReceipt = '/receipt/otherReceipt', + GetOtherReceiptDetail = '/receipt/otherReceiptDetail', +} + +export function getReceipt(params: queryReceipt, type: string, subType: string) { + return defHttp.get>( + { + url: API.GetOtherReceipt, + params: params + } + ); +} + +export function getReceiptDetail(params: queryReceipt) { + return defHttp.get>( + { + url: API.GetOtherReceiptDetail, + params: params + } + ); +} \ No newline at end of file diff --git a/src/api/report/report.ts b/src/api/report/report.ts new file mode 100644 index 0000000..e20afa9 --- /dev/null +++ b/src/api/report/report.ts @@ -0,0 +1,359 @@ +import {defHttp} from '/@/utils/http/axios'; +import {BaseDataResp} from "@/api/model/baseModel"; +import { + ProductStockResp, + QueryProductStockReq, + RetailStatisticalResp, + ProductStockFlowResp, + QueryProductStockFlowReq, + QueryAccountStatisticsReq, + AccountStatisticsResp, + AccountFlowResp, + QueryRetailStatisticsReq, + RetailStatisticsResp, + QueryPurchaseStatisticsReq, + PurchaseStatisticsResp, + QuerySalesStatisticsReq, + SalesStatisticsResp, + QueryShipmentsDetailStatisticsReq, + ShipmentsDetailStatisticsResp, + QueryStorageDetailStatisticsReq, + StorageDetailStatisticsResp, + RelatedPersonResp, + QueryShipmentsSummaryStatisticsReq, + ShipmentsSummaryStatisticsResp, + QueryStorageSummaryStatisticsReq, + StorageSummaryStatisticsResp, + CustomerBillStatisticsResp, + QueryCustomerBillReq, + QueryCustomerBillDetailReq, + CustomerBillDetailStatisticsResp, + SupplierBillStatisticsResp, + QuerySupplierBillReq, QuerySupplierBillDetailReq, SupplierBillDetailStatisticsResp +} from "@/api/report/reportModel"; + +enum API { + GetStatisticalData = '/report/homePage/statistics', + GetProductStockData = '/report/productStock', + GetProductStockFlowData = '/report/productStockFlow', + GetAccountStatistics = '/report/accountStatistics', + GetAccountFlow = '/report/accountFlow', + GetRetailStatistics = '/report/retailStatistics', + GetPurchaseStatistics = '/report/purchaseStatistics', + GetSalesStatistics = '/report/salesStatistics', + GetShipmentsDetail = '/report/shipmentsDetail', + GetStorageDetail = '/report/storageDetail', + GetRelatedPerson = '/report/relatedPerson', + GetShipmentsSummary = '/report/shipmentsSummary', + GetStorageSummary = '/report/storageSummary', + GetCustomerBill = '/report/customerBill', + GetCustomerBillDetail = '/report/customerBillDetail', + GetSupplierBill = '/report/supplierBill', + GetSupplierBillDetail = '/report/supplierBillDetail', + ExportProductStockData = '/report/productStock/export', + ExportAccountStatistics = '/report/accountStatistics/export', + ExportRetailStatistics = '/report/retailStatistics/export', + ExportPurchaseStatistics = '/report/purchaseStatistics/export', + ExportSalesStatistics = '/report/salesStatistics/export', + ExportShipmentsDetail = '/report/shipmentsDetail/export', + ExportStorageDetail = '/report/storageDetail/export', + ExportShipmentsSummary = '/report/shipmentsSummary/export', + ExportStorageSummary = '/report/storageSummary/export', + ExportCustomerBill = '/report/customerBill/export', + ExportSupplierBill = '/report/supplierBill/export', + ExportProductStockFlowData = '/report/productStockFlow/export', + ExportCustomerBillDetail = '/report/customerBillDetail/export', + ExportSupplierBillDetail = '/report/supplierBillDetail/export', +} + + +export function getStatistical() { + return defHttp.get>( + { + url: API.GetStatisticalData, + }, + ); +} + +export function getProductStock(params: QueryProductStockReq) { + return defHttp.post>( + { + url: API.GetProductStockData, + params + } + ); +} + +export function getProductStockFlow(params: QueryProductStockFlowReq, productId: number) { + return defHttp.post>( + { + url: API.GetProductStockFlowData, + params + } + ); +} + +export function getAccountStatistics(params: QueryAccountStatisticsReq) { + return defHttp.post>( + { + url: API.GetAccountStatistics, + params + } + ); +} + +export function getAccountFlow(accountId: number) { + return defHttp.get>( + { + url: API.GetAccountFlow, + params: accountId + } + ); +} + +export function getRetailStatistics(params: QueryRetailStatisticsReq) { + return defHttp.post>( + { + url: API.GetRetailStatistics, + params + } + ); +} + +export function getPurchaseStatistics(params: QueryPurchaseStatisticsReq) { + return defHttp.post>( + { + url: API.GetPurchaseStatistics, + params + } + ); +} + +export function getSalesStatistics(params: QuerySalesStatisticsReq) { + return defHttp.post>( + { + url: API.GetSalesStatistics, + params + } + ); +} + +export function getShipmentsDetail(params: QueryShipmentsDetailStatisticsReq) { + return defHttp.post>( + { + url: API.GetShipmentsDetail, + params + } + ); +} + +export function getStorageDetail(params: QueryStorageDetailStatisticsReq) { + return defHttp.post>( + { + url: API.GetStorageDetail, + params + } + ); +} + +export function getRelatedPerson() { + return defHttp.get>( + { + url: API.GetRelatedPerson, + } + ); +} + +export function getShipmentsSummary(params: QueryShipmentsSummaryStatisticsReq) { + return defHttp.post>( + { + url: API.GetShipmentsSummary, + params + } + ); +} + +export function getStorageSummary(params: QueryStorageSummaryStatisticsReq) { + return defHttp.post>( + { + url: API.GetStorageSummary, + params + } + ); +} + +export function getCustomerBill(params: QueryCustomerBillReq) { + return defHttp.post>( + { + url: API.GetCustomerBill, + params + } + ); +} + +export function getCustomerBillDetail(params: QueryCustomerBillDetailReq) { + return defHttp.post>( + { + url: API.GetCustomerBillDetail, + params + } + ); +} + +export function getSupplierBill(params: QuerySupplierBillReq) { + return defHttp.post>( + { + url: API.GetSupplierBill, + params + } + ); +} + +export function getSupplierBillDetail(params: QuerySupplierBillDetailReq) { + return defHttp.post>( + { + url: API.GetSupplierBillDetail, + params + } + ); +} + +export function exportProductStock(params: QueryProductStockReq) { + return defHttp.get>( + { + url: `${API.ExportProductStockData}`, + params, + responseType: "blob" + } + ); +} + +export function exportAccountStatistics(params: QueryAccountStatisticsReq) { + return defHttp.get>( + { + url: `${API.ExportAccountStatistics}`, + params, + responseType: "blob" + } + ); +} + +export function exportRetailStatistics(params: QueryRetailStatisticsReq) { + return defHttp.get>( + { + url: `${API.ExportRetailStatistics}`, + params, + responseType: "blob" + } + ); +} + +export function exportPurchaseStatistics(params: QueryPurchaseStatisticsReq) { + return defHttp.get>( + { + url: `${API.ExportPurchaseStatistics}`, + params, + responseType: "blob" + } + ); +} + +export function exportSalesStatistics(params: QuerySalesStatisticsReq) { + return defHttp.get>( + { + url: `${API.ExportSalesStatistics}`, + params, + responseType: "blob" + } + ); +} + +export function exportShipmentsDetail(params: QueryShipmentsDetailStatisticsReq) { + return defHttp.get>( + { + url: `${API.ExportShipmentsDetail}`, + params, + responseType: "blob" + } + ); +} + +export function exportStorageDetail(params: QueryStorageDetailStatisticsReq) { + return defHttp.get>( + { + url: `${API.ExportStorageDetail}`, + params, + responseType: "blob" + } + ); +} + +export function exportShipmentsSummary(params: QueryShipmentsSummaryStatisticsReq) { + return defHttp.get>( + { + url: `${API.ExportShipmentsSummary}`, + params, + responseType: "blob" + } + ); +} + +export function exportStorageSummary(params: QueryStorageSummaryStatisticsReq) { + return defHttp.get>( + { + url: `${API.ExportStorageSummary}`, + params, + responseType: "blob" + } + ); +} + +export function exportCustomerBill(params: QueryCustomerBillReq) { + return defHttp.get>( + { + url: `${API.ExportCustomerBill}`, + params, + responseType: "blob" + } + ); +} + +export function exportSupplierBill(params: QuerySupplierBillReq) { + return defHttp.get>( + { + url: `${API.ExportSupplierBill}`, + params, + responseType: "blob" + } + ); +} + +export function exportStockFlow(params: QueryProductStockFlowReq) { + return defHttp.get>( + { + url: `${API.ExportProductStockFlowData}`, + params, + responseType: "blob" + } + ); +} + +export function exportCustomerBillDetail(params: QueryCustomerBillDetailReq) { + return defHttp.get>( + { + url: `${API.ExportCustomerBillDetail}`, + params, + responseType: "blob" + } + ); +} + +export function exportSupplierBillDetail(params: QuerySupplierBillDetailReq) { + return defHttp.get>( + { + url: `${API.ExportSupplierBillDetail}`, + params, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/report/reportModel.ts b/src/api/report/reportModel.ts new file mode 100644 index 0000000..fe64e64 --- /dev/null +++ b/src/api/report/reportModel.ts @@ -0,0 +1,313 @@ +export interface RetailStatisticalResp { + todaySales: number; + yesterdaySales: number; + todayRetailSales: number; + yesterdayRetailSales: number; + todayPurchase: number; + yesterdayPurchase: number; + monthSales: number; + monthRetailSales: number; + monthPurchase: number; + yearSales: number; + yearRetailSales: number; + yearPurchase: number; + retailAxisStatisticalDataVO: XyAxisData[]; + saleAxisStatisticalDataVO: XyAxisData[]; + purchaseAxisStatisticalDataVO: XyAxisData[]; +} + +export interface XyAxisData { + xaxisData: string; + yaxisData: number; +} + +export interface QueryProductStockReq { + warehouseId: number | string; + productInfo: string; + productCategoryId: number | string; + warehouseShelves: string; +} + +export interface QueryProductStockFlowReq { + productId: number; + warehouseId: number; + productBarcode: number; + receiptNumber: string; +} + +export interface ProductStockResp { + id: string; + productBarcode: string; + productName: string; + productCategoryName: string; + productStandard: string; + productModel: string; + productColor: string; + productUnit: string; + warehouseShelves: string; + productWeight: number; + unitPrice: number; + initialStock: number; + currentStock: number; + stockAmount: number; +} + +export interface ProductStockFlowResp { + receiptNumber: string; + type: String; + productBarcode: number; + productName: string; + warehouseName: string; + productNumber: number; + receiptDate: string; +} + +export interface QueryAccountStatisticsReq { + accountName: string; + accountNumber: string; +} + +export interface AccountStatisticsResp { + accountId: string; + accountName: string; + accountNumber: string; + initialAmount: number; + thisMonthChangeAmount: number; + currentAmount: number; +} + +export interface AccountFlowResp { + receiptNumber: string; + subType: string; + useType: string; + name: string; + amount: number; + balance: number; + receiptDate: string; +} + +export interface QueryRetailStatisticsReq { + productExtendInfo: string; + memberId: number; + warehouseId: number; +} + +export interface RetailStatisticsResp { + productBarcode: string; + productName: string; + productStandard: string; + productModel: string; + productExtendInfo: string; + productUnit: string; + retailNumber: number; + retailAmount: number; + retailRefundNumber: number; + retailRefundAmount: number; + retailLastAmount: number; +} + +export interface QueryPurchaseStatisticsReq { + productExtendInfo: string; + supplierId: number; + warehouseId: number; +} + +export interface PurchaseStatisticsResp { + productBarcode: string; + productName: string; + productStandard: string; + productModel: string; + productExtendInfo: string; + productUnit: string; + purchaseNumber: number; + purchaseAmount: number; + purchaseRefundNumber: number; + purchaseRefundAmount: number; + purchaseLastAmount: number; +} + +export interface QuerySalesStatisticsReq { + productExtendInfo: string; + customerId: number; + warehouseId: number; +} + +export interface SalesStatisticsResp { + productBarcode: string; + productName: string; + productStandard: string; + productModel: string; + productExtendInfo: string; + productUnit: string; + salesNumber: number; + salesAmount: number; + salesRefundNumber: number; + salesRefundAmount: number; + salesLastAmount: number; +} + +export interface QueryShipmentsDetailStatisticsReq { + receiptNumber: string; + productInfo: string; + relatedPersonId: number; + warehouseId: number; + operatorId: number; + remark: string; +} + +export interface ShipmentsDetailStatisticsResp { + receiptNumber: string; + productBarcode: string; + productName: string; + productStandard: string; + productModel: string; + productUnit: string; + type: string; + name: string; + productNumber: number; + unitPrice: number; + amount: number; + taxRate: number; + taxAmount: number; + createTime: string; +} + +export interface QueryStorageDetailStatisticsReq { + receiptNumber: string; + productInfo: string; + relatedPersonId: number; + warehouseId: number; + operatorId: number; + remark: string; +} + +export interface RelatedPersonResp { + id: string; + type: string; + name: string; +} + +export interface StorageDetailStatisticsResp { + receiptNumber: string; + productBarcode: string; + productName: string; + productStandard: string; + productModel: string; + productUnit: string; + type: string; + name: string; + productNumber: number; + unitPrice: number; + amount: number; + taxRate: number; + taxAmount: number; + createTime: string; +} + +export interface QueryShipmentsSummaryStatisticsReq { + productInfo: string; + relatedPersonId: number; + warehouseId: number; +} + +export interface ShipmentsSummaryStatisticsResp { + productBarcode: string; + productName: string; + warehouseName: string; + productStandard: string; + productCategoryName: string; + productModel: string; + productUnit: string; + shipmentsNumber: number; + shipmentsAmount: number; +} + +export interface QueryStorageSummaryStatisticsReq { + productInfo: string; + relatedPersonId: number; + warehouseId: number; +} + +export interface StorageSummaryStatisticsResp { + productBarcode: string; + productName: string; + warehouseName: string; + productStandard: string; + productCategoryName: string; + productModel: string; + productUnit: string; + storageNumber: number; + storageAmount: number; +} + +export interface QueryCustomerBillReq { + customerId: number | string; +} + +export interface CustomerBillStatisticsResp { + id: string; + customerId: string; + customerName: string; + contactName: string; + contactPhone: string; + email: string; + firstQuarterReceivable: number; + secondQuarterReceivable: number; + thirdQuarterReceivable: number; + fourthQuarterReceivable: number; + totalQuarterReceivable: number; + totalQuarterArrears: number; + remainingReceivableArrears: number; +} + +export interface QueryCustomerBillDetailReq { + receiptNumber: number | string; + productInfo: string; +} + +export interface CustomerBillDetailStatisticsResp { + receiptNumber: string; + customerName: string; + productInfo: string; + receiptDate: string; + operator: string; + thisReceiptArrears: number; + receivedArrears: number; + receivableArrears: number; +} + +export interface QuerySupplierBillReq { + supplierId: number | string; +} + +export interface SupplierBillStatisticsResp { + id: string; + supplierId: string; + supplierName: string; + contactName: string; + contactPhone: string; + email: string; + firstQuarterPayment: number; + secondQuarterPayment: number; + thirdQuarterPayment: number; + fourthQuarterPayment: number; + totalPayment: number; + totalArrears: number; + remainingPaymentArrears: number; +} + +export interface QuerySupplierBillDetailReq { + receiptNumber: number | string; + productInfo: string; +} + +export interface SupplierBillDetailStatisticsResp { + receiptNumber: string; + supplierName: string; + productInfo: string; + receiptDate: string; + operator: string; + thisReceiptArrears: number; + prepaidArrears: number; + paymentArrears: number; +} \ No newline at end of file diff --git a/src/api/retail/model/refundModel.ts b/src/api/retail/model/refundModel.ts new file mode 100644 index 0000000..eeceab5 --- /dev/null +++ b/src/api/retail/model/refundModel.ts @@ -0,0 +1,49 @@ +import {ShipmentsData, FileData} from '/@/api/retail/model/shipmentsModel'; + +export interface AddOrUpdateRefundReq { + id: number | string | undefined; + memberId: string; + accountId: string; + receiptDate: string; + receiptNumber: string; + otherReceipt: string; + paymentAmount: number; + receiptAmount: number; + backAmount: number; + remark: string; + status: number; + tableData: ShipmentsData[]; + files: FileData[]; +} + +export interface AddOrUpdateRefundResp { + id: number | string | undefined; + memberId: string; + memberName: string; + accountId: string; + accountName: string; + receiptDate: string; + receiptNumber: string; + otherReceipt: string; + paymentAmount: number; + receiptAmount: number; + backAmount: number; + remark: string; + status: number; + tableData: ShipmentsData[]; + files: FileData[]; +} + +export interface RefundResp { + id: number | string; + memberName: string; + receiptNumber: string; + receiptDate: string; + productInfo: string; + operator: string; + productNumber: number; + totalPrice: number; + paymentAmount: number; + backAmount: string; + status: number; +} \ No newline at end of file diff --git a/src/api/retail/model/shipmentsModel.ts b/src/api/retail/model/shipmentsModel.ts new file mode 100644 index 0000000..96fad02 --- /dev/null +++ b/src/api/retail/model/shipmentsModel.ts @@ -0,0 +1,82 @@ +export interface FileData { + id: number | string; + uid: string; + fileName: string; + fileUrl: string; + fileType: string; + fileSize: number; + status: string; +} + +export interface ShipmentsData { + warehouseId: number | string; + barCode: string | number; + productId: number | string; + productName: string; + productStandard: string; + productUnit: string; + stock: number; + productNumber: number; + unitPrice: number; + amount: number; +} + +export interface AddOrUpdateShipmentsReq { + id: number | string | undefined; + memberId: number | string; + accountId: number | string; + receiptDate: string; + receiptNumber: string; + receiptType: string; + collectionAmount: number; + receiptAmount: number; + backAmount: number; + remark: string; + status: number; + tableData: ShipmentsData[]; + fileDataList: FileData[]; +} + +export interface AddOrUpdateShipmentsResp { + id: number | string | undefined; + memberId: number | string; + memberName: string; + paymentType: string; + accountId: number | string; + accountName: string; + receiptDate: string; + receiptNumber: string; + receiptType: string; + collectionAmount: number; + receiptAmount: number; + backAmount: number; + remark: string; + status: number; + tableData: ShipmentsData[]; + fileDataList: FileData[]; +} + +export interface QueryShipmentsReq { + receiptNumber: string; + productInfo: string; + memberId: number | string; + warehouseId: number | string; + accountId: number | string; + operatorId: number | string; + status: number; + remark: string; +} + +export interface ShipmentsResp { + id: number | string; + memberName: string; + receiptNumber: string; + receiptDate: string; + productInfo: string; + operator: string; + productNumber: number; + totalPrice: number; + collectionAmount: number; + backAmount: string; + status: number; +} \ No newline at end of file diff --git a/src/api/retail/refund.ts b/src/api/retail/refund.ts new file mode 100644 index 0000000..166243d --- /dev/null +++ b/src/api/retail/refund.ts @@ -0,0 +1,102 @@ +import {defHttp} from '/@/utils/http/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { QueryShipmentsReq } from "@/api/retail/model/shipmentsModel" +import { + AddOrUpdateRefundReq, AddOrUpdateRefundResp, + RefundResp +} from "@/api/retail/model/refundModel" +import {ErrorMessageMode, SuccessMessageMode} from "#/axios"; + +enum API { + PageList = '/retail/refund/pageList', + AddOrUpdate = '/retail/refund/addOrUpdate', + GetDetail = '/retail/refund/detail', + UpdateStatus = '/retail/refund/updateStatus', + Delete = '/retail/refund/deleteByIds', + GetLinkRefundDetail = '/retail/refund/getLinkRefundDetail', + Export = '/retail/refund/export', + ExportDetail = '/retail/refund/exportDetail', +} + +export function getRefundPageList(params: QueryShipmentsReq) { + return defHttp.post>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdateRefund(params: AddOrUpdateRefundReq, + successMode: SuccessMessageMode = 'message', + errorMode: ErrorMessageMode = 'message',) { + return defHttp.post( + { + url: API.AddOrUpdate, + params, + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getRefundDetail(id: string) { + return defHttp.get>( + { + url: `${API.GetDetail}/${id}`, + } + ); +} + +export function getLinkRefundDetail(otherReceipt: string) { + return defHttp.get>( + { + url: `${API.GetLinkRefundDetail}/${otherReceipt}`, + } + ); +} + +export function updateRefundStatus(ids: string[], status: number, successMode: SuccessMessageMode = 'message', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.UpdateStatus}?ids=${ids}&status=${status}`, + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteRefund(ids: string[], successMode: SuccessMessageMode = 'message', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: `${API.Delete}?ids=${ids}`, + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function exportRefund(params: QueryShipmentsReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} + +export function exportRefundDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.ExportDetail}/${receiptNumber}`, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/retail/shipments.ts b/src/api/retail/shipments.ts new file mode 100644 index 0000000..b5127f9 --- /dev/null +++ b/src/api/retail/shipments.ts @@ -0,0 +1,118 @@ +import {defHttp} from '/@/utils/http/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + AddOrUpdateShipmentsReq, AddOrUpdateShipmentsResp, + QueryShipmentsReq, + ShipmentsResp +} from "@/api/retail/model/shipmentsModel" +import {ErrorMessageMode, SuccessMessageMode} from "#/axios"; + +enum API { + PageList = '/retail/shipments/pageList', + List = '/retail/shipments/list', + AddOrUpdate = '/retail/shipments/addOrUpdate', + DeleteBatch = '/retail/shipments/deleteByIds', + UpdateStatus = '/retail/shipments/updateStatus', + GetDetail = '/retail/shipments/detail', + GetLinkShipmentDetail = '/retail/shipments/getLinkShipmentDetail', + Export = '/retail/shipments/export', + ExportDetail = '/retail/shipments/exportDetail', +} + +export function getShipmentsPageList(params: QueryShipmentsReq) { + return defHttp.post>( + { + url: API.PageList, + params, + } + ); +} + +export function getShipmentsList(params: QueryShipmentsReq) { + return defHttp.post>( + { + url: API.List, + params, + } + ); +} + +export function addOrUpdateShipments(params: AddOrUpdateShipmentsReq, + successMode: SuccessMessageMode = 'message', + errorMode: ErrorMessageMode = 'message',) { + return defHttp.post( + { + url: API.AddOrUpdate, + params, + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteShipments(ids: string[], successMode: SuccessMessageMode = 'message', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: `${API.DeleteBatch}?ids=${ids}`, + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function updateShipmentsStatus(ids: string[], status: number, successMode: SuccessMessageMode = 'message', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.UpdateStatus}?ids=${ids}&status=${status}`, + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getShipmentsDetail(id: string | number, errorMode: ErrorMessageMode = 'message') { + return defHttp.get>( + { + url: `${API.GetDetail}/${id}`, + }, + { + errorMessageMode: errorMode, + } + ); +} + +export function getLinkShipmentsDetail(otherReceipt: string, errorMode: ErrorMessageMode = 'message') { + return defHttp.get>( + { + url: `${API.GetLinkShipmentDetail}/${otherReceipt}`, + }, + { + errorMessageMode: errorMode, + } + ); +} + +export function exportShipments(params: QueryShipmentsReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} + +export function exportShipmentsDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.ExportDetail}/${receiptNumber}`, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/sale/model/orderModel.ts b/src/api/sale/model/orderModel.ts new file mode 100644 index 0000000..6fea523 --- /dev/null +++ b/src/api/sale/model/orderModel.ts @@ -0,0 +1,83 @@ +import {FileData} from '/@/api/retail/model/shipmentsModel'; + +export interface QuerySaleOrderReq { + receiptNumber: string; + productInfo: string; + customerId: number | string; + operatorId: number | string; + status: number; + remark: string; +} + +export interface SalesData { + warehouseId: number | string; + productId: number | string; + barCode: number | string; + productCode: string; + productName: string; + productUnit: string; + productStandard: string; + stock: number; + productNumber: number; + salePrice: number; + amount: number; + taxRate: number; + taxAmount: number; + taxTotalPrice: number; + remark: string; +} + +export interface AddOrUpdateReceiptReq { + id: number | string | undefined; + customerId: string; + receiptNumber: string; + receiptDate: string; + operatorIds: number[]; + discountRate: number; + discountAmount: number; + discountLastAmount: number; + deposit: number; + accountId: number | string; + multipleAccountIds: number[]; + multipleAccountAmounts: number[]; + status: number; + remark: string; + tableData: SalesData[]; + files: FileData[]; +} + +export interface LinkReceiptSaleOrderDetailResp { + id: number | string | undefined; + customerId: string; + customerName: string; + accountName: string; + receiptNumber: string; + receiptDate: string; + operatorIds: number[]; + discountRate: number; + discountAmount: number; + discountLastAmount: number; + deposit: number; + accountId: number | string; + multipleAccountIds: number[]; + multipleAccountAmounts: number[]; + status: number; + remark: string; + tableData: SalesData[]; + files: FileData[]; +} + +export interface SaleDetailData { + customerId: number | string; + receiptDate: string; + receiptNumber: string; + operatorIds: number[]; + discountRate: number; + discountAmount: number; + discountLastAmount: number; + deposit: number; + accountIds: number; + remark: string; + tableData: SalesData[]; + files: FileData[]; +} \ No newline at end of file diff --git a/src/api/sale/model/refundModel.ts b/src/api/sale/model/refundModel.ts new file mode 100644 index 0000000..c9ea1f6 --- /dev/null +++ b/src/api/sale/model/refundModel.ts @@ -0,0 +1,94 @@ +import {FileData} from '/@/api/retail/model/shipmentsModel'; + +export interface QuerySaleRefundReq { + receiptNumber: string; + productInfo: string; + customerId: number | string; + operatorId: number | string; + otherReceipt: string; + arrearsStatus: number; + status: number; + remark: string; +} + +export interface SaleRefundTableData { + warehouseId: number | string; + productId: number | string; + barCode: number | string; + productName: string; + productUnit: string; + productStandard: string; + stock: number; + productNumber: number; + unitPrice: number; + amount: number; + taxRate: number; + taxAmount: number; + taxTotalPrice: number; + remark: string; +} + +export interface AddOrUpdateReceiptSaleRefundReq { + id: number | string | undefined; + customerId: string; + receiptNumber: string; + receiptDate: string; + otherReceipt: string; + operatorIds: number[]; + refundOfferRate: number; + refundOfferAmount: number; + refundLastAmount: number; + otherAmount: number; + thisRefundAmount: number; + thisArrearsAmount: number; + accountId: number | string; + multipleAccountIds: number[]; + multipleAccountAmounts: number[]; + status: number; + remark: string; + tableData: SaleRefundTableData[]; + files: FileData[]; +} + +export interface LinkReceiptSaleRefundDetailResp { + id: number | string | undefined; + customerId: string; + customerName: string; + accountName: string; + receiptNumber: string; + receiptDate: string; + otherReceipt: string; + operatorIds: number[]; + refundOfferRate: number; + refundOfferAmount: number; + refundLastAmount: number; + otherAmount: number; + thisRefundAmount: number; + thisArrearsAmount: number; + accountId: number | string; + multipleAccountIds: number[]; + multipleAccountAmounts: number[]; + status: number; + remark: string; + tableData: SaleRefundTableData[]; + files: FileData[]; +} + +export interface SaleRefundDetailData { + customerId: number | string; + receiptDate: string; + receiptNumber: string; + operatorIds: number[]; + refundOfferRate: number; + refundOfferAmount: number; + refundLastAmount: number; + otherAmount: number; + thisRefundAmount: number; + thisArrearsAmount: number; + accountIds: number; + multipleAccountAmounts: number[]; + multipleAccountIds: number[]; + remark: string; + tableData: SaleRefundTableData[]; + files: FileData[]; +} \ No newline at end of file diff --git a/src/api/sale/model/shipmentsModel.ts b/src/api/sale/model/shipmentsModel.ts new file mode 100644 index 0000000..53744f2 --- /dev/null +++ b/src/api/sale/model/shipmentsModel.ts @@ -0,0 +1,94 @@ +import {FileData} from '/@/api/retail/model/shipmentsModel'; + +export interface QuerySaleShipmentsReq { + receiptNumber: string; + productInfo: string; + customerId: number | string; + operatorId: number | string; + otherReceipt: string; + arrearsStatus: number; + status: number; + remark: string; +} + +export interface tableData { + warehouseId: number | string; + productId: number | string; + barCode: number | string; + productName: string; + productUnit: string; + productStandard: string; + stock: number; + productNumber: number; + unitPrice: number; + amount: number; + taxRate: number; + taxAmount: number; + taxTotalPrice: number; + remark: string; +} + +export interface AddOrUpdateReceiptSaleShipmentsReq { + id: number | string | undefined; + customerId: string; + receiptNumber: string; + receiptDate: string; + otherReceipt: string; + operatorIds: number[]; + collectOfferRate: number; + collectOfferAmount: number; + collectOfferLastAmount: number; + otherAmount: number; + thisCollectAmount: number; + thisArrearsAmount: number; + accountId: number | string; + multipleAccountIds: number[]; + multipleAccountAmounts: number[]; + status: number; + remark: string; + tableData: tableData[]; + files: FileData[]; +} + +export interface LinkReceiptSaleShipmentsDetailResp { + id: number | string | undefined; + customerId: string; + customerName: string; + accountName: string; + receiptNumber: string; + receiptDate: string; + otherReceipt: string; + operatorIds: number[]; + collectOfferRate: number; + collectOfferAmount: number; + collectOfferLastAmount: number; + otherAmount: number; + thisCollectAmount: number; + thisArrearsAmount: number; + accountId: number | string; + multipleAccountIds: number[]; + multipleAccountAmounts: number[]; + status: number; + remark: string; + tableData: tableData[]; + files: FileData[]; +} + +export interface SaleShipmentDetailData { + customerId: number | string; + receiptDate: string; + receiptNumber: string; + operatorIds: number[]; + collectOfferRate: number; + collectOfferAmount: number; + collectOfferLastAmount: number; + otherAmount: number; + thisCollectAmount: number; + thisArrearsAmount: number; + accountIds: number; + multipleAccountAmounts: number[]; + multipleAccountIds: number[]; + remark: string; + tableData: tableData[]; + files: FileData[]; +} \ No newline at end of file diff --git a/src/api/sale/order.ts b/src/api/sale/order.ts new file mode 100644 index 0000000..c752ecb --- /dev/null +++ b/src/api/sale/order.ts @@ -0,0 +1,98 @@ +import {defHttp} from '/@/utils/http/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + QuerySaleOrderReq, + AddOrUpdateReceiptReq, + SaleDetailData, + LinkReceiptSaleOrderDetailResp +} from "@/api/sale/model/orderModel" +import {ErrorMessageMode, SuccessMessageMode} from "#/axios"; + +enum API { + PageList = '/sale/order/pageList', + AddOrUpdate = '/sale/order/addOrUpdate', + GetDetail = '/sale/order/detail', + UpdateStatus = '/sale/order/updateStatus', + Delete = '/sale/order/delete', + GetLinkOrderDetail = '/sale/order/getLinkOrderDetail', + Export = '/sale/order/export', + ExportDetail = '/sale/order/exportDetail', +} + +export function getSaleOrderPageList(params: QuerySaleOrderReq) { + return defHttp.get>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdateSaleOrder(params: AddOrUpdateReceiptReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdate, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getSaleOrderDetail(id: string) { + return defHttp.get>( + { + url: `${API.GetDetail}/${id}`, + } + ); +} + +export function updateSaleOrderStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.UpdateStatus}/${ids}/${status}`, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteSaleOrder(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.Delete}/${ids}`, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getLinkOrderDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.GetLinkOrderDetail}/${receiptNumber}`, + } + ); +} + +export function exportOrder(params: QuerySaleOrderReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} + +export function exportOrderDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.ExportDetail}/${receiptNumber}`, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/sale/refund.ts b/src/api/sale/refund.ts new file mode 100644 index 0000000..2a85e2c --- /dev/null +++ b/src/api/sale/refund.ts @@ -0,0 +1,98 @@ +import {defHttp} from '/@/utils/http/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + QuerySaleRefundReq, + AddOrUpdateReceiptSaleRefundReq, + SaleRefundDetailData, + LinkReceiptSaleRefundDetailResp +} from "@/api/sale/model/refundModel" +import {ErrorMessageMode, SuccessMessageMode} from "#/axios"; + +enum API { + PageList = '/sale/refund/pageList', + AddOrUpdate = '/sale/refund/addOrUpdate', + GetDetail = '/sale/refund/detail', + UpdateStatus = '/sale/refund/updateStatus', + Delete = '/sale/refund/delete', + GetLinkRefundDetail = '/sale/refund/getLinkRefundDetail', + Export = '/sale/refund/export', + ExportDetail = '/sale/refund/exportDetail', +} + +export function getSaleRefundPageList(params: QuerySaleRefundReq) { + return defHttp.get>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdateSaleRefund(params: AddOrUpdateReceiptSaleRefundReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdate, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getSaleRefundDetail(id: string) { + return defHttp.get>( + { + url: `${API.GetDetail}/${id}`, + } + ); +} + +export function updateSaleRefundStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.UpdateStatus}/${ids}/${status}`, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteSaleRefund(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.Delete}/${ids}`, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getLinkRefundDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.GetLinkRefundDetail}/${receiptNumber}`, + } + ); +} + +export function exportRefund(params: QuerySaleRefundReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} + +export function exportRefundDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.ExportDetail}/${receiptNumber}`, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/sale/shipments.ts b/src/api/sale/shipments.ts new file mode 100644 index 0000000..426c064 --- /dev/null +++ b/src/api/sale/shipments.ts @@ -0,0 +1,98 @@ +import {defHttp} from '/@/utils/http/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + QuerySaleShipmentsReq, + AddOrUpdateReceiptSaleShipmentsReq, + SaleShipmentDetailData, + LinkReceiptSaleShipmentsDetailResp +} from "@/api/sale/model/shipmentsModel" +import {ErrorMessageMode, SuccessMessageMode} from "#/axios"; + +enum API { + PageList = '/sale/shipments/pageList', + AddOrUpdate = '/sale/shipments/addOrUpdate', + GetDetail = '/sale/shipments/detail', + UpdateStatus = '/sale/shipments/updateStatus', + Delete = '/sale/shipments/delete', + GetLinkShipmentsDetail = '/sale/shipments/getLinkShipmentDetail', + Export = '/sale/shipments/export', + ExportDetail = '/sale/shipments/exportDetail', +} + +export function getSaleShipmentsPageList(params: QuerySaleShipmentsReq) { + return defHttp.get>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdateSaleShipments(params: AddOrUpdateReceiptSaleShipmentsReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdate, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getSaleShipmentsDetail(id: string) { + return defHttp.get>( + { + url: `${API.GetDetail}/${id}`, + } + ); +} + +export function updateSaleShipmentsStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.UpdateStatus}/${ids}/${status}`, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteSaleShipments(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.Delete}/${ids}`, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getLinkShipmentsDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.GetLinkShipmentsDetail}/${receiptNumber}`, + } + ); +} + +export function exportShipments(params: QuerySaleShipmentsReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} + +export function exportShipmentsDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.ExportDetail}/${receiptNumber}`, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/sys/captcha.ts b/src/api/sys/captcha.ts new file mode 100644 index 0000000..57902f1 --- /dev/null +++ b/src/api/sys/captcha.ts @@ -0,0 +1,23 @@ +import { BaseDataResp } from '../model/baseModel'; +import { ErrorMessageMode } from '/#/axios'; +import { defHttp } from '/@/utils/http/axios'; + +enum Api { + GetCaptcha = '/v2/common/captcha' +} + +interface CaptchaResp { + captchaId: string; + imagePath: string; +} + +export function getCaptcha(mode: ErrorMessageMode = 'notice') { + return defHttp.get>( + { + url: Api.GetCaptcha, + }, + { + errorMessageMode: mode, + }, + ); +} diff --git a/src/api/sys/config.ts b/src/api/sys/config.ts new file mode 100644 index 0000000..b7b4416 --- /dev/null +++ b/src/api/sys/config.ts @@ -0,0 +1,20 @@ +import { defHttp } from '/@/utils/http/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + AddOrUpdateSystemConfigModel, + GetSystemConfigModel, +} from '@/api/sys/model/configModel'; + +enum Api { + GetConfigInfo = '/sys/config/getCompanyInfo', + AddOrUpdateConfigInfo = '/sys/config/addOrUpdate', +} + +export function getConfigInfo() { + return defHttp.get>({url: Api.GetConfigInfo}) +} + +export function addOrUpdateConfigInfo(params: AddOrUpdateSystemConfigModel) { + return defHttp.post({url: Api.AddOrUpdateConfigInfo, params}) +} + diff --git a/src/api/sys/dept.ts b/src/api/sys/dept.ts new file mode 100644 index 0000000..d0d43be --- /dev/null +++ b/src/api/sys/dept.ts @@ -0,0 +1,42 @@ +import { + addOrUpdateDeptReq, + DeptListItem, + GetDeptInfoModel, +} from './model/dpetModel'; + +import { defHttp } from '/@/utils/http/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import {ErrorMessageMode, SuccessMessageMode} from "#/axios"; + +enum Api { + DeptList = '/dept/list', + UserBindDept = '/dept/userBindDept', + AddOrUpdateDept = '/dept/addOrUpdate', + DeleteDept = '/dept/delete', +} +export function getDeptList(params?: DeptListItem) { + return defHttp.get>({url: Api.DeptList, params}) +} +export function getUserBindDept() { + return defHttp.get>({url: Api.UserBindDept}) +} + +export function addOrUpdateDept(params: addOrUpdateDeptReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'notice') { + return defHttp.post({ + url: Api.AddOrUpdateDept, params}, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ) +} + +export function deleteDept(id: number | string, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'notice') { + return defHttp.post({ + url: `${Api.DeleteDept}?id=${id}`}, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ) +} \ No newline at end of file diff --git a/src/api/sys/menu.ts b/src/api/sys/menu.ts new file mode 100644 index 0000000..6ddac62 --- /dev/null +++ b/src/api/sys/menu.ts @@ -0,0 +1,37 @@ +import {defHttp} from '/@/utils/http/axios'; +import {BaseDataResp} from "@/api/model/baseModel"; +import {MenuListResp, AddOrUpdateMenuReq} from "@/api/sys/model/menuModel"; +import {ErrorMessageMode, SuccessMessageMode} from "#/axios"; +enum Api { + GetMenuList = '/sysRole/menu', + AddOrUpdateMenu = '/menu/addOrUpdate', + DeleteMenu = '/menu/delete', +} + +/** + * @description: Get user menu based on id + */ + +export const getMenuList = () => { + return defHttp.get>({url: Api.GetMenuList}); +}; + +export const addOrUpdateMenu = (params: AddOrUpdateMenuReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'notice') => { + return defHttp.post>( + {url: Api.AddOrUpdateMenu, params}, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ) +} + +export const deleteMenu = (id: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'notice') => { + return defHttp.post>( + {url: `${Api.DeleteMenu}?id=${id}`}, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ) +} diff --git a/src/api/sys/model/captchaModel.ts b/src/api/sys/model/captchaModel.ts new file mode 100644 index 0000000..8266e78 --- /dev/null +++ b/src/api/sys/model/captchaModel.ts @@ -0,0 +1,12 @@ +export interface CaptchaResp { + captchaId: string; + imgPath: string; +} + +export interface GetEmailCaptchaReq { + email: string; +} + +export interface GetSmsCaptchaReq { + phoneNumber: string; +} diff --git a/src/api/sys/model/configModel.ts b/src/api/sys/model/configModel.ts new file mode 100644 index 0000000..83d5f40 --- /dev/null +++ b/src/api/sys/model/configModel.ts @@ -0,0 +1,20 @@ +export interface GetSystemConfigModel { + companyName: string; + companyContact: string; + companyAddress: string; + companyPhone: string; + companyFax: string; + companyPostCode: string; + companyLogo: string; +} + +export interface AddOrUpdateSystemConfigModel { + id: number | string; + companyName: string; + companyContact: string; + companyAddress: string; + companyPhone: string; + companyFax: string; + companyPostCode: string; + companyLogo: string; +} \ No newline at end of file diff --git a/src/api/sys/model/dpetModel.ts b/src/api/sys/model/dpetModel.ts new file mode 100644 index 0000000..ba02138 --- /dev/null +++ b/src/api/sys/model/dpetModel.ts @@ -0,0 +1,29 @@ +export interface DeptListItem { + deptName: string; +} + +export interface GetDeptInfoModel { + // 机构id + id: string | number; + // 机构编号 + deptNumber: string; + // 机构名称 + deptName: string; + // 备注 + remark: string; + // 父级部门id + parentId: string; + // 排序 + sort: number; +} + +export interface addOrUpdateDeptReq { + id: number | string; + deptName: string; + parentId: number; + deptNumber: string; + leader: string; + status: number; + remark: string; + sort: string; +} diff --git a/src/api/sys/model/menuModel.ts b/src/api/sys/model/menuModel.ts new file mode 100644 index 0000000..d618169 --- /dev/null +++ b/src/api/sys/model/menuModel.ts @@ -0,0 +1,70 @@ +import type {RouteMeta} from 'vue-router'; +import {BaseListResp} from '../../model/baseModel'; + +export interface RouteItem { + path: string; + component: any; + meta: RouteMeta; + name?: string; + alias?: string | string[]; + redirect?: string; + caseSensitive?: boolean; + children?: RouteItem[]; +} + +export interface MenuPageResp { + total: number; + data: RouteItem[]; +} + +export interface MenuInfo { + id: number; + type?: number; + parentId?: number; + path?: string; + name?: string; + title?: string; + redirect?: string; + component?: string; + sort?: number; + disabled?: boolean; + meta: Meta; +} + +interface Meta { + title?: string; + icon?: string; + hideMenu?: boolean; + hideBreadcrumb?: boolean; + ignoreKeepAlive?: boolean; + hideTab?: boolean; + frameSrc?: string; + carryParam?: boolean; + hideChildrenInMenu?: boolean; + affix?: boolean; + dynamicLevel?: number; + realPath?: string; +} + +export interface AddOrUpdateMenuReq { + id: number; + menuType: number; + name: string; + title: string; + parentId: number; + sort: number; + icon: string; + path: string; + component: string; + status: number; + blank: number; + ignoreKeepAlive: number; + hideMenu: number; +} + +export type MenuListResp = BaseListResp; + +/** + * @description: Get menu return value + */ +export type RoleMenuResp = BaseListResp; diff --git a/src/api/sys/model/roleModel.ts b/src/api/sys/model/roleModel.ts new file mode 100644 index 0000000..7c9c59d --- /dev/null +++ b/src/api/sys/model/roleModel.ts @@ -0,0 +1,35 @@ +export interface GetRoleInfoModel { + // 角色id + id: number | string, + // 角色名称 + roleName: string, + // 角色类型 + type: string, + // 价格屏蔽 1-屏蔽采购价 2-屏蔽零售价 3-屏蔽销售价 + priceLimit: number, + // 状态 0-启用 1-停用 + status: number, + // 描述 + description: string, + // 创建时间 + createTime: string +} + +export interface queryRoleListReq { + roleName: string; + status: number; +} + +export interface addOrUpdateRoleInfoReq { + id: string | undefined + roleName: string, + type: string, + priceLimit: number, + status: number, + description: string, +} + +export interface addOrUpdateRolePermissionReq { + id: string | undefined, + menuIds: number[] +} \ No newline at end of file diff --git a/src/api/sys/model/uploadModel.ts b/src/api/sys/model/uploadModel.ts new file mode 100644 index 0000000..4015bbd --- /dev/null +++ b/src/api/sys/model/uploadModel.ts @@ -0,0 +1,5 @@ +export interface UploadApiResult { + msg: string; + code: string; + url: string; +} diff --git a/src/api/sys/model/userModel.ts b/src/api/sys/model/userModel.ts new file mode 100644 index 0000000..e606d78 --- /dev/null +++ b/src/api/sys/model/userModel.ts @@ -0,0 +1,119 @@ +/** + * @description: Login interface parameters + */ +export interface LoginReq { + username: string; + password: string; + captcha: string; + captchaId: string; +} + +export interface mobileLoginReq { + phoneNumber: string; + sms: string; + type: number; +} + +export interface registerReq { + username: string; + password: string; + phoneNumber: string; + sms: number; +} + +export interface queryUserListReq { + username: string; + name: string; +} + +export interface updatePasswordReq { + username: string; + password: string; + phoneNumber: string; + sms: number; +} + +export interface resetPasswordReq { + id: number | string; + userName: string; + password: string; + newPassword: string; +} + +export interface resetPhoneNumberReq { + userId: number | string; + oldPhoneNumber: string; + phoneNumber: string; + sms: string; +} + +export interface resetEmailReq { + userId: number | string; + oldEmail: string; + email: string; + emailCode: string; +} + +export interface updateUserInfoReq { + id: number | string; + name: string; + status: number; + email: string; + phoneNumber: string; + position: string; + leaderFlag: number; +} + +export interface addOrUpdateUserReq { + id: number | string; + username: string; + password: string; + name: string; + email: string; + phoneNumber: string; + roleId: number; + deptId: number; + remake: string; +} + +export interface RoleInfo { + roleName: string; + value: string; +} + +export interface LoginResp { + userId: string | number; + token: string; + expire?: number; +} + +/** + * @description: Login interface return value + */ +export interface LoginResultModel { + userId: string | number; + token: string; + roles: RoleInfo[]; +} + +/** + * @description: Get user information return value + */ +export interface GetUserInfoModel { + // 用户id + id: string | number; + // 用户名 + username: string; + // 昵称 + name: string; + // 邮箱 + email: string; + // 电话 + phoneNumber: string; + // 状态 + status: number; + // 用户角色名称 + roleName: string; + // 头像 + avatar: string; +} diff --git a/src/api/sys/role.ts b/src/api/sys/role.ts new file mode 100644 index 0000000..5d26ac0 --- /dev/null +++ b/src/api/sys/role.ts @@ -0,0 +1,73 @@ +import {ErrorMessageMode, SuccessMessageMode} from "#/axios"; +import {defHttp} from "@/utils/http/axios"; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + addOrUpdateRoleInfoReq, + addOrUpdateRolePermissionReq, + GetRoleInfoModel, + queryRoleListReq +} from "@/api/sys/model/roleModel"; + +enum Api { + List = '/sysRole/list', + PageList = '/sysRole/PageList', + UpdateStatus = '/sysRole/updateStatus', + AddOrUpdateRole = '/sysRole/addOrUpdateRole', + DeleteRole = '/sysRole/deleteRole', + RolePermission = '/sysRole/permission' +} + +export function getRoleList(errorMode: ErrorMessageMode = 'notice') { + return defHttp.get( + {url: Api.List}, + { + errorMessageMode: errorMode, + } + ) +} + +export function getPageList(params: queryRoleListReq) { + return defHttp.post>( + {url: Api.PageList, params}, + ) +} + +export function setRoleStatus(id: string, status: number, successMode: SuccessMessageMode ='notice', errorMode: ErrorMessageMode = 'notice'){ + return defHttp.post( + {url: `${Api.UpdateStatus}?id=${id}&status=${status}`}, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + }, + ) +} + +export function addOrUpdateRole(params: addOrUpdateRoleInfoReq, successMode: SuccessMessageMode ='notice', errorMode: ErrorMessageMode = 'notice'){ + return defHttp.post( + {url: Api.AddOrUpdateRole, params: params}, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ) +} + +export function deleteRole(id: string, successMode: SuccessMessageMode ='notice', errorMode: ErrorMessageMode = 'notice') { + return defHttp.post( + {url: `${Api.DeleteRole}?id=${id}`}, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ) +} + +export function rolePermission(params: addOrUpdateRolePermissionReq, successMode: SuccessMessageMode ='notice', errorMode: ErrorMessageMode = 'notice') { + return defHttp.post( + {url: Api.RolePermission, params: params}, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ) +} \ No newline at end of file diff --git a/src/api/sys/upload.ts b/src/api/sys/upload.ts new file mode 100644 index 0000000..1eb3039 --- /dev/null +++ b/src/api/sys/upload.ts @@ -0,0 +1,25 @@ +import { defHttp } from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode, UploadFileParams} from '/#/axios'; +import {BaseResp} from "@/api/model/baseModel"; +import {ContentTypeEnum} from "@/enums/httpEnum"; + +enum Api { + UploadOss = '/v2/common/uploadOss', +} + +export function uploadApi(params: UploadFileParams, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: Api.UploadOss, + params, + headers: { + 'Content-type': ContentTypeEnum.FORM_DATA, + // @ts-ignore + ignoreCancelToken: true, + }, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} \ No newline at end of file diff --git a/src/api/sys/user.ts b/src/api/sys/user.ts new file mode 100644 index 0000000..39f9ad7 --- /dev/null +++ b/src/api/sys/user.ts @@ -0,0 +1,271 @@ +import {defHttp} from '/@/utils/http/axios'; +import { + addOrUpdateUserReq, + GetUserInfoModel, + LoginReq, + LoginResp, + mobileLoginReq, queryUserListReq, + registerReq, resetEmailReq, resetPasswordReq, resetPhoneNumberReq, + updatePasswordReq, + updateUserInfoReq, +} from './model/userModel'; + +import {ErrorMessageMode, SuccessMessageMode, UploadFileParams} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import {ContentTypeEnum} from "@/enums/httpEnum"; + +enum Api { + Login = '/user/login', + MobileLogin = '/user/mobileLogin', + Logout = '/user/logout', + Register = '/user/register', + SMS = '/v2/common/sms', + EmailSMS = '/v2/common/email', + UpdatePassword = '/user/updatePassword', + GetUserInfo = '/user/info', + GetPermCode = '/user/perm', + TestRetry = '/testRetry', + List = '/user/list', + ListAll = '/user/listAll', + UpdateUser = '/user/update', + AddOrUpdateUser = '/user/addOrUpdate', + DeleteUser = '/user/delete', + ResetPassword = '/user/resetPassword', + GetUserOperatorList = '/user/operator', + UpdateAvatar = '/user/uploadAvatar', + UserUpdatePassword = '/user/userUpdatePassword', + ResetPhoneNumber = '/user/resetPhoneNumber', + ResetEmail = '/user/resetEmail', +} + +/** + * @description: user login api + */ +export function login(params: LoginReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'notice') { + return defHttp.post>( + { + url: Api.Login, + params, + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + }, + ); +} + +export function mobileLogin(params: mobileLoginReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'notice') { + return defHttp.post>( + { + url: Api.MobileLogin, + params, + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + }, + ); +} + +export function register(params: registerReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'notice') { + return defHttp.post( + { + url: Api.Register, + params, + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ) +} + +export function sendSmsRegister(type: number, phoneNumber: string, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'notice') { + return defHttp.get( + { + url: `${Api.SMS}/${type}/${phoneNumber}` + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ) +} + +export function sendEmailCode(type: number, email: string, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'notice') { + return defHttp.get( + { + url: `${Api.EmailSMS}/${type}/${email}` + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ) +} + +export function updatePassword(params: updatePasswordReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'notice') { + return defHttp.post( + { + url: Api.UpdatePassword, + params, + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ) +} + +/** + * @description: getUserInfo + */ +export function getUserInfo() { + return defHttp.get>( + {url: Api.GetUserInfo}, + {errorMessageMode: 'none'}, + ); +} + +export function getUserList(params: queryUserListReq) { + return defHttp.post>( + {url: Api.List, params}, + ); +} + +export function getTenantUserList(mode: ErrorMessageMode = 'notice') { + return defHttp.get>( + {url: Api.ListAll}, + { + errorMessageMode: mode, + successMessageMode: mode, + }, + ); +} + +export function updateUser(params: updateUserInfoReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'notice') { + return defHttp.post( + {url: Api.UpdateUser, params}, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + }, + ) +} + +export function updateStatus(params: { id: any; status: number }, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'notice') { + return defHttp.post( + {url: Api.UpdateUser, params}, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + }, + ) +} + +export function addOrUpdateUser(params: addOrUpdateUserReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'notice') { + return defHttp.post( + {url: Api.AddOrUpdateUser, params}, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ) +} + +export function deleteUser(ids: string[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'notice') { + return defHttp.post( + {url: `${Api.DeleteUser}?ids=${ids}`}, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ) +} + +export function resetPassword(id: string, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'notice') { + return defHttp.post( + {url: `${Api.ResetPassword}?id=${id}`}, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ) +} + +export function getPermCode() { + return defHttp.get({url: Api.GetPermCode}); +} + +export function doLogout(successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'notice') { + return defHttp.get({url: Api.Logout}, { + successMessageMode: successMode, + errorMessageMode: errorMode, + }); +} + +export function getUserOperatorList() { + return defHttp.get>({url: Api.GetUserOperatorList}); +} + +export function testRetry() { + return defHttp.get( + {url: Api.TestRetry}, + { + retryRequest: { + isOpenRetry: true, + count: 5, + waitTime: 1000, + }, + }, + ); +} + +export function UpdateAvatar(params: UploadFileParams) { + return defHttp.post( + { + url: Api.UpdateAvatar, + params, + headers: { + 'Content-type': ContentTypeEnum.FORM_DATA, + // @ts-ignore + ignoreCancelToken: true, + }, + } + ); +} + +export function userUpdatePassword(params: resetPasswordReq) { + return defHttp.put( + { + url: Api.UserUpdatePassword, + params, + } + ); +} + +export function resetPhoneNumber(params: resetPhoneNumberReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'notice') { + return defHttp.put( + { + url: Api.ResetPhoneNumber, + params, + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function resetEmail(params: resetEmailReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'notice') { + return defHttp.put( + { + url: Api.ResetEmail, + params, + }, + { + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} \ No newline at end of file diff --git a/src/api/warehouse/allotShipments.ts b/src/api/warehouse/allotShipments.ts new file mode 100644 index 0000000..3c4acc4 --- /dev/null +++ b/src/api/warehouse/allotShipments.ts @@ -0,0 +1,89 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + AddOrUpdateAllotShipmentsReq, + QueryAllotShipmentsReq, + AllotShipmentsResp, + AllotShipmentsDetailResp, +} from "@/api/warehouse/model/allotShipmentsModel"; + +enum API { + PageList = '/warehouse/allotShipments/pageList', + AddOrUpdateAccount = '/warehouse/allotShipments/addOrUpdate', + DeleteBatch = '/warehouse/allotShipments/deleteByIds', + UpdateStatus = '/warehouse/allotShipments/updateStatusByIds', + GetDetail = '/warehouse/allotShipments/getDetailById', + Export = '/warehouse/allotShipments/export', + ExportDetail = '/warehouse/allotShipments/exportDetail', +} + +export function getAllotShipmentsPageList(params: QueryAllotShipmentsReq) { + return defHttp.post>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdateAllotShipments(params: AddOrUpdateAllotShipmentsReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdateAccount, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function updateAllotShipmentsStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.UpdateStatus}?ids=${ids}&status=${status}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteBatchAllotShipments(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.DeleteBatch}?ids=${ids}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getAllotShipmentsDetailById(id: number) { + return defHttp.get>( + { + url: `${API.GetDetail}/${id}` + }, + ); +} + +export function exportAllotShipments(params: QueryAllotShipmentsReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} + +export function exportAllotShipmentsDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.ExportDetail}/${receiptNumber}`, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/warehouse/assemble.ts b/src/api/warehouse/assemble.ts new file mode 100644 index 0000000..93e4b7a --- /dev/null +++ b/src/api/warehouse/assemble.ts @@ -0,0 +1,89 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + AddOrUpdateAssembleReq, + QueryAssembleReq, + AssembleResp, + AssembleDetailResp, +} from "@/api/warehouse/model/assembleModel"; + +enum API { + PageList = '/warehouse/assemble/pageList', + AddOrUpdateAccount = '/warehouse/assemble/addOrUpdate', + DeleteBatch = '/warehouse/assemble/deleteByIds', + UpdateStatus = '/warehouse/assemble/updateStatusByIds', + GetDetail = '/warehouse/assemble/getDetailById', + Export = '/warehouse/assemble/export', + ExportDetail = '/warehouse/assemble/exportDetail', +} + +export function getAssemblePageList(params: QueryAssembleReq) { + return defHttp.post>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdateAssemble(params: AddOrUpdateAssembleReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdateAccount, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function updateAssembleStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.UpdateStatus}?ids=${ids}&status=${status}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteBatchAssemble(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.DeleteBatch}?ids=${ids}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getAssembleDetailById(id: number) { + return defHttp.get>( + { + url: `${API.GetDetail}/${id}` + }, + ); +} + +export function exportAssemble(params: QueryAssembleReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} + +export function exportAssembleDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.ExportDetail}/${receiptNumber}`, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/warehouse/disassemble.ts b/src/api/warehouse/disassemble.ts new file mode 100644 index 0000000..5f80ce2 --- /dev/null +++ b/src/api/warehouse/disassemble.ts @@ -0,0 +1,89 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + AddOrUpdateDisAssembleReq, + QueryDisAssembleReq, + DisAssembleResp, + DisAssembleDetailResp, ExportDisAssembleReq, +} from "@/api/warehouse/model/disassembleModel"; + +enum API { + PageList = '/warehouse/disassemble/pageList', + AddOrUpdateAccount = '/warehouse/disassemble/addOrUpdate', + DeleteBatch = '/warehouse/disassemble/deleteByIds', + UpdateStatus = '/warehouse/disassemble/updateStatusByIds', + GetDetail = '/warehouse/disassemble/getDetailById', + Export = '/warehouse/disassemble/export', + ExportDetail = '/warehouse/disassemble/exportDetail', +} + +export function getDisAssemblePageList(params: QueryDisAssembleReq) { + return defHttp.post>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdateDisAssemble(params: AddOrUpdateDisAssembleReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdateAccount, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function updateDisAssembleStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.UpdateStatus}?ids=${ids}&status=${status}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteBatchDisAssemble(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.DeleteBatch}?ids=${ids}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getDisAssembleDetailById(id: number) { + return defHttp.get>( + { + url: `${API.GetDetail}/${id}` + }, + ); +} + +export function exportDisAssemble(params: ExportDisAssembleReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} + +export function exportDisAssembleDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.ExportDetail}/${receiptNumber}`, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/warehouse/model/allotShipmentsModel.ts b/src/api/warehouse/model/allotShipmentsModel.ts new file mode 100644 index 0000000..af9768b --- /dev/null +++ b/src/api/warehouse/model/allotShipmentsModel.ts @@ -0,0 +1,60 @@ +import {FileData} from "@/api/financial/model/advanceModel"; + +export interface AllotShipmentsData { + id: number | string; + warehouseId: number | string; + warehouseName: string; + otherWarehouseId: number | string; + otherWarehouseName: string; + barCode: string; + productId: number | string; + productName: string; + productModel: string; + productUnit: string; + productStandard: string; + stock: number; + productNumber: number; + unitPrice: number; + amount: number; + remark: string; +} + +export interface AddOrUpdateAllotShipmentsReq { + id: number | undefined; + receiptNumber: string; + receiptDate: string; + remark: string; + status: number; + files: FileData[]; + tableData: AllotShipmentsData[]; +} + +export interface QueryAllotShipmentsReq { + receiptNumber: string; + productInfo: string; + operatorId: number; + otherReceipt: string; + status: number; + remark: string; +} + +export interface AllotShipmentsResp { + id: string | undefined; + receiptNumber: string; + productInfo: string; + receiptDate: string; + operator: string; + productNumber: number; + totalAmount: number; + status: number; +} + +export interface AllotShipmentsDetailResp { + id: string | undefined; + receiptNumber: string; + receiptDate: string; + remark: string; + status: number; + files: FileData[]; + tableData: AllotShipmentsData[]; +} \ No newline at end of file diff --git a/src/api/warehouse/model/assembleModel.ts b/src/api/warehouse/model/assembleModel.ts new file mode 100644 index 0000000..c951621 --- /dev/null +++ b/src/api/warehouse/model/assembleModel.ts @@ -0,0 +1,60 @@ +import {FileData} from "@/api/financial/model/advanceModel"; + +export interface AssembleStockData { + id: number | string; + type: string; + warehouseId: number | string; + warehouseName: string; + barCode: string; + productId: number | string; + productName: string; + productModel: string; + productUnit: string; + productStandard: string; + stock: number; + productNumber: number; + unitPrice: number; + amount: number; + remark: string; +} + +export interface AddOrUpdateAssembleReq { + id: number | undefined; + receiptNumber: string; + receiptDate: string; + remark: string; + status: number; + files: FileData[]; + tableData: AssembleStockData[]; +} + +export interface QueryAssembleReq { + receiptNumber: string; + productInfo: string; + operatorId: number; + warehouseId: number; + otherReceipt: string; + status: number; + remark: string; +} + +export interface AssembleResp { + id: string | undefined; + receiptNumber: string; + productInfo: string; + receiptDate: string; + operator: string; + productNumber: number; + totalAmount: number; + status: number; +} + +export interface AssembleDetailResp { + id: string | undefined; + receiptNumber: string; + receiptDate: string; + remark: string; + status: number; + files: FileData[]; + tableData: AssembleStockData[]; +} \ No newline at end of file diff --git a/src/api/warehouse/model/disassembleModel.ts b/src/api/warehouse/model/disassembleModel.ts new file mode 100644 index 0000000..ac0cfb7 --- /dev/null +++ b/src/api/warehouse/model/disassembleModel.ts @@ -0,0 +1,71 @@ +import {FileData} from "@/api/financial/model/advanceModel"; + +export interface DisAssembleStockData { + id: number | string; + type: string; + warehouseId: number | string; + warehouseName: string; + barCode: string; + productId: number | string; + productName: string; + productModel: string; + productUnit: string; + productStandard: string; + stock: number; + productNumber: number; + unitPrice: number; + amount: number; + remark: string; +} + +export interface AddOrUpdateDisAssembleReq { + id: number | undefined; + receiptNumber: string; + receiptDate: string; + remark: string; + status: number; + files: FileData[]; + tableData: DisAssembleStockData[]; +} + +export interface QueryDisAssembleReq { + receiptNumber: string; + productInfo: string; + operatorId: number; + warehouseId: number; + otherReceipt: string; + status: number; + remark: string; +} + +export interface ExportDisAssembleReq { + receiptNumber: string; + productInfo: string; + operatorId: number; + warehouseId: number; + otherReceipt: string; + status: number; + remark: string; + isExportDetail: boolean; +} + +export interface DisAssembleResp { + id: string | undefined; + receiptNumber: string; + productInfo: string; + receiptDate: string; + operator: string; + productNumber: number; + totalAmount: number; + status: number; +} + +export interface DisAssembleDetailResp { + id: string | undefined; + receiptNumber: string; + receiptDate: string; + remark: string; + status: number; + files: FileData[]; + tableData: DisAssembleStockData[]; +} \ No newline at end of file diff --git a/src/api/warehouse/model/shipmentsModel.ts b/src/api/warehouse/model/shipmentsModel.ts new file mode 100644 index 0000000..db33aa9 --- /dev/null +++ b/src/api/warehouse/model/shipmentsModel.ts @@ -0,0 +1,65 @@ +import {FileData} from "@/api/financial/model/advanceModel"; + +export interface OtherShipmentsData { + id: number | string; + warehouseId: number | string; + customerId: number | string; + warehouseName: string; + barCode: string; + productId: number | string; + productName: string; + productModel: string; + productUnit: string; + productStandard: string; + stock: number; + productNumber: number; + unitPrice: number; + amount: number; + remark: string; +} + +export interface AddOrUpdateOtherShipmentsReq { + id: number | undefined; + customerId: number; + receiptNumber: string; + receiptDate: string; + remark: string; + status: number; + files: FileData[]; + tableData: OtherShipmentsData[]; +} + +export interface QueryOtherShipmentsReq { + receiptNumber: string; + productInfo: string; + customerId: number; + warehouseId: number; + operatorId: number; + otherReceipt: string; + status: number; + remark: string; +} + +export interface OtherShipmentsResp { + id: string | undefined; + customerName: string; + receiptNumber: string; + productInfo: string; + receiptDate: string; + operator: string; + productNumber: number; + totalAmount: number; + status: number; +} + +export interface OtherShipmentsDetailResp { + id: string | undefined; + customerId: string; + customerName: string; + receiptNumber: string; + receiptDate: string; + remark: string; + status: number; + files: FileData[]; + tableData: OtherShipmentsData[]; +} \ No newline at end of file diff --git a/src/api/warehouse/model/storageModel.ts b/src/api/warehouse/model/storageModel.ts new file mode 100644 index 0000000..165d43e --- /dev/null +++ b/src/api/warehouse/model/storageModel.ts @@ -0,0 +1,64 @@ +import {FileData} from "@/api/financial/model/advanceModel"; + +export interface OtherStorageData { + id: number | string; + warehouseId: number | string; + warehouseName: string; + barCode: string; + productId: number | string; + productName: string; + productModel: string; + productUnit: string; + productStandard: string; + stock: number; + productNumber: number; + unitPrice: number; + amount: number; + remark: string; +} + +export interface AddOrUpdateOtherStorageReq { + id: number | undefined; + supplierId: number; + receiptNumber: string; + receiptDate: string; + remark: string; + status: number; + files: FileData[]; + tableData: OtherStorageData[]; +} + +export interface QueryOtherStorageReq { + receiptNumber: string; + productInfo: string; + supplierId: number; + warehouseId: number; + operatorId: number; + otherReceipt: string; + status: number; + remark: string; +} + +export interface OtherStorageResp { + id: string | undefined; + supplierName: string; + receiptNumber: string; + productInfo: string; + receiptDate: string; + operator: string; + productNumber: number; + totalAmount: number; + status: number; +} + +export interface OtherStorageDetailResp { + id: string | undefined; + supplierId: string; + supplierName: string; + receiptNumber: string; + receiptDate: string; + remark: string; + status: number; + files: FileData[]; + tableData: OtherStorageData[]; +} \ No newline at end of file diff --git a/src/api/warehouse/shipments.ts b/src/api/warehouse/shipments.ts new file mode 100644 index 0000000..83188df --- /dev/null +++ b/src/api/warehouse/shipments.ts @@ -0,0 +1,89 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + AddOrUpdateOtherShipmentsReq, + QueryOtherShipmentsReq, + OtherShipmentsResp, + OtherShipmentsDetailResp, +} from "@/api/warehouse/model/shipmentsModel"; + +enum API { + PageList = '/warehouse/otherShipments/pageList', + AddOrUpdateAccount = '/warehouse/otherShipments/addOrUpdate', + DeleteBatch = '/warehouse/otherShipments/deleteByIds', + UpdateStatus = '/warehouse/otherShipments/updateStatusByIds', + GetDetail = '/warehouse/otherShipments/getDetailById', + Export = '/warehouse/otherShipments/export', + ExportDetail = '/warehouse/otherShipments/exportDetail', +} + +export function getOtherShipmentsPageList(params: QueryOtherShipmentsReq) { + return defHttp.post>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdateOtherShipments(params: AddOrUpdateOtherShipmentsReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdateAccount, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function updateOtherShipmentsStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.UpdateStatus}?ids=${ids}&status=${status}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteBatchOtherShipments(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.DeleteBatch}?ids=${ids}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getOtherShipmentsDetailById(id: number) { + return defHttp.get>( + { + url: `${API.GetDetail}/${id}` + }, + ); +} + +export function exportOtherShipments(params: QueryOtherShipmentsReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} + +export function exportOtherShipmentsDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.ExportDetail}/${receiptNumber}`, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/api/warehouse/storage.ts b/src/api/warehouse/storage.ts new file mode 100644 index 0000000..1ef9dea --- /dev/null +++ b/src/api/warehouse/storage.ts @@ -0,0 +1,89 @@ +import {defHttp} from '/@/utils/http/axios'; +import {ErrorMessageMode, SuccessMessageMode} from '/#/axios'; +import {BaseDataResp, BaseResp} from "@/api/model/baseModel"; +import { + AddOrUpdateOtherStorageReq, + QueryOtherStorageReq, + OtherStorageResp, + OtherStorageDetailResp, +} from "@/api/warehouse/model/storageModel"; + +enum API { + PageList = '/warehouse/otherStorage/pageList', + AddOrUpdateAccount = '/warehouse/otherStorage/addOrUpdate', + DeleteBatch = '/warehouse/otherStorage/deleteByIds', + UpdateStatus = '/warehouse/otherStorage/updateStatusByIds', + GetDetail = '/warehouse/otherStorage/getDetailById', + Export = '/warehouse/otherStorage/export', + ExportDetail = '/warehouse/otherStorage/exportDetail', +} + +export function getOtherStoragePageList(params: QueryOtherStorageReq) { + return defHttp.post>( + { + url: API.PageList, + params, + } + ); +} + +export function addOrUpdateOtherStorage(params: AddOrUpdateOtherStorageReq, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.post( + { + url: API.AddOrUpdateAccount, + params, + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function updateOtherStorageStatus(ids: number[], status: number, successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.UpdateStatus}?ids=${ids}&status=${status}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function deleteBatchOtherStorage(ids: number[], successMode: SuccessMessageMode = 'notice', errorMode: ErrorMessageMode = 'message') { + return defHttp.put( + { + url: `${API.DeleteBatch}?ids=${ids}` + },{ + successMessageMode: successMode, + errorMessageMode: errorMode, + } + ); +} + +export function getOtherStorageDetailById(id: number) { + return defHttp.get>( + { + url: `${API.GetDetail}/${id}` + }, + ); +} + +export function exportOtherStorage(params: QueryOtherStorageReq) { + return defHttp.get>( + { + url: `${API.Export}`, + params, + responseType: "blob" + } + ); +} + +export function exportOtherStorageDetail(receiptNumber: string) { + return defHttp.get>( + { + url: `${API.ExportDetail}/${receiptNumber}`, + responseType: "blob" + } + ); +} \ No newline at end of file diff --git a/src/assets/.DS_Store b/src/assets/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..0d57b3ff43b68ba19b2db2f0747fb23eb2ec915f GIT binary patch literal 6148 zcmeHKOHRW;47Jk+6~UrQ*v%2>4MG)`tjYnPEou=BsZ_x_H-SsA-~g<+4hP_QY!#+$ z#10U$CC{7q6Hi`7afXO^ct0Hw^@*ql70mWA>=5ybZb@dALm_m`c&r{1bA%kiQf!zvr%?e_8YbTeZ5O~i8kWrt)>NT)s2ujqX{l{_Emh5%)XRd@b8!Zo z0cYU17(mY!=^ZHg=nOam&cK=h`91`wU}4xO#!m-^cmx1;VUB{ioFybD7#4<&B0Lb* zRG_A^9WhwbVGkBp7&eNUPHcw{w#sZL6pqz#{}9883q>ED0cRj(pre<4>HlZ#=l?Xx zubcsA;9oJo-Eve8@krKNw;oPAsset 91 \ No newline at end of file diff --git a/src/assets/icons/dynamic-avatar-1.svg b/src/assets/icons/dynamic-avatar-1.svg new file mode 100644 index 0000000..e1553e5 --- /dev/null +++ b/src/assets/icons/dynamic-avatar-1.svg @@ -0,0 +1 @@ +Asset 15 \ No newline at end of file diff --git a/src/assets/icons/dynamic-avatar-2.svg b/src/assets/icons/dynamic-avatar-2.svg new file mode 100644 index 0000000..c4c1722 --- /dev/null +++ b/src/assets/icons/dynamic-avatar-2.svg @@ -0,0 +1 @@ +Asset 16 \ No newline at end of file diff --git a/src/assets/icons/dynamic-avatar-3.svg b/src/assets/icons/dynamic-avatar-3.svg new file mode 100644 index 0000000..81145f9 --- /dev/null +++ b/src/assets/icons/dynamic-avatar-3.svg @@ -0,0 +1 @@ +Asset 17 \ No newline at end of file diff --git a/src/assets/icons/dynamic-avatar-4.svg b/src/assets/icons/dynamic-avatar-4.svg new file mode 100644 index 0000000..e586ed4 --- /dev/null +++ b/src/assets/icons/dynamic-avatar-4.svg @@ -0,0 +1 @@ +Asset 120 \ No newline at end of file diff --git a/src/assets/icons/dynamic-avatar-5.svg b/src/assets/icons/dynamic-avatar-5.svg new file mode 100644 index 0000000..746e4b8 --- /dev/null +++ b/src/assets/icons/dynamic-avatar-5.svg @@ -0,0 +1 @@ +Asset 110 \ No newline at end of file diff --git a/src/assets/icons/dynamic-avatar-6.svg b/src/assets/icons/dynamic-avatar-6.svg new file mode 100644 index 0000000..b2432f2 --- /dev/null +++ b/src/assets/icons/dynamic-avatar-6.svg @@ -0,0 +1 @@ +Asset 100 \ No newline at end of file diff --git a/src/assets/icons/moon.svg b/src/assets/icons/moon.svg new file mode 100644 index 0000000..e6667f0 --- /dev/null +++ b/src/assets/icons/moon.svg @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/src/assets/icons/sun.svg b/src/assets/icons/sun.svg new file mode 100644 index 0000000..a3997cb --- /dev/null +++ b/src/assets/icons/sun.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/icons/test.svg b/src/assets/icons/test.svg new file mode 100644 index 0000000..244252d --- /dev/null +++ b/src/assets/icons/test.svg @@ -0,0 +1,21 @@ + + + + Icon1@3x + Created with Sketch. + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/icons/total-sales.svg b/src/assets/icons/total-sales.svg new file mode 100644 index 0000000..eff7964 --- /dev/null +++ b/src/assets/icons/total-sales.svg @@ -0,0 +1 @@ +Asset 500 \ No newline at end of file diff --git a/src/assets/icons/transaction.svg b/src/assets/icons/transaction.svg new file mode 100644 index 0000000..7ba9e2f --- /dev/null +++ b/src/assets/icons/transaction.svg @@ -0,0 +1 @@ +Asset 480% \ No newline at end of file diff --git a/src/assets/icons/visit-count.svg b/src/assets/icons/visit-count.svg new file mode 100644 index 0000000..ba2a306 --- /dev/null +++ b/src/assets/icons/visit-count.svg @@ -0,0 +1 @@ +Asset 510 \ No newline at end of file diff --git a/src/assets/images/demo.png b/src/assets/images/demo.png new file mode 100644 index 0000000000000000000000000000000000000000..1a45c9835b7b2c708c114b04fb445e6ef00d8827 GIT binary patch literal 33342 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 literal 0 HcmV?d00001 diff --git a/src/assets/images/login-page-bg-2.png b/src/assets/images/login-page-bg-2.png new file mode 100644 index 0000000000000000000000000000000000000000..dd4b4c9e56a587e7c30b088519ebc294d30556ce GIT binary patch literal 253341 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 literal 0 HcmV?d00001 diff --git a/src/assets/images/logo.png b/src/assets/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..c04e95efb7b01555c2c79e5cad114013a9ea5bd5 GIT binary patch literal 16025 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 literal 0 HcmV?d00001 diff --git a/src/assets/svg/illustration.svg b/src/assets/svg/illustration.svg new file mode 100644 index 0000000..b45215b --- /dev/null +++ b/src/assets/svg/illustration.svg @@ -0,0 +1 @@ +Asset 336 \ No newline at end of file diff --git a/src/assets/svg/login-bg-dark.svg b/src/assets/svg/login-bg-dark.svg new file mode 100644 index 0000000..888da7a --- /dev/null +++ b/src/assets/svg/login-bg-dark.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/svg/login-bg.svg b/src/assets/svg/login-bg.svg new file mode 100644 index 0000000..7b66baf --- /dev/null +++ b/src/assets/svg/login-bg.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/src/assets/svg/login-box-bg.svg b/src/assets/svg/login-box-bg.svg new file mode 100644 index 0000000..ee7dbdc --- /dev/null +++ b/src/assets/svg/login-box-bg.svg @@ -0,0 +1 @@ +responsive \ No newline at end of file diff --git a/src/assets/svg/net-error.svg b/src/assets/svg/net-error.svg new file mode 100644 index 0000000..81f2004 --- /dev/null +++ b/src/assets/svg/net-error.svg @@ -0,0 +1 @@ +personal settings \ No newline at end of file diff --git a/src/assets/svg/no-data.svg b/src/assets/svg/no-data.svg new file mode 100644 index 0000000..2b9f257 --- /dev/null +++ b/src/assets/svg/no-data.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svg/preview/p-rotate.svg b/src/assets/svg/preview/p-rotate.svg new file mode 100644 index 0000000..5153a81 --- /dev/null +++ b/src/assets/svg/preview/p-rotate.svg @@ -0,0 +1 @@ + diff --git a/src/assets/svg/preview/resume.svg b/src/assets/svg/preview/resume.svg new file mode 100644 index 0000000..0e86c5f --- /dev/null +++ b/src/assets/svg/preview/resume.svg @@ -0,0 +1 @@ + diff --git a/src/assets/svg/preview/scale.svg b/src/assets/svg/preview/scale.svg new file mode 100644 index 0000000..1f7adae --- /dev/null +++ b/src/assets/svg/preview/scale.svg @@ -0,0 +1 @@ + diff --git a/src/assets/svg/preview/unrotate.svg b/src/assets/svg/preview/unrotate.svg new file mode 100644 index 0000000..e4708be --- /dev/null +++ b/src/assets/svg/preview/unrotate.svg @@ -0,0 +1 @@ + diff --git a/src/assets/svg/preview/unscale.svg b/src/assets/svg/preview/unscale.svg new file mode 100644 index 0000000..1359b34 --- /dev/null +++ b/src/assets/svg/preview/unscale.svg @@ -0,0 +1 @@ + diff --git a/src/components/.DS_Store b/src/components/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..f296e5b4d931db4533bb6b690232b18e81f0f438 GIT binary patch literal 14340 zcmeHNzi$*r6n=Z0jp1-Gsh|Ka1$9gl0TSYDE=Y)=7}=yjim>la#^Qch=d(ac<0?%k zXrh!c;vb-*NrR9m5DotT5={yUL`$mVdo%0Jyq$R`rHJCGMZN25*A#7BQ`Ej`R-_o2 zZ;tah!%;Vjde_&!Ic2^%Wd(CqWGI&5Ib-gr|MMX-dp$1ue68# zEf3q{>M(tatbC0+$hZfz(c1_SUoORn{;;*5|A+Z|rJrDxU;;|&S!O+Tx=CFq*^x>v z{u;&<4P{$}y^KrVJ?5PP?+`AmQBN}e{76O>?x4NG9v}pNmV*G-y$tRR>Pq&LAH$f! zUA9%2%edh6U%boUdl%dyuJBhd<@!)K@&Y4uxZCjvtw6;HW6;CjI=mQ3 zC(f-xO#-E8N+OfW5=g0!ZJ?vjw@H1sHq}kvqfh_PaEiucpUM~}u|j9Iz&dB4a||E( z8QQ?nJ*Rby&lNvs|C)?eG*9SXQ9hxC(C;S%Q?!b)U&lQlpM=_-ub?-GD*6N>Io<(6 z@E>{)0z8MSZk#1M9e*Ci6z;OE;zSu2y#HMH(B1vp^1h!PfSENHQH5I|)ax$#kopMQsk6yC*+ag&E93LynJ}j4DcdR<%DCix z&%D!g+dcd4f2H(g^sX9L_(dOz27yWFn4$0KA+A6Dl+e2;&=O%3JqcX$&WUhBSM4qP zW5paW2h0I;z#K3K4vqs~LrVCodK+`Rigye7X$W4QP2QH1{Iq(G8E$G;G>sy=9l>Gjk|D+=oeM-NIZwgxKbSwv(m8>V zI`%+=JeGCvICfHZ{p?~2qv(nHQe28~Qr80Os?#;-8Bt%{>Dlj>!kD6?Y^(5>alu=A z;dzU7e8EfO&yKfzzpfRn&nsG@yk5~1;iR^=tj&r!U=ElA=72e14jc>zro4;=e*f +

    + + + \ No newline at end of file diff --git a/src/components/Application/src/AppLocalePicker.vue b/src/components/Application/src/AppLocalePicker.vue new file mode 100644 index 0000000..3e57092 --- /dev/null +++ b/src/components/Application/src/AppLocalePicker.vue @@ -0,0 +1,72 @@ + + + + diff --git a/src/components/Application/src/AppLogo.vue b/src/components/Application/src/AppLogo.vue new file mode 100644 index 0000000..306e2ba --- /dev/null +++ b/src/components/Application/src/AppLogo.vue @@ -0,0 +1,96 @@ + + + diff --git a/src/components/Application/src/AppProvider.vue b/src/components/Application/src/AppProvider.vue new file mode 100644 index 0000000..fe19a80 --- /dev/null +++ b/src/components/Application/src/AppProvider.vue @@ -0,0 +1,82 @@ + diff --git a/src/components/Application/src/search/AppSearch.vue b/src/components/Application/src/search/AppSearch.vue new file mode 100644 index 0000000..63d346e --- /dev/null +++ b/src/components/Application/src/search/AppSearch.vue @@ -0,0 +1,33 @@ + diff --git a/src/components/Application/src/search/AppSearchFooter.vue b/src/components/Application/src/search/AppSearchFooter.vue new file mode 100644 index 0000000..6c39938 --- /dev/null +++ b/src/components/Application/src/search/AppSearchFooter.vue @@ -0,0 +1,57 @@ + + + + diff --git a/src/components/Application/src/search/AppSearchKeyItem.vue b/src/components/Application/src/search/AppSearchKeyItem.vue new file mode 100644 index 0000000..08e3dbd --- /dev/null +++ b/src/components/Application/src/search/AppSearchKeyItem.vue @@ -0,0 +1,12 @@ + + diff --git a/src/components/Application/src/search/AppSearchModal.vue b/src/components/Application/src/search/AppSearchModal.vue new file mode 100644 index 0000000..612b372 --- /dev/null +++ b/src/components/Application/src/search/AppSearchModal.vue @@ -0,0 +1,267 @@ + + + + diff --git a/src/components/Application/src/search/useMenuSearch.ts b/src/components/Application/src/search/useMenuSearch.ts new file mode 100644 index 0000000..c938792 --- /dev/null +++ b/src/components/Application/src/search/useMenuSearch.ts @@ -0,0 +1,167 @@ +import { type Menu } from '/@/router/types'; +import { type AnyFunction } from '@vben/types'; +import { ref, onBeforeMount, unref, Ref, nextTick } from 'vue'; +import { getMenus } from '/@/router/menus'; +import { cloneDeep } from 'lodash-es'; +import { filter, forEach } from '/@/utils/helper/treeHelper'; +import { useGo } from '/@/hooks/web/usePage'; +import { useScrollTo } from '@vben/hooks'; +import { onKeyStroke, useDebounceFn } from '@vueuse/core'; +import { useI18n } from '/@/hooks/web/useI18n'; + +export interface SearchResult { + name: string; + path: string; + icon?: string; +} + +// Translate special characters +function transform(c: string) { + const code: string[] = ['$', '(', ')', '*', '+', '.', '[', ']', '?', '\\', '^', '{', '}', '|']; + return code.includes(c) ? `\\${c}` : c; +} + +function createSearchReg(key: string) { + const keys = [...key].map((item) => transform(item)); + const str = ['', ...keys, ''].join('.*'); + return new RegExp(str); +} + +export function useMenuSearch(refs: Ref, scrollWrap: Ref, emit: AnyFunction) { + const searchResult = ref([]); + const keyword = ref(''); + const activeIndex = ref(-1); + + let menuList: Menu[] = []; + + const { t } = useI18n(); + const go = useGo(); + const handleSearch = useDebounceFn(search, 200); + + onBeforeMount(async () => { + const list = await getMenus(); + menuList = cloneDeep(list); + forEach(menuList, (item) => { + item.name = t(item.name); + }); + }); + + function search(e: ChangeEvent) { + e?.stopPropagation(); + const key = e.target.value; + keyword.value = key.trim(); + if (!key) { + searchResult.value = []; + return; + } + const reg = createSearchReg(unref(keyword)); + const filterMenu = filter(menuList, (item) => { + return reg.test(item.name) && !item.hideMenu; + }); + searchResult.value = handlerSearchResult(filterMenu, reg); + activeIndex.value = 0; + } + + function handlerSearchResult(filterMenu: Menu[], reg: RegExp, parent?: Menu) { + const ret: SearchResult[] = []; + filterMenu.forEach((item) => { + const { name, path, icon, children, hideMenu, meta } = item; + if (!hideMenu && reg.test(name) && (!children?.length || meta?.hideChildrenInMenu)) { + ret.push({ + name: parent?.name ? `${parent.name} > ${name}` : name, + path, + icon, + }); + } + if (!meta?.hideChildrenInMenu && Array.isArray(children) && children.length) { + ret.push(...handlerSearchResult(children, reg, item)); + } + }); + return ret; + } + + // Activate when the mouse moves to a certain line + function handleMouseenter(e: any) { + const index = e.target.dataset.index; + activeIndex.value = Number(index); + } + + // Arrow key up + function handleUp() { + if (!searchResult.value.length) return; + activeIndex.value--; + if (activeIndex.value < 0) { + activeIndex.value = searchResult.value.length - 1; + } + handleScroll(); + } + + // Arrow key down + function handleDown() { + if (!searchResult.value.length) return; + activeIndex.value++; + if (activeIndex.value > searchResult.value.length - 1) { + activeIndex.value = 0; + } + handleScroll(); + } + + // When the keyboard up and down keys move to an invisible place + // the scroll bar needs to scroll automatically + function handleScroll() { + const refList = unref(refs); + if (!refList || !Array.isArray(refList) || refList.length === 0 || !unref(scrollWrap)) { + return; + } + + const index = unref(activeIndex); + const currentRef = refList[index]; + if (!currentRef) { + return; + } + const wrapEl = unref(scrollWrap); + if (!wrapEl) { + return; + } + const scrollHeight = currentRef.offsetTop + currentRef.offsetHeight; + const wrapHeight = wrapEl.offsetHeight; + const { start } = useScrollTo({ + el: wrapEl, + duration: 100, + to: scrollHeight - wrapHeight, + }); + start(); + } + + // enter keyboard event + async function handleEnter() { + if (!searchResult.value.length) { + return; + } + const result = unref(searchResult); + const index = unref(activeIndex); + if (result.length === 0 || index < 0) { + return; + } + const to = result[index]; + handleClose(); + await nextTick(); + go(to.path); + } + + // close search modal + function handleClose() { + searchResult.value = []; + emit('close'); + } + + // enter search + onKeyStroke('Enter', handleEnter); + // Monitor keyboard arrow keys + onKeyStroke('ArrowUp', handleUp); + onKeyStroke('ArrowDown', handleDown); + // esc close + onKeyStroke('Escape', handleClose); + + return { handleSearch, searchResult, keyword, activeIndex, handleMouseenter, handleEnter }; +} diff --git a/src/components/Application/src/useAppContext.ts b/src/components/Application/src/useAppContext.ts new file mode 100644 index 0000000..8bdfb4f --- /dev/null +++ b/src/components/Application/src/useAppContext.ts @@ -0,0 +1,17 @@ +import { InjectionKey, Ref } from 'vue'; +import { createContext, useContext } from '/@/hooks/core/useContext'; + +export interface AppProviderContextProps { + prefixCls: Ref; + isMobile: Ref; +} + +const key: InjectionKey = Symbol(); + +export function createAppProviderContext(context: AppProviderContextProps) { + return createContext(context, key); +} + +export function useAppProviderContext() { + return useContext(key); +} diff --git a/src/components/Basic/index.ts b/src/components/Basic/index.ts new file mode 100644 index 0000000..97a53a1 --- /dev/null +++ b/src/components/Basic/index.ts @@ -0,0 +1,8 @@ +import { withInstall } from '/@/utils'; +import basicArrow from './src/BasicArrow.vue'; +import basicTitle from './src/BasicTitle.vue'; +import basicHelp from './src/BasicHelp.vue'; + +export const BasicArrow = withInstall(basicArrow); +export const BasicTitle = withInstall(basicTitle); +export const BasicHelp = withInstall(basicHelp); diff --git a/src/components/Basic/src/BasicArrow.vue b/src/components/Basic/src/BasicArrow.vue new file mode 100644 index 0000000..2de3a44 --- /dev/null +++ b/src/components/Basic/src/BasicArrow.vue @@ -0,0 +1,80 @@ + + + diff --git a/src/components/Basic/src/BasicHelp.vue b/src/components/Basic/src/BasicHelp.vue new file mode 100644 index 0000000..3b7dd4c --- /dev/null +++ b/src/components/Basic/src/BasicHelp.vue @@ -0,0 +1,114 @@ + + diff --git a/src/components/Basic/src/BasicTitle.vue b/src/components/Basic/src/BasicTitle.vue new file mode 100644 index 0000000..8ad399f --- /dev/null +++ b/src/components/Basic/src/BasicTitle.vue @@ -0,0 +1,76 @@ + + + diff --git a/src/components/Button/index.ts b/src/components/Button/index.ts new file mode 100644 index 0000000..98add5c --- /dev/null +++ b/src/components/Button/index.ts @@ -0,0 +1,9 @@ +import { withInstall } from '/@/utils'; +import type { ExtractPropTypes } from 'vue'; +import button from './src/BasicButton.vue'; +import popConfirmButton from './src/PopConfirmButton.vue'; +import { buttonProps } from './src/props'; + +export const Button = withInstall(button); +export const PopConfirmButton = withInstall(popConfirmButton); +export declare type ButtonProps = Partial>; diff --git a/src/components/Button/src/BasicButton.vue b/src/components/Button/src/BasicButton.vue new file mode 100644 index 0000000..19e6dbb --- /dev/null +++ b/src/components/Button/src/BasicButton.vue @@ -0,0 +1,39 @@ + + + diff --git a/src/components/Button/src/PopConfirmButton.vue b/src/components/Button/src/PopConfirmButton.vue new file mode 100644 index 0000000..4c90ace --- /dev/null +++ b/src/components/Button/src/PopConfirmButton.vue @@ -0,0 +1,54 @@ + diff --git a/src/components/Button/src/props.ts b/src/components/Button/src/props.ts new file mode 100644 index 0000000..fd5fa52 --- /dev/null +++ b/src/components/Button/src/props.ts @@ -0,0 +1,26 @@ +const validColors = ['primary', 'error', 'warning', 'success', ''] as const; +type ButtonColorType = (typeof validColors)[number]; + +export const buttonProps = { + color: { + type: String as PropType, + validator: (v) => validColors.includes(v), + default: '', + }, + loading: { type: Boolean }, + disabled: { type: Boolean }, + /** + * Text before icon. + */ + preIcon: { type: String }, + /** + * Text after icon. + */ + postIcon: { type: String }, + /** + * preIcon and postIcon icon size. + * @default: 14 + */ + iconSize: { type: Number, default: 14 }, + onClick: { type: [Function, Array] as PropType<(() => any) | (() => any)[]>, default: null }, +}; diff --git a/src/components/ClickOutSide/index.ts b/src/components/ClickOutSide/index.ts new file mode 100644 index 0000000..5e7dd2d --- /dev/null +++ b/src/components/ClickOutSide/index.ts @@ -0,0 +1,4 @@ +import { withInstall } from '/@/utils'; +import clickOutSide from './src/ClickOutSide.vue'; + +export const ClickOutSide = withInstall(clickOutSide); diff --git a/src/components/ClickOutSide/src/ClickOutSide.vue b/src/components/ClickOutSide/src/ClickOutSide.vue new file mode 100644 index 0000000..901a508 --- /dev/null +++ b/src/components/ClickOutSide/src/ClickOutSide.vue @@ -0,0 +1,20 @@ + + diff --git a/src/components/Container/index.ts b/src/components/Container/index.ts new file mode 100644 index 0000000..502a0dd --- /dev/null +++ b/src/components/Container/index.ts @@ -0,0 +1,8 @@ +import { withInstall } from '/@/utils'; +import collapseContainer from './src/collapse/CollapseContainer.vue'; +import scrollContainer from './src/ScrollContainer.vue'; + +export const CollapseContainer = withInstall(collapseContainer); +export const ScrollContainer = withInstall(scrollContainer); + +export * from './src/typing'; diff --git a/src/components/Container/src/ScrollContainer.vue b/src/components/Container/src/ScrollContainer.vue new file mode 100644 index 0000000..ca19003 --- /dev/null +++ b/src/components/Container/src/ScrollContainer.vue @@ -0,0 +1,94 @@ + + + + diff --git a/src/components/Container/src/collapse/CollapseContainer.vue b/src/components/Container/src/collapse/CollapseContainer.vue new file mode 100644 index 0000000..c9128b0 --- /dev/null +++ b/src/components/Container/src/collapse/CollapseContainer.vue @@ -0,0 +1,118 @@ + + + diff --git a/src/components/Container/src/collapse/CollapseHeader.vue b/src/components/Container/src/collapse/CollapseHeader.vue new file mode 100644 index 0000000..8b80cf8 --- /dev/null +++ b/src/components/Container/src/collapse/CollapseHeader.vue @@ -0,0 +1,44 @@ + diff --git a/src/components/Container/src/typing.ts b/src/components/Container/src/typing.ts new file mode 100644 index 0000000..86c03be --- /dev/null +++ b/src/components/Container/src/typing.ts @@ -0,0 +1,17 @@ +export type ScrollType = 'default' | 'main'; + +export interface CollapseContainerOptions { + canExpand?: boolean; + title?: string; + helpMessage?: Array | string; +} +export interface ScrollContainerOptions { + enableScroll?: boolean; + type?: ScrollType; +} + +export type ScrollActionType = RefType<{ + scrollBottom: () => void; + getScrollWrap: () => Nullable; + scrollTo: (top: number) => void; +}>; diff --git a/src/components/ContextMenu/index.ts b/src/components/ContextMenu/index.ts new file mode 100644 index 0000000..ed294d7 --- /dev/null +++ b/src/components/ContextMenu/index.ts @@ -0,0 +1,3 @@ +export { createContextMenu, destroyContextMenu } from './src/createContextMenu'; + +export * from './src/typing'; diff --git a/src/components/ContextMenu/src/ContextMenu.vue b/src/components/ContextMenu/src/ContextMenu.vue new file mode 100644 index 0000000..823b90e --- /dev/null +++ b/src/components/ContextMenu/src/ContextMenu.vue @@ -0,0 +1,209 @@ + + diff --git a/src/components/ContextMenu/src/createContextMenu.ts b/src/components/ContextMenu/src/createContextMenu.ts new file mode 100644 index 0000000..0d93290 --- /dev/null +++ b/src/components/ContextMenu/src/createContextMenu.ts @@ -0,0 +1,77 @@ +import contextMenuVue from './ContextMenu.vue'; +import { isClient } from '/@/utils/is'; +import { CreateContextOptions, ContextMenuProps } from './typing'; +import { createVNode, render } from 'vue'; + +const menuManager: { + domList: Element[]; + resolve: Fn; +} = { + domList: [], + resolve: () => {}, +}; + +export const createContextMenu = function (options: CreateContextOptions) { + const { event } = options || {}; + + event && event?.preventDefault(); + + if (!isClient) { + return; + } + return new Promise((resolve) => { + const body = document.body; + + const container = document.createElement('div'); + const propsData: Partial = {}; + if (options.styles) { + propsData.styles = options.styles; + } + + if (options.items) { + propsData.items = options.items; + } + + if (options.event) { + propsData.customEvent = event; + propsData.axis = { x: event.clientX, y: event.clientY }; + } + + const vm = createVNode(contextMenuVue, propsData); + render(vm, container); + + const handleClick = function () { + menuManager.resolve(''); + }; + + menuManager.domList.push(container); + + const remove = function () { + menuManager.domList.forEach((dom: Element) => { + try { + dom && body.removeChild(dom); + } catch (error) { + // + } + }); + body.removeEventListener('click', handleClick); + body.removeEventListener('scroll', handleClick); + }; + + menuManager.resolve = function (arg) { + remove(); + resolve(arg); + }; + remove(); + body.appendChild(container); + body.addEventListener('click', handleClick); + body.addEventListener('scroll', handleClick); + }); +}; + +export const destroyContextMenu = function () { + if (menuManager) { + menuManager.resolve(''); + menuManager.domList = []; + } +}; diff --git a/src/components/ContextMenu/src/typing.ts b/src/components/ContextMenu/src/typing.ts new file mode 100644 index 0000000..63d3d37 --- /dev/null +++ b/src/components/ContextMenu/src/typing.ts @@ -0,0 +1,36 @@ +export interface Axis { + x: number; + y: number; +} + +export interface ContextMenuItem { + label: string; + icon?: string; + hidden?: boolean; + disabled?: boolean; + handler?: Fn; + divider?: boolean; + children?: ContextMenuItem[]; +} +export interface CreateContextOptions { + event: MouseEvent; + icon?: string; + styles?: any; + items?: ContextMenuItem[]; +} + +export interface ContextMenuProps { + event?: MouseEvent; + styles?: any; + items: ContextMenuItem[]; + customEvent?: MouseEvent; + axis?: Axis; + width?: number; + showIcon?: boolean; +} + +export interface ItemContentProps { + showIcon: boolean | undefined; + item: ContextMenuItem; + handler: Fn; +} diff --git a/src/components/CountDown/index.ts b/src/components/CountDown/index.ts new file mode 100644 index 0000000..9809416 --- /dev/null +++ b/src/components/CountDown/index.ts @@ -0,0 +1,6 @@ +import { withInstall } from '/@/utils'; +import countButton from './src/CountButton.vue'; +import countdownInput from './src/CountdownInput.vue'; + +export const CountdownInput = withInstall(countdownInput); +export const CountButton = withInstall(countButton); diff --git a/src/components/CountDown/src/CountButton.vue b/src/components/CountDown/src/CountButton.vue new file mode 100644 index 0000000..1ef520e --- /dev/null +++ b/src/components/CountDown/src/CountButton.vue @@ -0,0 +1,62 @@ + + diff --git a/src/components/CountDown/src/CountdownInput.vue b/src/components/CountDown/src/CountdownInput.vue new file mode 100644 index 0000000..5cd939d --- /dev/null +++ b/src/components/CountDown/src/CountdownInput.vue @@ -0,0 +1,54 @@ + + + diff --git a/src/components/CountDown/src/useCountdown.ts b/src/components/CountDown/src/useCountdown.ts new file mode 100644 index 0000000..316d69a --- /dev/null +++ b/src/components/CountDown/src/useCountdown.ts @@ -0,0 +1,51 @@ +import { ref, unref } from 'vue'; +import { tryOnUnmounted } from '@vueuse/core'; + +export function useCountdown(count: number) { + const currentCount = ref(count); + + const isStart = ref(false); + + let timerId: ReturnType | null; + + function clear() { + timerId && window.clearInterval(timerId); + } + + function stop() { + isStart.value = false; + clear(); + timerId = null; + } + + function start() { + if (unref(isStart) || !!timerId) { + return; + } + isStart.value = true; + timerId = setInterval(() => { + if (unref(currentCount) === 1) { + stop(); + currentCount.value = count; + } else { + currentCount.value -= 1; + } + }, 1000); + } + + function reset() { + currentCount.value = count; + stop(); + } + + function restart() { + reset(); + start(); + } + + tryOnUnmounted(() => { + reset(); + }); + + return { start, reset, restart, clear, stop, currentCount, isStart }; +} diff --git a/src/components/CountTo/index.ts b/src/components/CountTo/index.ts new file mode 100644 index 0000000..36a4e65 --- /dev/null +++ b/src/components/CountTo/index.ts @@ -0,0 +1,4 @@ +import { withInstall } from '/@/utils'; +import countTo from './src/CountTo.vue'; + +export const CountTo = withInstall(countTo); diff --git a/src/components/CountTo/src/CountTo.vue b/src/components/CountTo/src/CountTo.vue new file mode 100644 index 0000000..7de3361 --- /dev/null +++ b/src/components/CountTo/src/CountTo.vue @@ -0,0 +1,110 @@ + + diff --git a/src/components/Cropper/index.ts b/src/components/Cropper/index.ts new file mode 100644 index 0000000..88d6d1d --- /dev/null +++ b/src/components/Cropper/index.ts @@ -0,0 +1,7 @@ +import { withInstall } from '/@/utils'; +import cropperImage from './src/Cropper.vue'; +import avatarCropper from './src/CropperAvatar.vue'; + +export * from './src/typing'; +export const CropperImage = withInstall(cropperImage); +export const CropperAvatar = withInstall(avatarCropper); diff --git a/src/components/Cropper/src/Cropper.vue b/src/components/Cropper/src/Cropper.vue new file mode 100644 index 0000000..4523ad4 --- /dev/null +++ b/src/components/Cropper/src/Cropper.vue @@ -0,0 +1,188 @@ + + + diff --git a/src/components/Cropper/src/CropperAvatar.vue b/src/components/Cropper/src/CropperAvatar.vue new file mode 100644 index 0000000..ee15757 --- /dev/null +++ b/src/components/Cropper/src/CropperAvatar.vue @@ -0,0 +1,166 @@ + + + + diff --git a/src/components/Cropper/src/CropperModal.vue b/src/components/Cropper/src/CropperModal.vue new file mode 100644 index 0000000..3755a03 --- /dev/null +++ b/src/components/Cropper/src/CropperModal.vue @@ -0,0 +1,295 @@ + + + + diff --git a/src/components/Cropper/src/typing.ts b/src/components/Cropper/src/typing.ts new file mode 100644 index 0000000..e76cc6f --- /dev/null +++ b/src/components/Cropper/src/typing.ts @@ -0,0 +1,8 @@ +import type Cropper from 'cropperjs'; + +export interface CropendResult { + imgBase64: string; + imgInfo: Cropper.Data; +} + +export type { Cropper }; diff --git a/src/components/Description/index.ts b/src/components/Description/index.ts new file mode 100644 index 0000000..58277d0 --- /dev/null +++ b/src/components/Description/index.ts @@ -0,0 +1,6 @@ +import { withInstall } from '/@/utils'; +import description from './src/Description.vue'; + +export * from './src/typing'; +export { useDescription } from './src/useDescription'; +export const Description = withInstall(description); diff --git a/src/components/Description/src/Description.vue b/src/components/Description/src/Description.vue new file mode 100644 index 0000000..d24b381 --- /dev/null +++ b/src/components/Description/src/Description.vue @@ -0,0 +1,195 @@ + diff --git a/src/components/Description/src/typing.ts b/src/components/Description/src/typing.ts new file mode 100644 index 0000000..ee96084 --- /dev/null +++ b/src/components/Description/src/typing.ts @@ -0,0 +1,50 @@ +import type { VNode, CSSProperties } from 'vue'; +import type { CollapseContainerOptions } from '/@/components/Container/index'; +import type { DescriptionsProps } from 'ant-design-vue/es/descriptions/index'; + +export interface DescItem { + labelMinWidth?: number; + contentMinWidth?: number; + labelStyle?: CSSProperties; + field: string; + label: string | VNode | JSX.Element; + // Merge column + span?: number; + show?: (...arg: any) => boolean; + // render + render?: ( + val: any, + data: Recordable, + ) => VNode | undefined | JSX.Element | Element | string | number; +} + +export interface DescriptionProps extends DescriptionsProps { + // Whether to include the collapse component + useCollapse?: boolean; + /** + * item configuration + * @type DescItem + */ + schema: DescItem[]; + /** + * 数据 + * @type object + */ + data: Recordable; + /** + * Built-in CollapseContainer component configuration + * @type CollapseContainerOptions + */ + collapseOptions?: CollapseContainerOptions; +} + +export interface DescInstance { + setDescProps(descProps: Partial): void; +} + +export type Register = (descInstance: DescInstance) => void; + +/** + * @description: + */ +export type UseDescReturnType = [Register, DescInstance]; diff --git a/src/components/Description/src/useDescription.ts b/src/components/Description/src/useDescription.ts new file mode 100644 index 0000000..d1037d0 --- /dev/null +++ b/src/components/Description/src/useDescription.ts @@ -0,0 +1,28 @@ +import type { DescriptionProps, DescInstance, UseDescReturnType } from './typing'; +import { ref, getCurrentInstance, unref } from 'vue'; +import { isProdMode } from '/@/utils/env'; + +export function useDescription(props?: Partial): UseDescReturnType { + if (!getCurrentInstance()) { + throw new Error('useDescription() can only be used inside setup() or functional components!'); + } + const desc = ref>(null); + const loaded = ref(false); + + function register(instance: DescInstance) { + if (unref(loaded) && isProdMode()) { + return; + } + desc.value = instance; + props && instance.setDescProps(props); + loaded.value = true; + } + + const methods: DescInstance = { + setDescProps: (descProps: Partial): void => { + unref(desc)?.setDescProps(descProps); + }, + }; + + return [register, methods]; +} diff --git a/src/components/Drawer/index.ts b/src/components/Drawer/index.ts new file mode 100644 index 0000000..820ade5 --- /dev/null +++ b/src/components/Drawer/index.ts @@ -0,0 +1,6 @@ +import { withInstall } from '/@/utils'; +import basicDrawer from './src/BasicDrawer.vue'; + +export const BasicDrawer = withInstall(basicDrawer); +export * from './src/typing'; +export { useDrawer, useDrawerInner } from './src/useDrawer'; diff --git a/src/components/Drawer/src/BasicDrawer.vue b/src/components/Drawer/src/BasicDrawer.vue new file mode 100644 index 0000000..b3fd122 --- /dev/null +++ b/src/components/Drawer/src/BasicDrawer.vue @@ -0,0 +1,256 @@ + + + diff --git a/src/components/Drawer/src/components/DrawerFooter.vue b/src/components/Drawer/src/components/DrawerFooter.vue new file mode 100644 index 0000000..507b693 --- /dev/null +++ b/src/components/Drawer/src/components/DrawerFooter.vue @@ -0,0 +1,83 @@ + + + + diff --git a/src/components/Drawer/src/components/DrawerHeader.vue b/src/components/Drawer/src/components/DrawerHeader.vue new file mode 100644 index 0000000..09a3ad0 --- /dev/null +++ b/src/components/Drawer/src/components/DrawerHeader.vue @@ -0,0 +1,75 @@ + + + + diff --git a/src/components/Drawer/src/props.ts b/src/components/Drawer/src/props.ts new file mode 100644 index 0000000..824ec67 --- /dev/null +++ b/src/components/Drawer/src/props.ts @@ -0,0 +1,45 @@ +import type { PropType } from 'vue'; + +import { useI18n } from '/@/hooks/web/useI18n'; + +const { t } = useI18n(); + +export const footerProps = { + confirmLoading: { type: Boolean }, + /** + * @description: Show close button + */ + showCancelBtn: { type: Boolean, default: true }, + cancelButtonProps: Object as PropType, + cancelText: { type: String, default: t('common.cancelText') }, + /** + * @description: Show confirmation button + */ + showOkBtn: { type: Boolean, default: true }, + okButtonProps: Object as PropType, + okText: { type: String, default: t('common.okText') }, + okType: { type: String, default: 'primary' }, + showFooter: { type: Boolean }, + footerHeight: { + type: [String, Number] as PropType, + default: 60, + }, +}; +export const basicProps = { + isDetail: { type: Boolean }, + title: { type: String, default: '' }, + loadingText: { type: String }, + showDetailBack: { type: Boolean, default: true }, + open: { type: Boolean }, + loading: { type: Boolean }, + maskClosable: { type: Boolean, default: true }, + getContainer: { + type: [Object, String] as PropType, + }, + closeFunc: { + type: [Function, Object] as PropType, + default: null, + }, + destroyOnClose: { type: Boolean }, + ...footerProps, +}; diff --git a/src/components/Drawer/src/typing.ts b/src/components/Drawer/src/typing.ts new file mode 100644 index 0000000..c8ac392 --- /dev/null +++ b/src/components/Drawer/src/typing.ts @@ -0,0 +1,194 @@ +import type { ButtonProps } from 'ant-design-vue/lib/button/buttonTypes'; +import type { CSSProperties, VNodeChild, ComputedRef } from 'vue'; +import type { ScrollContainerOptions } from '/@/components/Container/index'; + +export interface DrawerInstance { + setDrawerProps: (props: Partial | boolean) => void; + emitOpen?: (open: boolean, uid: number) => void; +} + +export interface ReturnMethods extends DrawerInstance { + openDrawer: (open?: boolean, data?: T, openOnSet?: boolean) => void; + closeDrawer: () => void; + getOpen?: ComputedRef; +} + +export type RegisterFn = (drawerInstance: DrawerInstance, uuid?: string) => void; + +export interface ReturnInnerMethods extends DrawerInstance { + closeDrawer: () => void; + changeLoading: (loading: boolean) => void; + changeOkLoading: (loading: boolean) => void; + getOpen?: ComputedRef; +} + +export type UseDrawerReturnType = [RegisterFn, ReturnMethods]; + +export type UseDrawerInnerReturnType = [RegisterFn, ReturnInnerMethods]; + +export interface DrawerFooterProps { + showOkBtn: boolean; + showCancelBtn: boolean; + /** + * Text of the Cancel button + * @default 'cancel' + * @type string + */ + cancelText: string; + /** + * Text of the OK button + * @default 'OK' + * @type string + */ + okText: string; + + /** + * Button type of the OK button + * @default 'primary' + * @type string + */ + okType: 'primary' | 'danger' | 'dashed' | 'ghost' | 'default'; + /** + * The ok button props, follow jsx rules + * @type object + */ + okButtonProps: { props: ButtonProps; on: {} }; + + /** + * The cancel button props, follow jsx rules + * @type object + */ + cancelButtonProps: { props: ButtonProps; on: {} }; + /** + * Whether to apply loading visual effect for OK button or not + * @default false + * @type boolean + */ + confirmLoading: boolean; + + showFooter: boolean; + footerHeight: string | number; +} +export interface DrawerProps extends DrawerFooterProps { + isDetail?: boolean; + loading?: boolean; + showDetailBack?: boolean; + open?: boolean; + /** + * Built-in ScrollContainer component configuration + * @type ScrollContainerOptions + */ + scrollOptions?: ScrollContainerOptions; + closeFunc?: () => Promise; + triggerWindowResize?: boolean; + /** + * Whether a close (x) button is visible on top right of the Drawer dialog or not. + * @default true + * @type boolean + */ + closable?: boolean; + + /** + * Whether to unmount child components on closing drawer or not. + * @default false + * @type boolean + */ + destroyOnClose?: boolean; + + /** + * Return the mounted node for Drawer. + * @default 'body' + * @type any ( HTMLElement| () => HTMLElement | string) + */ + getContainer?: () => HTMLElement | string; + + /** + * Whether to show mask or not. + * @default true + * @type boolean + */ + mask?: boolean; + + /** + * Clicking on the mask (area outside the Drawer) to close the Drawer or not. + * @default true + * @type boolean + */ + maskClosable?: boolean; + + /** + * Style for Drawer's mask element. + * @default {} + * @type object + */ + maskStyle?: CSSProperties; + + /** + * The title for Drawer. + * @type any (string | slot) + */ + title?: VNodeChild | JSX.Element; + /** + * The class name of the container of the Drawer dialog. + * @type string + */ + wrapClassName?: string; + class?: string; + rootClassName?: string; + /** + * Style of wrapper element which **contains mask** compare to `drawerStyle` + * @type object + */ + wrapStyle?: CSSProperties; + + /** + * Style of the popup layer element + * @type object + */ + drawerStyle?: CSSProperties; + + /** + * Style of floating layer, typically used for adjusting its position. + * @type object + */ + bodyStyle?: CSSProperties; + headerStyle?: CSSProperties; + + /** + * Width of the Drawer dialog. + * @default 256 + * @type string | number + */ + width?: string | number; + + /** + * placement is top or bottom, height of the Drawer dialog. + * @type string | number + */ + height?: string | number; + + /** + * The z-index of the Drawer. + * @default 1000 + * @type number + */ + zIndex?: number; + + /** + * The placement of the Drawer. + * @default 'right' + * @type string + */ + placement?: 'top' | 'right' | 'bottom' | 'left'; + afterOpenChange?: (open?: boolean) => void; + keyboard?: boolean; + /** + * Specify a callback that will be called when a user clicks mask, close button or Cancel button. + */ + onClose?: (e?: Event) => void; +} +export interface DrawerActionType { + scrollBottom: () => void; + scrollTo: (to: number) => void; + getScrollWrap: () => Element | null; +} diff --git a/src/components/Drawer/src/useDrawer.ts b/src/components/Drawer/src/useDrawer.ts new file mode 100644 index 0000000..60b65af --- /dev/null +++ b/src/components/Drawer/src/useDrawer.ts @@ -0,0 +1,161 @@ +import type { + UseDrawerReturnType, + DrawerInstance, + ReturnMethods, + DrawerProps, + UseDrawerInnerReturnType, +} from './typing'; +import { + ref, + getCurrentInstance, + unref, + reactive, + watchEffect, + nextTick, + toRaw, + computed, +} from 'vue'; +import { isProdMode } from '/@/utils/env'; +import { isFunction } from '/@/utils/is'; +import { tryOnUnmounted } from '@vueuse/core'; +import { isEqual } from 'lodash-es'; +import { error } from '/@/utils/log'; + +const dataTransferRef = reactive({}); + +const openData = reactive<{ [key: number]: boolean }>({}); + +/** + * @description: Applicable to separate drawer and call outside + */ +export function useDrawer(): UseDrawerReturnType { + if (!getCurrentInstance()) { + throw new Error('useDrawer() can only be used inside setup() or functional components!'); + } + const drawer = ref(null); + const loaded = ref>(false); + const uid = ref(''); + + function register(drawerInstance: DrawerInstance, uuid: string) { + isProdMode() && + tryOnUnmounted(() => { + drawer.value = null; + loaded.value = null; + dataTransferRef[unref(uid)] = null; + }); + + if (unref(loaded) && isProdMode() && drawerInstance === unref(drawer)) { + return; + } + uid.value = uuid; + drawer.value = drawerInstance; + loaded.value = true; + + drawerInstance.emitOpen = (open: boolean, uid: number) => { + openData[uid] = open; + }; + } + + const getInstance = () => { + const instance = unref(drawer); + if (!instance) { + error('useDrawer instance is undefined!'); + } + return instance; + }; + + const methods: ReturnMethods = { + setDrawerProps: (props: Partial): void => { + getInstance()?.setDrawerProps(props); + }, + + getOpen: computed((): boolean => { + return openData[~~unref(uid)]; + }), + + openDrawer: (open = true, data?: T, openOnSet = true): void => { + getInstance()?.setDrawerProps({ + open, + }); + if (!data) return; + + if (openOnSet) { + dataTransferRef[unref(uid)] = null; + dataTransferRef[unref(uid)] = toRaw(data); + return; + } + const equal = isEqual(toRaw(dataTransferRef[unref(uid)]), toRaw(data)); + if (!equal) { + dataTransferRef[unref(uid)] = toRaw(data); + } + }, + closeDrawer: () => { + getInstance()?.setDrawerProps({ open: false }); + }, + }; + + return [register, methods]; +} + +export const useDrawerInner = (callbackFn?: Fn): UseDrawerInnerReturnType => { + const drawerInstanceRef = ref>(null); + const currentInstance = getCurrentInstance(); + const uidRef = ref(''); + + if (!getCurrentInstance()) { + throw new Error('useDrawerInner() can only be used inside setup() or functional components!'); + } + + const getInstance = () => { + const instance = unref(drawerInstanceRef); + if (!instance) { + error('useDrawerInner instance is undefined!'); + return; + } + return instance; + }; + + const register = (modalInstance: DrawerInstance, uuid: string) => { + isProdMode() && + tryOnUnmounted(() => { + drawerInstanceRef.value = null; + }); + + uidRef.value = uuid; + drawerInstanceRef.value = modalInstance; + currentInstance?.emit('register', modalInstance, uuid); + }; + + watchEffect(() => { + const data = dataTransferRef[unref(uidRef)]; + if (!data) return; + if (!callbackFn || !isFunction(callbackFn)) return; + nextTick(() => { + callbackFn(data); + }); + }); + + return [ + register, + { + changeLoading: (loading = true) => { + getInstance()?.setDrawerProps({ loading }); + }, + + changeOkLoading: (loading = true) => { + getInstance()?.setDrawerProps({ confirmLoading: loading }); + }, + getOpen: computed((): boolean => { + return openData[~~unref(uidRef)]; + }), + + closeDrawer: () => { + getInstance()?.setDrawerProps({ open: false }); + }, + + setDrawerProps: (props: Partial | boolean) => { + getInstance()?.setDrawerProps(props); + }, + }, + ]; +}; diff --git a/src/components/Dropdown/index.ts b/src/components/Dropdown/index.ts new file mode 100644 index 0000000..80439e5 --- /dev/null +++ b/src/components/Dropdown/index.ts @@ -0,0 +1,5 @@ +import { withInstall } from '/@/utils'; +import dropdown from './src/Dropdown.vue'; + +export * from './src/typing'; +export const Dropdown = withInstall(dropdown); diff --git a/src/components/Dropdown/src/Dropdown.vue b/src/components/Dropdown/src/Dropdown.vue new file mode 100644 index 0000000..973a7a3 --- /dev/null +++ b/src/components/Dropdown/src/Dropdown.vue @@ -0,0 +1,98 @@ + + + diff --git a/src/components/Dropdown/src/typing.ts b/src/components/Dropdown/src/typing.ts new file mode 100644 index 0000000..29de8cb --- /dev/null +++ b/src/components/Dropdown/src/typing.ts @@ -0,0 +1,9 @@ +export interface DropMenu { + onClick?: Fn; + to?: string; + icon?: string; + event: string | number; + text: string; + disabled?: boolean; + divider?: boolean; +} diff --git a/src/components/Form/index.ts b/src/components/Form/index.ts new file mode 100644 index 0000000..d85b3c5 --- /dev/null +++ b/src/components/Form/index.ts @@ -0,0 +1,17 @@ +import BasicForm from './src/BasicForm.vue'; + +export * from './src/types/form'; +export * from './src/types/formItem'; + +export { useComponentRegister } from './src/hooks/useComponentRegister'; +export { useForm } from './src/hooks/useForm'; + +export { default as ApiSelect } from './src/components/ApiSelect.vue'; +export { default as RadioButtonGroup } from './src/components/RadioButtonGroup.vue'; +export { default as ApiTreeSelect } from './src/components/ApiTreeSelect.vue'; +export { default as ApiTree } from './src/components/ApiTree.vue'; +export { default as ApiRadioGroup } from './src/components/ApiRadioGroup.vue'; +export { default as ApiCascader } from './src/components/ApiCascader.vue'; +export { default as ApiTransfer } from './src/components/ApiTransfer.vue'; + +export { BasicForm }; diff --git a/src/components/Form/src/BasicForm.vue b/src/components/Form/src/BasicForm.vue new file mode 100644 index 0000000..a9ee8b7 --- /dev/null +++ b/src/components/Form/src/BasicForm.vue @@ -0,0 +1,354 @@ + + + diff --git a/src/components/Form/src/componentMap.ts b/src/components/Form/src/componentMap.ts new file mode 100644 index 0000000..5f7b964 --- /dev/null +++ b/src/components/Form/src/componentMap.ts @@ -0,0 +1,88 @@ +import type { Component } from 'vue'; +import type { ComponentType } from './types/index'; + +/** + * Component list, register here to setting it in the form + */ +import { + Input, + Select, + Radio, + Checkbox, + AutoComplete, + Cascader, + DatePicker, + InputNumber, + Switch, + TimePicker, + TreeSelect, + Slider, + Rate, + Divider, +} from 'ant-design-vue'; + +import ApiRadioGroup from './components/ApiRadioGroup.vue'; +import RadioButtonGroup from './components/RadioButtonGroup.vue'; +import ApiSelect from './components/ApiSelect.vue'; +import ApiTree from './components/ApiTree.vue'; +import ApiTreeSelect from './components/ApiTreeSelect.vue'; +import ApiMultipleSelect from './components/ApiMultipleSelect.vue'; +import ApiMultipleTreeSelect from "./components/ApiMultipleTreeSelect.vue"; +import ApiCascader from './components/ApiCascader.vue'; +import ApiTransfer from './components/ApiTransfer.vue'; +import { BasicUpload } from '/@/components/Upload'; +import { StrengthMeter } from '/@/components/StrengthMeter'; +import { IconPicker } from '/@/components/Icon'; +import { CountdownInput } from '/@/components/CountDown'; + +const componentMap = new Map(); + +componentMap.set('Input', Input); +componentMap.set('InputGroup', Input.Group); +componentMap.set('InputPassword', Input.Password); +componentMap.set('InputSearch', Input.Search); +componentMap.set('InputTextArea', Input.TextArea); +componentMap.set('InputNumber', InputNumber); +componentMap.set('AutoComplete', AutoComplete); + +componentMap.set('Select', Select); +componentMap.set('ApiSelect', ApiSelect); +componentMap.set('ApiTree', ApiTree); +componentMap.set('TreeSelect', TreeSelect); +componentMap.set('ApiTreeSelect', ApiTreeSelect); +componentMap.set('ApiMultipleSelect', ApiMultipleSelect); +componentMap.set('ApiMultipleTreeSelect', ApiMultipleTreeSelect); +componentMap.set('ApiRadioGroup', ApiRadioGroup); +componentMap.set('Switch', Switch); +componentMap.set('RadioButtonGroup', RadioButtonGroup); +componentMap.set('RadioGroup', Radio.Group); +componentMap.set('Checkbox', Checkbox); +componentMap.set('CheckboxGroup', Checkbox.Group); +componentMap.set('ApiCascader', ApiCascader); +componentMap.set('Cascader', Cascader); +componentMap.set('Slider', Slider); +componentMap.set('Rate', Rate); +componentMap.set('ApiTransfer', ApiTransfer); + +componentMap.set('DatePicker', DatePicker); +componentMap.set('MonthPicker', DatePicker.MonthPicker); +componentMap.set('RangePicker', DatePicker.RangePicker); +componentMap.set('WeekPicker', DatePicker.WeekPicker); +componentMap.set('TimePicker', TimePicker); +componentMap.set('TimeRangePicker', TimePicker.TimeRangePicker); +componentMap.set('StrengthMeter', StrengthMeter); +componentMap.set('IconPicker', IconPicker); +componentMap.set('InputCountDown', CountdownInput); + +componentMap.set('Upload', BasicUpload); +componentMap.set('Divider', Divider); + +export function add(compName: ComponentType, component: Component) { + componentMap.set(compName, component); +} + +export function del(compName: ComponentType) { + componentMap.delete(compName); +} + +export { componentMap }; diff --git a/src/components/Form/src/components/ApiCascader.vue b/src/components/Form/src/components/ApiCascader.vue new file mode 100644 index 0000000..cc400b1 --- /dev/null +++ b/src/components/Form/src/components/ApiCascader.vue @@ -0,0 +1,200 @@ + + diff --git a/src/components/Form/src/components/ApiMultipleSelect.vue b/src/components/Form/src/components/ApiMultipleSelect.vue new file mode 100644 index 0000000..b42d420 --- /dev/null +++ b/src/components/Form/src/components/ApiMultipleSelect.vue @@ -0,0 +1,155 @@ + + \ No newline at end of file diff --git a/src/components/Form/src/components/ApiMultipleTreeSelect.vue b/src/components/Form/src/components/ApiMultipleTreeSelect.vue new file mode 100644 index 0000000..71e925d --- /dev/null +++ b/src/components/Form/src/components/ApiMultipleTreeSelect.vue @@ -0,0 +1,104 @@ + + + diff --git a/src/components/Form/src/components/ApiRadioGroup.vue b/src/components/Form/src/components/ApiRadioGroup.vue new file mode 100644 index 0000000..8285cdf --- /dev/null +++ b/src/components/Form/src/components/ApiRadioGroup.vue @@ -0,0 +1,136 @@ + + + diff --git a/src/components/Form/src/components/ApiSelect.vue b/src/components/Form/src/components/ApiSelect.vue new file mode 100644 index 0000000..000de3c --- /dev/null +++ b/src/components/Form/src/components/ApiSelect.vue @@ -0,0 +1,153 @@ + + diff --git a/src/components/Form/src/components/ApiTransfer.vue b/src/components/Form/src/components/ApiTransfer.vue new file mode 100644 index 0000000..7eccd43 --- /dev/null +++ b/src/components/Form/src/components/ApiTransfer.vue @@ -0,0 +1,137 @@ + + + diff --git a/src/components/Form/src/components/ApiTree.vue b/src/components/Form/src/components/ApiTree.vue new file mode 100644 index 0000000..41a7413 --- /dev/null +++ b/src/components/Form/src/components/ApiTree.vue @@ -0,0 +1,92 @@ + + + diff --git a/src/components/Form/src/components/ApiTreeSelect.vue b/src/components/Form/src/components/ApiTreeSelect.vue new file mode 100644 index 0000000..7e9a0b9 --- /dev/null +++ b/src/components/Form/src/components/ApiTreeSelect.vue @@ -0,0 +1,101 @@ + + + \ No newline at end of file diff --git a/src/components/Form/src/components/FormAction.vue b/src/components/Form/src/components/FormAction.vue new file mode 100644 index 0000000..3f02675 --- /dev/null +++ b/src/components/Form/src/components/FormAction.vue @@ -0,0 +1,134 @@ + + diff --git a/src/components/Form/src/components/FormItem.vue b/src/components/Form/src/components/FormItem.vue new file mode 100644 index 0000000..7652941 --- /dev/null +++ b/src/components/Form/src/components/FormItem.vue @@ -0,0 +1,414 @@ + diff --git a/src/components/Form/src/components/RadioButtonGroup.vue b/src/components/Form/src/components/RadioButtonGroup.vue new file mode 100644 index 0000000..698635e --- /dev/null +++ b/src/components/Form/src/components/RadioButtonGroup.vue @@ -0,0 +1,63 @@ + + + diff --git a/src/components/Form/src/helper.ts b/src/components/Form/src/helper.ts new file mode 100644 index 0000000..ce251a6 --- /dev/null +++ b/src/components/Form/src/helper.ts @@ -0,0 +1,91 @@ +import type { ValidationRule } from 'ant-design-vue/lib/form/Form'; +import type { ComponentType } from './types/index'; +import { useI18n } from '/@/hooks/web/useI18n'; +import { dateUtil } from '/@/utils/dateUtil'; +import { isNumber, isObject } from '/@/utils/is'; + +const { t } = useI18n(); + +/** + * @description: 生成placeholder + */ +export function createPlaceholderMessage(component: ComponentType) { + if (component.includes('Input') || component.includes('Complete')) { + return t('common.inputText'); + } + if (component.includes('Picker')) { + return t('common.chooseText'); + } + if ( + component.includes('Select') || + component.includes('Cascader') || + component.includes('Checkbox') || + component.includes('Radio') || + component.includes('Switch') + ) { + // return `请选择${label}`; + return t('common.chooseText'); + } + return ''; +} + +const DATE_TYPE = ['DatePicker', 'MonthPicker', 'WeekPicker', 'TimePicker']; + +function genType() { + return [...DATE_TYPE, 'RangePicker']; +} + +export function setComponentRuleType( + rule: ValidationRule, + component: ComponentType, + valueFormat: string, +) { + if (Reflect.has(rule, 'type')) { + return; + } + if (['DatePicker', 'MonthPicker', 'WeekPicker', 'TimePicker'].includes(component)) { + rule.type = valueFormat ? 'string' : 'object'; + } else if (['RangePicker', 'Upload', 'CheckboxGroup', 'TimePicker'].includes(component)) { + rule.type = 'array'; + } else if (['InputNumber'].includes(component)) { + rule.type = 'number'; + } +} + +export function processDateValue(attr: Recordable, component: string) { + const { valueFormat, value } = attr; + if (valueFormat) { + attr.value = isObject(value) ? dateUtil(value).format(valueFormat) : value; + } else if (DATE_TYPE.includes(component) && value) { + attr.value = dateUtil(attr.value); + } +} + +export function handleInputNumberValue(component?: ComponentType, val?: any) { + if (!component) return val; + if (['Input', 'InputPassword', 'InputSearch', 'InputTextArea'].includes(component)) { + return val && isNumber(val) ? `${val}` : val; + } + return val; +} + +/** + * 时间字段 + */ +export const dateItemType = genType(); + +export const defaultValueComponents = ['Input', 'InputPassword', 'InputSearch', 'InputTextArea']; + +// TODO 自定义组件封装会出现验证问题,因此这里目前改成手动触发验证 +export const NO_AUTO_LINK_COMPONENTS: ComponentType[] = [ + 'Upload', + 'ApiTransfer', + 'ApiTree', + 'ApiSelect', + 'ApiMultipleSelect', + 'ApiTreeSelect', + 'ApiRadioGroup', + 'ApiCascader', + 'AutoComplete', + 'RadioButtonGroup', +]; diff --git a/src/components/Form/src/hooks/useAdvanced.ts b/src/components/Form/src/hooks/useAdvanced.ts new file mode 100644 index 0000000..96dacb2 --- /dev/null +++ b/src/components/Form/src/hooks/useAdvanced.ts @@ -0,0 +1,171 @@ +import type { ColEx } from '../types'; +import type { AdvanceState } from '../types/hooks'; +import { ComputedRef, getCurrentInstance, Ref, shallowReactive, computed, unref, watch } from 'vue'; +import type { FormProps, FormSchema } from '../types/form'; +import { isBoolean, isFunction, isNumber, isObject } from '/@/utils/is'; +import { useBreakpoint } from '/@/hooks/event/useBreakpoint'; +import { useDebounceFn } from '@vueuse/core'; + +const BASIC_COL_LEN = 24; + +interface UseAdvancedContext { + advanceState: AdvanceState; + emit: EmitType; + getProps: ComputedRef; + getSchema: ComputedRef; + formModel: Recordable; + defaultValueRef: Ref; +} + +export default function ({ + advanceState, + emit, + getProps, + getSchema, + formModel, + defaultValueRef, +}: UseAdvancedContext) { + const vm = getCurrentInstance(); + + const { realWidthRef, screenEnum, screenRef } = useBreakpoint(); + + const getEmptySpan = computed((): number => { + if (!advanceState.isAdvanced) { + return 0; + } + // For some special cases, you need to manually specify additional blank lines + const emptySpan = unref(getProps).emptySpan || 0; + + if (isNumber(emptySpan)) { + return emptySpan; + } + if (isObject(emptySpan)) { + const { span = 0 } = emptySpan; + const screen = unref(screenRef) as string; + + const screenSpan = (emptySpan as any)[screen.toLowerCase()]; + return screenSpan || span || 0; + } + return 0; + }); + + const debounceUpdateAdvanced = useDebounceFn(updateAdvanced, 30); + + watch( + [() => unref(getSchema), () => advanceState.isAdvanced, () => unref(realWidthRef)], + () => { + const { showAdvancedButton } = unref(getProps); + if (showAdvancedButton) { + debounceUpdateAdvanced(); + } + }, + { immediate: true }, + ); + + function getAdvanced(itemCol: Partial, itemColSum = 0, isLastAction = false) { + const width = unref(realWidthRef); + + const mdWidth = + parseInt(itemCol.md as string) || + parseInt(itemCol.xs as string) || + parseInt(itemCol.sm as string) || + (itemCol.span as number) || + BASIC_COL_LEN; + + const lgWidth = parseInt(itemCol.lg as string) || mdWidth; + const xlWidth = parseInt(itemCol.xl as string) || lgWidth; + const xxlWidth = parseInt(itemCol.xxl as string) || xlWidth; + if (width <= screenEnum.LG) { + itemColSum += mdWidth; + } else if (width < screenEnum.XL) { + itemColSum += lgWidth; + } else if (width < screenEnum.XXL) { + itemColSum += xlWidth; + } else { + itemColSum += xxlWidth; + } + + if (isLastAction) { + advanceState.hideAdvanceBtn = false; + if (itemColSum <= BASIC_COL_LEN * 2) { + // When less than or equal to 2 lines, the collapse and expand buttons are not displayed + advanceState.hideAdvanceBtn = true; + advanceState.isAdvanced = true; + } else if ( + itemColSum > BASIC_COL_LEN * 2 && + itemColSum <= BASIC_COL_LEN * (unref(getProps).autoAdvancedLine || 3) + ) { + advanceState.hideAdvanceBtn = false; + + // More than 3 lines collapsed by default + } else if (!advanceState.isLoad) { + advanceState.isLoad = true; + advanceState.isAdvanced = !advanceState.isAdvanced; + } + return { isAdvanced: advanceState.isAdvanced, itemColSum }; + } + if (itemColSum > BASIC_COL_LEN * (unref(getProps).alwaysShowLines || 1)) { + return { isAdvanced: advanceState.isAdvanced, itemColSum }; + } else { + // The first line is always displayed + return { isAdvanced: true, itemColSum }; + } + } + + const fieldsIsAdvancedMap = shallowReactive({}); + + function updateAdvanced() { + let itemColSum = 0; + let realItemColSum = 0; + const { baseColProps = {} } = unref(getProps); + + for (const schema of unref(getSchema)) { + const { show, colProps } = schema; + let isShow = true; + + if (isBoolean(show)) { + isShow = show; + } + + if (isFunction(show)) { + isShow = show({ + schema: schema, + model: formModel, + field: schema.field, + values: { + ...unref(defaultValueRef), + ...formModel, + }, + }); + } + + if (isShow && (colProps || baseColProps)) { + const { itemColSum: sum, isAdvanced } = getAdvanced( + { ...baseColProps, ...colProps }, + itemColSum, + ); + + itemColSum = sum || 0; + if (isAdvanced) { + realItemColSum = itemColSum; + } + fieldsIsAdvancedMap[schema.field] = isAdvanced; + } + } + + // 确保页面发送更新 + vm?.proxy?.$forceUpdate(); + + advanceState.actionSpan = (realItemColSum % BASIC_COL_LEN) + unref(getEmptySpan); + + getAdvanced(unref(getProps).actionColOptions || { span: BASIC_COL_LEN }, itemColSum, true); + + emit('advanced-change'); + } + + function handleToggleAdvanced() { + advanceState.isAdvanced = !advanceState.isAdvanced; + } + + return { handleToggleAdvanced, fieldsIsAdvancedMap }; +} diff --git a/src/components/Form/src/hooks/useAutoFocus.ts b/src/components/Form/src/hooks/useAutoFocus.ts new file mode 100644 index 0000000..e24dd6b --- /dev/null +++ b/src/components/Form/src/hooks/useAutoFocus.ts @@ -0,0 +1,40 @@ +import type { ComputedRef, Ref } from 'vue'; +import type { FormSchema, FormActionType, FormProps } from '../types/form'; + +import { unref, nextTick, watchEffect } from 'vue'; + +interface UseAutoFocusContext { + getSchema: ComputedRef; + getProps: ComputedRef; + isInitedDefault: Ref; + formElRef: Ref; +} +export async function useAutoFocus({ + getSchema, + getProps, + formElRef, + isInitedDefault, +}: UseAutoFocusContext) { + watchEffect(async () => { + if (unref(isInitedDefault) || !unref(getProps).autoFocusFirstItem) { + return; + } + await nextTick(); + const schemas = unref(getSchema); + const formEl = unref(formElRef); + const el = (formEl as any)?.$el as HTMLElement; + if (!formEl || !el || !schemas || schemas.length === 0) { + return; + } + + const firstItem = schemas[0]; + // Only open when the first form item is input type + if (!firstItem.component.includes('Input')) { + return; + } + + const inputEl = el.querySelector('.ant-row:first-child input') as Nullable; + if (!inputEl) return; + inputEl?.focus(); + }); +} diff --git a/src/components/Form/src/hooks/useComponentRegister.ts b/src/components/Form/src/hooks/useComponentRegister.ts new file mode 100644 index 0000000..218aaa9 --- /dev/null +++ b/src/components/Form/src/hooks/useComponentRegister.ts @@ -0,0 +1,11 @@ +import type { ComponentType } from '../types/index'; +import { tryOnUnmounted } from '@vueuse/core'; +import { add, del } from '../componentMap'; +import type { Component } from 'vue'; + +export function useComponentRegister(compName: ComponentType, comp: Component) { + add(compName, comp); + tryOnUnmounted(() => { + del(compName); + }); +} diff --git a/src/components/Form/src/hooks/useForm.ts b/src/components/Form/src/hooks/useForm.ts new file mode 100644 index 0000000..40f246d --- /dev/null +++ b/src/components/Form/src/hooks/useForm.ts @@ -0,0 +1,122 @@ +import type { FormProps, FormActionType, UseFormReturnType, FormSchema } from '../types/form'; +import type { NamePath } from 'ant-design-vue/lib/form/interface'; +import type { DynamicProps } from '/#/utils'; +import { ref, onUnmounted, unref, nextTick, watch } from 'vue'; +import { isProdMode } from '/@/utils/env'; +import { error } from '/@/utils/log'; +import { getDynamicProps } from '/@/utils'; + +export declare type ValidateFields = (nameList?: NamePath[]) => Promise; + +type Props = Partial>; + +export function useForm(props?: Props): UseFormReturnType { + const formRef = ref>(null); + const loadedRef = ref>(false); + + async function getForm() { + const form = unref(formRef); + if (!form) { + error( + 'The form instance has not been obtained, please make sure that the form has been rendered when performing the form operation!', + ); + } + await nextTick(); + return form as FormActionType; + } + + function register(instance: FormActionType) { + isProdMode() && + onUnmounted(() => { + formRef.value = null; + loadedRef.value = null; + }); + if (unref(loadedRef) && isProdMode() && instance === unref(formRef)) return; + + formRef.value = instance; + loadedRef.value = true; + + watch( + () => props, + () => { + props && instance.setProps(getDynamicProps(props)); + }, + { + immediate: true, + deep: true, + }, + ); + } + + const methods: FormActionType = { + scrollToField: async (name: NamePath, options?: ScrollOptions | undefined) => { + const form = await getForm(); + form.scrollToField(name, options); + }, + setProps: async (formProps: Partial) => { + const form = await getForm(); + form.setProps(formProps); + }, + + updateSchema: async (data: Partial | Partial[]) => { + const form = await getForm(); + form.updateSchema(data); + }, + + resetSchema: async (data: Partial | Partial[]) => { + const form = await getForm(); + form.resetSchema(data); + }, + + clearValidate: async (name?: string | string[]) => { + const form = await getForm(); + form.clearValidate(name); + }, + + resetFields: async () => { + getForm().then(async (form) => { + await form.resetFields(); + }); + }, + + removeSchemaByField: async (field: string | string[]) => { + unref(formRef)?.removeSchemaByField(field); + }, + + // TODO promisify + getFieldsValue: () => { + return unref(formRef)?.getFieldsValue() as T; + }, + + setFieldsValue: async (values: T) => { + const form = await getForm(); + form.setFieldsValue(values); + }, + + appendSchemaByField: async ( + schema: FormSchema | FormSchema[], + prefixField: string | undefined, + first: boolean, + ) => { + const form = await getForm(); + form.appendSchemaByField(schema, prefixField, first); + }, + + submit: async (): Promise => { + const form = await getForm(); + return form.submit(); + }, + + validate: async (nameList?: NamePath[]): Promise => { + const form = await getForm(); + return form.validate(nameList); + }, + + validateFields: async (nameList?: NamePath[]): Promise => { + const form = await getForm(); + return form.validateFields(nameList); + }, + }; + + return [register, methods]; +} diff --git a/src/components/Form/src/hooks/useFormContext.ts b/src/components/Form/src/hooks/useFormContext.ts new file mode 100644 index 0000000..01dfadd --- /dev/null +++ b/src/components/Form/src/hooks/useFormContext.ts @@ -0,0 +1,17 @@ +import type { InjectionKey } from 'vue'; +import { createContext, useContext } from '/@/hooks/core/useContext'; + +export interface FormContextProps { + resetAction: () => Promise; + submitAction: () => Promise; +} + +const key: InjectionKey = Symbol(); + +export function createFormContext(context: FormContextProps) { + return createContext(context, key); +} + +export function useFormContext() { + return useContext(key); +} diff --git a/src/components/Form/src/hooks/useFormEvents.ts b/src/components/Form/src/hooks/useFormEvents.ts new file mode 100644 index 0000000..3dcf37e --- /dev/null +++ b/src/components/Form/src/hooks/useFormEvents.ts @@ -0,0 +1,428 @@ +import type { ComputedRef, Ref } from 'vue'; +import type { FormProps, FormSchema, FormActionType } from '../types/form'; +import type { NamePath } from 'ant-design-vue/lib/form/interface'; +import { unref, toRaw, nextTick } from 'vue'; +import { + isArray, + isFunction, + isObject, + isString, + isDef, + isNullOrUnDef, + isEmpty, +} from '/@/utils/is'; +import { deepMerge } from '/@/utils'; +import { dateItemType, handleInputNumberValue, defaultValueComponents } from '../helper'; +import { dateUtil } from '/@/utils/dateUtil'; +import { cloneDeep, set, uniqBy, get } from 'lodash-es'; +import { error } from '/@/utils/log'; + +interface UseFormActionContext { + emit: EmitType; + getProps: ComputedRef; + getSchema: ComputedRef; + formModel: Recordable; + defaultValueRef: Ref; + formElRef: Ref; + schemaRef: Ref; + handleFormValues: Fn; +} + +function tryConstructArray(field: string, values: Recordable = {}): any[] | undefined { + const pattern = /^\[(.+)\]$/; + if (pattern.test(field)) { + const match = field.match(pattern); + if (match && match[1]) { + const keys = match[1].split(','); + if (!keys.length) { + return undefined; + } + + const result = []; + keys.forEach((k, index) => { + set(result, index, values[k.trim()]); + }); + + return result.filter(Boolean).length ? result : undefined; + } + } +} + +function tryConstructObject(field: string, values: Recordable = {}): Recordable | undefined { + const pattern = /^\{(.+)\}$/; + if (pattern.test(field)) { + const match = field.match(pattern); + if (match && match[1]) { + const keys = match[1].split(','); + if (!keys.length) { + return; + } + + const result = {}; + keys.forEach((k) => { + set(result, k.trim(), values[k.trim()]); + }); + + return Object.values(result).filter(Boolean).length ? result : undefined; + } + } +} + +export function useFormEvents({ + emit, + getProps, + formModel, + getSchema, + defaultValueRef, + formElRef, + schemaRef, + handleFormValues, +}: UseFormActionContext) { + async function resetFields(): Promise { + const { resetFunc, submitOnReset } = unref(getProps); + resetFunc && isFunction(resetFunc) && (await resetFunc()); + + const formEl = unref(formElRef); + if (!formEl) return; + + Object.keys(formModel).forEach((key) => { + const schema = unref(getSchema).find((item) => item.field === key); + const defaultValueObj = schema?.defaultValueObj; + const fieldKeys = Object.keys(defaultValueObj || {}); + if (fieldKeys.length) { + fieldKeys.map((field) => { + formModel[field] = defaultValueObj![field]; + }); + } + formModel[key] = getDefaultValue(schema, defaultValueRef, key); + }); + nextTick(() => clearValidate()); + + emit('reset', toRaw(formModel)); + submitOnReset && handleSubmit(); + } + // 获取表单fields + const getAllFields = () => + unref(getSchema) + .map((item) => [...(item.fields || []), item.field]) + .flat(1) + .filter(Boolean); + /** + * @description: Set form value + */ + async function setFieldsValue(values: Recordable): Promise { + const fields = getAllFields(); + + // key 支持 a.b.c 的嵌套写法 + const delimiter = '.'; + const nestKeyArray = fields.filter((item) => String(item).indexOf(delimiter) >= 0); + + const validKeys: string[] = []; + fields.forEach((key) => { + const schema = unref(getSchema).find((item) => item.field === key); + let value = get(values, key); + const hasKey = Reflect.has(values, key); + + value = handleInputNumberValue(schema?.component, value); + const { componentProps } = schema || {}; + let _props = componentProps as any; + if (typeof componentProps === 'function') { + _props = _props({ formModel: unref(formModel) }); + } + + const constructValue = tryConstructArray(key, values) || tryConstructObject(key, values); + + // 0| '' is allow + if (hasKey || !!constructValue) { + const fieldValue = constructValue || value; + // time type + if (itemIsDateType(key)) { + if (Array.isArray(fieldValue)) { + const arr: any[] = []; + for (const ele of fieldValue) { + arr.push(ele ? dateUtil(ele) : null); + } + unref(formModel)[key] = arr; + } else { + unref(formModel)[key] = fieldValue + ? _props?.valueFormat + ? fieldValue + : dateUtil(fieldValue) + : null; + } + } else { + unref(formModel)[key] = fieldValue; + } + if (_props?.onChange) { + _props?.onChange(fieldValue); + } + validKeys.push(key); + } else { + nestKeyArray.forEach((nestKey: string) => { + try { + const value = nestKey.split('.').reduce((out, item) => out[item], values); + if (isDef(value)) { + unref(formModel)[nestKey] = unref(value); + validKeys.push(nestKey); + } + } catch (e) { + // key not exist + if (isDef(defaultValueRef.value[nestKey])) { + unref(formModel)[nestKey] = cloneDeep(unref(defaultValueRef.value[nestKey])); + } + } + }); + } + }); + validateFields(validKeys).catch((_) => {}); + } + + /** + * @description: Delete based on field name + */ + async function removeSchemaByField(fields: string | string[]): Promise { + const schemaList: FormSchema[] = cloneDeep(unref(getSchema)); + if (!fields) { + return; + } + + let fieldList: string[] = isString(fields) ? [fields] : fields; + if (isString(fields)) { + fieldList = [fields]; + } + for (const field of fieldList) { + _removeSchemaByFeild(field, schemaList); + } + schemaRef.value = schemaList; + } + + /** + * @description: Delete based on field name + */ + function _removeSchemaByFeild(field: string, schemaList: FormSchema[]): void { + if (isString(field)) { + const index = schemaList.findIndex((schema) => schema.field === field); + if (index !== -1) { + delete formModel[field]; + schemaList.splice(index, 1); + } + } + } + + /** + * @description: Insert after a certain field, if not insert the last + */ + async function appendSchemaByField( + schema: FormSchema | FormSchema[], + prefixField?: string, + first = false, + ) { + const schemaList: FormSchema[] = cloneDeep(unref(getSchema)); + const addSchemaIds: string[] = Array.isArray(schema) + ? schema.map((item) => item.field) + : [schema.field]; + if (schemaList.find((item) => addSchemaIds.includes(item.field))) { + error('There are schemas that have already been added'); + return; + } + const index = schemaList.findIndex((schema) => schema.field === prefixField); + const _schemaList = isObject(schema) ? [schema as FormSchema] : (schema as FormSchema[]); + if (!prefixField || index === -1 || first) { + first ? schemaList.unshift(..._schemaList) : schemaList.push(..._schemaList); + } else if (index !== -1) { + schemaList.splice(index + 1, 0, ..._schemaList); + } + schemaRef.value = schemaList; + _setDefaultValue(schema); + } + + async function resetSchema(data: Partial | Partial[]) { + let updateData: Partial[] = []; + if (isObject(data)) { + updateData.push(data as FormSchema); + } + if (isArray(data)) { + updateData = [...data]; + } + + const hasField = updateData.every( + (item) => item.component === 'Divider' || (Reflect.has(item, 'field') && item.field), + ); + + if (!hasField) { + error( + 'All children of the form Schema array that need to be updated must contain the `field` field', + ); + return; + } + schemaRef.value = updateData as FormSchema[]; + } + + async function updateSchema(data: Partial | Partial[]) { + let updateData: Partial[] = []; + if (isObject(data)) { + updateData.push(data as FormSchema); + } + if (isArray(data)) { + updateData = [...data]; + } + + const hasField = updateData.every( + (item) => item.component === 'Divider' || (Reflect.has(item, 'field') && item.field), + ); + + if (!hasField) { + error( + 'All children of the form Schema array that need to be updated must contain the `field` field', + ); + return; + } + const schema: FormSchema[] = []; + unref(getSchema).forEach((val) => { + let _val; + updateData.forEach((item) => { + if (val.field === item.field) { + _val = item; + } + }); + if (_val !== undefined && val.field === _val.field) { + const newSchema = deepMerge(val, _val); + schema.push(newSchema as FormSchema); + } else { + schema.push(val); + } + }); + _setDefaultValue(schema); + + schemaRef.value = uniqBy(schema, 'field'); + } + + function _setDefaultValue(data: FormSchema | FormSchema[]) { + let schemas: FormSchema[] = []; + if (isObject(data)) { + schemas.push(data as FormSchema); + } + if (isArray(data)) { + schemas = [...data]; + } + + const obj: Recordable = {}; + const currentFieldsValue = getFieldsValue(); + schemas.forEach((item) => { + if ( + item.component != 'Divider' && + Reflect.has(item, 'field') && + item.field && + !isNullOrUnDef(item.defaultValue) && + (!(item.field in currentFieldsValue) || + isNullOrUnDef(currentFieldsValue[item.field]) || + isEmpty(currentFieldsValue[item.field])) + ) { + obj[item.field] = item.defaultValue; + } + }); + setFieldsValue(obj); + } + + function getFieldsValue(): Recordable { + const formEl = unref(formElRef); + if (!formEl) return {}; + return handleFormValues(toRaw(unref(formModel))); + } + + /** + * @description: Is it time + */ + function itemIsDateType(key: string) { + return unref(getSchema).some((item) => { + return item.field === key ? dateItemType.includes(item.component) : false; + }); + } + + async function validateFields(nameList?: NamePath[] | undefined) { + return unref(formElRef)?.validateFields(nameList); + } + + async function validate(nameList?: NamePath[] | false | undefined) { + let _nameList: any; + if (nameList === undefined) { + _nameList = getAllFields(); + } else { + _nameList = nameList === Array.isArray(nameList) ? nameList : undefined; + } + return await unref(formElRef)?.validate(_nameList); + } + + async function clearValidate(name?: string | string[]) { + await unref(formElRef)?.clearValidate(name); + } + + async function scrollToField(name: NamePath, options?: ScrollOptions | undefined) { + await unref(formElRef)?.scrollToField(name, options); + } + + /** + * @description: Form submission + */ + async function handleSubmit(e?: Event): Promise { + e && e.preventDefault(); + const { submitFunc } = unref(getProps); + if (submitFunc && isFunction(submitFunc)) { + await submitFunc(); + return; + } + const formEl = unref(formElRef); + if (!formEl) return; + try { + const values = await validate(); + const res = handleFormValues(values); + emit('submit', res); + } catch (error: any) { + if (error?.outOfDate === false && error?.errorFields) { + return; + } + throw new Error(error); + } + } + + return { + handleSubmit, + clearValidate, + validate, + validateFields, + getFieldsValue, + updateSchema, + resetSchema, + appendSchemaByField, + removeSchemaByField, + resetFields, + setFieldsValue, + scrollToField, + }; +} + +function getDefaultValue( + schema: FormSchema | undefined, + defaultValueRef: UseFormActionContext['defaultValueRef'], + key: string, +) { + let defaultValue = cloneDeep(defaultValueRef.value[key]); + const isInput = checkIsInput(schema); + if (isInput) { + return defaultValue || ''; + } + if (!defaultValue && schema && checkIsRangeSlider(schema)) { + defaultValue = [0, 0]; + } + return defaultValue; +} + +function checkIsRangeSlider(schema: FormSchema) { + if (schema.component === 'Slider' && schema.componentProps && schema.componentProps.range) { + return true; + } +} + +function checkIsInput(schema?: FormSchema) { + return schema?.component && defaultValueComponents.includes(schema.component); +} diff --git a/src/components/Form/src/hooks/useFormValues.ts b/src/components/Form/src/hooks/useFormValues.ts new file mode 100644 index 0000000..4317287 --- /dev/null +++ b/src/components/Form/src/hooks/useFormValues.ts @@ -0,0 +1,161 @@ +import { isArray, isFunction, isObject, isString, isNullOrUnDef } from '/@/utils/is'; +import { dateUtil } from '/@/utils/dateUtil'; +import { unref } from 'vue'; +import type { Ref, ComputedRef } from 'vue'; +import type { FormProps, FormSchema } from '../types/form'; +import { cloneDeep, set } from 'lodash-es'; + +interface UseFormValuesContext { + defaultValueRef: Ref; + getSchema: ComputedRef; + getProps: ComputedRef; + formModel: Recordable; +} + +/** + * @desription deconstruct array-link key. This method will mutate the target. + */ +function tryDeconstructArray(key: string, value: any, target: Recordable) { + const pattern = /^\[(.+)\]$/; + if (pattern.test(key)) { + const match = key.match(pattern); + if (match && match[1]) { + const keys = match[1].split(','); + value = Array.isArray(value) ? value : [value]; + keys.forEach((k, index) => { + set(target, k.trim(), value[index]); + }); + return true; + } + } +} + +/** + * @desription deconstruct object-link key. This method will mutate the target. + */ +function tryDeconstructObject(key: string, value: any, target: Recordable) { + const pattern = /^\{(.+)\}$/; + if (pattern.test(key)) { + const match = key.match(pattern); + if (match && match[1]) { + const keys = match[1].split(','); + value = isObject(value) ? value : {}; + keys.forEach((k) => { + set(target, k.trim(), value[k.trim()]); + }); + return true; + } + } +} + +export function useFormValues({ + defaultValueRef, + getSchema, + formModel, + getProps, +}: UseFormValuesContext) { + // Processing form values + function handleFormValues(values: Recordable) { + if (!isObject(values)) { + return {}; + } + const res: Recordable = {}; + for (const item of Object.entries(values)) { + let [, value] = item; + const [key] = item; + if (!key || (isArray(value) && value.length === 0) || isFunction(value)) { + continue; + } + const transformDateFunc = unref(getProps).transformDateFunc; + if (isObject(value)) { + value = transformDateFunc?.(value); + } + + if (isArray(value) && value[0]?.format && value[1]?.format) { + value = value.map((item) => transformDateFunc?.(item)); + } + // Remove spaces + if (isString(value)) { + // remove params from URL + if (value === '') { + value = undefined; + } else { + value = value.trim(); + } + } + if (!tryDeconstructArray(key, value, res) && !tryDeconstructObject(key, value, res)) { + // 没有解构成功的,按原样赋值 + set(res, key, value); + } + } + return handleRangeTimeValue(res); + } + + /** + * @description: Processing time interval parameters + */ + function handleRangeTimeValue(values: Recordable) { + const fieldMapToTime = unref(getProps).fieldMapToTime; + + if (!fieldMapToTime || !Array.isArray(fieldMapToTime)) { + return values; + } + + for (const [field, [startTimeKey, endTimeKey], format = 'YYYY-MM-DD'] of fieldMapToTime) { + if (!field || !startTimeKey || !endTimeKey) { + continue; + } + // If the value to be converted is empty, remove the field + if (!values[field]) { + Reflect.deleteProperty(values, field); + continue; + } + + const [startTime, endTime]: string[] = values[field]; + + const [startTimeFormat, endTimeFormat] = Array.isArray(format) ? format : [format, format]; + + values[startTimeKey] = formatTime(startTime, startTimeFormat); + values[endTimeKey] = formatTime(endTime, endTimeFormat); + Reflect.deleteProperty(values, field); + } + + return values; + } + + function formatTime(time: string, format: string) { + if (format === 'timestamp') { + return dateUtil(time).unix(); + } else if (format === 'timestampStartDay') { + return dateUtil(time).startOf('day').unix(); + } + return dateUtil(time).format(format); + } + + function initDefault() { + const schemas = unref(getSchema); + const obj: Recordable = {}; + schemas.forEach((item) => { + const { defaultValue, defaultValueObj } = item; + const fieldKeys = Object.keys(defaultValueObj || {}); + if (fieldKeys.length) { + fieldKeys.map((field) => { + obj[field] = defaultValueObj![field]; + if (formModel[field] === undefined) { + formModel[field] = defaultValueObj![field]; + } + }); + } + if (!isNullOrUnDef(defaultValue)) { + obj[item.field] = defaultValue; + + if (formModel[item.field] === undefined) { + formModel[item.field] = defaultValue; + } + } + }); + defaultValueRef.value = cloneDeep(obj); + } + + return { handleFormValues, initDefault }; +} diff --git a/src/components/Form/src/hooks/useLabelWidth.ts b/src/components/Form/src/hooks/useLabelWidth.ts new file mode 100644 index 0000000..3befa1c --- /dev/null +++ b/src/components/Form/src/hooks/useLabelWidth.ts @@ -0,0 +1,42 @@ +import type { Ref } from 'vue'; +import { computed, unref } from 'vue'; +import type { FormProps, FormSchema } from '../types/form'; +import { isNumber } from '/@/utils/is'; + +export function useItemLabelWidth(schemaItemRef: Ref, propsRef: Ref) { + return computed(() => { + const schemaItem = unref(schemaItemRef); + const { labelCol = {}, wrapperCol = {} } = schemaItem.itemProps || {}; + const { labelWidth, disabledLabelWidth } = schemaItem; + + const { + labelWidth: globalLabelWidth, + labelCol: globalLabelCol, + wrapperCol: globWrapperCol, + layout, + } = unref(propsRef); + + // If labelWidth is set globally, all items setting + if ((!globalLabelWidth && !labelWidth && !globalLabelCol) || disabledLabelWidth) { + labelCol.style = { + textAlign: 'left', + }; + return { labelCol, wrapperCol }; + } + let width = labelWidth || globalLabelWidth; + const col = { ...globalLabelCol, ...labelCol }; + const wrapCol = { ...globWrapperCol, ...wrapperCol }; + + if (width) { + width = isNumber(width) ? `${width}px` : width; + } + + return { + labelCol: { style: { width }, ...col }, + wrapperCol: { + style: { width: layout === 'vertical' ? '100%' : `calc(100% - ${width})` }, + ...wrapCol, + }, + }; + }); +} diff --git a/src/components/Form/src/props.ts b/src/components/Form/src/props.ts new file mode 100644 index 0000000..f3f6a2e --- /dev/null +++ b/src/components/Form/src/props.ts @@ -0,0 +1,103 @@ +import type { FieldMapToTime, FormSchema } from './types/form'; +import type { CSSProperties, PropType } from 'vue'; +import type { ColEx } from './types'; +import type { TableActionType } from '/@/components/Table'; +import type { ButtonProps } from 'ant-design-vue/es/button/buttonTypes'; +import type { RowProps } from 'ant-design-vue/lib/grid/Row'; +import { propTypes } from '/@/utils/propTypes'; + +export const basicProps = { + model: { + type: Object as PropType, + default: () => ({}), + }, + // 标签宽度 固定宽度 + labelWidth: { + type: [Number, String] as PropType, + default: 0, + }, + fieldMapToTime: { + type: Array as PropType, + default: () => [], + }, + compact: propTypes.bool, + // 表单配置规则 + schemas: { + type: Array as PropType, + default: () => [], + }, + mergeDynamicData: { + type: Object as PropType, + default: null, + }, + baseRowStyle: { + type: Object as PropType, + }, + baseColProps: { + type: Object as PropType>, + }, + autoSetPlaceHolder: propTypes.bool.def(true), + // 在INPUT组件上单击回车时,是否自动提交 + autoSubmitOnEnter: propTypes.bool.def(false), + submitOnReset: propTypes.bool, + submitOnChange: propTypes.bool, + size: propTypes.oneOf(['default', 'small', 'large']).def('default'), + // 禁用表单 + disabled: propTypes.bool, + emptySpan: { + type: [Number, Object] as PropType, + default: 0, + }, + // 是否显示收起展开按钮 + showAdvancedButton: propTypes.bool, + // 转化时间 + transformDateFunc: { + type: Function as PropType, + default: (date: any) => { + return date?.format?.('YYYY-MM-DD HH:mm:ss') ?? date; + }, + }, + rulesMessageJoinLabel: propTypes.bool.def(true), + // 超过3行自动折叠 + autoAdvancedLine: propTypes.number.def(3), + // 不受折叠影响的行数 + alwaysShowLines: propTypes.number.def(1), + + // 是否显示操作按钮 + showActionButtonGroup: propTypes.bool.def(true), + // 操作列Col配置 + actionColOptions: Object as PropType>, + // 显示重置按钮 + showResetButton: propTypes.bool.def(true), + // 是否聚焦第一个输入框,只在第一个表单项为input的时候作用 + autoFocusFirstItem: propTypes.bool, + // 重置按钮配置 + resetButtonOptions: Object as PropType>, + + // 显示确认按钮 + showSubmitButton: propTypes.bool.def(true), + // 确认按钮配置 + submitButtonOptions: Object as PropType>, + + // 自定义重置函数 + resetFunc: Function as PropType<() => Promise>, + submitFunc: Function as PropType<() => Promise>, + + // 以下为默认props + hideRequiredMark: propTypes.bool, + + labelCol: Object as PropType>, + + layout: propTypes.oneOf(['horizontal', 'vertical', 'inline']).def('horizontal'), + tableAction: { + type: Object as PropType, + }, + + wrapperCol: Object as PropType>, + + colon: propTypes.bool, + + labelAlign: propTypes.string, + + rowProps: Object as PropType, +}; diff --git a/src/components/Form/src/types/form.ts b/src/components/Form/src/types/form.ts new file mode 100644 index 0000000..0cd5708 --- /dev/null +++ b/src/components/Form/src/types/form.ts @@ -0,0 +1,241 @@ +import type { NamePath, RuleObject } from 'ant-design-vue/lib/form/interface'; +import type { VNode, CSSProperties } from 'vue'; +import type { ButtonProps as AntdButtonProps } from '/@/components/Button'; +import type { FormItem } from './formItem'; +import type { ColEx, ComponentType } from './index'; +import type { TableActionType } from '/@/components/Table/src/types/table'; +import type { RowProps } from 'ant-design-vue/lib/grid/Row'; + +export type FieldMapToTime = [string, [string, string], (string | [string, string])?][]; + +export type Rule = RuleObject & { + trigger?: 'blur' | 'change' | ['change', 'blur']; +}; + +export interface RenderCallbackParams { + schema: FormSchema; + values: Recordable; + model: Recordable; + field: string; +} + +export interface ButtonProps extends AntdButtonProps { + text?: string; +} + +export interface FormActionType { + submit: () => Promise; + setFieldsValue: (values: Recordable) => Promise; + resetFields: () => Promise; + getFieldsValue: () => Recordable; + clearValidate: (name?: string | string[]) => Promise; + updateSchema: (data: Partial | Partial[]) => Promise; + resetSchema: (data: Partial | Partial[]) => Promise; + setProps: (formProps: Partial) => Promise; + removeSchemaByField: (field: string | string[]) => Promise; + appendSchemaByField: ( + schema: FormSchema | FormSchema[], + prefixField: string | undefined, + first?: boolean | undefined, + ) => Promise; + validateFields: (nameList?: NamePath[]) => Promise; + validate: (nameList?: NamePath[] | false) => Promise; + scrollToField: (name: NamePath, options?: ScrollOptions) => Promise; +} + +export type RegisterFn = (formInstance: FormActionType) => void; + +export type UseFormReturnType = [RegisterFn, FormActionType]; + +export interface FormProps { + name?: string; + layout?: 'vertical' | 'inline' | 'horizontal'; + // Form value + model?: Recordable; + // The width of all items in the entire form + labelWidth?: number | string; + // alignment + labelAlign?: 'left' | 'right'; + // Row configuration for the entire form + rowProps?: RowProps; + // Submit form on reset + submitOnReset?: boolean; + // Submit form on form changing + submitOnChange?: boolean; + // Col configuration for the entire form + labelCol?: Partial; + // Col configuration for the entire form + wrapperCol?: Partial; + + // General row style + baseRowStyle?: CSSProperties; + + // General col configuration + baseColProps?: Partial; + + // Form configuration rules + schemas?: FormSchema[]; + // Function values used to merge into dynamic control form items + mergeDynamicData?: Recordable; + // Compact mode for search forms + compact?: boolean; + // Blank line span + emptySpan?: number | Partial; + // Internal component size of the form + size?: 'default' | 'small' | 'large'; + // Whether to disable + disabled?: boolean; + // Time interval fields are mapped into multiple + fieldMapToTime?: FieldMapToTime; + // Placeholder is set automatically + autoSetPlaceHolder?: boolean; + // Auto submit on press enter on input + autoSubmitOnEnter?: boolean; + // Check whether the information is added to the label + rulesMessageJoinLabel?: boolean; + // Whether to show collapse and expand buttons + showAdvancedButton?: boolean; + // Whether to focus on the first input box, only works when the first form item is input + autoFocusFirstItem?: boolean; + // Automatically collapse over the specified number of rows + autoAdvancedLine?: number; + // Always show lines + alwaysShowLines?: number; + // Whether to show the operation button + showActionButtonGroup?: boolean; + + // Reset button configuration + resetButtonOptions?: Partial; + + // Confirm button configuration + submitButtonOptions?: Partial; + + // Operation column configuration + actionColOptions?: Partial; + + // Show reset button + showResetButton?: boolean; + // Show confirmation button + showSubmitButton?: boolean; + + resetFunc?: () => Promise; + submitFunc?: () => Promise; + transformDateFunc?: (date: any) => string; + colon?: boolean; +} +export type RenderOpts = { + disabled: boolean; + [key: string]: any; +}; +export interface FormSchema { + // Field name + field: string; + // Extra Fields name[] + fields?: string[]; + // Event name triggered by internal value change, default change + changeEvent?: string; + // Variable name bound to v-model Default value + valueField?: string; + // Label name + label?: string | VNode; + // Auxiliary text + subLabel?: string; + // Help text on the right side of the text + helpMessage?: + | string + | string[] + | ((renderCallbackParams: RenderCallbackParams) => string | string[]); + // BaseHelp component props + helpComponentProps?: Partial; + // Label width, if it is passed, the labelCol and WrapperCol configured by itemProps will be invalid + labelWidth?: string | number; + // Disable the adjustment of labelWidth with global settings of formModel, and manually set labelCol and wrapperCol by yourself + disabledLabelWidth?: boolean; + // render component + component: ComponentType; + // Component parameters + componentProps?: + | ((opt: { + schema: FormSchema; + tableAction: TableActionType; + formActionType: FormActionType; + formModel: Recordable; + }) => Recordable) + | object; + // Required + required?: boolean | ((renderCallbackParams: RenderCallbackParams) => boolean); + + suffix?: string | number | ((values: RenderCallbackParams) => string | number); + + // Validation rules + rules?: Rule[]; + // Check whether the information is added to the label + rulesMessageJoinLabel?: boolean; + + // Reference formModelItem + itemProps?: Partial; + + // col configuration outside formModelItem + colProps?: Partial; + + // 默认值 + defaultValue?: any; + + // 额外默认值数组对象 + defaultValueObj?: { [key: string]: any }; + + // 是否自动处理与时间相关组件的默认值 + isHandleDateDefaultValue?: boolean; + + isAdvanced?: boolean; + + // Matching details components + span?: number; + + ifShow?: boolean | ((renderCallbackParams: RenderCallbackParams) => boolean); + + show?: boolean | ((renderCallbackParams: RenderCallbackParams) => boolean); + + // Render the content in the form-item tag + render?: ( + renderCallbackParams: RenderCallbackParams, + opts: RenderOpts, + ) => VNode | VNode[] | string; + + // Rendering col content requires outer wrapper form-item + renderColContent?: ( + renderCallbackParams: RenderCallbackParams, + opts: RenderOpts, + ) => VNode | VNode[] | string; + + renderComponentContent?: + | ((renderCallbackParams: RenderCallbackParams, opts: RenderOpts) => any) + | VNode + | VNode[] + | string; + + // Custom slot, in from-item + slot?: string; + + // Custom slot, similar to renderColContent + colSlot?: string; + + dynamicDisabled?: boolean | ((renderCallbackParams: RenderCallbackParams) => boolean); + + dynamicRules?: (renderCallbackParams: RenderCallbackParams) => Rule[]; +} +export interface HelpComponentProps { + maxWidth: string; + // Whether to display the serial number + showIndex: boolean; + // Text list + text: any; + // colour + color: string; + // font size + fontSize: string; + icon: string; + absolute: boolean; + // Positioning + position: any; +} diff --git a/src/components/Form/src/types/formItem.ts b/src/components/Form/src/types/formItem.ts new file mode 100644 index 0000000..77b238a --- /dev/null +++ b/src/components/Form/src/types/formItem.ts @@ -0,0 +1,91 @@ +import type { NamePath } from 'ant-design-vue/lib/form/interface'; +import type { ColProps } from 'ant-design-vue/lib/grid/Col'; +import type { HTMLAttributes, VNodeChild } from 'vue'; + +export interface FormItem { + /** + * Used with label, whether to display : after label text. + * @default true + * @type boolean + */ + colon?: boolean; + + /** + * The extra prompt message. It is similar to help. Usage example: to display error message and prompt message at the same time. + * @type any (string | slot) + */ + extra?: string | VNodeChild | JSX.Element; + + /** + * Used with validateStatus, this option specifies the validation status icon. Recommended to be used only with Input. + * @default false + * @type boolean + */ + hasFeedback?: boolean; + + /** + * The prompt message. If not provided, the prompt message will be generated by the validation rule. + * @type any (string | slot) + */ + help?: string | VNodeChild | JSX.Element; + + /** + * Label test + * @type any (string | slot) + */ + label?: string | VNodeChild | JSX.Element; + + /** + * The layout of label. You can set span offset to something like {span: 3, offset: 12} or sm: {span: 3, offset: 12} same as with + * @type Col + */ + labelCol?: ColProps & HTMLAttributes; + + /** + * Whether provided or not, it will be generated by the validation rule. + * @default false + * @type boolean + */ + required?: boolean; + + /** + * The validation status. If not provided, it will be generated by validation rule. options: 'success' 'warning' 'error' 'validating' + * @type string + */ + validateStatus?: '' | 'success' | 'warning' | 'error' | 'validating'; + + /** + * The layout for input controls, same as labelCol + * @type Col + */ + wrapperCol?: ColProps; + /** + * Set sub label htmlFor. + */ + htmlFor?: string; + /** + * text align of label + */ + labelAlign?: 'left' | 'right'; + /** + * a key of model. In the setting of validate and resetFields method, the attribute is required + */ + name?: NamePath; + /** + * validation rules of form + */ + rules?: object | object[]; + /** + * Whether to automatically associate form fields. In most cases, you can setting automatic association. + * If the conditions for automatic association are not met, you can manually associate them. See the notes below. + */ + autoLink?: boolean; + /** + * Whether stop validate on first rule of error for this field. + */ + validateFirst?: boolean; + /** + * When to validate the value of children node + */ + validateTrigger?: string | string[] | false; +} diff --git a/src/components/Form/src/types/hooks.ts b/src/components/Form/src/types/hooks.ts new file mode 100644 index 0000000..0308e73 --- /dev/null +++ b/src/components/Form/src/types/hooks.ts @@ -0,0 +1,6 @@ +export interface AdvanceState { + isAdvanced: boolean; + hideAdvanceBtn: boolean; + isLoad: boolean; + actionSpan: number; +} diff --git a/src/components/Form/src/types/index.ts b/src/components/Form/src/types/index.ts new file mode 100644 index 0000000..7238247 --- /dev/null +++ b/src/components/Form/src/types/index.ts @@ -0,0 +1,120 @@ +type ColSpanType = number | string; +export interface ColEx { + style?: any; + /** + * raster number of cells to occupy, 0 corresponds to display: none + * @default none (0) + * @type ColSpanType + */ + span?: ColSpanType; + + /** + * raster order, used in flex layout mode + * @default 0 + * @type ColSpanType + */ + order?: ColSpanType; + + /** + * the layout fill of flex + * @default none + * @type ColSpanType + */ + flex?: ColSpanType; + + /** + * the number of cells to offset Col from the left + * @default 0 + * @type ColSpanType + */ + offset?: ColSpanType; + + /** + * the number of cells that raster is moved to the right + * @default 0 + * @type ColSpanType + */ + push?: ColSpanType; + + /** + * the number of cells that raster is moved to the left + * @default 0 + * @type ColSpanType + */ + pull?: ColSpanType; + + /** + * <576px and also default setting, could be a span value or an object containing above props + * @type { span: ColSpanType, offset: ColSpanType } | ColSpanType + */ + xs?: { span: ColSpanType; offset: ColSpanType } | ColSpanType; + + /** + * ≥576px, could be a span value or an object containing above props + * @type { span: ColSpanType, offset: ColSpanType } | ColSpanType + */ + sm?: { span: ColSpanType; offset: ColSpanType } | ColSpanType; + + /** + * ≥768px, could be a span value or an object containing above props + * @type { span: ColSpanType, offset: ColSpanType } | ColSpanType + */ + md?: { span: ColSpanType; offset: ColSpanType } | ColSpanType; + + /** + * ≥992px, could be a span value or an object containing above props + * @type { span: ColSpanType, offset: ColSpanType } | ColSpanType + */ + lg?: { span: ColSpanType; offset: ColSpanType } | ColSpanType; + + /** + * ≥1200px, could be a span value or an object containing above props + * @type { span: ColSpanType, offset: ColSpanType } | ColSpanType + */ + xl?: { span: ColSpanType; offset: ColSpanType } | ColSpanType; + + /** + * ≥1600px, could be a span value or an object containing above props + * @type { span: ColSpanType, offset: ColSpanType } | ColSpanType + */ + xxl?: { span: ColSpanType; offset: ColSpanType } | ColSpanType; +} + +export type ComponentType = + | 'Input' + | 'InputGroup' + | 'InputPassword' + | 'InputSearch' + | 'InputTextArea' + | 'InputNumber' + | 'InputCountDown' + | 'Select' + | 'ApiSelect' + | 'TreeSelect' + | 'ApiTree' + | 'ApiTreeSelect' + | 'ApiMultipleSelect' + | 'ApiMultipleTreeSelect' + | 'ApiRadioGroup' + | 'RadioButtonGroup' + | 'RadioGroup' + | 'Checkbox' + | 'CheckboxGroup' + | 'AutoComplete' + | 'ApiCascader' + | 'Cascader' + | 'DatePicker' + | 'MonthPicker' + | 'RangePicker' + | 'WeekPicker' + | 'TimePicker' + | 'TimeRangePicker' + | 'Switch' + | 'StrengthMeter' + | 'Upload' + | 'IconPicker' + | 'Render' + | 'Slider' + | 'Rate' + | 'Divider' + | 'ApiTransfer'; diff --git a/src/components/Icon/Icon.vue b/src/components/Icon/Icon.vue new file mode 100644 index 0000000..58b970e --- /dev/null +++ b/src/components/Icon/Icon.vue @@ -0,0 +1,121 @@ + + + diff --git a/src/components/Icon/data/icons.data.ts b/src/components/Icon/data/icons.data.ts new file mode 100644 index 0000000..e5fe3e2 --- /dev/null +++ b/src/components/Icon/data/icons.data.ts @@ -0,0 +1,793 @@ +export default { + prefix: 'ant-design', + icons: [ + 'account-book-filled', + 'account-book-outlined', + 'account-book-twotone', + 'aim-outlined', + 'alert-filled', + 'alert-outlined', + 'alert-twotone', + 'alibaba-outlined', + 'align-center-outlined', + 'align-left-outlined', + 'align-right-outlined', + 'alipay-circle-filled', + 'alipay-circle-outlined', + 'alipay-outlined', + 'alipay-square-filled', + 'aliwangwang-filled', + 'aliwangwang-outlined', + 'aliyun-outlined', + 'amazon-circle-filled', + 'amazon-outlined', + 'amazon-square-filled', + 'android-filled', + 'android-outlined', + 'ant-cloud-outlined', + 'ant-design-outlined', + 'apartment-outlined', + 'api-filled', + 'api-outlined', + 'api-twotone', + 'apple-filled', + 'apple-outlined', + 'appstore-add-outlined', + 'appstore-filled', + 'appstore-outlined', + 'appstore-twotone', + 'area-chart-outlined', + 'arrow-down-outlined', + 'arrow-left-outlined', + 'arrow-right-outlined', + 'arrow-up-outlined', + 'arrows-alt-outlined', + 'audio-filled', + 'audio-muted-outlined', + 'audio-outlined', + 'audio-twotone', + 'audit-outlined', + 'backward-filled', + 'backward-outlined', + 'bank-filled', + 'bank-outlined', + 'bank-twotone', + 'bar-chart-outlined', + 'barcode-outlined', + 'bars-outlined', + 'behance-circle-filled', + 'behance-outlined', + 'behance-square-filled', + 'behance-square-outlined', + 'bell-filled', + 'bell-outlined', + 'bell-twotone', + 'bg-colors-outlined', + 'block-outlined', + 'bold-outlined', + 'book-filled', + 'book-outlined', + 'book-twotone', + 'border-bottom-outlined', + 'border-horizontal-outlined', + 'border-inner-outlined', + 'border-left-outlined', + 'border-outer-outlined', + 'border-outlined', + 'border-right-outlined', + 'border-top-outlined', + 'border-verticle-outlined', + 'borderless-table-outlined', + 'box-plot-filled', + 'box-plot-outlined', + 'box-plot-twotone', + 'branches-outlined', + 'bug-filled', + 'bug-outlined', + 'bug-twotone', + 'build-filled', + 'build-outlined', + 'build-twotone', + 'bulb-filled', + 'bulb-outlined', + 'bulb-twotone', + 'calculator-filled', + 'calculator-outlined', + 'calculator-twotone', + 'calendar-filled', + 'calendar-outlined', + 'calendar-twotone', + 'camera-filled', + 'camera-outlined', + 'camera-twotone', + 'car-filled', + 'car-outlined', + 'car-twotone', + 'caret-down-filled', + 'caret-down-outlined', + 'caret-left-filled', + 'caret-left-outlined', + 'caret-right-filled', + 'caret-right-outlined', + 'caret-up-filled', + 'caret-up-outlined', + 'carry-out-filled', + 'carry-out-outlined', + 'carry-out-twotone', + 'check-circle-filled', + 'check-circle-outlined', + 'check-circle-twotone', + 'check-outlined', + 'check-square-filled', + 'check-square-outlined', + 'check-square-twotone', + 'chrome-filled', + 'chrome-outlined', + 'ci-circle-filled', + 'ci-circle-outlined', + 'ci-circle-twotone', + 'ci-outlined', + 'ci-twotone', + 'clear-outlined', + 'clock-circle-filled', + 'clock-circle-outlined', + 'clock-circle-twotone', + 'close-circle-filled', + 'close-circle-outlined', + 'close-circle-twotone', + 'close-outlined', + 'close-square-filled', + 'close-square-outlined', + 'close-square-twotone', + 'cloud-download-outlined', + 'cloud-filled', + 'cloud-outlined', + 'cloud-server-outlined', + 'cloud-sync-outlined', + 'cloud-twotone', + 'cloud-upload-outlined', + 'cluster-outlined', + 'code-filled', + 'code-outlined', + 'code-sandbox-circle-filled', + 'code-sandbox-outlined', + 'code-sandbox-square-filled', + 'code-twotone', + 'codepen-circle-filled', + 'codepen-circle-outlined', + 'codepen-outlined', + 'codepen-square-filled', + 'coffee-outlined', + 'column-height-outlined', + 'column-width-outlined', + 'comment-outlined', + 'compass-filled', + 'compass-outlined', + 'compass-twotone', + 'compress-outlined', + 'console-sql-outlined', + 'contacts-filled', + 'contacts-outlined', + 'contacts-twotone', + 'container-filled', + 'container-outlined', + 'container-twotone', + 'control-filled', + 'control-outlined', + 'control-twotone', + 'copy-filled', + 'copy-outlined', + 'copy-twotone', + 'copyright-circle-filled', + 'copyright-circle-outlined', + 'copyright-circle-twotone', + 'copyright-outlined', + 'copyright-twotone', + 'credit-card-filled', + 'credit-card-outlined', + 'credit-card-twotone', + 'crown-filled', + 'crown-outlined', + 'crown-twotone', + 'customer-service-filled', + 'customer-service-outlined', + 'customer-service-twotone', + 'dash-outlined', + 'dashboard-filled', + 'dashboard-outlined', + 'dashboard-twotone', + 'database-filled', + 'database-outlined', + 'database-twotone', + 'delete-column-outlined', + 'delete-filled', + 'delete-outlined', + 'delete-row-outlined', + 'delete-twotone', + 'delivered-procedure-outlined', + 'deployment-unit-outlined', + 'desktop-outlined', + 'diff-filled', + 'diff-outlined', + 'diff-twotone', + 'dingding-outlined', + 'dingtalk-circle-filled', + 'dingtalk-outlined', + 'dingtalk-square-filled', + 'disconnect-outlined', + 'dislike-filled', + 'dislike-outlined', + 'dislike-twotone', + 'dollar-circle-filled', + 'dollar-circle-outlined', + 'dollar-circle-twotone', + 'dollar-outlined', + 'dollar-twotone', + 'dot-chart-outlined', + 'double-left-outlined', + 'double-right-outlined', + 'down-circle-filled', + 'down-circle-outlined', + 'down-circle-twotone', + 'down-outlined', + 'down-square-filled', + 'down-square-outlined', + 'down-square-twotone', + 'download-outlined', + 'drag-outlined', + 'dribbble-circle-filled', + 'dribbble-outlined', + 'dribbble-square-filled', + 'dribbble-square-outlined', + 'dropbox-circle-filled', + 'dropbox-outlined', + 'dropbox-square-filled', + 'edit-filled', + 'edit-outlined', + 'edit-twotone', + 'ellipsis-outlined', + 'enter-outlined', + 'environment-filled', + 'environment-outlined', + 'environment-twotone', + 'euro-circle-filled', + 'euro-circle-outlined', + 'euro-circle-twotone', + 'euro-outlined', + 'euro-twotone', + 'exception-outlined', + 'exclamation-circle-filled', + 'exclamation-circle-outlined', + 'exclamation-circle-twotone', + 'exclamation-outlined', + 'expand-alt-outlined', + 'expand-outlined', + 'experiment-filled', + 'experiment-outlined', + 'experiment-twotone', + 'export-outlined', + 'eye-filled', + 'eye-invisible-filled', + 'eye-invisible-outlined', + 'eye-invisible-twotone', + 'eye-outlined', + 'eye-twotone', + 'facebook-filled', + 'facebook-outlined', + 'fall-outlined', + 'fast-backward-filled', + 'fast-backward-outlined', + 'fast-forward-filled', + 'fast-forward-outlined', + 'field-binary-outlined', + 'field-number-outlined', + 'field-string-outlined', + 'field-time-outlined', + 'file-add-filled', + 'file-add-outlined', + 'file-add-twotone', + 'file-done-outlined', + 'file-excel-filled', + 'file-excel-outlined', + 'file-excel-twotone', + 'file-exclamation-filled', + 'file-exclamation-outlined', + 'file-exclamation-twotone', + 'file-filled', + 'file-gif-outlined', + 'file-image-filled', + 'file-image-outlined', + 'file-image-twotone', + 'file-jpg-outlined', + 'file-markdown-filled', + 'file-markdown-outlined', + 'file-markdown-twotone', + 'file-outlined', + 'file-pdf-filled', + 'file-pdf-outlined', + 'file-pdf-twotone', + 'file-ppt-filled', + 'file-ppt-outlined', + 'file-ppt-twotone', + 'file-protect-outlined', + 'file-search-outlined', + 'file-sync-outlined', + 'file-text-filled', + 'file-text-outlined', + 'file-text-twotone', + 'file-twotone', + 'file-unknown-filled', + 'file-unknown-outlined', + 'file-unknown-twotone', + 'file-word-filled', + 'file-word-outlined', + 'file-word-twotone', + 'file-zip-filled', + 'file-zip-outlined', + 'file-zip-twotone', + 'filter-filled', + 'filter-outlined', + 'filter-twotone', + 'fire-filled', + 'fire-outlined', + 'fire-twotone', + 'flag-filled', + 'flag-outlined', + 'flag-twotone', + 'folder-add-filled', + 'folder-add-outlined', + 'folder-add-twotone', + 'folder-filled', + 'folder-open-filled', + 'folder-open-outlined', + 'folder-open-twotone', + 'folder-outlined', + 'folder-twotone', + 'folder-view-outlined', + 'font-colors-outlined', + 'font-size-outlined', + 'fork-outlined', + 'form-outlined', + 'format-painter-filled', + 'format-painter-outlined', + 'forward-filled', + 'forward-outlined', + 'frown-filled', + 'frown-outlined', + 'frown-twotone', + 'fullscreen-exit-outlined', + 'fullscreen-outlined', + 'function-outlined', + 'fund-filled', + 'fund-outlined', + 'fund-projection-screen-outlined', + 'fund-twotone', + 'fund-view-outlined', + 'funnel-plot-filled', + 'funnel-plot-outlined', + 'funnel-plot-twotone', + 'gateway-outlined', + 'gif-outlined', + 'gift-filled', + 'gift-outlined', + 'gift-twotone', + 'github-filled', + 'github-outlined', + 'gitlab-filled', + 'gitlab-outlined', + 'global-outlined', + 'gold-filled', + 'gold-outlined', + 'gold-twotone', + 'golden-filled', + 'google-circle-filled', + 'google-outlined', + 'google-plus-circle-filled', + 'google-plus-outlined', + 'google-plus-square-filled', + 'google-square-filled', + 'group-outlined', + 'hdd-filled', + 'hdd-outlined', + 'hdd-twotone', + 'heart-filled', + 'heart-outlined', + 'heart-twotone', + 'heat-map-outlined', + 'highlight-filled', + 'highlight-outlined', + 'highlight-twotone', + 'history-outlined', + 'home-filled', + 'home-outlined', + 'home-twotone', + 'hourglass-filled', + 'hourglass-outlined', + 'hourglass-twotone', + 'html5-filled', + 'html5-outlined', + 'html5-twotone', + 'idcard-filled', + 'idcard-outlined', + 'idcard-twotone', + 'ie-circle-filled', + 'ie-outlined', + 'ie-square-filled', + 'import-outlined', + 'inbox-outlined', + 'info-circle-filled', + 'info-circle-outlined', + 'info-circle-twotone', + 'info-outlined', + 'insert-row-above-outlined', + 'insert-row-below-outlined', + 'insert-row-left-outlined', + 'insert-row-right-outlined', + 'instagram-filled', + 'instagram-outlined', + 'insurance-filled', + 'insurance-outlined', + 'insurance-twotone', + 'interaction-filled', + 'interaction-outlined', + 'interaction-twotone', + 'issues-close-outlined', + 'italic-outlined', + 'key-outlined', + 'laptop-outlined', + 'layout-filled', + 'layout-outlined', + 'layout-twotone', + 'left-circle-filled', + 'left-circle-outlined', + 'left-circle-twotone', + 'left-outlined', + 'left-square-filled', + 'left-square-outlined', + 'left-square-twotone', + 'like-filled', + 'like-outlined', + 'like-twotone', + 'line-chart-outlined', + 'line-height-outlined', + 'line-outlined', + 'link-outlined', + 'linkedin-filled', + 'linkedin-outlined', + 'loading-3-quarters-outlined', + 'loading-outlined', + 'lock-filled', + 'lock-outlined', + 'lock-twotone', + 'login-outlined', + 'logout-outlined', + 'mac-command-filled', + 'mac-command-outlined', + 'mail-filled', + 'mail-outlined', + 'mail-twotone', + 'man-outlined', + 'medicine-box-filled', + 'medicine-box-outlined', + 'medicine-box-twotone', + 'medium-circle-filled', + 'medium-outlined', + 'medium-square-filled', + 'medium-workmark-outlined', + 'meh-filled', + 'meh-outlined', + 'meh-twotone', + 'menu-fold-outlined', + 'menu-outlined', + 'menu-unfold-outlined', + 'merge-cells-outlined', + 'message-filled', + 'message-outlined', + 'message-twotone', + 'minus-circle-filled', + 'minus-circle-outlined', + 'minus-circle-twotone', + 'minus-outlined', + 'minus-square-filled', + 'minus-square-outlined', + 'minus-square-twotone', + 'mobile-filled', + 'mobile-outlined', + 'mobile-twotone', + 'money-collect-filled', + 'money-collect-outlined', + 'money-collect-twotone', + 'monitor-outlined', + 'more-outlined', + 'node-collapse-outlined', + 'node-expand-outlined', + 'node-index-outlined', + 'notification-filled', + 'notification-outlined', + 'notification-twotone', + 'number-outlined', + 'one-to-one-outlined', + 'ordered-list-outlined', + 'paper-clip-outlined', + 'partition-outlined', + 'pause-circle-filled', + 'pause-circle-outlined', + 'pause-circle-twotone', + 'pause-outlined', + 'pay-circle-filled', + 'pay-circle-outlined', + 'percentage-outlined', + 'phone-filled', + 'phone-outlined', + 'phone-twotone', + 'pic-center-outlined', + 'pic-left-outlined', + 'pic-right-outlined', + 'picture-filled', + 'picture-outlined', + 'picture-twotone', + 'pie-chart-filled', + 'pie-chart-outlined', + 'pie-chart-twotone', + 'play-circle-filled', + 'play-circle-outlined', + 'play-circle-twotone', + 'play-square-filled', + 'play-square-outlined', + 'play-square-twotone', + 'plus-circle-filled', + 'plus-circle-outlined', + 'plus-circle-twotone', + 'plus-outlined', + 'plus-square-filled', + 'plus-square-outlined', + 'plus-square-twotone', + 'pound-circle-filled', + 'pound-circle-outlined', + 'pound-circle-twotone', + 'pound-outlined', + 'poweroff-outlined', + 'printer-filled', + 'printer-outlined', + 'printer-twotone', + 'profile-filled', + 'profile-outlined', + 'profile-twotone', + 'project-filled', + 'project-outlined', + 'project-twotone', + 'property-safety-filled', + 'property-safety-outlined', + 'property-safety-twotone', + 'pull-request-outlined', + 'pushpin-filled', + 'pushpin-outlined', + 'pushpin-twotone', + 'qq-circle-filled', + 'qq-outlined', + 'qq-square-filled', + 'qrcode-outlined', + 'question-circle-filled', + 'question-circle-outlined', + 'question-circle-twotone', + 'question-outlined', + 'radar-chart-outlined', + 'radius-bottomleft-outlined', + 'radius-bottomright-outlined', + 'radius-setting-outlined', + 'radius-upleft-outlined', + 'radius-upright-outlined', + 'read-filled', + 'read-outlined', + 'reconciliation-filled', + 'reconciliation-outlined', + 'reconciliation-twotone', + 'red-envelope-filled', + 'red-envelope-outlined', + 'red-envelope-twotone', + 'reddit-circle-filled', + 'reddit-outlined', + 'reddit-square-filled', + 'redo-outlined', + 'reload-outlined', + 'rest-filled', + 'rest-outlined', + 'rest-twotone', + 'retweet-outlined', + 'right-circle-filled', + 'right-circle-outlined', + 'right-circle-twotone', + 'right-outlined', + 'right-square-filled', + 'right-square-outlined', + 'right-square-twotone', + 'rise-outlined', + 'robot-filled', + 'robot-outlined', + 'rocket-filled', + 'rocket-outlined', + 'rocket-twotone', + 'rollback-outlined', + 'rotate-left-outlined', + 'rotate-right-outlined', + 'safety-certificate-filled', + 'safety-certificate-outlined', + 'safety-certificate-twotone', + 'safety-outlined', + 'save-filled', + 'save-outlined', + 'save-twotone', + 'scan-outlined', + 'schedule-filled', + 'schedule-outlined', + 'schedule-twotone', + 'scissor-outlined', + 'search-outlined', + 'security-scan-filled', + 'security-scan-outlined', + 'security-scan-twotone', + 'select-outlined', + 'send-outlined', + 'setting-filled', + 'setting-outlined', + 'setting-twotone', + 'shake-outlined', + 'share-alt-outlined', + 'shop-filled', + 'shop-outlined', + 'shop-twotone', + 'shopping-cart-outlined', + 'shopping-filled', + 'shopping-outlined', + 'shopping-twotone', + 'shrink-outlined', + 'signal-filled', + 'sisternode-outlined', + 'sketch-circle-filled', + 'sketch-outlined', + 'sketch-square-filled', + 'skin-filled', + 'skin-outlined', + 'skin-twotone', + 'skype-filled', + 'skype-outlined', + 'slack-circle-filled', + 'slack-outlined', + 'slack-square-filled', + 'slack-square-outlined', + 'sliders-filled', + 'sliders-outlined', + 'sliders-twotone', + 'small-dash-outlined', + 'smile-filled', + 'smile-outlined', + 'smile-twotone', + 'snippets-filled', + 'snippets-outlined', + 'snippets-twotone', + 'solution-outlined', + 'sort-ascending-outlined', + 'sort-descending-outlined', + 'sound-filled', + 'sound-outlined', + 'sound-twotone', + 'split-cells-outlined', + 'star-filled', + 'star-outlined', + 'star-twotone', + 'step-backward-filled', + 'step-backward-outlined', + 'step-forward-filled', + 'step-forward-outlined', + 'stock-outlined', + 'stop-filled', + 'stop-outlined', + 'stop-twotone', + 'strikethrough-outlined', + 'subnode-outlined', + 'swap-left-outlined', + 'swap-outlined', + 'swap-right-outlined', + 'switcher-filled', + 'switcher-outlined', + 'switcher-twotone', + 'sync-outlined', + 'table-outlined', + 'tablet-filled', + 'tablet-outlined', + 'tablet-twotone', + 'tag-filled', + 'tag-outlined', + 'tag-twotone', + 'tags-filled', + 'tags-outlined', + 'tags-twotone', + 'taobao-circle-filled', + 'taobao-circle-outlined', + 'taobao-outlined', + 'taobao-square-filled', + 'team-outlined', + 'thunderbolt-filled', + 'thunderbolt-outlined', + 'thunderbolt-twotone', + 'to-top-outlined', + 'tool-filled', + 'tool-outlined', + 'tool-twotone', + 'trademark-circle-filled', + 'trademark-circle-outlined', + 'trademark-circle-twotone', + 'trademark-outlined', + 'transaction-outlined', + 'translation-outlined', + 'trophy-filled', + 'trophy-outlined', + 'trophy-twotone', + 'twitter-circle-filled', + 'twitter-outlined', + 'twitter-square-filled', + 'underline-outlined', + 'undo-outlined', + 'ungroup-outlined', + 'unlock-filled', + 'unlock-outlined', + 'unlock-twotone', + 'unordered-list-outlined', + 'up-circle-filled', + 'up-circle-outlined', + 'up-circle-twotone', + 'up-outlined', + 'up-square-filled', + 'up-square-outlined', + 'up-square-twotone', + 'upload-outlined', + 'usb-filled', + 'usb-outlined', + 'usb-twotone', + 'user-add-outlined', + 'user-delete-outlined', + 'user-outlined', + 'user-switch-outlined', + 'usergroup-add-outlined', + 'usergroup-delete-outlined', + 'verified-outlined', + 'vertical-align-bottom-outlined', + 'vertical-align-middle-outlined', + 'vertical-align-top-outlined', + 'vertical-left-outlined', + 'vertical-right-outlined', + 'video-camera-add-outlined', + 'video-camera-filled', + 'video-camera-outlined', + 'video-camera-twotone', + 'wallet-filled', + 'wallet-outlined', + 'wallet-twotone', + 'warning-filled', + 'warning-outlined', + 'warning-twotone', + 'wechat-filled', + 'wechat-outlined', + 'weibo-circle-filled', + 'weibo-circle-outlined', + 'weibo-outlined', + 'weibo-square-filled', + 'weibo-square-outlined', + 'whats-app-outlined', + 'wifi-outlined', + 'windows-filled', + 'windows-outlined', + 'woman-outlined', + 'yahoo-filled', + 'yahoo-outlined', + 'youtube-filled', + 'youtube-outlined', + 'yuque-filled', + 'yuque-outlined', + 'zhihu-circle-filled', + 'zhihu-outlined', + 'zhihu-square-filled', + 'zoom-in-outlined', + 'zoom-out-outlined', + ], +}; diff --git a/src/components/Icon/index.ts b/src/components/Icon/index.ts new file mode 100644 index 0000000..9e2bc0b --- /dev/null +++ b/src/components/Icon/index.ts @@ -0,0 +1,4 @@ +import SvgIcon from './src/SvgIcon.vue'; +import IconPicker from './src/IconPicker.vue'; + +export { IconPicker, SvgIcon }; diff --git a/src/components/Icon/src/IconPicker.vue b/src/components/Icon/src/IconPicker.vue new file mode 100644 index 0000000..adcf01a --- /dev/null +++ b/src/components/Icon/src/IconPicker.vue @@ -0,0 +1,200 @@ + + + diff --git a/src/components/Icon/src/SvgIcon.vue b/src/components/Icon/src/SvgIcon.vue new file mode 100644 index 0000000..c79c644 --- /dev/null +++ b/src/components/Icon/src/SvgIcon.vue @@ -0,0 +1,65 @@ + + + diff --git a/src/components/Loading/index.ts b/src/components/Loading/index.ts new file mode 100644 index 0000000..3673a44 --- /dev/null +++ b/src/components/Loading/index.ts @@ -0,0 +1,5 @@ +import Loading from './src/Loading.vue'; + +export { Loading }; +export { useLoading } from './src/useLoading'; +export { createLoading } from './src/createLoading'; diff --git a/src/components/Loading/src/Loading.vue b/src/components/Loading/src/Loading.vue new file mode 100644 index 0000000..3803085 --- /dev/null +++ b/src/components/Loading/src/Loading.vue @@ -0,0 +1,78 @@ + + + diff --git a/src/components/Loading/src/createLoading.ts b/src/components/Loading/src/createLoading.ts new file mode 100644 index 0000000..0076dc1 --- /dev/null +++ b/src/components/Loading/src/createLoading.ts @@ -0,0 +1,63 @@ +import { VNode, defineComponent, createVNode, render, reactive, h } from 'vue'; +import type { LoadingProps } from './typing'; + +import Loading from './Loading.vue'; + +export function createLoading(props?: Partial, target?: HTMLElement, wait = false) { + let vm: Nullable = null; + const data = reactive({ + tip: '', + loading: true, + ...props, + }); + + const LoadingWrap = defineComponent({ + render() { + return h(Loading, { ...data }); + }, + }); + + vm = createVNode(LoadingWrap); + + if (wait) { + setTimeout(() => { + render(vm, document.createElement('div')); + }, 0); + } else { + render(vm, document.createElement('div')); + } + + function close() { + if (vm?.el && vm.el.parentNode) { + vm.el.parentNode.removeChild(vm.el); + } + } + + function open(target: HTMLElement = document.body) { + if (!vm || !vm.el) { + return; + } + target.appendChild(vm.el as HTMLElement); + } + + if (target) { + open(target); + } + return { + vm, + close, + open, + setTip: (tip: string) => { + data.tip = tip; + }, + setLoading: (loading: boolean) => { + data.loading = loading; + }, + get loading() { + return data.loading; + }, + get $el() { + return vm?.el as HTMLElement; + }, + }; +} diff --git a/src/components/Loading/src/typing.ts b/src/components/Loading/src/typing.ts new file mode 100644 index 0000000..9af60e6 --- /dev/null +++ b/src/components/Loading/src/typing.ts @@ -0,0 +1,10 @@ +import { SizeEnum } from '/@/enums/sizeEnum'; + +export interface LoadingProps { + tip: string; + size: SizeEnum; + absolute: boolean; + loading: boolean; + background: string; + theme: 'dark' | 'light'; +} diff --git a/src/components/Loading/src/useLoading.ts b/src/components/Loading/src/useLoading.ts new file mode 100644 index 0000000..356df7d --- /dev/null +++ b/src/components/Loading/src/useLoading.ts @@ -0,0 +1,49 @@ +import { unref } from 'vue'; +import { createLoading } from './createLoading'; +import type { LoadingProps } from './typing'; +import type { Ref } from 'vue'; + +export interface UseLoadingOptions { + target?: any; + props?: Partial; +} + +interface Fn { + (): void; +} + +export function useLoading(props: Partial): [Fn, Fn, (string) => void]; +export function useLoading(opt: Partial): [Fn, Fn, (string) => void]; + +export function useLoading( + opt: Partial | Partial, +): [Fn, Fn, (string) => void] { + let props: Partial; + let target: HTMLElement | Ref = document.body; + + if (Reflect.has(opt, 'target') || Reflect.has(opt, 'props')) { + const options = opt as Partial; + props = options.props || {}; + target = options.target || document.body; + } else { + props = opt as Partial; + } + + const instance = createLoading(props, undefined, true); + + const open = (): void => { + const t = unref(target as Ref); + if (!t) return; + instance.open(t); + }; + + const close = (): void => { + instance.close(); + }; + + const setTip = (tip: string) => { + instance.setTip(tip); + }; + + return [open, close, setTip]; +} diff --git a/src/components/Menu/index.ts b/src/components/Menu/index.ts new file mode 100644 index 0000000..4a59225 --- /dev/null +++ b/src/components/Menu/index.ts @@ -0,0 +1,3 @@ +import BasicMenu from './src/BasicMenu.vue'; + +export { BasicMenu }; diff --git a/src/components/Menu/src/BasicMenu.vue b/src/components/Menu/src/BasicMenu.vue new file mode 100644 index 0000000..ca8dcaa --- /dev/null +++ b/src/components/Menu/src/BasicMenu.vue @@ -0,0 +1,164 @@ + + + diff --git a/src/components/Menu/src/components/BasicMenuItem.vue b/src/components/Menu/src/components/BasicMenuItem.vue new file mode 100644 index 0000000..4d48362 --- /dev/null +++ b/src/components/Menu/src/components/BasicMenuItem.vue @@ -0,0 +1,21 @@ + + diff --git a/src/components/Menu/src/components/BasicSubMenuItem.vue b/src/components/Menu/src/components/BasicSubMenuItem.vue new file mode 100644 index 0000000..d5139fc --- /dev/null +++ b/src/components/Menu/src/components/BasicSubMenuItem.vue @@ -0,0 +1,55 @@ + + diff --git a/src/components/Menu/src/components/MenuItemContent.vue b/src/components/Menu/src/components/MenuItemContent.vue new file mode 100644 index 0000000..3d3351d --- /dev/null +++ b/src/components/Menu/src/components/MenuItemContent.vue @@ -0,0 +1,34 @@ + + diff --git a/src/components/Menu/src/index.less b/src/components/Menu/src/index.less new file mode 100644 index 0000000..ff85930 --- /dev/null +++ b/src/components/Menu/src/index.less @@ -0,0 +1,74 @@ +@basic-menu-prefix-cls: ~'@{namespace}-basic-menu'; + +.app-top-menu-popup { + min-width: 150px; +} + +.@{basic-menu-prefix-cls} { + width: 100%; + + .ant-menu-item { + transition: unset; + } + + &__sidebar-hor { + &.ant-menu-horizontal { + display: flex; + align-items: center; + + &.ant-menu-dark { + background-color: transparent; + + .ant-menu-submenu:hover, + .ant-menu-item-open, + .ant-menu-submenu-open, + .ant-menu-item-selected, + .ant-menu-submenu-selected, + .ant-menu-item:hover, + .ant-menu-item-active, + .ant-menu:not(.ant-menu-inline) .ant-menu-submenu-open, + .ant-menu-submenu-active, + .ant-menu-submenu-title:hover { + background-color: @top-menu-active-bg-color !important; + color: #fff; + } + + .ant-menu-item:hover, + .ant-menu-item-active, + .ant-menu:not(.ant-menu-inline) .ant-menu-submenu-open, + .ant-menu-submenu-active, + .ant-menu-submenu-title:hover { + background-color: @top-menu-active-bg-color; + } + + .@{basic-menu-prefix-cls}-item__level1 { + background-color: transparent; + + &.ant-menu-item-selected, + &.ant-menu-submenu-selected { + background-color: @top-menu-active-bg-color !important; + } + } + + .ant-menu-item, + .ant-menu-submenu { + &.@{basic-menu-prefix-cls}-item__level1, + .ant-menu-submenu-title { + height: @header-height; + line-height: @header-height; + } + } + } + } + } + + .ant-menu-submenu, + .ant-menu-submenu-inline { + transition: unset; + } + + .ant-menu-inline.ant-menu-sub { + transition: unset; + box-shadow: unset !important; + } +} diff --git a/src/components/Menu/src/props.ts b/src/components/Menu/src/props.ts new file mode 100644 index 0000000..480297d --- /dev/null +++ b/src/components/Menu/src/props.ts @@ -0,0 +1,61 @@ +import type { Menu } from '/@/router/types'; +import type { PropType } from 'vue'; + +import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum'; +import { ThemeEnum } from '/@/enums/appEnum'; +import { propTypes } from '/@/utils/propTypes'; +import type { MenuTheme } from 'ant-design-vue'; +import type { MenuMode } from 'ant-design-vue/lib/menu/src/interface'; + +export const basicProps = { + items: { + type: Array as PropType, + default: () => [], + }, + collapsedShowTitle: propTypes.bool, + // 最好是4 倍数 + inlineIndent: propTypes.number.def(20), + // 菜单组件的mode属性 + mode: { + type: String as PropType, + default: MenuModeEnum.INLINE, + }, + + type: { + type: String as PropType, + default: MenuTypeEnum.MIX, + }, + theme: { + type: String as PropType, + default: ThemeEnum.DARK, + }, + inlineCollapsed: propTypes.bool, + mixSider: propTypes.bool, + + isHorizontal: propTypes.bool, + accordion: propTypes.bool.def(true), + beforeClickFn: { + type: Function as PropType<(key: string) => Promise>, + }, +}; + +export const itemProps = { + item: { + type: Object as PropType, + default: () => ({}), + }, + level: propTypes.number, + theme: propTypes.oneOf(['dark', 'light']), + showTitle: propTypes.bool, + isHorizontal: propTypes.bool, +}; + +export const contentProps = { + item: { + type: Object as PropType, + default: null, + }, + showTitle: propTypes.bool.def(true), + level: propTypes.number.def(0), + isHorizontal: propTypes.bool.def(true), +}; diff --git a/src/components/Menu/src/types.ts b/src/components/Menu/src/types.ts new file mode 100644 index 0000000..ad711c2 --- /dev/null +++ b/src/components/Menu/src/types.ts @@ -0,0 +1,25 @@ +// import { ComputedRef } from 'vue'; +// import { ThemeEnum } from '/@/enums/appEnum'; +// import { MenuModeEnum } from '/@/enums/menuEnum'; +export interface MenuState { + // 默认选中的列表 + defaultSelectedKeys: string[]; + + // 模式 + // mode: MenuModeEnum; + + // // 主题 + // theme: ComputedRef | ThemeEnum; + + // 缩进 + inlineIndent?: number; + + // 展开数组 + openKeys: string[]; + + // 当前选中的菜单项 key 数组 + selectedKeys: string[]; + + // 收缩状态下展开的数组 + collapsedOpenKeys: string[]; +} diff --git a/src/components/Menu/src/useOpenKeys.ts b/src/components/Menu/src/useOpenKeys.ts new file mode 100644 index 0000000..fc0b5a5 --- /dev/null +++ b/src/components/Menu/src/useOpenKeys.ts @@ -0,0 +1,81 @@ +import { MenuModeEnum } from '/@/enums/menuEnum'; +import type { Menu as MenuType } from '/@/router/types'; +import type { MenuState } from './types'; +import { computed, Ref, toRaw, unref } from 'vue'; +import { useTimeoutFn } from '@vben/hooks'; +import { uniq } from 'lodash-es'; +import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; +import { getAllParentPath } from '/@/router/helper/menuHelper'; + +export function useOpenKeys( + menuState: MenuState, + menus: Ref, + mode: Ref, + accordion: Ref, +) { + const { getCollapsed, getIsMixSidebar } = useMenuSetting(); + + async function setOpenKeys(path: string) { + if (mode.value === MenuModeEnum.HORIZONTAL) { + return; + } + const native = unref(getIsMixSidebar); + const handle = () => { + const menuList = toRaw(menus.value); + if (menuList?.length === 0) { + menuState.openKeys = []; + return; + } + if (!unref(accordion)) { + menuState.openKeys = uniq([...menuState.openKeys, ...getAllParentPath(menuList, path)]); + } else { + menuState.openKeys = getAllParentPath(menuList, path); + } + }; + if (native) { + handle(); + } else { + useTimeoutFn(handle, 16); + } + } + + const getOpenKeys = computed(() => { + const collapse = unref(getIsMixSidebar) ? false : unref(getCollapsed); + + return collapse ? menuState.collapsedOpenKeys : menuState.openKeys; + }); + + /** + * @description: 重置值 + */ + function resetKeys() { + menuState.selectedKeys = []; + menuState.openKeys = []; + } + + function handleOpenChange(openKeys: string[]) { + if (unref(mode) === MenuModeEnum.HORIZONTAL || !unref(accordion) || unref(getIsMixSidebar)) { + menuState.openKeys = openKeys; + } else { + // const menuList = toRaw(menus.value); + // getAllParentPath(menuList, path); + const rootSubMenuKeys: string[] = []; + for (const { children, path } of unref(menus)) { + if (children && children.length > 0) { + rootSubMenuKeys.push(path); + } + } + if (!unref(getCollapsed)) { + const latestOpenKey = openKeys.find((key) => menuState.openKeys.indexOf(key) === -1); + if (rootSubMenuKeys.indexOf(latestOpenKey as string) === -1) { + menuState.openKeys = openKeys; + } else { + menuState.openKeys = latestOpenKey ? [latestOpenKey] : []; + } + } else { + menuState.collapsedOpenKeys = openKeys; + } + } + } + return { setOpenKeys, resetKeys, getOpenKeys, handleOpenChange }; +} diff --git a/src/components/Modal/index.ts b/src/components/Modal/index.ts new file mode 100644 index 0000000..6188c5c --- /dev/null +++ b/src/components/Modal/index.ts @@ -0,0 +1,8 @@ +import { withInstall } from '/@/utils'; +import './src/index.less'; +import basicModal from './src/BasicModal.vue'; + +export const BasicModal = withInstall(basicModal); +export { useModalContext } from './src/hooks/useModalContext'; +export { useModal, useModalInner } from './src/hooks/useModal'; +export * from './src/typing'; diff --git a/src/components/Modal/src/BasicModal.vue b/src/components/Modal/src/BasicModal.vue new file mode 100644 index 0000000..39288c2 --- /dev/null +++ b/src/components/Modal/src/BasicModal.vue @@ -0,0 +1,243 @@ + + diff --git a/src/components/Modal/src/components/Modal.tsx b/src/components/Modal/src/components/Modal.tsx new file mode 100644 index 0000000..3b3a50d --- /dev/null +++ b/src/components/Modal/src/components/Modal.tsx @@ -0,0 +1,31 @@ +import { Modal } from 'ant-design-vue'; +import { defineComponent, toRefs, unref } from 'vue'; +import { basicProps } from '../props'; +import { useModalDragMove } from '../hooks/useModalDrag'; +import { useAttrs } from '@vben/hooks'; +import { extendSlots } from '/@/utils/helper/tsxHelper'; + +export default defineComponent({ + name: 'Modal', + inheritAttrs: false, + props: basicProps as any, + emits: ['cancel'], + setup(props, { slots, emit }) { + const { open, draggable, destroyOnClose } = toRefs(props); + const attrs = useAttrs(); + useModalDragMove({ + open, + destroyOnClose, + draggable, + }); + + const onCancel = (e: Event) => { + emit('cancel', e); + }; + + return () => { + const propsData = { ...unref(attrs), ...props, onCancel } as Recordable; + return {extendSlots(slots)}; + }; + }, +}); diff --git a/src/components/Modal/src/components/ModalClose.vue b/src/components/Modal/src/components/ModalClose.vue new file mode 100644 index 0000000..6dbf2c0 --- /dev/null +++ b/src/components/Modal/src/components/ModalClose.vue @@ -0,0 +1,106 @@ + + + diff --git a/src/components/Modal/src/components/ModalFooter.vue b/src/components/Modal/src/components/ModalFooter.vue new file mode 100644 index 0000000..7ea98dd --- /dev/null +++ b/src/components/Modal/src/components/ModalFooter.vue @@ -0,0 +1,41 @@ + + diff --git a/src/components/Modal/src/components/ModalHeader.vue b/src/components/Modal/src/components/ModalHeader.vue new file mode 100644 index 0000000..ac0b2b1 --- /dev/null +++ b/src/components/Modal/src/components/ModalHeader.vue @@ -0,0 +1,21 @@ + + diff --git a/src/components/Modal/src/components/ModalWrapper.vue b/src/components/Modal/src/components/ModalWrapper.vue new file mode 100644 index 0000000..d48be56 --- /dev/null +++ b/src/components/Modal/src/components/ModalWrapper.vue @@ -0,0 +1,170 @@ + + diff --git a/src/components/Modal/src/hooks/useModal.ts b/src/components/Modal/src/hooks/useModal.ts new file mode 100644 index 0000000..da1883e --- /dev/null +++ b/src/components/Modal/src/hooks/useModal.ts @@ -0,0 +1,163 @@ +import type { + UseModalReturnType, + ModalMethods, + ModalProps, + ReturnMethods, + UseModalInnerReturnType, +} from '../typing'; +import { + ref, + onUnmounted, + unref, + getCurrentInstance, + reactive, + watchEffect, + nextTick, + toRaw, + computed, +} from 'vue'; +import { isProdMode } from '/@/utils/env'; +import { isFunction } from '/@/utils/is'; +import { isEqual } from 'lodash-es'; +import { tryOnUnmounted } from '@vueuse/core'; +import { error } from '/@/utils/log'; + +const dataTransfer = reactive({}); + +const openData = reactive<{ [key: number]: boolean }>({}); + +/** + * @description: Applicable to independent modal and call outside + */ +export function useModal(): UseModalReturnType { + const modal = ref>(null); + const loaded = ref>(false); + const uid = ref(''); + + function register(modalMethod: ModalMethods, uuid: string) { + if (!getCurrentInstance()) { + throw new Error('useModal() can only be used inside setup() or functional components!'); + } + uid.value = uuid; + isProdMode() && + onUnmounted(() => { + modal.value = null; + loaded.value = false; + dataTransfer[unref(uid)] = null; + }); + if (unref(loaded) && isProdMode() && modalMethod === unref(modal)) return; + + modal.value = modalMethod; + loaded.value = true; + modalMethod.emitOpen = (open: boolean, uid: number) => { + openData[uid] = open; + }; + } + + const getInstance = () => { + const instance = unref(modal); + if (!instance) { + error('useModal instance is undefined!'); + } + return instance; + }; + + const methods: ReturnMethods = { + setModalProps: (props: Partial): void => { + getInstance()?.setModalProps(props); + }, + + getOpen: computed((): boolean => { + return openData[~~unref(uid)]; + }), + + redoModalHeight: () => { + getInstance()?.redoModalHeight?.(); + }, + + openModal: (open = true, data?: T, openOnSet = true): void => { + getInstance()?.setModalProps({ + open, + }); + + if (!data) return; + const id = unref(uid); + if (openOnSet) { + dataTransfer[id] = null; + dataTransfer[id] = toRaw(data); + return; + } + const equal = isEqual(toRaw(dataTransfer[id]), toRaw(data)); + if (!equal) { + dataTransfer[id] = toRaw(data); + } + }, + + closeModal: () => { + getInstance()?.setModalProps({ open: false }); + }, + }; + return [register, methods]; +} + +export const useModalInner = (callbackFn?: Fn): UseModalInnerReturnType => { + const modalInstanceRef = ref>(null); + const currentInstance = getCurrentInstance(); + const uidRef = ref(''); + + const getInstance = () => { + const instance = unref(modalInstanceRef); + if (!instance) { + error('useModalInner instance is undefined!'); + } + return instance; + }; + + const register = (modalInstance: ModalMethods, uuid: string) => { + isProdMode() && + tryOnUnmounted(() => { + modalInstanceRef.value = null; + }); + uidRef.value = uuid; + modalInstanceRef.value = modalInstance; + currentInstance?.emit('register', modalInstance, uuid); + }; + + watchEffect(() => { + const data = dataTransfer[unref(uidRef)]; + if (!data) return; + if (!callbackFn || !isFunction(callbackFn)) return; + nextTick(() => { + callbackFn(data); + }); + }); + + return [ + register, + { + changeLoading: (loading = true) => { + getInstance()?.setModalProps({ loading }); + }, + getOpen: computed((): boolean => { + return openData[~~unref(uidRef)]; + }), + + changeOkLoading: (loading = true) => { + getInstance()?.setModalProps({ confirmLoading: loading }); + }, + + closeModal: () => { + getInstance()?.setModalProps({ open: false }); + }, + + setModalProps: (props: Partial) => { + getInstance()?.setModalProps(props); + }, + + redoModalHeight: () => { + const callRedo = getInstance()?.redoModalHeight; + callRedo && callRedo(); + }, + }, + ]; +}; diff --git a/src/components/Modal/src/hooks/useModalContext.ts b/src/components/Modal/src/hooks/useModalContext.ts new file mode 100644 index 0000000..94d4c4e --- /dev/null +++ b/src/components/Modal/src/hooks/useModalContext.ts @@ -0,0 +1,16 @@ +import { InjectionKey } from 'vue'; +import { createContext, useContext } from '/@/hooks/core/useContext'; + +export interface ModalContextProps { + redoModalHeight: () => void; +} + +const key: InjectionKey = Symbol(); + +export function createModalContext(context: ModalContextProps) { + return createContext(context, key); +} + +export function useModalContext() { + return useContext(key); +} diff --git a/src/components/Modal/src/hooks/useModalDrag.ts b/src/components/Modal/src/hooks/useModalDrag.ts new file mode 100644 index 0000000..d17b27e --- /dev/null +++ b/src/components/Modal/src/hooks/useModalDrag.ts @@ -0,0 +1,107 @@ +import { Ref, unref, watchEffect } from 'vue'; +import { useTimeoutFn } from '@vben/hooks'; + +export interface UseModalDragMoveContext { + draggable: Ref; + destroyOnClose: Ref | undefined; + open: Ref; +} + +export function useModalDragMove(context: UseModalDragMoveContext) { + const getStyle = (dom: any, attr: any) => { + return getComputedStyle(dom)[attr]; + }; + const drag = (wrap: any) => { + if (!wrap) return; + wrap.setAttribute('data-drag', unref(context.draggable)); + const dialogHeaderEl = wrap.querySelector('.ant-modal-header'); + const dragDom = wrap.querySelector('.ant-modal'); + + if (!dialogHeaderEl || !dragDom || !unref(context.draggable)) return; + + dialogHeaderEl.style.cursor = 'move'; + + dialogHeaderEl.onmousedown = (e: any) => { + if (!e) return; + // 鼠标按下,计算当前元素距离可视区的距离 + const disX = e.clientX; + const disY = e.clientY; + const screenWidth = document.body.clientWidth; // body当前宽度 + const screenHeight = document.documentElement.clientHeight; // 可见区域高度(应为body高度,可某些环境下无法获取) + + const dragDomWidth = dragDom.offsetWidth; // 对话框宽度 + const dragDomheight = dragDom.offsetHeight; // 对话框高度 + + const minDragDomLeft = dragDom.offsetLeft; + + const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth; + const minDragDomTop = dragDom.offsetTop; + const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight; + // 获取到的值带px 正则匹配替换 + const domLeft = getStyle(dragDom, 'left'); + const domTop = getStyle(dragDom, 'top'); + let styL = +domLeft; + let styT = +domTop; + + // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px + if (domLeft.includes('%')) { + styL = +document.body.clientWidth * (+domLeft.replace(/%/g, '') / 100); + styT = +document.body.clientHeight * (+domTop.replace(/%/g, '') / 100); + } else { + styL = +domLeft.replace(/px/g, ''); + styT = +domTop.replace(/px/g, ''); + } + + document.onmousemove = function (e) { + // 通过事件委托,计算移动的距离 + let left = e.clientX - disX; + let top = e.clientY - disY; + + // 边界处理 + if (-left > minDragDomLeft) { + left = -minDragDomLeft; + } else if (left > maxDragDomLeft) { + left = maxDragDomLeft; + } + + if (-top > minDragDomTop) { + top = -minDragDomTop; + } else if (top > maxDragDomTop) { + top = maxDragDomTop; + } + + // 移动当前元素 + dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`; + }; + + document.onmouseup = () => { + document.onmousemove = null; + document.onmouseup = null; + }; + }; + }; + + const handleDrag = () => { + const dragWraps = document.querySelectorAll('.ant-modal-wrap'); + for (const wrap of Array.from(dragWraps)) { + if (!wrap) continue; + const display = getStyle(wrap, 'display'); + const draggable = wrap.getAttribute('data-drag'); + if (display !== 'none') { + // 拖拽位置 + if (draggable === null || unref(context.destroyOnClose)) { + drag(wrap); + } + } + } + }; + + watchEffect(() => { + if (!unref(context.open) || !unref(context.draggable)) { + return; + } + useTimeoutFn(() => { + handleDrag(); + }, 30); + }); +} diff --git a/src/components/Modal/src/hooks/useModalFullScreen.ts b/src/components/Modal/src/hooks/useModalFullScreen.ts new file mode 100644 index 0000000..b53563a --- /dev/null +++ b/src/components/Modal/src/hooks/useModalFullScreen.ts @@ -0,0 +1,43 @@ +import { computed, Ref, ref, unref } from 'vue'; + +export interface UseFullScreenContext { + wrapClassName: Ref; + modalWrapperRef: Ref; + extHeightRef: Ref; +} + +export function useFullScreen(context: UseFullScreenContext) { + // const formerHeightRef = ref(0); + const fullScreenRef = ref(false); + + const getWrapClassName = computed(() => { + const clsName = unref(context.wrapClassName) || ''; + return unref(fullScreenRef) ? `fullscreen-modal ${clsName} ` : unref(clsName); + }); + + function handleFullScreen(e: Event) { + e && e.stopPropagation(); + fullScreenRef.value = !unref(fullScreenRef); + + // const modalWrapper = unref(context.modalWrapperRef); + + // if (!modalWrapper) return; + + // const wrapperEl = modalWrapper.$el as HTMLElement; + // if (!wrapperEl) return; + // const modalWrapSpinEl = wrapperEl.querySelector('.ant-spin-nested-loading') as HTMLElement; + + // if (!modalWrapSpinEl) return; + + // if (!unref(formerHeightRef) && unref(fullScreenRef)) { + // formerHeightRef.value = modalWrapSpinEl.offsetHeight; + // } + + // if (unref(fullScreenRef)) { + // modalWrapSpinEl.style.height = `${window.innerHeight - unref(context.extHeightRef)}px`; + // } else { + // modalWrapSpinEl.style.height = `${unref(formerHeightRef)}px`; + // } + } + return { getWrapClassName, handleFullScreen, fullScreenRef }; +} diff --git a/src/components/Modal/src/index.less b/src/components/Modal/src/index.less new file mode 100644 index 0000000..0921c37 --- /dev/null +++ b/src/components/Modal/src/index.less @@ -0,0 +1,139 @@ +/* stylelint-disable media-feature-range-notation */ +.fullscreen-modal { + overflow: hidden; + + .ant-modal { + inset: 0 !important; + width: 100% !important; + height: 100%; + + &-content { + height: 100%; + } + } + + .ant-modal-footer { + margin-top: 0; + } +} + +.ant-modal { + width: 520px; + padding-bottom: 0; + + .ant-modal-body > .scrollbar { + padding: 14px; + } + + &-title { + font-size: 16px; + font-weight: bold; + + .base-title { + cursor: move !important; + } + } + + .ant-modal-body { + padding: 0; + + > .scrollbar > .scrollbar__bar.is-horizontal { + display: none; + } + } + + &-large { + top: 60px; + + &--mini { + top: 16px; + } + } + + &-header { + padding: 16px; + border-bottom: 1px solid @border-color-base; + } + + &-content { + padding: 0 !important; + box-shadow: 0 4px 8px 0 rgb(0 0 0 / 20%), 0 6px 20px 0 rgb(0 0 0 / 19%); + } + + &-footer { + padding: 10px 16px; + border-top: 1px solid @border-color-base; + + button + button { + margin-left: 10px; + } + } + + &-close { + top: 0 !important; + right: 0 !important; + width: auto !important; + outline: none; + background: transparent !important; + font-weight: normal; + } + + &-close-x { + display: inline-block; + width: 96px; + height: 56px; + line-height: 56px; + } + + &-confirm-body { + .ant-modal-confirm-content { + > * { + color: @text-color-help-dark; + } + } + } + + &-confirm-confirm.error .ant-modal-confirm-body > .anticon { + color: @error-color; + } + + &-confirm-btns { + .ant-btn:last-child { + margin-right: 0; + } + } + + &-confirm-info { + .ant-modal-confirm-body > .anticon { + color: @warning-color; + } + } + + &-confirm-confirm.success { + .ant-modal-confirm-body > .anticon { + color: @success-color; + } + } +} + +.ant-modal-confirm .ant-modal-body { + padding: 24px !important; +} + +@media screen and (max-height: 600px) { + .ant-modal { + top: 60px; + } +} + +@media screen and (max-height: 540px) { + .ant-modal { + top: 30px; + } +} + +@media screen and (max-height: 480px) { + .ant-modal { + top: 10px; + } +} \ No newline at end of file diff --git a/src/components/Modal/src/props.ts b/src/components/Modal/src/props.ts new file mode 100644 index 0000000..209cfe3 --- /dev/null +++ b/src/components/Modal/src/props.ts @@ -0,0 +1,83 @@ +import type { PropType, CSSProperties } from 'vue'; +import type { ModalWrapperProps } from './typing'; +import { ButtonProps } from 'ant-design-vue/es/button/buttonTypes'; +import { useI18n } from '/@/hooks/web/useI18n'; + +const { t } = useI18n(); + +export const modalProps = { + open: { type: Boolean }, + scrollTop: { type: Boolean, default: true }, + height: { type: Number }, + minHeight: { type: Number }, + // open drag + draggable: { type: Boolean, default: true }, + centered: { type: Boolean }, + cancelText: { type: String, default: t('common.cancelText') }, + okText: { type: String, default: t('common.okText') }, + + closeFunc: Function as PropType<() => Promise>, +}; + +export const basicProps = Object.assign({}, modalProps, { + defaultFullscreen: { type: Boolean }, + // Can it be full screen + canFullscreen: { type: Boolean, default: true }, + // After enabling the wrapper, the bottom can be increased in height + wrapperFooterOffset: { type: Number, default: 0 }, + // Warm reminder message + helpMessage: [String, Array] as PropType, + // Whether to setting wrapper + useWrapper: { type: Boolean, default: true }, + loading: { type: Boolean }, + loadingTip: { type: String }, + /** + * @description: Show close button + */ + showCancelBtn: { type: Boolean, default: true }, + /** + * @description: Show confirmation button + */ + showOkBtn: { type: Boolean, default: true }, + + wrapperProps: Object as PropType>, + + afterClose: Function as PropType<() => Promise>, + + bodyStyle: Object as PropType, + + closable: { type: Boolean, default: true }, + + closeIcon: Object as PropType, + + confirmLoading: { type: Boolean }, + + destroyOnClose: { type: Boolean }, + + footer: Object as PropType, + + getContainer: Function as PropType<() => any>, + + mask: { type: Boolean, default: true }, + + maskClosable: { type: Boolean, default: true }, + keyboard: { type: Boolean, default: true }, + + maskStyle: Object as PropType, + + okType: { type: String, default: 'primary' }, + + okButtonProps: Object as PropType, + + cancelButtonProps: Object as PropType, + + title: { type: String }, + + open: { type: Boolean }, + + width: [String, Number] as PropType, + + wrapClassName: { type: String }, + + zIndex: { type: Number }, +}); diff --git a/src/components/Modal/src/typing.ts b/src/components/Modal/src/typing.ts new file mode 100644 index 0000000..fd9aa55 --- /dev/null +++ b/src/components/Modal/src/typing.ts @@ -0,0 +1,209 @@ +import type { ButtonProps } from 'ant-design-vue/lib/button/buttonTypes'; +import type { CSSProperties, VNodeChild, ComputedRef } from 'vue'; +/** + * @description: 弹窗对外暴露的方法 + */ +export interface ModalMethods { + setModalProps: (props: Partial) => void; + emitOpen?: (open: boolean, uid: number) => void; + redoModalHeight?: () => void; +} + +export type RegisterFn = (modalMethods: ModalMethods, uuid?: string) => void; + +export interface ReturnMethods extends ModalMethods { + openModal: (props?: boolean, data?: T, openOnSet?: boolean) => void; + closeModal: () => void; + getOpen?: ComputedRef; +} + +export type UseModalReturnType = [RegisterFn, ReturnMethods]; + +export interface ReturnInnerMethods extends ModalMethods { + closeModal: () => void; + changeLoading: (loading: boolean) => void; + changeOkLoading: (loading: boolean) => void; + getOpen?: ComputedRef; + redoModalHeight: () => void; +} + +export type UseModalInnerReturnType = [RegisterFn, ReturnInnerMethods]; + +export interface ModalProps { + minHeight?: number; + height?: number; + // 启用wrapper后 底部可以适当增加高度 + wrapperFooterOffset?: number; + draggable?: boolean; + scrollTop?: boolean; + + // 是否可以进行全屏 + canFullscreen?: boolean; + defaultFullscreen?: boolean; + open?: boolean; + // 温馨提醒信息 + helpMessage: string | string[]; + + // 是否使用modalWrapper + useWrapper: boolean; + + loading: boolean; + loadingTip?: string; + + wrapperProps: Omit; + + showOkBtn: boolean; + showCancelBtn: boolean; + closeFunc: () => Promise; + + /** + * Specify a function that will be called when modal is closed completely. + * @type Function + */ + afterClose?: () => any; + + /** + * Body style for modal body element. Such as height, padding etc. + * @default {} + * @type object + */ + bodyStyle?: CSSProperties; + + /** + * Text of the Cancel button + * @default 'cancel' + * @type string + */ + cancelText?: string; + + /** + * Centered Modal + * @default false + * @type boolean + */ + centered?: boolean; + + /** + * Whether a close (x) button is visible on top right of the modal dialog or not + * @default true + * @type boolean + */ + closable?: boolean; + /** + * Whether a close (x) button is visible on top right of the modal dialog or not + */ + closeIcon?: VNodeChild | JSX.Element; + + /** + * Whether to apply loading visual effect for OK button or not + * @default false + * @type boolean + */ + confirmLoading?: boolean; + + /** + * Whether to unmount child components on onClose + * @default false + * @type boolean + */ + destroyOnClose?: boolean; + + /** + * Footer content, set as :footer="null" when you don't need default buttons + * @default OK and Cancel buttons + * @type any (string | slot) + */ + footer?: VNodeChild | JSX.Element; + + /** + * Return the mount node for Modal + * @default () => document.body + * @type Function + */ + getContainer?: (instance: any) => HTMLElement; + + /** + * Whether show mask or not. + * @default true + * @type boolean + */ + mask?: boolean; + + /** + * Whether to close the modal dialog when the mask (area outside the modal) is clicked + * @default true + * @type boolean + */ + maskClosable?: boolean; + + /** + * Style for modal's mask element. + * @default {} + * @type object + */ + maskStyle?: CSSProperties; + + /** + * Text of the OK button + * @default 'OK' + * @type string + */ + okText?: string; + + /** + * Button type of the OK button + * @default 'primary' + * @type string + */ + okType?: 'primary' | 'danger' | 'dashed' | 'ghost' | 'default'; + + /** + * The ok button props, follow jsx rules + * @type object + */ + okButtonProps?: ButtonProps; + + /** + * The cancel button props, follow jsx rules + * @type object + */ + cancelButtonProps?: ButtonProps; + + /** + * The modal dialog's title + * @type any (string | slot) + */ + title?: VNodeChild | JSX.Element; + + /** + * Width of the modal dialog + * @default 520 + * @type string | number + */ + width?: string | number; + + /** + * The class name of the container of the modal dialog + * @type string + */ + wrapClassName?: string; + + /** + * The z-index of the Modal + * @default 1000 + * @type number + */ + zIndex?: number; +} + +export interface ModalWrapperProps { + footerOffset?: number; + loading: boolean; + modalHeaderHeight: number; + modalFooterHeight: number; + minHeight: number; + height: number; + open: boolean; + fullScreen: boolean; + useWrapper: boolean; +} diff --git a/src/components/Page/index.ts b/src/components/Page/index.ts new file mode 100644 index 0000000..d096264 --- /dev/null +++ b/src/components/Page/index.ts @@ -0,0 +1,7 @@ +import { withInstall } from '/@/utils'; + +import pageFooter from './src/PageFooter.vue'; +import pageWrapper from './src/PageWrapper.vue'; + +export const PageFooter = withInstall(pageFooter); +export const PageWrapper = withInstall(pageWrapper); diff --git a/src/components/Page/src/PageFooter.vue b/src/components/Page/src/PageFooter.vue new file mode 100644 index 0000000..8d45fb6 --- /dev/null +++ b/src/components/Page/src/PageFooter.vue @@ -0,0 +1,47 @@ + + + diff --git a/src/components/Page/src/PageWrapper.vue b/src/components/Page/src/PageWrapper.vue new file mode 100644 index 0000000..fc3024f --- /dev/null +++ b/src/components/Page/src/PageWrapper.vue @@ -0,0 +1,205 @@ + + + diff --git a/src/components/Qrcode/index.ts b/src/components/Qrcode/index.ts new file mode 100644 index 0000000..16a2f40 --- /dev/null +++ b/src/components/Qrcode/index.ts @@ -0,0 +1,5 @@ +import { withInstall } from '/@/utils'; +import qrCode from './src/Qrcode.vue'; + +export const QrCode = withInstall(qrCode); +export * from './src/typing'; diff --git a/src/components/Qrcode/src/Qrcode.vue b/src/components/Qrcode/src/Qrcode.vue new file mode 100644 index 0000000..81194e1 --- /dev/null +++ b/src/components/Qrcode/src/Qrcode.vue @@ -0,0 +1,112 @@ + + diff --git a/src/components/Qrcode/src/drawCanvas.ts b/src/components/Qrcode/src/drawCanvas.ts new file mode 100644 index 0000000..53198e8 --- /dev/null +++ b/src/components/Qrcode/src/drawCanvas.ts @@ -0,0 +1,37 @@ +import { toCanvas } from 'qrcode'; +import type { QRCodeRenderersOptions } from 'qrcode'; +import { RenderQrCodeParams, ContentType } from './typing'; +import { cloneDeep } from 'lodash-es'; + +export const renderQrCode = ({ + canvas, + content, + width = 0, + options: params = {}, +}: RenderQrCodeParams) => { + const options = cloneDeep(params); + // 容错率,默认对内容少的二维码采用高容错率,内容多的二维码采用低容错率 + options.errorCorrectionLevel = options.errorCorrectionLevel || getErrorCorrectionLevel(content); + + return getOriginWidth(content, options).then((_width: number) => { + options.scale = width === 0 ? undefined : (width / _width) * 4; + return toCanvas(canvas, content, options); + }); +}; + +// 得到原QrCode的大小,以便缩放得到正确的QrCode大小 +function getOriginWidth(content: ContentType, options: QRCodeRenderersOptions) { + const _canvas = document.createElement('canvas'); + return toCanvas(_canvas, content, options).then(() => _canvas.width); +} + +// 对于内容少的QrCode,增大容错率 +function getErrorCorrectionLevel(content: ContentType) { + if (content.length > 36) { + return 'M'; + } else if (content.length > 16) { + return 'Q'; + } else { + return 'H'; + } +} diff --git a/src/components/Qrcode/src/drawLogo.ts b/src/components/Qrcode/src/drawLogo.ts new file mode 100644 index 0000000..82df278 --- /dev/null +++ b/src/components/Qrcode/src/drawLogo.ts @@ -0,0 +1,89 @@ +import { isString } from '/@/utils/is'; +import { RenderQrCodeParams, LogoType } from './typing'; + +export const drawLogo = ({ canvas, logo }: RenderQrCodeParams) => { + if (!logo) { + return new Promise((resolve) => { + resolve((canvas as HTMLCanvasElement).toDataURL()); + }); + } + const canvasWidth = (canvas as HTMLCanvasElement).width; + const { + logoSize = 0.15, + bgColor = '#ffffff', + borderSize = 0.05, + crossOrigin, + borderRadius = 8, + logoRadius = 0, + } = logo as LogoType; + + const logoSrc: string = isString(logo) ? logo : logo.src; + const logoWidth = canvasWidth * logoSize; + const logoXY = (canvasWidth * (1 - logoSize)) / 2; + const logoBgWidth = canvasWidth * (logoSize + borderSize); + const logoBgXY = (canvasWidth * (1 - logoSize - borderSize)) / 2; + + const ctx = canvas.getContext('2d'); + if (!ctx) return; + + // logo 底色 + canvasRoundRect(ctx)(logoBgXY, logoBgXY, logoBgWidth, logoBgWidth, borderRadius); + ctx.fillStyle = bgColor; + ctx.fill(); + + // logo + const image = new Image(); + if (crossOrigin || logoRadius) { + image.setAttribute('crossOrigin', crossOrigin || 'anonymous'); + } + image.src = logoSrc; + + // 使用image绘制可以避免某些跨域情况 + const drawLogoWithImage = (image: CanvasImageSource) => { + ctx.drawImage(image, logoXY, logoXY, logoWidth, logoWidth); + }; + + // 使用canvas绘制以获得更多的功能 + const drawLogoWithCanvas = (image: HTMLImageElement) => { + const canvasImage = document.createElement('canvas'); + canvasImage.width = logoXY + logoWidth; + canvasImage.height = logoXY + logoWidth; + const imageCanvas = canvasImage.getContext('2d'); + if (!imageCanvas || !ctx) return; + imageCanvas.drawImage(image, logoXY, logoXY, logoWidth, logoWidth); + + canvasRoundRect(ctx)(logoXY, logoXY, logoWidth, logoWidth, logoRadius); + if (!ctx) return; + const fillStyle = ctx.createPattern(canvasImage, 'no-repeat'); + if (fillStyle) { + ctx.fillStyle = fillStyle; + ctx.fill(); + } + }; + + // 将 logo绘制到 canvas上 + return new Promise((resolve) => { + image.onload = () => { + logoRadius ? drawLogoWithCanvas(image) : drawLogoWithImage(image); + resolve((canvas as HTMLCanvasElement).toDataURL()); + }; + }); +}; + +// copy来的方法,用于绘制圆角 +function canvasRoundRect(ctx: CanvasRenderingContext2D) { + return (x: number, y: number, w: number, h: number, r: number) => { + const minSize = Math.min(w, h); + if (r > minSize / 2) { + r = minSize / 2; + } + ctx.beginPath(); + ctx.moveTo(x + r, y); + ctx.arcTo(x + w, y, x + w, y + h, r); + ctx.arcTo(x + w, y + h, x, y + h, r); + ctx.arcTo(x, y + h, x, y, r); + ctx.arcTo(x, y, x + w, y, r); + ctx.closePath(); + return ctx; + }; +} diff --git a/src/components/Qrcode/src/qrcodePlus.ts b/src/components/Qrcode/src/qrcodePlus.ts new file mode 100644 index 0000000..ddf6116 --- /dev/null +++ b/src/components/Qrcode/src/qrcodePlus.ts @@ -0,0 +1,5 @@ +// 参考 qr-code-with-logo 进行ts版本修改 +import { toCanvas } from './toCanvas'; + +export * from './typing'; +export { toCanvas }; diff --git a/src/components/Qrcode/src/toCanvas.ts b/src/components/Qrcode/src/toCanvas.ts new file mode 100644 index 0000000..0a9799f --- /dev/null +++ b/src/components/Qrcode/src/toCanvas.ts @@ -0,0 +1,11 @@ +import { renderQrCode } from './drawCanvas'; +import { drawLogo } from './drawLogo'; +import { RenderQrCodeParams } from './typing'; + +export const toCanvas = (options: RenderQrCodeParams) => { + return renderQrCode(options) + .then(() => { + return options; + }) + .then(drawLogo) as Promise; +}; diff --git a/src/components/Qrcode/src/typing.ts b/src/components/Qrcode/src/typing.ts new file mode 100644 index 0000000..3a037e9 --- /dev/null +++ b/src/components/Qrcode/src/typing.ts @@ -0,0 +1,38 @@ +import type { QRCodeSegment, QRCodeRenderersOptions } from 'qrcode'; + +export type ContentType = string | QRCodeSegment[]; + +export type { QRCodeRenderersOptions }; + +export type LogoType = { + src: string; + logoSize: number; + borderColor: string; + bgColor: string; + borderSize: number; + crossOrigin: string; + borderRadius: number; + logoRadius: number; +}; + +export interface RenderQrCodeParams { + canvas: any; + content: ContentType; + width?: number; + options?: QRCodeRenderersOptions; + logo?: LogoType | string; + image?: HTMLImageElement; + downloadName?: string; + download?: boolean | Fn; +} + +export type ToCanvasFn = (options: RenderQrCodeParams) => Promise; + +export interface QrCodeActionType { + download: (fileName?: string) => void; +} + +export interface QrcodeDoneEventParams { + url: string; + ctx?: CanvasRenderingContext2D | null; +} diff --git a/src/components/Scrollbar/index.ts b/src/components/Scrollbar/index.ts new file mode 100644 index 0000000..e5b2cb2 --- /dev/null +++ b/src/components/Scrollbar/index.ts @@ -0,0 +1,8 @@ +/** + * copy from element-ui + */ + +import Scrollbar from './src/Scrollbar.vue'; + +export { Scrollbar }; +export type { ScrollbarType } from './src/types'; diff --git a/src/components/Scrollbar/src/Scrollbar.vue b/src/components/Scrollbar/src/Scrollbar.vue new file mode 100644 index 0000000..daeb230 --- /dev/null +++ b/src/components/Scrollbar/src/Scrollbar.vue @@ -0,0 +1,207 @@ + + + diff --git a/src/components/Scrollbar/src/bar.ts b/src/components/Scrollbar/src/bar.ts new file mode 100644 index 0000000..64bd289 --- /dev/null +++ b/src/components/Scrollbar/src/bar.ts @@ -0,0 +1,110 @@ +import { + defineComponent, + h, + computed, + ref, + getCurrentInstance, + onUnmounted, + inject, + Ref, +} from 'vue'; +import { on, off } from '/@/utils/domUtils'; + +import { renderThumbStyle, BAR_MAP } from './util'; + +export default defineComponent({ + name: 'Bar', + + props: { + vertical: Boolean, + size: String, + move: Number, + }, + + setup(props) { + const instance = getCurrentInstance(); + const thumb = ref(); + const wrap = inject('scroll-bar-wrap', {} as Ref>) as any; + const bar = computed(() => { + return BAR_MAP[props.vertical ? 'vertical' : 'horizontal']; + }); + const barStore = ref({}); + const cursorDown = ref(); + const clickThumbHandler = (e: any) => { + // prevent click event of right button + if (e.ctrlKey || e.button === 2) { + return; + } + window.getSelection()?.removeAllRanges(); + startDrag(e); + barStore.value[bar.value.axis] = + e.currentTarget[bar.value.offset] - + (e[bar.value.client] - e.currentTarget.getBoundingClientRect()[bar.value.direction]); + }; + + const clickTrackHandler = (e: any) => { + const offset = Math.abs( + e.target.getBoundingClientRect()[bar.value.direction] - e[bar.value.client], + ); + const thumbHalf = thumb.value[bar.value.offset] / 2; + const thumbPositionPercentage = + ((offset - thumbHalf) * 100) / instance?.vnode.el?.[bar.value.offset]; + + wrap.value[bar.value.scroll] = + (thumbPositionPercentage * wrap.value[bar.value.scrollSize]) / 100; + }; + const startDrag = (e: any) => { + e.stopImmediatePropagation(); + cursorDown.value = true; + on(document, 'mousemove', mouseMoveDocumentHandler); + on(document, 'mouseup', mouseUpDocumentHandler); + document.onselectstart = () => false; + }; + + const mouseMoveDocumentHandler = (e: any) => { + if (cursorDown.value === false) return; + const prevPage = barStore.value[bar.value.axis]; + + if (!prevPage) return; + + const offset = + (instance?.vnode.el?.getBoundingClientRect()[bar.value.direction] - e[bar.value.client]) * + -1; + const thumbClickPosition = thumb.value[bar.value.offset] - prevPage; + const thumbPositionPercentage = + ((offset - thumbClickPosition) * 100) / instance?.vnode.el?.[bar.value.offset]; + wrap.value[bar.value.scroll] = + (thumbPositionPercentage * wrap.value[bar.value.scrollSize]) / 100; + }; + + function mouseUpDocumentHandler() { + cursorDown.value = false; + barStore.value[bar.value.axis] = 0; + off(document, 'mousemove', mouseMoveDocumentHandler); + document.onselectstart = null; + } + + onUnmounted(() => { + off(document, 'mouseup', mouseUpDocumentHandler); + }); + + return () => + h( + 'div', + { + class: ['scrollbar__bar', 'is-' + bar.value.key], + onMousedown: clickTrackHandler, + }, + h('div', { + ref: thumb, + class: 'scrollbar__thumb', + onMousedown: clickThumbHandler, + style: renderThumbStyle({ + size: props.size, + move: props.move, + bar: bar.value, + }), + }), + ); + }, +}); diff --git a/src/components/Scrollbar/src/types.d.ts b/src/components/Scrollbar/src/types.d.ts new file mode 100644 index 0000000..4c7eeea --- /dev/null +++ b/src/components/Scrollbar/src/types.d.ts @@ -0,0 +1,18 @@ +export interface BarMapItem { + offset: string; + scroll: string; + scrollSize: string; + size: string; + key: string; + axis: string; + client: string; + direction: string; +} +export interface BarMap { + vertical: BarMapItem; + horizontal: BarMapItem; +} + +export interface ScrollbarType { + wrap: ElRef; +} diff --git a/src/components/Scrollbar/src/util.ts b/src/components/Scrollbar/src/util.ts new file mode 100644 index 0000000..77694a9 --- /dev/null +++ b/src/components/Scrollbar/src/util.ts @@ -0,0 +1,51 @@ +import type { BarMap } from './types'; + +export const BAR_MAP: BarMap = { + vertical: { + offset: 'offsetHeight', + scroll: 'scrollTop', + scrollSize: 'scrollHeight', + size: 'height', + key: 'vertical', + axis: 'Y', + client: 'clientY', + direction: 'top', + }, + horizontal: { + offset: 'offsetWidth', + scroll: 'scrollLeft', + scrollSize: 'scrollWidth', + size: 'width', + key: 'horizontal', + axis: 'X', + client: 'clientX', + direction: 'left', + }, +}; + +// @ts-ignore +export function renderThumbStyle({ move, size, bar }) { + const style = {} as any; + const translate = `translate${bar.axis}(${move}%)`; + + style[bar.size] = size; + style.transform = translate; + style.msTransform = translate; + style.webkitTransform = translate; + + return style; +} + +function extend(to: T, _from: K): T & K { + return Object.assign(to, _from); +} + +export function toObject(arr: Array): Recordable { + const res = {}; + for (let i = 0; i < arr.length; i++) { + if (arr[i]) { + extend(res, arr[i]); + } + } + return res; +} diff --git a/src/components/SimpleMenu/index.ts b/src/components/SimpleMenu/index.ts new file mode 100644 index 0000000..0dfd248 --- /dev/null +++ b/src/components/SimpleMenu/index.ts @@ -0,0 +1,2 @@ +export { default as SimpleMenu } from './src/SimpleMenu.vue'; +export { default as SimpleMenuTag } from './src/SimpleMenuTag.vue'; diff --git a/src/components/SimpleMenu/src/SimpleMenu.vue b/src/components/SimpleMenu/src/SimpleMenu.vue new file mode 100644 index 0000000..a391d06 --- /dev/null +++ b/src/components/SimpleMenu/src/SimpleMenu.vue @@ -0,0 +1,161 @@ + + + diff --git a/src/components/SimpleMenu/src/SimpleMenuTag.vue b/src/components/SimpleMenu/src/SimpleMenuTag.vue new file mode 100644 index 0000000..b7d3cb3 --- /dev/null +++ b/src/components/SimpleMenu/src/SimpleMenuTag.vue @@ -0,0 +1,68 @@ + + diff --git a/src/components/SimpleMenu/src/SimpleSubMenu.vue b/src/components/SimpleMenu/src/SimpleSubMenu.vue new file mode 100644 index 0000000..1accfc7 --- /dev/null +++ b/src/components/SimpleMenu/src/SimpleSubMenu.vue @@ -0,0 +1,116 @@ + + diff --git a/src/components/SimpleMenu/src/components/Menu.vue b/src/components/SimpleMenu/src/components/Menu.vue new file mode 100644 index 0000000..28e0b3e --- /dev/null +++ b/src/components/SimpleMenu/src/components/Menu.vue @@ -0,0 +1,159 @@ + + + + diff --git a/src/components/SimpleMenu/src/components/MenuCollapseTransition.vue b/src/components/SimpleMenu/src/components/MenuCollapseTransition.vue new file mode 100644 index 0000000..5295439 --- /dev/null +++ b/src/components/SimpleMenu/src/components/MenuCollapseTransition.vue @@ -0,0 +1,78 @@ + + diff --git a/src/components/SimpleMenu/src/components/MenuItem.vue b/src/components/SimpleMenu/src/components/MenuItem.vue new file mode 100644 index 0000000..3a99796 --- /dev/null +++ b/src/components/SimpleMenu/src/components/MenuItem.vue @@ -0,0 +1,107 @@ + + + diff --git a/src/components/SimpleMenu/src/components/SubMenuItem.vue b/src/components/SimpleMenu/src/components/SubMenuItem.vue new file mode 100644 index 0000000..87c9e07 --- /dev/null +++ b/src/components/SimpleMenu/src/components/SubMenuItem.vue @@ -0,0 +1,336 @@ + + + diff --git a/src/components/SimpleMenu/src/components/menu.less b/src/components/SimpleMenu/src/components/menu.less new file mode 100644 index 0000000..2fe0b54 --- /dev/null +++ b/src/components/SimpleMenu/src/components/menu.less @@ -0,0 +1,309 @@ +@menu-prefix-cls: ~'@{namespace}-menu'; +@menu-popup-prefix-cls: ~'@{namespace}-menu-popup'; +@submenu-popup-prefix-cls: ~'@{namespace}-menu-submenu-popup'; + +@transition-time: 0.2s; +@menu-dark-subsidiary-color: rgba(255, 255, 255, 0.7); + +.light-border { + &::after { + content: ''; + display: block; + position: absolute; + top: 0; + right: 0; + bottom: 0; + width: 2px; + background-color: @primary-color; + } +} + +.@{menu-prefix-cls}-menu-popover { + .ant-popover-arrow { + display: none; + } + + .ant-popover-inner-content { + padding: 0; + } + + .@{menu-prefix-cls} { + &-opened > * > &-submenu-title-icon { + transform: translateY(-50%) rotate(90deg) !important; + } + + &-item, + &-submenu-title { + position: relative; + z-index: 1; + padding: 12px 20px; + transition: all @transition-time @ease-in-out; + color: @menu-dark-subsidiary-color; + cursor: pointer; + + &-icon { + position: absolute; + top: 50%; + right: 18px; + transform: translateY(-50%) rotate(-90deg); + transition: transform @transition-time @ease-in-out; + } + } + + &-dark { + .@{menu-prefix-cls}-item, + .@{menu-prefix-cls}-submenu-title { + color: @menu-dark-subsidiary-color; + // background: @menu-dark-active-bg; + + &:hover { + color: #fff; + } + + &-selected { + background-color: @primary-color !important; + color: #fff; + } + } + } + + &-light { + .@{menu-prefix-cls}-item, + .@{menu-prefix-cls}-submenu-title { + color: @text-color-base; + + &:hover { + color: @primary-color; + } + + &-selected { + z-index: 2; + background-color: fade(@primary-color, 10); + color: @primary-color; + + .light-border(); + } + } + } + } +} + +.content(); +.content() { + .@{menu-prefix-cls} { + display: block; + position: relative; + width: 100%; + margin: 0; + padding: 0; + outline: none; + color: @text-color-base; + font-size: @font-size-base; + list-style: none; + + // .collapse-transition { + // transition: @transition-time height ease-in-out, @transition-time padding-top ease-in-out, + // @transition-time padding-bottom ease-in-out; + // } + + &-light { + background-color: #fff; + + .@{menu-prefix-cls}-submenu-active { + color: @primary-color !important; + + &-border { + .light-border(); + } + } + } + + &-dark { + .@{menu-prefix-cls}-submenu-active { + color: #fff !important; + } + } + + &-item { + display: flex; + position: relative; + z-index: 1; + align-items: center; + outline: none; + color: inherit; + font-size: @font-size-base; + list-style: none; + cursor: pointer; + + &:hover, + &:active { + color: inherit; + } + } + + &-item > i { + margin-right: 6px; + } + + &-submenu-title > i, + &-submenu-title span > i { + margin-right: 8px; + } + + // vertical + &-vertical &-item, + &-vertical &-submenu-title { + position: relative; + z-index: 1; + padding: 14px 24px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + cursor: pointer; + + &:hover { + color: @primary-color; + } + + .@{menu-prefix-cls}-tooltip { + width: calc(100% - 0px); + padding: 12px 0; + text-align: center; + } + .@{menu-prefix-cls}-submenu-popup { + padding: 12px 0; + } + } + + &-vertical &-submenu-collapse { + .@{submenu-popup-prefix-cls} { + display: flex; + align-items: center; + justify-content: center; + } + .@{menu-prefix-cls}-submenu-collapsed-show-tit { + flex-direction: column; + } + } + + &-vertical&-collapse &-item, + &-vertical&-collapse &-submenu-title { + padding: 0; + } + + &-vertical &-submenu-title-icon { + position: absolute; + top: 50%; + right: 18px; + transform: translateY(-50%); + } + + &-submenu-title-icon { + transition: transform @transition-time @ease-in-out; + } + + &-vertical &-opened > * > &-submenu-title-icon { + transform: translateY(-50%) rotate(180deg); + } + + &-vertical &-submenu { + &-nested { + padding-left: 20px; + } + .@{menu-prefix-cls}-item { + padding-left: 43px; + } + } + + &-light&-vertical &-item { + &-active:not(.@{menu-prefix-cls}-submenu) { + z-index: 2; + background-color: fade(@primary-color, 10); + color: @primary-color; + + .light-border(); + } + &-active.@{menu-prefix-cls}-submenu { + color: @primary-color; + } + } + + &-light&-vertical&-collapse { + > li.@{menu-prefix-cls}-item-active, + .@{menu-prefix-cls}-submenu-active { + position: relative; + background-color: fade(@primary-color, 5); + + &::after { + display: none; + } + + &::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 3px; + height: 100%; + background-color: @primary-color; + } + } + } + + &-dark&-vertical &-item, + &-dark&-vertical &-submenu-title { + color: @menu-dark-subsidiary-color; + &-active:not(.@{menu-prefix-cls}-submenu) { + background-color: @primary-color !important; + color: #fff !important; + } + + &:hover { + color: #fff; + } + } + + &-dark&-vertical&-collapse { + > li.@{menu-prefix-cls}-item-active, + .@{menu-prefix-cls}-submenu-active { + position: relative; + background-color: @sider-dark-darken-bg-color !important; + color: #fff !important; + + &::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 3px; + height: 100%; + background-color: @primary-color; + } + + .@{menu-prefix-cls}-submenu-collapse { + background-color: transparent; + } + } + } + + &-dark&-vertical &-submenu &-item { + &-active, + &-active:hover { + border-right: none; + color: #fff; + } + } + + &-dark&-vertical &-child-item-active > &-submenu-title { + color: #fff; + } + + &-dark&-vertical &-opened { + .@{menu-prefix-cls}-submenu-has-parent-submenu { + .@{menu-prefix-cls}-submenu-title { + background-color: transparent; + } + } + } + } +} diff --git a/src/components/SimpleMenu/src/components/types.ts b/src/components/SimpleMenu/src/components/types.ts new file mode 100644 index 0000000..d828e89 --- /dev/null +++ b/src/components/SimpleMenu/src/components/types.ts @@ -0,0 +1,25 @@ +import { Ref } from 'vue'; + +export interface Props { + theme: string; + activeName?: string | number | undefined; + openNames: string[]; + accordion: boolean; + width: string; + collapsedWidth: string; + indentSize: number; + collapse: boolean; + activeSubMenuNames: (string | number)[]; +} + +export interface SubMenuProvider { + addSubMenu: (name: string | number, update?: boolean) => void; + removeSubMenu: (name: string | number, update?: boolean) => void; + removeAll: () => void; + sliceIndex: (index: number) => void; + isRemoveAllPopup: Ref; + getOpenNames: () => (string | number)[]; + handleMouseleave?: Fn; + level: number; + props: Props; +} diff --git a/src/components/SimpleMenu/src/components/useMenu.ts b/src/components/SimpleMenu/src/components/useMenu.ts new file mode 100644 index 0000000..8830559 --- /dev/null +++ b/src/components/SimpleMenu/src/components/useMenu.ts @@ -0,0 +1,84 @@ +import { computed, ComponentInternalInstance, unref } from 'vue'; +import type { CSSProperties } from 'vue'; + +export function useMenuItem(instance: ComponentInternalInstance | null) { + const getParentMenu = computed(() => { + return findParentMenu(['Menu', 'SubMenu']); + }); + + const getParentRootMenu = computed(() => { + return findParentMenu(['Menu']); + }); + + const getParentSubMenu = computed(() => { + return findParentMenu(['SubMenu']); + }); + + const getItemStyle = computed((): CSSProperties => { + let parent = instance?.parent; + if (!parent) return {}; + const indentSize = (unref(getParentRootMenu)?.props.indentSize as number) ?? 20; + let padding = indentSize; + + if (unref(getParentRootMenu)?.props.collapse) { + padding = indentSize; + } else { + while (parent && parent.type.name !== 'Menu') { + if (parent.type.name === 'SubMenu') { + padding += indentSize; + } + parent = parent.parent; + } + } + return { paddingLeft: padding + 'px' }; + }); + + function findParentMenu(name: string[]) { + let parent = instance?.parent; + if (!parent) return null; + while (parent && name.indexOf(parent.type.name!) === -1) { + parent = parent.parent; + } + return parent; + } + + function getParentList() { + let parent = instance; + if (!parent) + return { + uidList: [], + list: [], + }; + const ret: any[] = []; + while (parent && parent.type.name !== 'Menu') { + if (parent.type.name === 'SubMenu') { + ret.push(parent); + } + parent = parent.parent; + } + return { + uidList: ret.map((item) => item.uid), + list: ret, + }; + } + + function getParentInstance(instance: ComponentInternalInstance, name = 'SubMenu') { + let parent = instance.parent; + while (parent) { + if (parent.type.name !== name) { + return parent; + } + parent = parent.parent; + } + return parent; + } + + return { + getParentMenu, + getParentInstance, + getParentRootMenu, + getParentList, + getParentSubMenu, + getItemStyle, + }; +} diff --git a/src/components/SimpleMenu/src/components/useSimpleMenuContext.ts b/src/components/SimpleMenu/src/components/useSimpleMenuContext.ts new file mode 100644 index 0000000..f3d8100 --- /dev/null +++ b/src/components/SimpleMenu/src/components/useSimpleMenuContext.ts @@ -0,0 +1,18 @@ +import type { InjectionKey, Ref } from 'vue'; +import type { Emitter } from '/@/utils/mitt'; +import { createContext, useContext } from '/@/hooks/core/useContext'; + +export interface SimpleRootMenuContextProps { + rootMenuEmitter: Emitter; + activeName: Ref; +} + +const key: InjectionKey = Symbol(); + +export function createSimpleRootMenuContext(context: SimpleRootMenuContextProps) { + return createContext(context, key, { readonly: false, native: true }); +} + +export function useSimpleRootMenuContext() { + return useContext(key); +} diff --git a/src/components/SimpleMenu/src/index.less b/src/components/SimpleMenu/src/index.less new file mode 100644 index 0000000..74fe82b --- /dev/null +++ b/src/components/SimpleMenu/src/index.less @@ -0,0 +1,77 @@ +@simple-prefix-cls: ~'@{namespace}-simple-menu'; +@prefix-cls: ~'@{namespace}-menu'; + +.@{prefix-cls} { + &-dark&-vertical .@{simple-prefix-cls}__parent { + background-color: @sider-dark-bg-color; + > .@{prefix-cls}-submenu-title { + background-color: @sider-dark-bg-color; + } + } + + &-dark&-vertical .@{simple-prefix-cls}__children, + &-dark&-popup .@{simple-prefix-cls}__children { + background-color: @sider-dark-lighten-bg-color; + > .@{prefix-cls}-submenu-title { + background-color: @sider-dark-lighten-bg-color; + } + } + + .collapse-title { + overflow: hidden; + font-size: 12px; + text-overflow: ellipsis; + white-space: nowrap; + } +} + +.@{simple-prefix-cls} { + &-sub-title { + overflow: hidden; + transition: all 0.3s; + text-overflow: ellipsis; + white-space: nowrap; + } + + &-tag { + display: inline-block; + position: absolute; + top: calc(50% - 8px); + right: 30px; + margin-right: 4px; + padding: 2px 3px; + border-radius: 2px; + color: #fff; + font-size: 10px; + line-height: 14px; + + &--collapse { + top: 6px !important; + right: 2px; + } + + &--dot { + top: calc(50% - 2px); + width: 6px; + height: 6px; + padding: 0; + border-radius: 50%; + } + + &--primary { + background-color: @primary-color; + } + + &--error { + background-color: @error-color; + } + + &--success { + background-color: @success-color; + } + + &--warn { + background-color: @warning-color; + } + } +} diff --git a/src/components/SimpleMenu/src/types.ts b/src/components/SimpleMenu/src/types.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/components/SimpleMenu/src/useOpenKeys.ts b/src/components/SimpleMenu/src/useOpenKeys.ts new file mode 100644 index 0000000..1028f97 --- /dev/null +++ b/src/components/SimpleMenu/src/useOpenKeys.ts @@ -0,0 +1,48 @@ +import type { Menu as MenuType } from '/@/router/types'; +import type { MenuState } from './types'; +import { computed, Ref, toRaw, unref } from 'vue'; +import { uniq } from 'lodash-es'; +import { getAllParentPath } from '/@/router/helper/menuHelper'; +import { useTimeoutFn } from '@vben/hooks'; +import { useDebounceFn } from '@vueuse/core'; + +export function useOpenKeys( + menuState: MenuState, + menus: Ref, + accordion: Ref, + mixSider: Ref, + collapse: Ref, +) { + const debounceSetOpenKeys = useDebounceFn(setOpenKeys, 50); + async function setOpenKeys(path: string) { + const native = !mixSider.value; + const menuList = toRaw(menus.value); + + const handle = () => { + if (menuList?.length === 0) { + menuState.activeSubMenuNames = []; + menuState.openNames = []; + return; + } + const keys = getAllParentPath(menuList, path); + + if (!unref(accordion)) { + menuState.openNames = uniq([...menuState.openNames, ...keys]); + } else { + menuState.openNames = keys; + } + menuState.activeSubMenuNames = menuState.openNames; + }; + if (native) { + handle(); + } else { + useTimeoutFn(handle, 30); + } + } + + const getOpenKeys = computed(() => { + return unref(collapse) ? [] : menuState.openNames; + }); + + return { setOpenKeys: debounceSetOpenKeys, getOpenKeys }; +} diff --git a/src/components/StrengthMeter/index.ts b/src/components/StrengthMeter/index.ts new file mode 100644 index 0000000..9763afa --- /dev/null +++ b/src/components/StrengthMeter/index.ts @@ -0,0 +1,4 @@ +import { withInstall } from '/@/utils'; +import strengthMeter from './src/StrengthMeter.vue'; + +export const StrengthMeter = withInstall(strengthMeter); diff --git a/src/components/StrengthMeter/src/StrengthMeter.vue b/src/components/StrengthMeter/src/StrengthMeter.vue new file mode 100644 index 0000000..39074d9 --- /dev/null +++ b/src/components/StrengthMeter/src/StrengthMeter.vue @@ -0,0 +1,142 @@ + + + + diff --git a/src/components/Table/index.ts b/src/components/Table/index.ts new file mode 100644 index 0000000..1ec9568 --- /dev/null +++ b/src/components/Table/index.ts @@ -0,0 +1,11 @@ +export { default as BasicTable } from './src/BasicTable.vue'; +export { default as TableAction } from './src/components/TableAction.vue'; +export { default as EditTableHeaderIcon } from './src/components/EditTableHeaderIcon.vue'; +export { default as TableImg } from './src/components/TableImg.vue'; + +export * from './src/types/table'; +export * from './src/types/pagination'; +export * from './src/types/tableAction'; +export { useTable } from './src/hooks/useTable'; +export type { FormSchema, FormProps } from '/@/components/Form/src/types/form'; +export type { EditRecordRow } from './src/components/editable'; diff --git a/src/components/Table/src/BasicTable.vue b/src/components/Table/src/BasicTable.vue new file mode 100644 index 0000000..038b8bb --- /dev/null +++ b/src/components/Table/src/BasicTable.vue @@ -0,0 +1,467 @@ + + + \ No newline at end of file diff --git a/src/components/Table/src/componentMap.ts b/src/components/Table/src/componentMap.ts new file mode 100644 index 0000000..ace83f5 --- /dev/null +++ b/src/components/Table/src/componentMap.ts @@ -0,0 +1,40 @@ +import type { Component } from 'vue'; +import { + Input, + Select, + Checkbox, + InputNumber, + Switch, + DatePicker, + TimePicker, + AutoComplete, + Radio, +} from 'ant-design-vue'; +import type { ComponentType } from './types/componentType'; +import { ApiSelect, ApiTreeSelect, RadioButtonGroup, ApiRadioGroup } from '/@/components/Form'; + +const componentMap = new Map(); + +componentMap.set('Input', Input); +componentMap.set('InputNumber', InputNumber); +componentMap.set('Select', Select); +componentMap.set('ApiSelect', ApiSelect); +componentMap.set('AutoComplete', AutoComplete); +componentMap.set('ApiTreeSelect', ApiTreeSelect); +componentMap.set('Switch', Switch); +componentMap.set('Checkbox', Checkbox); +componentMap.set('DatePicker', DatePicker); +componentMap.set('TimePicker', TimePicker); +componentMap.set('RadioGroup', Radio.Group); +componentMap.set('RadioButtonGroup', RadioButtonGroup); +componentMap.set('ApiRadioGroup', ApiRadioGroup); + +export function add(compName: ComponentType, component: Component) { + componentMap.set(compName, component); +} + +export function del(compName: ComponentType) { + componentMap.delete(compName); +} + +export { componentMap }; diff --git a/src/components/Table/src/components/EditTableHeaderIcon.vue b/src/components/Table/src/components/EditTableHeaderIcon.vue new file mode 100644 index 0000000..ed05c31 --- /dev/null +++ b/src/components/Table/src/components/EditTableHeaderIcon.vue @@ -0,0 +1,17 @@ + + diff --git a/src/components/Table/src/components/HeaderCell.vue b/src/components/Table/src/components/HeaderCell.vue new file mode 100644 index 0000000..e906bef --- /dev/null +++ b/src/components/Table/src/components/HeaderCell.vue @@ -0,0 +1,60 @@ + + diff --git a/src/components/Table/src/components/TableAction.vue b/src/components/Table/src/components/TableAction.vue new file mode 100644 index 0000000..73bf691 --- /dev/null +++ b/src/components/Table/src/components/TableAction.vue @@ -0,0 +1,202 @@ + + + diff --git a/src/components/Table/src/components/TableFooter.vue b/src/components/Table/src/components/TableFooter.vue new file mode 100644 index 0000000..68e556b --- /dev/null +++ b/src/components/Table/src/components/TableFooter.vue @@ -0,0 +1,94 @@ + + diff --git a/src/components/Table/src/components/TableHeader.vue b/src/components/Table/src/components/TableHeader.vue new file mode 100644 index 0000000..cfcd090 --- /dev/null +++ b/src/components/Table/src/components/TableHeader.vue @@ -0,0 +1,81 @@ + + + diff --git a/src/components/Table/src/components/TableImg.vue b/src/components/Table/src/components/TableImg.vue new file mode 100644 index 0000000..0867bda --- /dev/null +++ b/src/components/Table/src/components/TableImg.vue @@ -0,0 +1,91 @@ + + + diff --git a/src/components/Table/src/components/TableTitle.vue b/src/components/Table/src/components/TableTitle.vue new file mode 100644 index 0000000..0f7417b --- /dev/null +++ b/src/components/Table/src/components/TableTitle.vue @@ -0,0 +1,53 @@ + + + diff --git a/src/components/Table/src/components/editable/CellComponent.ts b/src/components/Table/src/components/editable/CellComponent.ts new file mode 100644 index 0000000..547940b --- /dev/null +++ b/src/components/Table/src/components/editable/CellComponent.ts @@ -0,0 +1,44 @@ +import type { FunctionalComponent, defineComponent } from 'vue'; +import type { ComponentType } from '../../types/componentType'; +import { componentMap } from '/@/components/Table/src/componentMap'; + +import { Popover } from 'ant-design-vue'; +import { h } from 'vue'; + +export interface ComponentProps { + component: ComponentType; + rule: boolean; + popoverVisible: boolean; + ruleMessage: string; + getPopupContainer?: Fn; +} + +export const CellComponent: FunctionalComponent = ( + { + component = 'Input', + rule = true, + ruleMessage, + popoverVisible, + getPopupContainer, + }: ComponentProps, + { attrs }, +) => { + const Comp = componentMap.get(component) as typeof defineComponent; + + const DefaultComp = h(Comp, attrs); + if (!rule) { + return DefaultComp; + } + return h( + Popover, + { + overlayClassName: 'edit-cell-rule-popover', + open: !!popoverVisible, + ...(getPopupContainer ? { getPopupContainer } : {}), + }, + { + default: () => DefaultComp, + content: () => ruleMessage, + }, + ); +}; diff --git a/src/components/Table/src/components/editable/EditableCell.vue b/src/components/Table/src/components/editable/EditableCell.vue new file mode 100644 index 0000000..e24e0e6 --- /dev/null +++ b/src/components/Table/src/components/editable/EditableCell.vue @@ -0,0 +1,535 @@ + + diff --git a/src/components/Table/src/components/editable/helper.ts b/src/components/Table/src/components/editable/helper.ts new file mode 100644 index 0000000..9c600c9 --- /dev/null +++ b/src/components/Table/src/components/editable/helper.ts @@ -0,0 +1,28 @@ +import { ComponentType } from '../../types/componentType'; +import { useI18n } from '/@/hooks/web/useI18n'; + +const { t } = useI18n(); + +/** + * @description: 生成placeholder + */ +export function createPlaceholderMessage(component: ComponentType) { + if (component.includes('Input') || component.includes('AutoComplete')) { + return t('common.inputText'); + } + if (component.includes('Picker')) { + return t('common.chooseText'); + } + + if ( + component.includes('Select') || + component.includes('Checkbox') || + component.includes('Radio') || + component.includes('Switch') || + component.includes('DatePicker') || + component.includes('TimePicker') + ) { + return t('common.chooseText'); + } + return ''; +} diff --git a/src/components/Table/src/components/editable/index.ts b/src/components/Table/src/components/editable/index.ts new file mode 100644 index 0000000..548c9e4 --- /dev/null +++ b/src/components/Table/src/components/editable/index.ts @@ -0,0 +1,68 @@ +import type { BasicColumn } from '/@/components/Table/src/types/table'; + +import { h, Ref, toRaw } from 'vue'; + +import EditableCell from './EditableCell.vue'; +import { isArray } from '/@/utils/is'; + +interface Params { + text: string; + record: Recordable; + index: number; +} + +export function renderEditCell(column: BasicColumn) { + return ({ text: value, record, index }: Params) => { + toRaw(record).onValid = async () => { + if (isArray(record?.validCbs)) { + const validFns = (record?.validCbs || []).map((fn) => fn()); + const res = await Promise.all(validFns); + return res.every((item) => !!item); + } else { + return false; + } + }; + + toRaw(record).onEdit = async (edit: boolean, submit = false) => { + if (!submit) { + record.editable = edit; + } + + if (!edit && submit) { + if (!(await record.onValid())) return false; + const res = await record.onSubmitEdit?.(); + if (res) { + record.editable = false; + return true; + } + return false; + } + // cancel + if (!edit && !submit) { + record.onCancelEdit?.(); + } + return true; + }; + + return h(EditableCell, { + value, + record, + column, + index, + }); + }; +} + +export type EditRecordRow = Partial< + { + onEdit: (editable: boolean, submit?: boolean) => Promise; + onValid: () => Promise; + editable: boolean; + onCancel: Fn; + onSubmit: Fn; + submitCbs: Fn[]; + cancelCbs: Fn[]; + validCbs: Fn[]; + editValueRefs: Recordable; + } & T +>; diff --git a/src/components/Table/src/components/settings/ColumnSetting.vue b/src/components/Table/src/components/settings/ColumnSetting.vue new file mode 100644 index 0000000..7b494b0 --- /dev/null +++ b/src/components/Table/src/components/settings/ColumnSetting.vue @@ -0,0 +1,515 @@ + + + diff --git a/src/components/Table/src/components/settings/FullScreenSetting.vue b/src/components/Table/src/components/settings/FullScreenSetting.vue new file mode 100644 index 0000000..af07f84 --- /dev/null +++ b/src/components/Table/src/components/settings/FullScreenSetting.vue @@ -0,0 +1,38 @@ + + diff --git a/src/components/Table/src/components/settings/RedoSetting.vue b/src/components/Table/src/components/settings/RedoSetting.vue new file mode 100644 index 0000000..81829a1 --- /dev/null +++ b/src/components/Table/src/components/settings/RedoSetting.vue @@ -0,0 +1,33 @@ + + diff --git a/src/components/Table/src/components/settings/SizeSetting.vue b/src/components/Table/src/components/settings/SizeSetting.vue new file mode 100644 index 0000000..79c4a22 --- /dev/null +++ b/src/components/Table/src/components/settings/SizeSetting.vue @@ -0,0 +1,64 @@ + + diff --git a/src/components/Table/src/components/settings/index.vue b/src/components/Table/src/components/settings/index.vue new file mode 100644 index 0000000..ab03cb2 --- /dev/null +++ b/src/components/Table/src/components/settings/index.vue @@ -0,0 +1,76 @@ + + + diff --git a/src/components/Table/src/const.ts b/src/components/Table/src/const.ts new file mode 100644 index 0000000..2a45fac --- /dev/null +++ b/src/components/Table/src/const.ts @@ -0,0 +1,38 @@ +import componentSetting from '/@/settings/componentSetting'; + +const { table } = componentSetting; + +const { + pageSizeOptions, + defaultPageSize, + fetchSetting, + defaultSize, + defaultSortFn, + defaultFilterFn, +} = table; + +export const ROW_KEY = 'key'; + +// Optional display number per page; +export const PAGE_SIZE_OPTIONS = pageSizeOptions; + +// Number of items displayed per page +export const PAGE_SIZE = defaultPageSize; + +// Common interface field settings +export const FETCH_SETTING = fetchSetting; + +// Default Size +export const DEFAULT_SIZE = defaultSize; + +// Configure general sort function +export const DEFAULT_SORT_FN = defaultSortFn; + +export const DEFAULT_FILTER_FN = defaultFilterFn; + +// Default layout of table cells +export const DEFAULT_ALIGN = 'center'; + +export const INDEX_COLUMN_FLAG = 'INDEX'; + +export const ACTION_COLUMN_FLAG = 'ACTION'; diff --git a/src/components/Table/src/hooks/useColumns.ts b/src/components/Table/src/hooks/useColumns.ts new file mode 100644 index 0000000..7523725 --- /dev/null +++ b/src/components/Table/src/hooks/useColumns.ts @@ -0,0 +1,329 @@ +import type { BasicColumn, BasicTableProps, CellFormat, GetColumnsParams } from '../types/table'; +import type { PaginationProps } from '../types/pagination'; +import type { ComputedRef } from 'vue'; +import { computed, Ref, ref, reactive, toRaw, unref, watch } from 'vue'; +import { renderEditCell } from '../components/editable'; +import { usePermission } from '/@/hooks/web/usePermission'; +import { useI18n } from '/@/hooks/web/useI18n'; +import { isArray, isBoolean, isFunction, isMap, isString } from '/@/utils/is'; +import { cloneDeep, isEqual } from 'lodash-es'; +import { formatToDate } from '/@/utils/dateUtil'; +import { ACTION_COLUMN_FLAG, DEFAULT_ALIGN, INDEX_COLUMN_FLAG, PAGE_SIZE } from '../const'; + +function handleItem(item: BasicColumn, ellipsis: boolean) { + const { key, dataIndex, children } = item; + item.align = item.align || DEFAULT_ALIGN; + if (ellipsis) { + if (!key) { + item.key = typeof dataIndex == 'object' ? dataIndex.join('-') : dataIndex; + } + if (!isBoolean(item.ellipsis)) { + Object.assign(item, { + ellipsis, + }); + } + } + if (children && children.length) { + handleChildren(children, !!ellipsis); + } +} + +function handleChildren(children: BasicColumn[] | undefined, ellipsis: boolean) { + if (!children) return; + children.forEach((item) => { + const { children } = item; + handleItem(item, ellipsis); + handleChildren(children, ellipsis); + }); +} + +function handleIndexColumn( + propsRef: ComputedRef, + getPaginationRef: ComputedRef, + columns: BasicColumn[], +) { + const { t } = useI18n(); + + const { showIndexColumn, indexColumnProps, isTreeTable } = unref(propsRef); + + let pushIndexColumns = false; + if (unref(isTreeTable)) { + return; + } + columns.forEach(() => { + const indIndex = columns.findIndex((column) => column.flag === INDEX_COLUMN_FLAG); + if (showIndexColumn) { + pushIndexColumns = indIndex === -1; + } else if (!showIndexColumn && indIndex !== -1) { + columns.splice(indIndex, 1); + } + }); + + if (!pushIndexColumns) return; + + const isFixedLeft = columns.some((item) => item.fixed === 'left'); + + columns.unshift({ + flag: INDEX_COLUMN_FLAG, + width: 50, + title: t('component.table.index'), + align: 'center', + customRender: ({ index }) => { + const getPagination = unref(getPaginationRef); + if (isBoolean(getPagination)) { + return `${index + 1}`; + } + const { current = 1, pageSize = PAGE_SIZE } = getPagination; + return ((current < 1 ? 1 : current) - 1) * pageSize + index + 1; + }, + ...(isFixedLeft + ? { + fixed: 'left', + } + : {}), + ...indexColumnProps, + }); +} + +function handleActionColumn(propsRef: ComputedRef, columns: BasicColumn[]) { + const { actionColumn } = unref(propsRef); + if (!actionColumn) return; + + const hasIndex = columns.findIndex((column) => column.flag === ACTION_COLUMN_FLAG); + if (hasIndex === -1) { + columns.push({ + ...columns[hasIndex], + fixed: 'right', + ...actionColumn, + flag: ACTION_COLUMN_FLAG, + }); + } +} + +export function useColumns( + propsRef: ComputedRef, + getPaginationRef: ComputedRef, +) { + const columnsRef = ref(unref(propsRef).columns) as unknown as Ref; + let cacheColumns = unref(propsRef).columns; + + const getColumnsRef = computed(() => { + const columns = cloneDeep(unref(columnsRef)); + + handleIndexColumn(propsRef, getPaginationRef, columns); + handleActionColumn(propsRef, columns); + if (!columns) { + return []; + } + const { ellipsis } = unref(propsRef); + + columns.forEach((item) => { + const { customRender, slots } = item; + + handleItem( + item, + Reflect.has(item, 'ellipsis') ? !!item.ellipsis : !!ellipsis && !customRender && !slots, + ); + }); + return columns; + }); + + function isIfShow(column: BasicColumn): boolean { + const ifShow = column.ifShow; + + let isIfShow = true; + + if (isBoolean(ifShow)) { + isIfShow = ifShow; + } + if (isFunction(ifShow)) { + isIfShow = ifShow(column); + } + return isIfShow; + } + const { hasPermission } = usePermission(); + + const getViewColumns = computed(() => { + const viewColumns = sortFixedColumn(unref(getColumnsRef)); + + const mapFn = (column) => { + const { slots, customRender, format, edit, editRow, flag } = column; + + if (!slots || !slots?.title) { + // column.slots = { title: `header-${dataIndex}`, ...(slots || {}) }; + column.customTitle = column.title; + Reflect.deleteProperty(column, 'title'); + } + const isDefaultAction = [INDEX_COLUMN_FLAG, ACTION_COLUMN_FLAG].includes(flag!); + if (!customRender && format && !edit && !isDefaultAction) { + column.customRender = ({ text, record, index }) => { + return formatCell(text, format, record, index); + }; + } + + // edit table + if ((edit || editRow) && !isDefaultAction) { + column.customRender = renderEditCell(column); + } + return reactive(column); + }; + + const columns = cloneDeep(viewColumns); + return columns + .filter((column) => hasPermission(column.auth) && isIfShow(column)) + .map((column) => { + // Support table multiple header editable + if (column.children?.length) { + column.children = column.children.map(mapFn); + } + + return mapFn(column); + }); + }); + + watch( + () => unref(propsRef).columns, + (columns) => { + columnsRef.value = columns; + cacheColumns = columns?.filter((item) => !item.flag) ?? []; + }, + ); + + function setCacheColumnsByField(dataIndex: string | undefined, value: Partial) { + if (!dataIndex || !value) { + return; + } + cacheColumns.forEach((item) => { + if (item.dataIndex === dataIndex) { + Object.assign(item, value); + return; + } + }); + } + /** + * set columns + * @param columnList key|column + */ + function setColumns(columnList: Partial[] | (string | string[])[]) { + const columns = cloneDeep(columnList); + if (!isArray(columns)) return; + + if (columns.length <= 0) { + columnsRef.value = []; + return; + } + + const firstColumn = columns[0]; + + const cacheKeys = cacheColumns.map((item) => item.dataIndex); + + if (!isString(firstColumn) && !isArray(firstColumn)) { + columnsRef.value = columns as BasicColumn[]; + } else { + const columnKeys = (columns as (string | string[])[]).map((m) => m.toString()); + const newColumns: BasicColumn[] = []; + cacheColumns.forEach((item) => { + newColumns.push({ + ...item, + defaultHidden: !columnKeys.includes(item.dataIndex?.toString() || (item.key as string)), + }); + }); + // Sort according to another array + if (!isEqual(cacheKeys, columns)) { + newColumns.sort((prev, next) => { + return ( + columnKeys.indexOf(prev.dataIndex?.toString() as string) - + columnKeys.indexOf(next.dataIndex?.toString() as string) + ); + }); + } + columnsRef.value = newColumns; + } + } + + function getColumns(opt?: GetColumnsParams) { + const { ignoreIndex, ignoreAction, sort } = opt || {}; + let columns = toRaw(unref(getColumnsRef)); + if (ignoreIndex) { + columns = columns.filter((item) => item.flag !== INDEX_COLUMN_FLAG); + } + if (ignoreAction) { + columns = columns.filter((item) => item.flag !== ACTION_COLUMN_FLAG); + } + + if (sort) { + columns = sortFixedColumn(columns); + } + + return columns; + } + function getCacheColumns() { + return cacheColumns; + } + function setCacheColumns(columns: BasicColumn[]) { + if (!isArray(columns)) return; + cacheColumns = columns.filter((item) => !item.flag); + } + + return { + getColumnsRef, + getCacheColumns, + getColumns, + setColumns, + getViewColumns, + setCacheColumnsByField, + setCacheColumns, + }; +} + +function sortFixedColumn(columns: BasicColumn[]) { + const fixedLeftColumns: BasicColumn[] = []; + const fixedRightColumns: BasicColumn[] = []; + const defColumns: BasicColumn[] = []; + for (const column of columns) { + if (column.fixed === 'left') { + fixedLeftColumns.push(column); + continue; + } + if (column.fixed === 'right') { + fixedRightColumns.push(column); + continue; + } + defColumns.push(column); + } + return [...fixedLeftColumns, ...defColumns, ...fixedRightColumns].filter( + (item) => !item.defaultHidden, + ); +} + +// format cell +export function formatCell(text: string, format: CellFormat, record: Recordable, index: number) { + if (!format) { + return text; + } + + // custom function + if (isFunction(format)) { + return format(text, record, index); + } + + try { + // date type + const DATE_FORMAT_PREFIX = 'date|'; + if (isString(format) && format.startsWith(DATE_FORMAT_PREFIX) && text) { + const dateFormat = format.replace(DATE_FORMAT_PREFIX, ''); + + if (!dateFormat) { + return text; + } + return formatToDate(text, dateFormat); + } + + // Map + if (isMap(format)) { + return format.get(text); + } + } catch (error) { + return text; + } +} diff --git a/src/components/Table/src/hooks/useCustomRow.ts b/src/components/Table/src/hooks/useCustomRow.ts new file mode 100644 index 0000000..0f7a6ea --- /dev/null +++ b/src/components/Table/src/hooks/useCustomRow.ts @@ -0,0 +1,101 @@ +import type { ComputedRef } from 'vue'; +import type { BasicTableProps } from '../types/table'; +import { unref } from 'vue'; +import { ROW_KEY } from '../const'; +import { isString, isFunction } from '/@/utils/is'; + +interface Options { + setSelectedRowKeys: (keys: string[]) => void; + getSelectRowKeys: () => string[]; + clearSelectedRowKeys: () => void; + emit: EmitType; + getAutoCreateKey: ComputedRef; +} + +function getKey( + record: Recordable, + rowKey: string | ((record: Record) => string) | undefined, + autoCreateKey?: boolean, +) { + if (!rowKey || autoCreateKey) { + return record[ROW_KEY]; + } + if (isString(rowKey)) { + return record[rowKey]; + } + if (isFunction(rowKey)) { + return record[rowKey(record)]; + } + return null; +} + +export function useCustomRow( + propsRef: ComputedRef, + { setSelectedRowKeys, getSelectRowKeys, getAutoCreateKey, clearSelectedRowKeys, emit }: Options, +) { + const customRow = (record: Recordable, index: number) => { + return { + onClick: (e: Event) => { + e?.stopPropagation(); + function handleClick() { + const { rowSelection, rowKey, clickToRowSelect } = unref(propsRef); + if (!rowSelection || !clickToRowSelect) return; + const keys = getSelectRowKeys() || []; + const key = getKey(record, rowKey, unref(getAutoCreateKey)); + if (key === null) return; + + const isCheckbox = rowSelection.type === 'checkbox'; + if (isCheckbox) { + // 找到tr + const tr: HTMLElement = (e as MouseEvent) + .composedPath?.() + .find((dom: HTMLElement) => dom.tagName === 'TR') as HTMLElement; + if (!tr) return; + // 找到Checkbox,检查是否为disabled + const checkBox = tr.querySelector('input[type=checkbox]'); + if (!checkBox || checkBox.hasAttribute('disabled')) return; + if (!keys.includes(key)) { + keys.push(key); + setSelectedRowKeys(keys); + return; + } + const keyIndex = keys.findIndex((item) => item === key); + keys.splice(keyIndex, 1); + setSelectedRowKeys(keys); + return; + } + + const isRadio = rowSelection.type === 'radio'; + if (isRadio) { + if (!keys.includes(key)) { + if (keys.length) { + clearSelectedRowKeys(); + } + setSelectedRowKeys([key]); + return; + } + clearSelectedRowKeys(); + } + } + handleClick(); + emit('row-click', record, index, e); + }, + onDblclick: (event: Event) => { + emit('row-dbClick', record, index, event); + }, + onContextmenu: (event: Event) => { + emit('row-contextmenu', record, index, event); + }, + onMouseenter: (event: Event) => { + emit('row-mouseenter', record, index, event); + }, + onMouseleave: (event: Event) => { + emit('row-mouseleave', record, index, event); + }, + }; + }; + + return { + customRow, + }; +} diff --git a/src/components/Table/src/hooks/useDataSource.ts b/src/components/Table/src/hooks/useDataSource.ts new file mode 100644 index 0000000..d748ac1 --- /dev/null +++ b/src/components/Table/src/hooks/useDataSource.ts @@ -0,0 +1,409 @@ +import type { BasicTableProps, FetchParams, SorterResult } from '../types/table'; +import type { PaginationProps } from '../types/pagination'; +import { + ref, + unref, + ComputedRef, + computed, + onMounted, + watch, + reactive, + Ref, + watchEffect, +} from 'vue'; +import { useTimeoutFn } from '@vben/hooks'; +import { buildUUID } from '/@/utils/uuid'; +import { isFunction, isBoolean, isObject } from '/@/utils/is'; +import { get, cloneDeep, merge } from 'lodash-es'; +import { FETCH_SETTING, ROW_KEY, PAGE_SIZE } from '../const'; +import { array2tree } from '@axolo/tree-array'; + +interface ActionType { + getPaginationInfo: ComputedRef; + setPagination: (info: Partial) => void; + setLoading: (loading: boolean) => void; + getFieldsValue: () => Recordable; + clearSelectedRowKeys: () => void; + tableData: Ref; +} + +interface SearchState { + sortInfo: Recordable; + filterInfo: Record; +} +export function useDataSource( + propsRef: ComputedRef, + { + getPaginationInfo, + setPagination, + setLoading, + getFieldsValue, + clearSelectedRowKeys, + tableData, + }: ActionType, + emit: EmitType, +) { + const searchState = reactive({ + sortInfo: {}, + filterInfo: {}, + }); + const dataSourceRef = ref([]); + const rawDataSourceRef = ref({}); + + watchEffect(() => { + tableData.value = unref(dataSourceRef); + }); + + watch( + () => unref(propsRef).dataSource, + () => { + const { dataSource, api } = unref(propsRef); + !api && dataSource && (dataSourceRef.value = dataSource); + }, + { + immediate: true, + }, + ); + + function handleTableChange( + pagination: PaginationProps, + filters: Partial>, + sorter: SorterResult, + ) { + const { clearSelectOnPageChange, sortFn, filterFn } = unref(propsRef); + if (clearSelectOnPageChange) { + clearSelectedRowKeys(); + } + setPagination(pagination); + + const params: Recordable = {}; + if (sorter && isFunction(sortFn)) { + const sortInfo = sortFn(sorter); + searchState.sortInfo = sortInfo; + params.sortInfo = sortInfo; + } + + if (filters && isFunction(filterFn)) { + const filterInfo = filterFn(filters); + searchState.filterInfo = filterInfo; + params.filterInfo = filterInfo; + } + fetch(params); + } + + function setTableKey(items: any[]) { + if (!items || !Array.isArray(items)) return; + items.forEach((item) => { + if (!item[ROW_KEY]) { + item[ROW_KEY] = buildUUID(); + } + if (item.children && item.children.length) { + setTableKey(item.children); + } + }); + } + + const getAutoCreateKey = computed(() => { + return unref(propsRef).autoCreateKey && !unref(propsRef).rowKey; + }); + + const getRowKey = computed(() => { + const { rowKey } = unref(propsRef); + return unref(getAutoCreateKey) ? ROW_KEY : rowKey; + }); + + const getDataSourceRef = computed(() => { + const dataSource = unref(dataSourceRef); + if (!dataSource || dataSource.length === 0) { + return unref(dataSourceRef); + } + if (unref(getAutoCreateKey)) { + const firstItem = dataSource[0]; + const lastItem = dataSource[dataSource.length - 1]; + + if (firstItem && lastItem) { + if (!firstItem[ROW_KEY] || !lastItem[ROW_KEY]) { + const data = cloneDeep(unref(dataSourceRef)); + data.forEach((item) => { + if (!item[ROW_KEY]) { + item[ROW_KEY] = buildUUID(); + } + if (item.children && item.children.length) { + setTableKey(item.children); + } + }); + dataSourceRef.value = data; + } + } + } + return unref(dataSourceRef); + }); + + async function updateTableData(index: number, key: string, value: any) { + const record = dataSourceRef.value[index]; + if (record) { + dataSourceRef.value[index][key] = value; + } + return dataSourceRef.value[index]; + } + + function updateTableDataRecord( + rowKey: string | number, + record: Recordable, + ): Recordable | undefined { + const row = findTableDataRecord(rowKey); + + if (row) { + for (const field in row) { + if (Reflect.has(record, field)) row[field] = record[field]; + } + return row; + } + } + + function deleteTableDataRecord(rowKey: string | number | string[] | number[]) { + if (!dataSourceRef.value || dataSourceRef.value.length == 0) return; + const rowKeyName = unref(getRowKey); + if (!rowKeyName) return; + const rowKeys = !Array.isArray(rowKey) ? [rowKey] : rowKey; + + function deleteRow(data, key) { + const row: { index: number; data: [] } = findRow(data, key); + if (row === null || row.index === -1) { + return; + } + row.data.splice(row.index, 1); + + function findRow(data, key) { + if (data === null || data === undefined) { + return null; + } + for (let i = 0; i < data.length; i++) { + const row = data[i]; + let targetKeyName: string = rowKeyName as string; + if (isFunction(rowKeyName)) { + targetKeyName = rowKeyName(row); + } + if (row[targetKeyName] === key) { + return { index: i, data }; + } + if (row.children?.length > 0) { + const result = findRow(row.children, key); + if (result != null) { + return result; + } + } + } + return null; + } + } + + for (const key of rowKeys) { + deleteRow(dataSourceRef.value, key); + deleteRow(unref(propsRef).dataSource, key); + } + setPagination({ + total: unref(propsRef).dataSource?.length, + }); + } + + function insertTableDataRecord( + record: Recordable | Recordable[], + index?: number, + ): Recordable[] | undefined { + // if (!dataSourceRef.value || dataSourceRef.value.length == 0) return; + index = index ?? dataSourceRef.value?.length; + const _record = isObject(record) ? [record as Recordable] : (record as Recordable[]); + unref(dataSourceRef).splice(index, 0, ..._record); + return unref(dataSourceRef); + } + + function findTableDataRecord(rowKey: string | number) { + if (!dataSourceRef.value || dataSourceRef.value.length == 0) return; + + const rowKeyName = unref(getRowKey); + if (!rowKeyName) return; + + const { childrenColumnName = 'children' } = unref(propsRef); + + const findRow = (array: any[]) => { + let ret; + array.some(function iter(r) { + if (typeof rowKeyName === 'function') { + if ((rowKeyName(r) as string) === rowKey) { + ret = r; + return true; + } + } else { + if (Reflect.has(r, rowKeyName) && r[rowKeyName] === rowKey) { + ret = r; + return true; + } + } + return r[childrenColumnName] && r[childrenColumnName].some(iter); + }); + return ret; + }; + + // const row = dataSourceRef.value.find(r => { + // if (typeof rowKeyName === 'function') { + // return (rowKeyName(r) as string) === rowKey + // } else { + // return Reflect.has(r, rowKeyName) && r[rowKeyName] === rowKey + // } + // }) + return findRow(dataSourceRef.value); + } + + async function fetch(opt?: FetchParams) { + const { + api, + searchInfo, + defSort, + fetchSetting, + beforeFetch, + afterFetch, + useSearchForm, + pagination, + isTreeTable, + } = unref(propsRef); + if (!api || !isFunction(api)) return; + try { + setLoading(true); + const { pageField, sizeField, listField, totalField } = Object.assign( + {}, + FETCH_SETTING, + fetchSetting, + ); + let pageParams: Recordable = {}; + + const { current = 1, pageSize = PAGE_SIZE } = unref(getPaginationInfo) as PaginationProps; + + if ((isBoolean(pagination) && !pagination) || isBoolean(getPaginationInfo)) { + pageParams = {}; + } else { + pageParams[pageField] = (opt && opt.page) || current; + pageParams[sizeField] = pageSize; + } + + const { sortInfo = {}, filterInfo } = searchState; + + let params: Recordable = merge( + pageParams, + useSearchForm ? getFieldsValue() : {}, + searchInfo, + opt?.searchInfo ?? {}, + defSort, + sortInfo, + filterInfo, + opt?.sortInfo ?? {}, + opt?.filterInfo ?? {}, + ); + if (beforeFetch && isFunction(beforeFetch)) { + params = (await beforeFetch(params)) || params; + } + + let isArrayResult: boolean; + let resultItems: Recordable[]; + let resultTotal: number; + + const result = await api(params); + const res = result.data; + if (isTreeTable) { + if(res.data){ + const tree = array2tree(res.data); + rawDataSourceRef.value = tree; + isArrayResult = Array.isArray(tree); + resultItems = isArrayResult ? tree : get(tree, listField); + resultTotal = isArrayResult ? tree.length : get(tree, totalField); + }else { + const tree = array2tree(res); + rawDataSourceRef.value = array2tree(res); + isArrayResult = Array.isArray(tree); + resultItems = isArrayResult ? tree : get(tree, listField); + resultTotal = isArrayResult ? tree.length : get(tree, totalField); + } + } else { + rawDataSourceRef.value = res; + isArrayResult = Array.isArray(res); + resultItems = isArrayResult ? res : get(res, listField); + resultTotal = isArrayResult ? res.length : get(res, totalField); + } + // 假如数据变少,导致总页数变少并小于当前选中页码,通过getPaginationRef获取到的页码是不正确的,需获取正确的页码再次执行 + if (Number(resultTotal)) { + const currentTotalPage = Math.ceil(resultTotal / pageSize); + if (current > currentTotalPage) { + setPagination({ + current: currentTotalPage, + }); + return await fetch(opt); + } + } + + if (afterFetch && isFunction(afterFetch)) { + resultItems = (await afterFetch(resultItems)) || resultItems; + } + dataSourceRef.value = resultItems; + setPagination({ + total: resultTotal || 0, + }); + if (opt && opt.page) { + setPagination({ + current: opt.page || 1, + }); + } + emit('fetch-success', { + items: unref(resultItems), + total: resultTotal, + }); + return resultItems; + } catch (error) { + emit('fetch-error', error); + dataSourceRef.value = []; + setPagination({ + total: 0, + }); + } finally { + setLoading(false); + } + } + + function setTableData(values: T[]) { + dataSourceRef.value = values as Recordable[]; + } + + function getDataSource() { + return getDataSourceRef.value as T[]; + } + + function getRawDataSource() { + return rawDataSourceRef.value as T; + } + + async function reload(opt?: FetchParams) { + return await fetch(opt); + } + + onMounted(() => { + useTimeoutFn(() => { + unref(propsRef).immediate && fetch(); + }, 16); + }); + + return { + getDataSourceRef, + getDataSource, + getRawDataSource, + getRowKey, + setTableData, + getAutoCreateKey, + fetch, + reload, + updateTableData, + updateTableDataRecord, + deleteTableDataRecord, + insertTableDataRecord, + findTableDataRecord, + handleTableChange, + }; +} diff --git a/src/components/Table/src/hooks/useLoading.ts b/src/components/Table/src/hooks/useLoading.ts new file mode 100644 index 0000000..fe8a0f1 --- /dev/null +++ b/src/components/Table/src/hooks/useLoading.ts @@ -0,0 +1,21 @@ +import { ref, ComputedRef, unref, computed, watch } from 'vue'; +import type { BasicTableProps } from '../types/table'; + +export function useLoading(props: ComputedRef) { + const loadingRef = ref(unref(props).loading); + + watch( + () => unref(props).loading, + (loading) => { + loadingRef.value = loading; + }, + ); + + const getLoading = computed(() => unref(loadingRef)); + + function setLoading(loading: boolean) { + loadingRef.value = loading; + } + + return { getLoading, setLoading }; +} diff --git a/src/components/Table/src/hooks/usePagination.tsx b/src/components/Table/src/hooks/usePagination.tsx new file mode 100644 index 0000000..ba310bd --- /dev/null +++ b/src/components/Table/src/hooks/usePagination.tsx @@ -0,0 +1,85 @@ +import type { PaginationProps } from '../types/pagination'; +import type { BasicTableProps } from '../types/table'; +import { computed, unref, ref, ComputedRef, watch } from 'vue'; +import { LeftOutlined, RightOutlined } from '@ant-design/icons-vue'; +import { isBoolean } from '/@/utils/is'; +import { PAGE_SIZE, PAGE_SIZE_OPTIONS } from '../const'; +import { useI18n } from '/@/hooks/web/useI18n'; + +interface ItemRender { + page: number; + type: 'page' | 'prev' | 'next'; + originalElement: any; +} + +function itemRender({ page, type, originalElement }: ItemRender) { + if (type === 'prev') { + return page === 0 ? null : ; + } else if (type === 'next') { + return page === 1 ? null : ; + } + return originalElement; +} + +export function usePagination(refProps: ComputedRef) { + const { t } = useI18n(); + + const configRef = ref({}); + const show = ref(true); + + watch( + () => unref(refProps).pagination, + (pagination) => { + if (!isBoolean(pagination) && pagination) { + configRef.value = { + ...unref(configRef), + ...(pagination ?? {}), + }; + } + }, + ); + + const getPaginationInfo = computed((): PaginationProps | boolean => { + const { pagination } = unref(refProps); + + if (!unref(show) || (isBoolean(pagination) && !pagination)) { + return false; + } + + return { + current: 1, + pageSize: PAGE_SIZE, + size: 'small', + defaultPageSize: PAGE_SIZE, + showTotal: (total) => t('component.table.total', { total }), + showSizeChanger: true, + pageSizeOptions: PAGE_SIZE_OPTIONS, + itemRender: itemRender, + showQuickJumper: true, + ...(isBoolean(pagination) ? {} : pagination), + ...unref(configRef), + }; + }); + + function setPagination(info: Partial) { + const paginationInfo = unref(getPaginationInfo); + configRef.value = { + ...(!isBoolean(paginationInfo) ? paginationInfo : {}), + ...info, + }; + } + + function getPagination() { + return unref(getPaginationInfo); + } + + function getShowPagination() { + return unref(show); + } + + async function setShowPagination(flag: boolean) { + show.value = flag; + } + + return { getPagination, getPaginationInfo, setShowPagination, getShowPagination, setPagination }; +} diff --git a/src/components/Table/src/hooks/useRowSelection.ts b/src/components/Table/src/hooks/useRowSelection.ts new file mode 100644 index 0000000..e87c3df --- /dev/null +++ b/src/components/Table/src/hooks/useRowSelection.ts @@ -0,0 +1,123 @@ +import { isFunction } from '/@/utils/is'; +import type { BasicTableProps, TableRowSelection } from '../types/table'; +import { computed, ComputedRef, nextTick, Ref, ref, toRaw, unref, watch } from 'vue'; +import { ROW_KEY } from '../const'; +import { omit } from 'lodash-es'; +import { findNodeAll } from '/@/utils/helper/treeHelper'; +import type { Key } from 'ant-design-vue/lib/table/interface'; + +export function useRowSelection( + propsRef: ComputedRef, + tableData: Ref, + emit: EmitType, +) { + const selectedRowKeysRef = ref([]); + const selectedRowRef = ref([]); + + const getRowSelectionRef = computed((): TableRowSelection | null => { + const { rowSelection } = unref(propsRef); + if (!rowSelection) { + return null; + } + + return { + selectedRowKeys: unref(selectedRowKeysRef), + onChange: (selectedRowKeys: Key[]) => { + setSelectedRowKeys(selectedRowKeys); + }, + ...omit(rowSelection, ['onChange']), + }; + }); + + watch( + () => unref(propsRef).rowSelection?.selectedRowKeys, + (v?: Key[]) => { + setSelectedRowKeys(v); + }, + ); + + watch( + () => unref(selectedRowKeysRef), + () => { + nextTick(() => { + const { rowSelection } = unref(propsRef); + if (rowSelection) { + const { onChange } = rowSelection; + if (onChange && isFunction(onChange)) onChange(getSelectRowKeys(), getSelectRows()); + } + emit('selection-change', { + keys: getSelectRowKeys(), + rows: getSelectRows(), + }); + }); + }, + { deep: true }, + ); + + const getAutoCreateKey = computed(() => { + return unref(propsRef).autoCreateKey && !unref(propsRef).rowKey; + }); + + const getRowKey = computed(() => { + const { rowKey } = unref(propsRef); + return unref(getAutoCreateKey) ? ROW_KEY : rowKey; + }); + + function setSelectedRowKeys(rowKeys?: Key[]) { + selectedRowKeysRef.value = rowKeys || []; + const allSelectedRows = findNodeAll( + toRaw(unref(tableData)).concat(toRaw(unref(selectedRowRef))), + (item) => rowKeys?.includes(item[unref(getRowKey) as string]), + { + children: propsRef.value.childrenColumnName ?? 'children', + }, + ); + const trueSelectedRows: any[] = []; + rowKeys?.forEach((key: Key) => { + const found = allSelectedRows.find((item) => item[unref(getRowKey) as string] === key); + found && trueSelectedRows.push(found); + }); + selectedRowRef.value = trueSelectedRows; + } + + function setSelectedRows(rows: Recordable[]) { + selectedRowRef.value = rows; + } + + function clearSelectedRowKeys() { + selectedRowRef.value = []; + selectedRowKeysRef.value = []; + } + + function deleteSelectRowByKey(key: string) { + const selectedRowKeys = unref(selectedRowKeysRef); + const index = selectedRowKeys.findIndex((item) => item === key); + if (index !== -1) { + unref(selectedRowKeysRef).splice(index, 1); + } + } + + function getSelectRowKeys() { + return unref(selectedRowKeysRef); + } + + function getSelectRows() { + // const ret = toRaw(unref(selectedRowRef)).map((item) => toRaw(item)); + return unref(selectedRowRef) as T[]; + } + + function getRowSelection() { + return unref(getRowSelectionRef)!; + } + + return { + getRowSelection, + getRowSelectionRef, + getSelectRows, + getSelectRowKeys, + setSelectedRowKeys, + clearSelectedRowKeys, + deleteSelectRowByKey, + setSelectedRows, + }; +} diff --git a/src/components/Table/src/hooks/useScrollTo.ts b/src/components/Table/src/hooks/useScrollTo.ts new file mode 100644 index 0000000..b368f81 --- /dev/null +++ b/src/components/Table/src/hooks/useScrollTo.ts @@ -0,0 +1,55 @@ +import type { ComputedRef, Ref } from 'vue'; +import { nextTick, unref } from 'vue'; +import { warn } from '/@/utils/log'; + +export function useTableScrollTo( + tableElRef: Ref, + getDataSourceRef: ComputedRef, +) { + let bodyEl: HTMLElement | null; + + async function findTargetRowToScroll(targetRowData: Recordable) { + const { id } = targetRowData; + const targetRowEl: HTMLElement | null | undefined = bodyEl?.querySelector( + `[data-row-key="${id}"]`, + ); + //Add a delay to get new dataSource + await nextTick(); + bodyEl?.scrollTo({ + top: targetRowEl?.offsetTop ?? 0, + behavior: 'smooth', + }); + } + + function scrollTo(pos: string): void { + const table = unref(tableElRef); + if (!table) return; + + const tableEl: Element = table.$el; + if (!tableEl) return; + + if (!bodyEl) { + bodyEl = tableEl.querySelector('.ant-table-body'); + if (!bodyEl) return; + } + + const dataSource = unref(getDataSourceRef); + if (!dataSource) return; + + // judge pos type + if (pos === 'top') { + findTargetRowToScroll(dataSource[0]); + } else if (pos === 'bottom') { + findTargetRowToScroll(dataSource[dataSource.length - 1]); + } else { + const targetRowData = dataSource.find((data) => data.id === pos); + if (targetRowData) { + findTargetRowToScroll(targetRowData); + } else { + warn(`id: ${pos} doesn't exist`); + } + } + } + + return { scrollTo }; +} diff --git a/src/components/Table/src/hooks/useTable.ts b/src/components/Table/src/hooks/useTable.ts new file mode 100644 index 0000000..f7f29df --- /dev/null +++ b/src/components/Table/src/hooks/useTable.ts @@ -0,0 +1,171 @@ +import type { BasicTableProps, TableActionType, FetchParams, BasicColumn } from '../types/table'; +import type { PaginationProps } from '../types/pagination'; +import type { DynamicProps } from '/#/utils'; +import type { FormActionType } from '/@/components/Form'; +import type { WatchStopHandle } from 'vue'; +import { getDynamicProps } from '/@/utils'; +import { ref, onUnmounted, unref, watch, toRaw } from 'vue'; +import { isProdMode } from '/@/utils/env'; +import { error } from '/@/utils/log'; +import type { Key } from 'ant-design-vue/lib/table/interface'; + +type Props = Partial>; + +type UseTableMethod = TableActionType & { + getForm: () => FormActionType; +}; + +export function useTable(tableProps?: Props): [ + (instance: TableActionType, formInstance: UseTableMethod) => void, + TableActionType & { + getForm: () => FormActionType; + }, +] { + const tableRef = ref>(null); + const loadedRef = ref>(false); + const formRef = ref>(null); + + let stopWatch: WatchStopHandle; + + function register(instance: TableActionType, formInstance: UseTableMethod) { + isProdMode() && + onUnmounted(() => { + tableRef.value = null; + loadedRef.value = null; + }); + + if (unref(loadedRef) && isProdMode() && instance === unref(tableRef)) return; + + tableRef.value = instance; + formRef.value = formInstance; + tableProps && instance.setProps(getDynamicProps(tableProps)); + loadedRef.value = true; + + stopWatch?.(); + + stopWatch = watch( + () => tableProps, + () => { + tableProps && instance.setProps(getDynamicProps(tableProps)); + }, + { + immediate: true, + deep: true, + }, + ); + } + + function getTableInstance(): TableActionType { + const table = unref(tableRef); + if (!table) { + error( + 'The table instance has not been obtained yet, please make sure the table is presented when performing the table operation!', + ); + } + return table as TableActionType; + } + + const methods: TableActionType & { + getForm: () => FormActionType; + } = { + reload: async (opt?: FetchParams) => { + return await getTableInstance().reload(opt); + }, + setProps: (props: Partial) => { + getTableInstance().setProps(props); + }, + redoHeight: () => { + getTableInstance().redoHeight(); + }, + setSelectedRows: (rows: Recordable[]) => { + return toRaw(getTableInstance().setSelectedRows(rows)); + }, + setLoading: (loading: boolean) => { + getTableInstance().setLoading(loading); + }, + getDataSource: () => { + return getTableInstance().getDataSource(); + }, + getRawDataSource: () => { + return getTableInstance().getRawDataSource(); + }, + getColumns: ({ ignoreIndex = false }: { ignoreIndex?: boolean } = {}) => { + const columns = getTableInstance().getColumns({ ignoreIndex }) || []; + return toRaw(columns); + }, + setColumns: (columns: BasicColumn[] | string[]) => { + getTableInstance().setColumns(columns); + }, + setTableData: (values: any[]) => { + return getTableInstance().setTableData(values); + }, + setPagination: (info: Partial) => { + return getTableInstance().setPagination(info); + }, + deleteSelectRowByKey: (key: string) => { + getTableInstance().deleteSelectRowByKey(key); + }, + getSelectRowKeys: () => { + return toRaw(getTableInstance().getSelectRowKeys()); + }, + getSelectRows: () => { + return toRaw(getTableInstance().getSelectRows()); + }, + clearSelectedRowKeys: () => { + getTableInstance().clearSelectedRowKeys(); + }, + setSelectedRowKeys: (keys: (string | number)[]) => { + getTableInstance().setSelectedRowKeys(keys); + }, + getPaginationRef: () => { + return getTableInstance().getPaginationRef(); + }, + getSize: () => { + return toRaw(getTableInstance().getSize()); + }, + updateTableData: (index: number, key: string, value: any) => { + return getTableInstance().updateTableData(index, key, value); + }, + deleteTableDataRecord: (rowKey: string | number | string[] | number[]) => { + return getTableInstance().deleteTableDataRecord(rowKey); + }, + insertTableDataRecord: (record: Recordable | Recordable[], index?: number) => { + return getTableInstance().insertTableDataRecord(record, index); + }, + updateTableDataRecord: (rowKey: string | number, record: Recordable) => { + return getTableInstance().updateTableDataRecord(rowKey, record); + }, + findTableDataRecord: (rowKey: string | number) => { + return getTableInstance().findTableDataRecord(rowKey); + }, + getRowSelection: () => { + return toRaw(getTableInstance().getRowSelection()); + }, + getCacheColumns: () => { + return toRaw(getTableInstance().getCacheColumns()); + }, + getForm: () => { + return unref(formRef) as unknown as FormActionType; + }, + setShowPagination: async (show: boolean) => { + getTableInstance().setShowPagination(show); + }, + getShowPagination: () => { + return toRaw(getTableInstance().getShowPagination()); + }, + expandAll: () => { + getTableInstance().expandAll(); + }, + expandRows: (keys: Key[]) => { + getTableInstance().expandRows(keys); + }, + collapseAll: () => { + getTableInstance().collapseAll(); + }, + scrollTo: (pos: string) => { + getTableInstance().scrollTo(pos); + }, + }; + + return [register, methods]; +} diff --git a/src/components/Table/src/hooks/useTableContext.ts b/src/components/Table/src/hooks/useTableContext.ts new file mode 100644 index 0000000..b657bb2 --- /dev/null +++ b/src/components/Table/src/hooks/useTableContext.ts @@ -0,0 +1,22 @@ +import type { Ref } from 'vue'; +import type { BasicTableProps, TableActionType } from '../types/table'; +import { provide, inject, ComputedRef } from 'vue'; + +const key = Symbol('basic-table'); + +type Instance = TableActionType & { + wrapRef: Ref>; + getBindValues: ComputedRef; +}; + +type RetInstance = Omit & { + getBindValues: ComputedRef; +}; + +export function createTableContext(instance: Instance) { + provide(key, instance); +} + +export function useTableContext(): RetInstance { + return inject(key) as RetInstance; +} diff --git a/src/components/Table/src/hooks/useTableExpand.ts b/src/components/Table/src/hooks/useTableExpand.ts new file mode 100644 index 0000000..49fd2d9 --- /dev/null +++ b/src/components/Table/src/hooks/useTableExpand.ts @@ -0,0 +1,65 @@ +import type { ComputedRef, Ref } from 'vue'; +import type { BasicTableProps } from '../types/table'; +import { computed, unref, ref, toRaw } from 'vue'; +import { ROW_KEY } from '../const'; + +export function useTableExpand( + propsRef: ComputedRef, + tableData: Ref, + emit: EmitType, +) { + const expandedRowKeys = ref<(string | number)[]>([]); + + const getAutoCreateKey = computed(() => { + return unref(propsRef).autoCreateKey && !unref(propsRef).rowKey; + }); + + const getRowKey = computed(() => { + const { rowKey } = unref(propsRef); + return unref(getAutoCreateKey) ? ROW_KEY : rowKey; + }); + + const getExpandOption = computed(() => { + const { isTreeTable } = unref(propsRef); + if (!isTreeTable) return {}; + + return { + expandedRowKeys: unref(expandedRowKeys), + onExpandedRowsChange: (keys: string[]) => { + expandedRowKeys.value = keys; + emit('expanded-rows-change', keys); + }, + }; + }); + + function expandAll() { + const keys = getAllKeys(); + expandedRowKeys.value = keys; + } + + function expandRows(keys: (string | number)[]) { + // use row ID expands the specified table row + const { isTreeTable } = unref(propsRef); + if (!isTreeTable) return; + expandedRowKeys.value = [...expandedRowKeys.value, ...keys]; + } + + function getAllKeys(data?: Recordable[]) { + const keys: string[] = []; + const { childrenColumnName } = unref(propsRef); + toRaw(data || unref(tableData)).forEach((item) => { + keys.push(item[unref(getRowKey) as string]); + const children = item[childrenColumnName || 'children']; + if (children?.length) { + keys.push(...getAllKeys(children)); + } + }); + return keys; + } + + function collapseAll() { + expandedRowKeys.value = []; + } + + return { getExpandOption, expandAll, expandRows, collapseAll }; +} diff --git a/src/components/Table/src/hooks/useTableFooter.ts b/src/components/Table/src/hooks/useTableFooter.ts new file mode 100644 index 0000000..6a3aa58 --- /dev/null +++ b/src/components/Table/src/hooks/useTableFooter.ts @@ -0,0 +1,56 @@ +import type { ComputedRef, Ref } from 'vue'; +import type { BasicTableProps } from '../types/table'; +import { unref, computed, h, nextTick, watchEffect } from 'vue'; +import TableFooter from '../components/TableFooter.vue'; +import { useEventListener } from '/@/hooks/event/useEventListener'; + +export function useTableFooter( + propsRef: ComputedRef, + scrollRef: ComputedRef<{ + x: string | number | true; + y: string | number | null; + scrollToFirstRowOnChange: boolean; + }>, + tableElRef: Ref, + getDataSourceRef: ComputedRef, +) { + const getIsEmptyData = computed(() => { + return (unref(getDataSourceRef) || []).length === 0; + }); + + const getFooterProps = computed((): Recordable | undefined => { + const { summaryFunc, showSummary, summaryData } = unref(propsRef); + return showSummary && !unref(getIsEmptyData) + ? () => h(TableFooter, { summaryFunc, summaryData, scroll: unref(scrollRef) }) + : undefined; + }); + + watchEffect(() => { + handleSummary(); + }); + + function handleSummary() { + const { showSummary } = unref(propsRef); + if (!showSummary || unref(getIsEmptyData)) return; + + nextTick(() => { + const tableEl = unref(tableElRef); + if (!tableEl) return; + const bodyDom = tableEl.$el.querySelector('.ant-table-content'); + useEventListener({ + el: bodyDom, + name: 'scroll', + listener: () => { + const footerBodyDom = tableEl.$el.querySelector( + '.ant-table-footer .ant-table-content', + ) as HTMLDivElement; + if (!footerBodyDom || !bodyDom) return; + footerBodyDom.scrollLeft = bodyDom.scrollLeft; + }, + wait: 0, + options: true, + }); + }); + } + return { getFooterProps }; +} diff --git a/src/components/Table/src/hooks/useTableForm.ts b/src/components/Table/src/hooks/useTableForm.ts new file mode 100644 index 0000000..9d5712d --- /dev/null +++ b/src/components/Table/src/hooks/useTableForm.ts @@ -0,0 +1,50 @@ +import type { ComputedRef, Slots } from 'vue'; +import type { BasicTableProps, FetchParams } from '../types/table'; +import { unref, computed } from 'vue'; +import type { FormProps } from '/@/components/Form'; +import { isFunction } from '/@/utils/is'; + +export function useTableForm( + propsRef: ComputedRef, + slots: Slots, + fetch: (opt?: FetchParams | undefined) => Promise, + getLoading: ComputedRef, +) { + const getFormProps = computed((): Partial => { + const { formConfig } = unref(propsRef); + const { submitButtonOptions } = formConfig || {}; + return { + showAdvancedButton: true, + ...formConfig, + submitButtonOptions: { loading: unref(getLoading), ...submitButtonOptions }, + compact: true, + }; + }); + + const getFormSlotKeys: ComputedRef = computed(() => { + const keys = Object.keys(slots); + return keys + .map((item) => (item.startsWith('form-') ? item : null)) + .filter((item) => !!item) as string[]; + }); + + function replaceFormSlotKey(key: string) { + if (!key) return ''; + return key?.replace?.(/form-/, '') ?? ''; + } + + function handleSearchInfoChange(info: Recordable) { + const { handleSearchInfoFn } = unref(propsRef); + if (handleSearchInfoFn && isFunction(handleSearchInfoFn)) { + info = handleSearchInfoFn(info) || info; + } + fetch({ searchInfo: info, page: 1 }); + } + + return { + getFormProps, + replaceFormSlotKey, + getFormSlotKeys, + handleSearchInfoChange, + }; +} diff --git a/src/components/Table/src/hooks/useTableHeader.ts b/src/components/Table/src/hooks/useTableHeader.ts new file mode 100644 index 0000000..e728207 --- /dev/null +++ b/src/components/Table/src/hooks/useTableHeader.ts @@ -0,0 +1,54 @@ +import type { ComputedRef, Slots } from 'vue'; +import type { BasicTableProps, InnerHandlers } from '../types/table'; +import { unref, computed, h } from 'vue'; +import TableHeader from '../components/TableHeader.vue'; +import { isString } from '/@/utils/is'; +import { getSlot } from '/@/utils/helper/tsxHelper'; + +export function useTableHeader( + propsRef: ComputedRef, + slots: Slots, + handlers: InnerHandlers, +) { + const getHeaderProps = computed((): Recordable => { + const { title, showTableSetting, titleHelpMessage, tableSetting } = unref(propsRef); + const hideTitle = !slots.tableTitle && !title && !slots.toolbar && !showTableSetting; + if (hideTitle && !isString(title)) { + return {}; + } + + return { + title: hideTitle + ? null + : () => + h( + TableHeader, + { + title, + titleHelpMessage, + showTableSetting, + tableSetting, + onColumnsChange: handlers.onColumnsChange, + } as Recordable, + { + ...(slots.toolbar + ? { + toolbar: () => getSlot(slots, 'toolbar'), + } + : {}), + ...(slots.tableTitle + ? { + tableTitle: () => getSlot(slots, 'tableTitle'), + } + : {}), + ...(slots.headerTop + ? { + headerTop: () => getSlot(slots, 'headerTop'), + } + : {}), + }, + ), + }; + }); + return { getHeaderProps }; +} diff --git a/src/components/Table/src/hooks/useTableScroll.ts b/src/components/Table/src/hooks/useTableScroll.ts new file mode 100644 index 0000000..95f3a91 --- /dev/null +++ b/src/components/Table/src/hooks/useTableScroll.ts @@ -0,0 +1,245 @@ +import type { BasicTableProps, TableRowSelection, BasicColumn } from '../types/table'; +import { Ref, ComputedRef, ref, computed, unref, nextTick, watch } from 'vue'; +import { getViewportOffset } from '/@/utils/domUtils'; +import { isBoolean } from '/@/utils/is'; +import { useWindowSizeFn, onMountedOrActivated } from '@vben/hooks'; +import { useModalContext } from '/@/components/Modal'; +import { useDebounceFn } from '@vueuse/core'; + +export function useTableScroll( + propsRef: ComputedRef, + tableElRef: Ref, + columnsRef: ComputedRef, + rowSelectionRef: ComputedRef, + getDataSourceRef: ComputedRef, + wrapRef: Ref, + formRef: Ref, +) { + const tableHeightRef: Ref> = ref(167); + const modalFn = useModalContext(); + + // Greater than animation time 280 + const debounceRedoHeight = useDebounceFn(redoHeight, 100); + + const getCanResize = computed(() => { + const { canResize, scroll } = unref(propsRef); + return canResize && !(scroll || {}).y; + }); + + watch( + () => [unref(getCanResize), unref(getDataSourceRef)?.length], + () => { + debounceRedoHeight(); + }, + { + flush: 'post', + }, + ); + + function redoHeight() { + nextTick(() => { + calcTableHeight(); + }); + } + + function setHeight(height: number) { + tableHeightRef.value = height; + // Solve the problem of modal adaptive height calculation when the form is placed in the modal + modalFn?.redoModalHeight?.(); + } + + // No need to repeat queries + let paginationEl: HTMLElement | null; + let footerEl: HTMLElement | null; + let bodyEl: HTMLElement | null; + + function handleScrollBar(bodyEl: HTMLElement, tableEl: Element) { + const hasScrollBarY = bodyEl.scrollHeight > bodyEl.clientHeight; + const hasScrollBarX = bodyEl.scrollWidth > bodyEl.clientWidth; + + if (hasScrollBarY) { + tableEl.classList.contains('hide-scrollbar-y') && + tableEl.classList.remove('hide-scrollbar-y'); + } else { + !tableEl.classList.contains('hide-scrollbar-y') && tableEl.classList.add('hide-scrollbar-y'); + } + + if (hasScrollBarX) { + tableEl.classList.contains('hide-scrollbar-x') && + tableEl.classList.remove('hide-scrollbar-x'); + } else { + !tableEl.classList.contains('hide-scrollbar-x') && tableEl.classList.add('hide-scrollbar-x'); + } + } + + function caclPaginationHeight(tableEl: Element): number { + const { pagination } = unref(propsRef); + // Pager height + let paginationHeight = 2; + if (!isBoolean(pagination)) { + paginationEl = tableEl.querySelector('.ant-pagination') as HTMLElement; + if (paginationEl) { + const offsetHeight = paginationEl.offsetHeight; + paginationHeight += offsetHeight || 0; + } else { + // TODO First fix 24 + paginationHeight += 24; + } + } else { + paginationHeight = -8; + } + return paginationHeight; + } + + function caclFooterHeight(tableEl: Element): number { + const { pagination } = unref(propsRef); + let footerHeight = 0; + if (!isBoolean(pagination)) { + if (!footerEl) { + footerEl = tableEl.querySelector('.ant-table-footer') as HTMLElement; + } else { + const offsetHeight = footerEl.offsetHeight; + footerHeight += offsetHeight || 0; + } + } + return footerHeight; + } + + function calcHeaderHeight(headEl: Element): number { + let headerHeight = 0; + if (headEl) { + headerHeight = (headEl as HTMLElement).offsetHeight; + } + return headerHeight; + } + + function calcBottomAndPaddingHeight(tableEl: Element, headEl: Element) { + const { pagination, isCanResizeParent, useSearchForm } = unref(propsRef); + // Table height from bottom height-custom offset + let paddingHeight = 30; + let bottomIncludeBody = 0; + if (unref(wrapRef) && isCanResizeParent) { + const tablePadding = 12; + const formMargin = 16; + let paginationMargin = 10; + const wrapHeight = unref(wrapRef)?.offsetHeight ?? 0; + + let formHeight = unref(formRef)?.$el.offsetHeight ?? 0; + if (formHeight) { + formHeight += formMargin; + } + if (isBoolean(pagination) && !pagination) { + paginationMargin = 0; + } + if (isBoolean(useSearchForm) && !useSearchForm) { + paddingHeight = 0; + } + + const headerCellHeight = + (tableEl.querySelector('.ant-table-title') as HTMLElement)?.offsetHeight ?? 0; + + console.log(wrapHeight - formHeight - headerCellHeight - tablePadding - paginationMargin); + bottomIncludeBody = + wrapHeight - formHeight - headerCellHeight - tablePadding - paginationMargin; + } else { + // Table height from bottom + bottomIncludeBody = getViewportOffset(headEl).bottomIncludeBody; + } + + return { + paddingHeight, + bottomIncludeBody, + }; + } + + async function calcTableHeight() { + const { resizeHeightOffset, maxHeight } = unref(propsRef); + const tableData = unref(getDataSourceRef); + + const table = unref(tableElRef); + if (!table) return; + + const tableEl: Element = table.$el; + if (!tableEl) return; + + if (!bodyEl) { + bodyEl = tableEl.querySelector('.ant-table-body'); + if (!bodyEl) return; + } + + handleScrollBar(bodyEl, tableEl); + + bodyEl!.style.height = 'unset'; + + if (!unref(getCanResize) || !unref(tableData) || tableData.length === 0) return; + + await nextTick(); + // Add a delay to get the correct bottomIncludeBody paginationHeight footerHeight headerHeight + + const headEl = tableEl.querySelector('.ant-table-thead '); + + if (!headEl) return; + + const paginationHeight = caclPaginationHeight(tableEl); + const footerHeight = caclFooterHeight(tableEl); + const headerHeight = calcHeaderHeight(headEl); + const { paddingHeight, bottomIncludeBody } = calcBottomAndPaddingHeight(tableEl, headEl); + + let height = + bottomIncludeBody - + (resizeHeightOffset || 0) - + paddingHeight - + paginationHeight - + footerHeight - + headerHeight; + height = (height > maxHeight! ? (maxHeight as number) : height) ?? height; + setHeight(height); + + bodyEl!.style.height = `${height}px`; + } + useWindowSizeFn(calcTableHeight, { wait: 280 }); + onMountedOrActivated(() => { + calcTableHeight(); + nextTick(() => { + debounceRedoHeight(); + }); + }); + + const getScrollX = computed(() => { + let width = 0; + if (unref(rowSelectionRef)) { + width += 60; + } + + // TODO props ?? 0; + const NORMAL_WIDTH = 150; + + const columns = unref(columnsRef).filter((item) => !item.defaultHidden); + columns.forEach((item) => { + width += Number.parseFloat(item.width as string) || 0; + }); + const unsetWidthColumns = columns.filter((item) => !Reflect.has(item, 'width')); + + const len = unsetWidthColumns.length; + if (len !== 0) { + width += len * NORMAL_WIDTH; + } + + const table = unref(tableElRef); + const tableWidth = table?.$el?.offsetWidth ?? 0; + return tableWidth > width ? '100%' : width; + }); + + const getScrollRef = computed(() => { + const tableHeight = unref(tableHeightRef); + const { canResize, scroll } = unref(propsRef); + return { + x: unref(getScrollX), + y: canResize ? tableHeight : null, + scrollToFirstRowOnChange: false, + ...scroll, + }; + }); + + return { getScrollRef, redoHeight }; +} diff --git a/src/components/Table/src/hooks/useTableStyle.ts b/src/components/Table/src/hooks/useTableStyle.ts new file mode 100644 index 0000000..292187d --- /dev/null +++ b/src/components/Table/src/hooks/useTableStyle.ts @@ -0,0 +1,20 @@ +import type { ComputedRef } from 'vue'; +import type { BasicTableProps, TableCustomRecord } from '../types/table'; +import { unref } from 'vue'; +import { isFunction } from '/@/utils/is'; + +export function useTableStyle(propsRef: ComputedRef, prefixCls: string) { + function getRowClassName(record: TableCustomRecord, index: number) { + const { striped, rowClassName } = unref(propsRef); + const classNames: string[] = []; + if (striped) { + classNames.push((index || 0) % 2 === 1 ? `${prefixCls}-row__striped` : ''); + } + if (rowClassName && isFunction(rowClassName)) { + classNames.push(rowClassName(record, index)); + } + return classNames.filter((cls) => !!cls).join(' '); + } + + return { getRowClassName }; +} diff --git a/src/components/Table/src/props.ts b/src/components/Table/src/props.ts new file mode 100644 index 0000000..888cd9f --- /dev/null +++ b/src/components/Table/src/props.ts @@ -0,0 +1,151 @@ +import type { PropType } from 'vue'; +import type { PaginationProps } from './types/pagination'; +import type { + BasicColumn, + FetchSetting, + TableSetting, + SorterResult, + TableCustomRecord, + TableRowSelection, + SizeType, +} from './types/table'; +import type { FormProps } from '/@/components/Form'; + +import { DEFAULT_FILTER_FN, DEFAULT_SORT_FN, FETCH_SETTING, DEFAULT_SIZE } from './const'; +import { propTypes } from '/@/utils/propTypes'; + +export const basicProps = { + clickToRowSelect: { type: Boolean, default: true }, + isTreeTable: Boolean, + tableSetting: propTypes.shape({}), + inset: Boolean, + sortFn: { + type: Function as PropType<(sortInfo: SorterResult) => any>, + default: DEFAULT_SORT_FN, + }, + filterFn: { + type: Function as PropType<(data: Partial>) => any>, + default: DEFAULT_FILTER_FN, + }, + showTableSetting: Boolean, + autoCreateKey: { type: Boolean, default: true }, + striped: { type: Boolean, default: true }, + showSummary: Boolean, + summaryFunc: { + type: [Function, Array] as PropType<(...arg: any[]) => any[]>, + default: null, + }, + summaryData: { + type: Array as PropType, + default: null, + }, + indentSize: propTypes.number.def(24), + canColDrag: { type: Boolean, default: true }, + api: { + type: Function as PropType<(...arg: any[]) => Promise>, + default: null, + }, + beforeFetch: { + type: Function as PropType, + default: null, + }, + afterFetch: { + type: Function as PropType, + default: null, + }, + handleSearchInfoFn: { + type: Function as PropType, + default: null, + }, + fetchSetting: { + type: Object as PropType, + default: () => { + return FETCH_SETTING; + }, + }, + // 立即请求接口 + immediate: { type: Boolean, default: true }, + emptyDataIsShowTable: { type: Boolean, default: true }, + // 额外的请求参数 + searchInfo: { + type: Object as PropType, + default: null, + }, + // 默认的排序参数 + defSort: { + type: Object as PropType, + default: null, + }, + // 使用搜索表单 + useSearchForm: propTypes.bool, + // 表单配置 + formConfig: { + type: Object as PropType>, + default: null, + }, + columns: { + type: Array as PropType, + default: () => [], + }, + showIndexColumn: { type: Boolean, default: true }, + indexColumnProps: { + type: Object as PropType, + default: null, + }, + actionColumn: { + type: Object as PropType, + default: null, + }, + ellipsis: { type: Boolean, default: true }, + isCanResizeParent: { type: Boolean, default: false }, + canResize: { type: Boolean, default: true }, + clearSelectOnPageChange: propTypes.bool, + resizeHeightOffset: propTypes.number.def(0), + rowSelection: { + type: Object as PropType, + default: null, + }, + title: { + type: [String, Function] as PropType string)>, + default: null, + }, + titleHelpMessage: { + type: [String, Array] as PropType, + }, + maxHeight: propTypes.number, + dataSource: { + type: Array as PropType, + default: null, + }, + rowKey: { + type: [String, Function] as PropType string)>, + default: '', + }, + bordered: propTypes.bool, + pagination: { + type: [Object, Boolean] as PropType, + default: null, + }, + loading: propTypes.bool, + rowClassName: { + type: Function as PropType<(record: TableCustomRecord, index: number) => string>, + }, + scroll: { + type: Object as PropType<{ x: number | string | true; y: number | string }>, + default: null, + }, + beforeEditSubmit: { + type: Function as PropType< + (data: { + record: Recordable; + index: number; + key: string | number; + value: any; + }) => Promise + >, + }, + size: { + type: String as PropType, + default: DEFAULT_SIZE, + }, +}; diff --git a/src/components/Table/src/types/column.ts b/src/components/Table/src/types/column.ts new file mode 100644 index 0000000..9ffd579 --- /dev/null +++ b/src/components/Table/src/types/column.ts @@ -0,0 +1,198 @@ +import { VNodeChild } from 'vue'; + +export interface ColumnFilterItem { + text?: string; + value?: string; + children?: any; +} + +export declare type SortOrder = 'ascend' | 'descend'; + +export interface RecordProps { + text: any; + record: T; + index: number; +} + +export interface FilterDropdownProps { + prefixCls?: string; + setSelectedKeys?: (selectedKeys: string[]) => void; + selectedKeys?: string[]; + confirm?: () => void; + clearFilters?: () => void; + filters?: ColumnFilterItem[]; + getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement; + visible?: boolean; +} + +export declare type CustomRenderFunction = (record: RecordProps) => VNodeChild | JSX.Element; + +export interface ColumnProps { + /** + * specify how content is aligned + * @default 'left' + * @type string + */ + align?: 'left' | 'right' | 'center'; + + /** + * ellipsize cell content, not working with sorter and filters for now. + * tableLayout would be fixed when ellipsis is true. + * @default false + * @type boolean + */ + ellipsis?: boolean; + + /** + * Span of this column's title + * @type number + */ + colSpan?: number; + + /** + * Display field of the data record, could be set like a.b.c + * @type string + */ + dataIndex?: string; + + /** + * Default filtered values + * @type string[] + */ + defaultFilteredValue?: string[]; + + /** + * Default order of sorted values: 'ascend' 'descend' null + * @type string + */ + defaultSortOrder?: SortOrder; + + /** + * Customized filter overlay + * @type any (slot) + */ + filterDropdown?: + | VNodeChild + | JSX.Element + | ((props: FilterDropdownProps) => VNodeChild | JSX.Element); + + /** + * Whether filterDropdown is visible + * @type boolean + */ + filterDropdownOpen?: boolean; + + /** + * Whether the dataSource is filtered + * @default false + * @type boolean + */ + filtered?: boolean; + + /** + * Controlled filtered value, filter icon will highlight + * @type string[] + */ + filteredValue?: string[]; + + /** + * Customized filter icon + * @default false + * @type any + */ + filterIcon?: boolean | VNodeChild | JSX.Element; + + /** + * Whether multiple filters can be selected + * @default true + * @type boolean + */ + filterMultiple?: boolean; + + /** + * Filter menu config + * @type object[] + */ + filters?: ColumnFilterItem[]; + + /** + * Set column to be fixed: true(same as left) 'left' 'right' + * @default false + * @type boolean | string + */ + fixed?: boolean | 'left' | 'right'; + + /** + * Unique key of this column, you can ignore this prop if you've set a unique dataIndex + * @type string + */ + key?: string; + + /** + * Renderer of the table cell. The return value should be a VNode, or an object for colSpan/rowSpan config + * @type Function | ScopedSlot + */ + customRender?: CustomRenderFunction | VNodeChild | JSX.Element; + + /** + * Sort function for local sort, see Array.sort's compareFunction. If you need sort buttons only, set to true + * @type boolean | Function + */ + sorter?: boolean | Function; + + /** + * Order of sorted values: 'ascend' 'descend' false + * @type boolean | string + */ + sortOrder?: boolean | SortOrder; + + /** + * supported sort way, could be 'ascend', 'descend' + * @default ['ascend', 'descend'] + * @type string[] + */ + sortDirections?: SortOrder[]; + + /** + * Title of this column + * @type any (string | slot) + */ + title?: VNodeChild | JSX.Element; + + /** + * Width of this column + * @type string | number + */ + width?: string | number; + + /** + * Set props on per cell + * @type Function + */ + customCell?: (record: T, rowIndex: number) => object; + + /** + * Set props on per header cell + * @type object + */ + customHeaderCell?: (column: ColumnProps) => object; + + /** + * Callback executed when the confirm filter button is clicked, Use as a filter event when using template or jsx + * @type Function + */ + onFilter?: (value: any, record: T) => boolean; + + /** + * Callback executed when filterDropdownVisible is changed, Use as a filterDropdownVisible event when using template or jsx + * @type Function + */ + onFilterDropdownVisibleChange?: (visible: boolean) => void; + + /** + * When using columns, you can setting this property to configure the properties that support the slot, + * such as slots: { filterIcon: 'XXX'} + * @type object + */ + slots?: Recordable; +} diff --git a/src/components/Table/src/types/componentType.ts b/src/components/Table/src/types/componentType.ts new file mode 100644 index 0000000..d71cc28 --- /dev/null +++ b/src/components/Table/src/types/componentType.ts @@ -0,0 +1,14 @@ +export type ComponentType = + | 'Input' + | 'InputNumber' + | 'Select' + | 'ApiSelect' + | 'AutoComplete' + | 'ApiTreeSelect' + | 'Checkbox' + | 'Switch' + | 'DatePicker' + | 'TimePicker' + | 'RadioGroup' + | 'RadioButtonGroup' + | 'ApiRadioGroup'; diff --git a/src/components/Table/src/types/pagination.ts b/src/components/Table/src/types/pagination.ts new file mode 100644 index 0000000..c705f33 --- /dev/null +++ b/src/components/Table/src/types/pagination.ts @@ -0,0 +1,115 @@ +import Pagination from 'ant-design-vue/lib/pagination'; +import { VNodeChild } from 'vue'; + +interface PaginationRenderProps { + page: number; + type: 'page' | 'prev' | 'next'; + originalElement: any; +} + +type PaginationPositon = + | 'topLeft' + | 'topCenter' + | 'topRight' + | 'bottomLeft' + | 'bottomCenter' + | 'bottomRight'; + +export declare class PaginationConfig extends Pagination { + position?: PaginationPositon[]; +} + +export interface PaginationProps { + /** + * total number of data items + * @default 0 + * @type number + */ + total?: number; + + /** + * default initial page number + * @default 1 + * @type number + */ + defaultCurrent?: number; + + /** + * current page number + * @type number + */ + current?: number; + + /** + * default number of data items per page + * @default 10 + * @type number + */ + defaultPageSize?: number; + + /** + * number of data items per page + * @type number + */ + pageSize?: number; + + /** + * Whether to hide pager on single page + * @default false + * @type boolean + */ + hideOnSinglePage?: boolean; + + /** + * determine whether pageSize can be changed + * @default false + * @type boolean + */ + showSizeChanger?: boolean; + + /** + * specify the sizeChanger options + * @default ['10', '20', '30', '40'] + * @type string[] + */ + pageSizeOptions?: string[]; + + /** + * determine whether you can jump to pages directly + * @default false + * @type boolean + */ + showQuickJumper?: boolean | object; + + /** + * to display the total number and range + * @type Function + */ + showTotal?: (total: number, range: [number, number]) => any; + + /** + * specify the size of Pagination, can be set to small + * @default '' + * @type string + */ + size?: string; + + /** + * whether to setting simple mode + * @type boolean + */ + simple?: boolean; + + /** + * to customize item innerHTML + * @type Function + */ + itemRender?: (props: PaginationRenderProps) => VNodeChild | JSX.Element; + + /** + * specify the position of Pagination + * @default ['bottomRight'] + * @type string[] + */ + position?: PaginationPositon[]; +} diff --git a/src/components/Table/src/types/table.ts b/src/components/Table/src/types/table.ts new file mode 100644 index 0000000..d9e9ce6 --- /dev/null +++ b/src/components/Table/src/types/table.ts @@ -0,0 +1,485 @@ +import type { VNodeChild } from 'vue'; +import type { PaginationProps } from './pagination'; +import type { FormProps } from '/@/components/Form'; +import type { + TableRowSelection as ITableRowSelection, + Key, +} from 'ant-design-vue/lib/table/interface'; +import type { ColumnProps } from 'ant-design-vue/lib/table'; + +import { ComponentType } from './componentType'; +import { VueNode } from '/@/utils/propTypes'; +import { RoleEnum } from '/@/enums/roleEnum'; + +export declare type SortOrder = 'ascend' | 'descend'; + +export interface TableCurrentDataSource { + currentDataSource: T[]; +} + +export interface TableRowSelection extends ITableRowSelection { + /** + * Callback executed when selected rows change + * @type Function + */ + onChange?: (selectedRowKeys: Key[], selectedRows: T[]) => any; + + /** + * Callback executed when select/deselect one row + * @type Function + */ + onSelect?: (record: T, selected: boolean, selectedRows: Object[], nativeEvent: Event) => any; + + /** + * Callback executed when select/deselect all rows + * @type Function + */ + onSelectAll?: (selected: boolean, selectedRows: T[], changeRows: T[]) => any; + + /** + * Callback executed when row selection is inverted + * @type Function + */ + onSelectInvert?: (selectedRows: Key[]) => any; +} + +export interface TableCustomRecord { + record?: T; + index?: number; +} + +export interface ExpandedRowRenderRecord extends TableCustomRecord { + indent?: number; + expanded?: boolean; +} +export interface ColumnFilterItem { + text?: string; + value?: string; + children?: any; +} + +export interface TableCustomRecord { + record?: T; + index?: number; +} + +export interface SorterResult { + column: ColumnProps; + order: SortOrder; + field: string; + columnKey: string; +} + +export interface FetchParams { + searchInfo?: Recordable; + page?: number; + sortInfo?: Recordable; + filterInfo?: Recordable; +} + +export interface GetColumnsParams { + ignoreIndex?: boolean; + ignoreAction?: boolean; + sort?: boolean; +} + +export type SizeType = 'default' | 'middle' | 'small' | 'large'; + +export interface TableActionType { + reload: (opt?: FetchParams) => Promise; + setSelectedRows: (rows: Recordable[]) => void; + getSelectRows: () => T[]; + clearSelectedRowKeys: () => void; + expandAll: () => void; + expandRows: (keys: (string | number)[]) => void; + collapseAll: () => void; + scrollTo: (pos: string) => void; // pos: id | "top" | "bottom" + getSelectRowKeys: () => string[]; + deleteSelectRowByKey: (key: string) => void; + setPagination: (info: Partial) => void; + setTableData: (values: T[]) => void; + updateTableDataRecord: (rowKey: string | number, record: Recordable) => Recordable | void; + deleteTableDataRecord: (rowKey: string | number | string[] | number[]) => void; + insertTableDataRecord: (record: Recordable | Recordable[], index?: number) => Recordable[] | void; + findTableDataRecord: (rowKey: string | number) => Recordable | void; + getColumns: (opt?: GetColumnsParams) => BasicColumn[]; + setColumns: (columns: BasicColumn[] | string[]) => void; + getDataSource: () => T[]; + getRawDataSource: () => T; + setLoading: (loading: boolean) => void; + setProps: (props: Partial) => void; + redoHeight: () => void; + setSelectedRowKeys: (rowKeys: Key[]) => void; + getPaginationRef: () => PaginationProps | boolean; + getSize: () => SizeType; + getRowSelection: () => TableRowSelection; + getCacheColumns: () => BasicColumn[]; + emit?: EmitType; + updateTableData: (index: number, key: string, value: any) => Recordable; + setShowPagination: (show: boolean) => Promise; + getShowPagination: () => boolean; + setCacheColumnsByField?: (dataIndex: string | undefined, value: BasicColumn) => void; + setCacheColumns?: (columns: BasicColumn[]) => void; +} + +export interface FetchSetting { + // 请求接口当前页数 + pageField: string; + // 每页显示多少条 + sizeField: string; + // 请求结果列表字段 支持 a.b.c + listField: string; + // 请求结果总数字段 支持 a.b.c + totalField: string; +} + +export interface TableSetting { + redo?: boolean; + size?: boolean; + setting?: boolean; + fullScreen?: boolean; +} + +export interface BasicTableProps { + // 点击行选中 + clickToRowSelect?: boolean; + isTreeTable?: boolean; + // 自定义排序方法 + sortFn?: (sortInfo: SorterResult) => any; + // 排序方法 + filterFn?: (data: Partial>) => any; + // 取消表格的默认padding + inset?: boolean; + // 显示表格设置 + showTableSetting?: boolean; + tableSetting?: TableSetting; + // 斑马纹 + striped?: boolean; + // 是否自动生成key + autoCreateKey?: boolean; + // 计算合计行的方法 + summaryFunc?: (...arg: any) => Recordable[]; + // 自定义合计表格内容 + summaryData?: Recordable[]; + // 是否显示合计行 + showSummary?: boolean; + // 是否可拖拽列 + canColDrag?: boolean; + // 接口请求对象 + api?: (...arg: any) => Promise; + // 请求之前处理参数 + beforeFetch?: Fn; + // 自定义处理接口返回参数 + afterFetch?: Fn; + // 查询条件请求之前处理 + handleSearchInfoFn?: Fn; + // 请求接口配置 + fetchSetting?: Partial; + // 立即请求接口 + immediate?: boolean; + // 在开起搜索表单的时候,如果没有数据是否显示表格 + emptyDataIsShowTable?: boolean; + // 额外的请求参数 + searchInfo?: Recordable; + // 默认的排序参数 + defSort?: Recordable; + // 使用搜索表单 + useSearchForm?: boolean; + // 表单配置 + formConfig?: Partial; + // 列配置 + columns: BasicColumn[]; + // 是否显示序号列 + showIndexColumn?: boolean; + // 序号列配置 + indexColumnProps?: BasicColumn; + actionColumn?: BasicColumn; + // 文本超过宽度是否显示。。。 + ellipsis?: boolean; + // 是否继承父级高度(父级高度-表单高度-padding高度) + isCanResizeParent?: boolean; + // 是否可以自适应高度 + canResize?: boolean; + // 自适应高度偏移, 计算结果-偏移量 + resizeHeightOffset?: number; + + // 在分页改变的时候清空选项 + clearSelectOnPageChange?: boolean; + // + rowKey?: string | ((record: Recordable) => string); + // 数据 + dataSource?: Recordable[]; + // 标题右侧提示 + titleHelpMessage?: string | string[]; + // 表格滚动最大高度 + maxHeight?: number; + // 是否显示边框 + bordered?: boolean; + // 分页配置 + pagination?: PaginationProps | boolean; + // loading加载 + loading?: boolean; + + /** + * The column contains children to display + * @default 'children' + * @type string | string[] + */ + childrenColumnName?: string; + + /** + * Override default table elements + * @type object + */ + components?: object; + + /** + * Expand all rows initially + * @default false + * @type boolean + */ + defaultExpandAllRows?: boolean; + + /** + * Initial expanded row keys + * @type string[] + */ + defaultExpandedRowKeys?: string[]; + + /** + * Current expanded row keys + * @type string[] + */ + expandedRowKeys?: string[]; + + /** + * Expanded container render for each row + * @type Function + */ + expandedRowRender?: (record?: ExpandedRowRenderRecord) => VNodeChild | JSX.Element; + + /** + * Customize row expand Icon. + * @type Function | VNodeChild + */ + expandIcon?: Function | VNodeChild | JSX.Element; + + /** + * Whether to expand row by clicking anywhere in the whole row + * @default false + * @type boolean + */ + expandRowByClick?: boolean; + + /** + * The index of `expandIcon` which column will be inserted when `expandIconAsCell` is false. default 0 + */ + expandIconColumnIndex?: number; + + /** + * Table footer renderer + * @type Function | VNodeChild + */ + footer?: Function | VNodeChild | JSX.Element; + + /** + * Indent size in pixels of tree data + * @default 15 + * @type number + */ + indentSize?: number; + + /** + * i18n text including filter, sort, empty text, etc + * @default { filterConfirm: 'Ok', filterReset: 'Reset', emptyText: 'No Data' } + * @type object + */ + locale?: object; + + /** + * Row's className + * @type Function + */ + rowClassName?: (record: TableCustomRecord, index: number) => string; + + /** + * Row selection config + * @type object + */ + rowSelection?: TableRowSelection; + + /** + * Set horizontal or vertical scrolling, can also be used to specify the width and height of the scroll area. + * It is recommended to set a number for x, if you want to set it to true, + * you need to add style .ant-table td { white-space: nowrap; }. + * @type object + */ + scroll?: { x?: number | string | true; y?: number | string }; + + /** + * Whether to show table header + * @default true + * @type boolean + */ + showHeader?: boolean; + + /** + * Size of table + * @default 'default' + * @type string + */ + size?: SizeType; + + /** + * Table title renderer + * @type Function | ScopedSlot + */ + title?: VNodeChild | JSX.Element | string | ((data: Recordable) => string); + + /** + * Set props on per header row + * @type Function + */ + customHeaderRow?: (column: ColumnProps, index: number) => object; + + /** + * Set props on per row + * @type Function + */ + customRow?: (record: T, index: number) => object; + + /** + * `table-layout` attribute of table element + * `fixed` when header/columns are fixed, or using `column.ellipsis` + * + * @see https://developer.mozilla.org/en-US/docs/Web/CSS/table-layout + * @version 1.5.0 + */ + tableLayout?: 'auto' | 'fixed' | string; + + /** + * the render container of dropdowns in table + * @param triggerNode + * @version 1.5.0 + */ + getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement; + + /** + * Data can be changed again before rendering. + * The default configuration of general user empty data. + * You can configured globally through [ConfigProvider](https://antdv.com/components/config-provider-cn/) + * + * @version 1.5.4 + */ + transformCellText?: Function; + + /** + * Callback executed before editable cell submit value, not for row-editor + * + * The cell will not submit data while callback return false + */ + beforeEditSubmit?: (data: { + record: Recordable; + index: number; + key: string | number; + value: any; + }) => Promise; + + /** + * Callback executed when pagination, filters or sorter is changed + * @param pagination + * @param filters + * @param sorter + * @param currentDataSource + */ + onChange?: (pagination: any, filters: any, sorter: any, extra: any) => void; + + /** + * Callback executed when the row expand icon is clicked + * + * @param expanded + * @param record + */ + onExpand?: (expande: boolean, record: T) => void; + + /** + * Callback executed when the expanded rows change + * @param expandedRows + */ + onExpandedRowsChange?: (expandedRows: string[] | number[]) => void; + + onColumnsChange?: (data: ColumnChangeParam[]) => void; +} + +export type CellFormat = + | string + | ((text: string, record: Recordable, index: number) => string | number) + | Map; + +// @ts-ignore +export interface BasicColumn extends ColumnProps { + children?: BasicColumn[]; + filters?: { + text: string; + value: string; + children?: + | unknown[] + | (((props: Record) => unknown[]) & (() => unknown[]) & (() => unknown[])); + }[]; + + // + flag?: 'INDEX' | 'DEFAULT' | 'CHECKBOX' | 'RADIO' | 'ACTION'; + customTitle?: VueNode; + + slots?: Recordable; + + // 自定义header渲染 + customHeaderRender?: (column: BasicColumn) => string | VNodeChild | JSX.Element; + // Whether to hide the column by default, it can be displayed in the column configuration + defaultHidden?: boolean; + + // Help text for table column header + helpMessage?: string | string[]; + + format?: CellFormat; + + // Editable + edit?: boolean; + editRow?: boolean; + editable?: boolean; + editComponent?: ComponentType; + editComponentProps?: + | ((opt: { + text: string | number | boolean | Recordable; + record: Recordable; + column: BasicColumn; + index: number; + }) => Recordable) + | Recordable; + editRule?: boolean | ((text: string, record: Recordable) => Promise); + editValueMap?: (value: any) => string; + onEditRow?: () => void; + // 权限编码控制是否显示 + auth?: RoleEnum | RoleEnum[] | string | string[]; + // 业务控制是否显示 + ifShow?: boolean | ((column: BasicColumn) => boolean); + // 自定义修改后显示的内容 + editRender?: (opt: { + text: string | number | boolean | Recordable; + record: Recordable; + column: BasicColumn; + index: number; + }) => VNodeChild | JSX.Element; + // 动态 Disabled + editDynamicDisabled?: boolean | ((record: Recordable) => boolean); +} + +export type ColumnChangeParam = { + dataIndex: string; + fixed: boolean | 'left' | 'right' | undefined; + visible: boolean; +}; + +export interface InnerHandlers { + onColumnsChange: (data: ColumnChangeParam[]) => void; +} diff --git a/src/components/Table/src/types/tableAction.ts b/src/components/Table/src/types/tableAction.ts new file mode 100644 index 0000000..d847707 --- /dev/null +++ b/src/components/Table/src/types/tableAction.ts @@ -0,0 +1,40 @@ +import { ButtonProps } from 'ant-design-vue/es/button/buttonTypes'; +import { TooltipProps } from 'ant-design-vue/es/tooltip/Tooltip'; +import { RoleEnum } from '/@/enums/roleEnum'; + +export interface ActionItem extends ButtonProps { + onClick?: Fn; + label?: string; + color?: 'success' | 'error' | 'warning'; + icon?: string; + popConfirm?: PopConfirm; + disabled?: boolean; + divider?: boolean; + // 权限编码控制是否显示 + auth?: RoleEnum | RoleEnum[] | string | string[]; + // 业务控制是否显示 + ifShow?: boolean | ((action: ActionItem) => boolean); + tooltip?: string | TooltipProps; +} + +export interface PopConfirm { + title: string; + okText?: string; + cancelText?: string; + confirm: Fn; + cancel?: Fn; + icon?: string; + placement?: + | 'top' + | 'left' + | 'right' + | 'bottom' + | 'topLeft' + | 'topRight' + | 'leftTop' + | 'leftBottom' + | 'rightTop' + | 'rightBottom' + | 'bottomLeft' + | 'bottomRight'; +} diff --git a/src/components/Time/index.ts b/src/components/Time/index.ts new file mode 100644 index 0000000..7e2f4c0 --- /dev/null +++ b/src/components/Time/index.ts @@ -0,0 +1,4 @@ +import { withInstall } from '/@/utils/index'; +import time from './src/Time.vue'; + +export const Time = withInstall(time); diff --git a/src/components/Time/src/Time.vue b/src/components/Time/src/Time.vue new file mode 100644 index 0000000..2789368 --- /dev/null +++ b/src/components/Time/src/Time.vue @@ -0,0 +1,108 @@ + + diff --git a/src/components/Tools/ImportFileModal.vue b/src/components/Tools/ImportFileModal.vue new file mode 100644 index 0000000..61a1c36 --- /dev/null +++ b/src/components/Tools/ImportFileModal.vue @@ -0,0 +1,124 @@ + + diff --git a/src/components/Transition/index.ts b/src/components/Transition/index.ts new file mode 100644 index 0000000..7eb79b5 --- /dev/null +++ b/src/components/Transition/index.ts @@ -0,0 +1,27 @@ +import { createSimpleTransition, createJavascriptTransition } from './src/CreateTransition'; + +import ExpandTransitionGenerator from './src/ExpandTransition'; + +export { default as CollapseTransition } from './src/CollapseTransition.vue'; + +export const FadeTransition = createSimpleTransition('fade-transition'); +export const ScaleTransition = createSimpleTransition('scale-transition'); +export const SlideYTransition = createSimpleTransition('slide-y-transition'); +export const ScrollYTransition = createSimpleTransition('scroll-y-transition'); +export const SlideYReverseTransition = createSimpleTransition('slide-y-reverse-transition'); +export const ScrollYReverseTransition = createSimpleTransition('scroll-y-reverse-transition'); +export const SlideXTransition = createSimpleTransition('slide-x-transition'); +export const ScrollXTransition = createSimpleTransition('scroll-x-transition'); +export const SlideXReverseTransition = createSimpleTransition('slide-x-reverse-transition'); +export const ScrollXReverseTransition = createSimpleTransition('scroll-x-reverse-transition'); +export const ScaleRotateTransition = createSimpleTransition('scale-rotate-transition'); + +export const ExpandXTransition = createJavascriptTransition( + 'expand-x-transition', + ExpandTransitionGenerator('', true), +); + +export const ExpandTransition = createJavascriptTransition( + 'expand-transition', + ExpandTransitionGenerator(''), +); diff --git a/src/components/Transition/src/CollapseTransition.vue b/src/components/Transition/src/CollapseTransition.vue new file mode 100644 index 0000000..6b50fa1 --- /dev/null +++ b/src/components/Transition/src/CollapseTransition.vue @@ -0,0 +1,78 @@ + + diff --git a/src/components/Transition/src/CreateTransition.tsx b/src/components/Transition/src/CreateTransition.tsx new file mode 100644 index 0000000..d12518d --- /dev/null +++ b/src/components/Transition/src/CreateTransition.tsx @@ -0,0 +1,73 @@ +import type { PropType } from 'vue'; + +import { defineComponent, Transition, TransitionGroup } from 'vue'; +import { getSlot } from '/@/utils/helper/tsxHelper'; + +type Mode = 'in-out' | 'out-in' | 'default' | undefined; + +export function createSimpleTransition(name: string, origin = 'top center 0', mode?: Mode) { + return defineComponent({ + name, + props: { + group: { + type: Boolean as PropType, + default: false, + }, + mode: { + type: String as PropType, + default: mode, + }, + origin: { + type: String as PropType, + default: origin, + }, + }, + setup(props, { slots, attrs }) { + const onBeforeEnter = (el: HTMLElement) => { + el.style.transformOrigin = props.origin; + }; + + return () => { + const Tag = !props.group ? Transition : TransitionGroup; + return ( + + {() => getSlot(slots)} + + ); + }; + }, + }); +} +export function createJavascriptTransition( + name: string, + functions: Recordable, + mode: Mode = 'in-out', +) { + return defineComponent({ + name, + props: { + mode: { + type: String as PropType, + default: mode, + }, + }, + setup(props, { attrs, slots }) { + return () => { + return ( + + {() => getSlot(slots)} + + ); + }; + }, + }); +} diff --git a/src/components/Transition/src/ExpandTransition.ts b/src/components/Transition/src/ExpandTransition.ts new file mode 100644 index 0000000..2aaef9a --- /dev/null +++ b/src/components/Transition/src/ExpandTransition.ts @@ -0,0 +1,89 @@ +/** + * Makes the first character of a string uppercase + */ +export function upperFirst(str: string): string { + return str.charAt(0).toUpperCase() + str.slice(1); +} + +interface HTMLExpandElement extends HTMLElement { + _parent?: (Node & ParentNode & HTMLElement) | null; + _initialStyle: { + transition: string; + overflow: string | null; + height?: string | null; + width?: string | null; + }; +} + +export default function (expandedParentClass = '', x = false) { + const sizeProperty = x ? 'width' : ('height' as 'width' | 'height'); + const offsetProperty = `offset${upperFirst(sizeProperty)}` as 'offsetHeight' | 'offsetWidth'; + + return { + beforeEnter(el: HTMLExpandElement) { + el._parent = el.parentNode as (Node & ParentNode & HTMLElement) | null; + el._initialStyle = { + transition: el.style.transition, + overflow: el.style.overflow, + [sizeProperty]: el.style[sizeProperty], + }; + }, + + enter(el: HTMLExpandElement) { + const initialStyle = el._initialStyle; + + el.style.setProperty('transition', 'none', 'important'); + el.style.overflow = 'hidden'; + // const offset = `${el[offsetProperty]}px`; + + // el.style[sizeProperty] = '0'; + + void el.offsetHeight; // force reflow + + el.style.transition = initialStyle.transition; + + if (expandedParentClass && el._parent) { + el._parent.classList.add(expandedParentClass); + } + + requestAnimationFrame(() => { + // el.style[sizeProperty] = offset; + }); + }, + + afterEnter: resetStyles, + enterCancelled: resetStyles, + + leave(el: HTMLExpandElement) { + el._initialStyle = { + transition: '', + overflow: el.style.overflow, + [sizeProperty]: el.style[sizeProperty], + }; + + el.style.overflow = 'hidden'; + el.style[sizeProperty] = `${el[offsetProperty]}px`; + /* eslint-disable-next-line */ + void el.offsetHeight; // force reflow + + requestAnimationFrame(() => (el.style[sizeProperty] = '0')); + }, + + afterLeave, + leaveCancelled: afterLeave, + }; + + function afterLeave(el: HTMLExpandElement) { + if (expandedParentClass && el._parent) { + el._parent.classList.remove(expandedParentClass); + } + resetStyles(el); + } + + function resetStyles(el: HTMLExpandElement) { + const size = el._initialStyle[sizeProperty]; + el.style.overflow = el._initialStyle.overflow!; + if (size != null) el.style[sizeProperty] = size; + Reflect.deleteProperty(el, '_initialStyle'); + } +} diff --git a/src/components/Tree/index.ts b/src/components/Tree/index.ts new file mode 100644 index 0000000..169035a --- /dev/null +++ b/src/components/Tree/index.ts @@ -0,0 +1,6 @@ +import BasicTree from './src/BasicTree.vue'; +import './style'; + +export { BasicTree }; +export type { ContextMenuItem } from '/@/hooks/web/useContextMenu'; +export * from './src/types/tree'; diff --git a/src/components/Tree/src/BasicTree.vue b/src/components/Tree/src/BasicTree.vue new file mode 100644 index 0000000..008b247 --- /dev/null +++ b/src/components/Tree/src/BasicTree.vue @@ -0,0 +1,459 @@ + diff --git a/src/components/Tree/src/TreeIcon.ts b/src/components/Tree/src/TreeIcon.ts new file mode 100644 index 0000000..dd4eab1 --- /dev/null +++ b/src/components/Tree/src/TreeIcon.ts @@ -0,0 +1,12 @@ +import type { VNode, FunctionalComponent } from 'vue'; +import { h } from 'vue'; +import { isString } from 'lodash-es'; +import Icon from '@/components/Icon/Icon.vue'; + +export const TreeIcon: FunctionalComponent = ({ icon }: { icon: VNode | string }) => { + if (!icon) return null; + if (isString(icon)) { + return h(Icon, { icon, class: 'mr-1' }); + } + return Icon; +}; diff --git a/src/components/Tree/src/components/TreeHeader.vue b/src/components/Tree/src/components/TreeHeader.vue new file mode 100644 index 0000000..cb269f5 --- /dev/null +++ b/src/components/Tree/src/components/TreeHeader.vue @@ -0,0 +1,170 @@ + + diff --git a/src/components/Tree/src/hooks/useTree.ts b/src/components/Tree/src/hooks/useTree.ts new file mode 100644 index 0000000..6bd0539 --- /dev/null +++ b/src/components/Tree/src/hooks/useTree.ts @@ -0,0 +1,211 @@ +import type { InsertNodeParams, KeyType, FieldNames, TreeItem } from '../types/tree'; +import type { Ref, ComputedRef } from 'vue'; +import type { TreeDataItem } from 'ant-design-vue/es/tree/Tree'; + +import { cloneDeep } from 'lodash-es'; +import { unref } from 'vue'; +import { forEach } from '/@/utils/helper/treeHelper'; + +export function useTree(treeDataRef: Ref, getFieldNames: ComputedRef) { + function getAllKeys(list?: TreeDataItem[]) { + const keys: string[] = []; + const treeData = list || unref(treeDataRef); + const { key: keyField, children: childrenField } = unref(getFieldNames); + if (!childrenField || !keyField) return keys; + + for (let index = 0; index < treeData.length; index++) { + const node = treeData[index]; + keys.push(node[keyField]!); + const children = node[childrenField]; + if (children && children.length) { + keys.push(...(getAllKeys(children) as string[])); + } + } + return keys as KeyType[]; + } + + // get keys that can be checked and selected + function getEnabledKeys(list?: TreeDataItem[]) { + const keys: string[] = []; + const treeData = list || unref(treeDataRef); + const { key: keyField, children: childrenField } = unref(getFieldNames); + if (!childrenField || !keyField) return keys; + + for (let index = 0; index < treeData.length; index++) { + const node = treeData[index]; + node.disabled !== true && node.selectable !== false && keys.push(node[keyField]!); + const children = node[childrenField]; + if (children && children.length) { + keys.push(...(getEnabledKeys(children) as string[])); + } + } + return keys as KeyType[]; + } + + function getChildrenKeys(nodeKey: string | number, list?: TreeDataItem[]) { + const keys: KeyType[] = []; + const treeData = list || unref(treeDataRef); + const { key: keyField, children: childrenField } = unref(getFieldNames); + if (!childrenField || !keyField) return keys; + for (let index = 0; index < treeData.length; index++) { + const node = treeData[index]; + const children = node[childrenField]; + if (nodeKey === node[keyField]) { + keys.push(node[keyField]!); + if (children && children.length) { + keys.push(...(getAllKeys(children) as string[])); + } + } else { + if (children && children.length) { + keys.push(...getChildrenKeys(nodeKey, children)); + } + } + } + return keys as KeyType[]; + } + + // Update node + function updateNodeByKey(key: string, node: TreeDataItem, list?: TreeDataItem[]) { + if (!key) return; + const treeData = list || unref(treeDataRef); + const { key: keyField, children: childrenField } = unref(getFieldNames); + + if (!childrenField || !keyField) return; + + for (let index = 0; index < treeData.length; index++) { + const element: any = treeData[index]; + const children = element[childrenField]; + + if (element[keyField] === key) { + treeData[index] = { ...treeData[index], ...node }; + break; + } else if (children && children.length) { + updateNodeByKey(key, node, element[childrenField]); + } + } + } + + // Expand the specified level + function filterByLevel(level = 1, list?: TreeDataItem[], currentLevel = 1) { + if (!level) { + return []; + } + const res: (string | number)[] = []; + const data = list || unref(treeDataRef) || []; + for (let index = 0; index < data.length; index++) { + const item = data[index]; + + const { key: keyField, children: childrenField } = unref(getFieldNames); + const key = keyField ? item[keyField] : ''; + const children = childrenField ? item[childrenField] : []; + res.push(key); + if (children && children.length && currentLevel < level) { + currentLevel += 1; + res.push(...filterByLevel(level, children, currentLevel)); + } + } + return res as string[] | number[]; + } + + /** + * 添加节点 + */ + function insertNodeByKey({ parentKey = null, node, push = 'push' }: InsertNodeParams) { + const treeData: any = cloneDeep(unref(treeDataRef)); + if (!parentKey) { + treeData[push](node); + treeDataRef.value = treeData; + return; + } + const { key: keyField, children: childrenField } = unref(getFieldNames); + if (!childrenField || !keyField) return; + + forEach(treeData, (treeItem) => { + if (treeItem[keyField] === parentKey) { + treeItem[childrenField] = treeItem[childrenField] || []; + treeItem[childrenField][push](node); + return true; + } + }); + treeDataRef.value = treeData; + } + /** + * 批量添加节点 + */ + function insertNodesByKey({ parentKey = null, list, push = 'push' }: InsertNodeParams) { + const treeData: any = cloneDeep(unref(treeDataRef)); + if (!list || list.length < 1) { + return; + } + if (!parentKey) { + for (let i = 0; i < list.length; i++) { + treeData[push](list[i]); + } + treeDataRef.value = treeData; + return; + } else { + const { key: keyField, children: childrenField } = unref(getFieldNames); + if (!childrenField || !keyField) return; + + forEach(treeData, (treeItem) => { + if (treeItem[keyField] === parentKey) { + treeItem[childrenField] = treeItem[childrenField] || []; + for (let i = 0; i < list.length; i++) { + treeItem[childrenField][push](list[i]); + } + treeDataRef.value = treeData; + return true; + } + }); + } + } + // Delete node + function deleteNodeByKey(key: string, list?: TreeDataItem[]) { + if (!key) return; + const treeData = list || unref(treeDataRef); + const { key: keyField, children: childrenField } = unref(getFieldNames); + if (!childrenField || !keyField) return; + + for (let index = 0; index < treeData.length; index++) { + const element: any = treeData[index]; + const children = element[childrenField]; + + if (element[keyField] === key) { + treeData.splice(index, 1); + break; + } else if (children && children.length) { + deleteNodeByKey(key, element[childrenField]); + } + } + } + + // Get selected node + function getSelectedNode(key: KeyType, list?: TreeItem[], selectedNode?: TreeItem | null) { + if (!key && key !== 0) return null; + const treeData = list || unref(treeDataRef); + const { key: keyField, children: childrenField } = unref(getFieldNames); + if (!keyField) return; + treeData.forEach((item) => { + if (selectedNode?.key || selectedNode?.key === 0) return selectedNode; + if (item[keyField] === key) { + selectedNode = item; + return; + } + if (item[childrenField!] && item[childrenField!].length) { + selectedNode = getSelectedNode(key, item[childrenField!], selectedNode); + } + }); + return selectedNode || null; + } + return { + deleteNodeByKey, + insertNodeByKey, + insertNodesByKey, + filterByLevel, + updateNodeByKey, + getAllKeys, + getChildrenKeys, + getEnabledKeys, + getSelectedNode, + }; +} diff --git a/src/components/Tree/src/types/tree.ts b/src/components/Tree/src/types/tree.ts new file mode 100644 index 0000000..8988d59 --- /dev/null +++ b/src/components/Tree/src/types/tree.ts @@ -0,0 +1,195 @@ +import type { ExtractPropTypes } from 'vue'; +import type { TreeDataItem } from 'ant-design-vue/es/tree/Tree'; + +import { buildProps } from '/@/utils/props'; + +export enum ToolbarEnum { + SELECT_ALL, + UN_SELECT_ALL, + EXPAND_ALL, + UN_EXPAND_ALL, + CHECK_STRICTLY, + CHECK_UN_STRICTLY, +} + +export const treeEmits = [ + 'update:expandedKeys', + 'update:selectedKeys', + 'update:value', + 'change', + 'check', + 'update:searchValue', +]; + +export interface TreeState { + expandedKeys: KeyType[]; + selectedKeys: KeyType[]; + checkedKeys: CheckKeys; + checkStrictly: boolean; +} + +export interface FieldNames { + children?: string; + title?: string; + key?: string; +} + +export type KeyType = string | number; + +export type CheckKeys = + | KeyType[] + | { checked: string[] | number[]; halfChecked: string[] | number[] }; + +export const treeProps = buildProps({ + value: { + type: [Object, Array] as PropType, + }, + + renderIcon: { + type: Function as PropType<(params: Recordable) => string>, + }, + + helpMessage: { + type: [String, Array] as PropType, + default: '', + }, + + title: { + type: String, + default: '', + }, + toolbar: Boolean, + search: Boolean, + searchValue: { + type: String, + default: '', + }, + checkStrictly: Boolean, + clickRowToExpand: { + type: Boolean, + default: false, + }, + checkable: Boolean, + defaultExpandLevel: { + type: [String, Number] as PropType, + default: '', + }, + defaultExpandAll: Boolean, + + fieldNames: { + type: Object as PropType, + }, + + treeData: { + type: Array as PropType, + }, + + actionList: { + type: Array as PropType, + default: () => [], + }, + + expandedKeys: { + type: Array as PropType, + default: () => [], + }, + + selectedKeys: { + type: Array as PropType, + default: () => [], + }, + + checkedKeys: { + type: [Array, Object] as PropType, + default: () => [], + }, + + beforeRightClick: { + type: Function as PropType<(...arg: any) => Promise>, + default: undefined, + }, + + rightMenuList: { + type: Array as PropType, + }, + // 自定义数据过滤判断方法(注: 不是整个过滤方法,而是内置过滤的判断方法,用于增强原本仅能通过title进行过滤的方式) + filterFn: { + type: Function as PropType< + (searchValue: any, node: TreeItem, fieldNames: FieldNames) => boolean + >, + default: undefined, + }, + // 高亮搜索值,仅高亮具体匹配值(通过title)值为true时使用默认色值,值为#xxx时使用此值替代且高亮开启 + highlight: { + type: [Boolean, String] as PropType, + default: false, + }, + // 搜索完成时自动展开结果 + expandOnSearch: Boolean, + // 搜索完成自动选中所有结果,当且仅当 checkable===true 时生效 + checkOnSearch: Boolean, + // 搜索完成自动select所有结果 + selectedOnSearch: Boolean, + loading: { + type: Boolean, + default: false, + }, + treeWrapperClassName: String, +}); + +export type TreeProps = ExtractPropTypes; + +export interface ContextMenuItem { + label: string; + icon?: string; + hidden?: boolean; + disabled?: boolean; + handler?: Fn; + divider?: boolean; + children?: ContextMenuItem[]; +} + +export interface ContextMenuOptions { + icon?: string; + styles?: any; + items?: ContextMenuItem[]; +} + +export interface TreeItem extends TreeDataItem { + icon?: any; +} + +export interface TreeActionItem { + render: (record: Recordable) => any; + show?: boolean | ((record: Recordable) => boolean); +} + +export interface InsertNodeParams { + parentKey: string | null; + node: TreeDataItem; + list?: TreeDataItem[]; + push?: 'push' | 'unshift'; +} + +export interface TreeActionType { + checkAll: (checkAll: boolean) => void; + expandAll: (expandAll: boolean) => void; + setExpandedKeys: (keys: KeyType[]) => void; + getExpandedKeys: () => KeyType[]; + setSelectedKeys: (keys: KeyType[]) => void; + getSelectedKeys: () => KeyType[]; + setCheckedKeys: (keys: CheckKeys) => void; + getCheckedKeys: () => CheckKeys; + filterByLevel: (level: number) => void; + insertNodeByKey: (opt: InsertNodeParams) => void; + insertNodesByKey: (opt: InsertNodeParams) => void; + deleteNodeByKey: (key: string) => void; + updateNodeByKey: (key: string, node: Omit) => void; + setSearchValue: (value: string) => void; + getSearchValue: () => string; + getSelectedNode: ( + key: KeyType, + treeList?: TreeItem[], + selectNode?: TreeItem | null, + ) => TreeItem | null; +} diff --git a/src/components/Tree/style/index.less b/src/components/Tree/style/index.less new file mode 100644 index 0000000..231f27b --- /dev/null +++ b/src/components/Tree/style/index.less @@ -0,0 +1,52 @@ +@tree-prefix-cls: ~'@{namespace}-tree'; + +.@{tree-prefix-cls} { + background-color: @component-background; + + .ant-tree-node-content-wrapper { + position: relative; + + .ant-tree-title { + position: absolute; + left: 0; + width: 100%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + } + + &__title { + display: flex; + position: relative; + align-items: center; + width: 100%; + padding-right: 10px; + + &:hover { + .@{tree-prefix-cls}__action { + visibility: visible; + } + } + } + + &__content { + overflow: hidden; + } + + &__actions { + display: flex; + position: absolute; + //top: 2px; + right: 3px; + } + + &__action { + visibility: hidden; + margin-left: 4px; + } + + &-header { + border-bottom: 1px solid @border-color-base; + } +} diff --git a/src/components/Tree/style/index.ts b/src/components/Tree/style/index.ts new file mode 100644 index 0000000..d74e52e --- /dev/null +++ b/src/components/Tree/style/index.ts @@ -0,0 +1 @@ +import './index.less'; diff --git a/src/components/Upload/index.ts b/src/components/Upload/index.ts new file mode 100644 index 0000000..568a7d9 --- /dev/null +++ b/src/components/Upload/index.ts @@ -0,0 +1,4 @@ +import { withInstall } from '/@/utils'; +import basicUpload from './src/BasicUpload.vue'; + +export const BasicUpload = withInstall(basicUpload); diff --git a/src/components/Upload/src/BasicUpload.vue b/src/components/Upload/src/BasicUpload.vue new file mode 100644 index 0000000..9f4b348 --- /dev/null +++ b/src/components/Upload/src/BasicUpload.vue @@ -0,0 +1,124 @@ + + diff --git a/src/components/Upload/src/FileList.vue b/src/components/Upload/src/FileList.vue new file mode 100644 index 0000000..ddb087e --- /dev/null +++ b/src/components/Upload/src/FileList.vue @@ -0,0 +1,104 @@ + + diff --git a/src/components/Upload/src/ThumbUrl.vue b/src/components/Upload/src/ThumbUrl.vue new file mode 100644 index 0000000..1b268dc --- /dev/null +++ b/src/components/Upload/src/ThumbUrl.vue @@ -0,0 +1,29 @@ + + + diff --git a/src/components/Upload/src/UploadModal.vue b/src/components/Upload/src/UploadModal.vue new file mode 100644 index 0000000..268e560 --- /dev/null +++ b/src/components/Upload/src/UploadModal.vue @@ -0,0 +1,323 @@ + + + diff --git a/src/components/Upload/src/UploadPreviewModal.vue b/src/components/Upload/src/UploadPreviewModal.vue new file mode 100644 index 0000000..bc4091b --- /dev/null +++ b/src/components/Upload/src/UploadPreviewModal.vue @@ -0,0 +1,99 @@ + + + diff --git a/src/components/Upload/src/data.tsx b/src/components/Upload/src/data.tsx new file mode 100644 index 0000000..8e08833 --- /dev/null +++ b/src/components/Upload/src/data.tsx @@ -0,0 +1,153 @@ +import type { BasicColumn, ActionItem } from '/@/components/Table'; +import { FileItem, PreviewFileItem, UploadResultStatus } from './typing'; +import { + // checkImgType, + isImgTypeByName, +} from './helper'; +import { Progress, Tag } from 'ant-design-vue'; +import TableAction from '/@/components/Table/src/components/TableAction.vue'; +import ThumbUrl from './ThumbUrl.vue'; +import { useI18n } from '/@/hooks/web/useI18n'; + +const { t } = useI18n(); + +// 文件上传列表 +export function createTableColumns(): BasicColumn[] { + return [ + { + dataIndex: 'thumbUrl', + title: t('component.upload.legend'), + width: 100, + customRender: ({ record }) => { + const { thumbUrl } = (record as FileItem) || {}; + return thumbUrl && ; + }, + }, + { + dataIndex: 'name', + title: t('component.upload.fileName'), + align: 'left', + customRender: ({ text, record }) => { + const { percent, status: uploadStatus } = (record as FileItem) || {}; + let status: 'normal' | 'exception' | 'active' | 'success' = 'normal'; + if (uploadStatus === UploadResultStatus.ERROR) { + status = 'exception'; + } else if (uploadStatus === UploadResultStatus.UPLOADING) { + status = 'active'; + } else if (uploadStatus === UploadResultStatus.SUCCESS) { + status = 'success'; + } + return ( + +

    + {text} +

    + +
    + ); + }, + }, + { + dataIndex: 'size', + title: t('component.upload.fileSize'), + width: 100, + customRender: ({ text = 0 }) => { + return text && (text / 1024).toFixed(2) + 'KB'; + }, + }, + // { + // dataIndex: 'type', + // title: '文件类型', + // width: 100, + // }, + { + dataIndex: 'status', + title: t('component.upload.fileStatue'), + width: 100, + customRender: ({ text }) => { + if (text === UploadResultStatus.SUCCESS) { + return {() => t('component.upload.uploadSuccess')}; + } else if (text === UploadResultStatus.ERROR) { + return {() => t('component.upload.uploadError')}; + } else if (text === UploadResultStatus.UPLOADING) { + return {() => t('component.upload.uploading')}; + } + + return text; + }, + }, + ]; +} +export function createActionColumn(handleRemove: Function): BasicColumn { + return { + width: 120, + title: t('component.upload.operating'), + dataIndex: 'action', + fixed: false, + customRender: ({ record }) => { + const actions: ActionItem[] = [ + { + label: t('component.upload.del'), + color: 'error', + onClick: handleRemove.bind(null, record), + }, + ]; + // if (checkImgType(record)) { + // actions.unshift({ + // label: t('component.upload.preview'), + // onClick: handlePreview.bind(null, record), + // }); + // } + return ; + }, + }; +} +// 文件预览列表 +export function createPreviewColumns(): BasicColumn[] { + return [ + { + dataIndex: 'url', + title: t('component.upload.legend'), + width: 100, + customRender: ({ record }) => { + const { url } = (record as PreviewFileItem) || {}; + return isImgTypeByName(url) && ; + }, + }, + { + dataIndex: 'name', + title: t('component.upload.fileName'), + align: 'left', + }, + ]; +} + +export function createPreviewActionColumn({ + handleRemove, + handleDownload, +}: { + handleRemove: Fn; + handleDownload: Fn; +}): BasicColumn { + return { + width: 160, + title: t('component.upload.operating'), + dataIndex: 'action', + fixed: false, + customRender: ({ record }) => { + const actions: ActionItem[] = [ + { + label: t('component.upload.del'), + color: 'error', + onClick: handleRemove.bind(null, record), + }, + { + label: t('component.upload.download'), + onClick: handleDownload.bind(null, record), + }, + ]; + + return ; + }, + }; +} diff --git a/src/components/Upload/src/helper.ts b/src/components/Upload/src/helper.ts new file mode 100644 index 0000000..7e8494e --- /dev/null +++ b/src/components/Upload/src/helper.ts @@ -0,0 +1,27 @@ +export function checkFileType(file: File, accepts: string[]) { + const newTypes = accepts.join('|'); + // const reg = /\.(jpg|jpeg|png|gif|txt|doc|docx|xls|xlsx|xml)$/i; + const reg = new RegExp('\\.(' + newTypes + ')$', 'i'); + + return reg.test(file.name); +} + +export function checkImgType(file: File) { + return isImgTypeByName(file.name); +} + +export function isImgTypeByName(name: string) { + return /\.(jpg|jpeg|png|gif|webp)$/i.test(name); +} + +export function getBase64WithFile(file: File) { + return new Promise<{ + result: string; + file: File; + }>((resolve, reject) => { + const reader = new FileReader(); + reader.readAsDataURL(file); + reader.onload = () => resolve({ result: reader.result as string, file }); + reader.onerror = (error) => reject(error); + }); +} diff --git a/src/components/Upload/src/props.ts b/src/components/Upload/src/props.ts new file mode 100644 index 0000000..d37f68b --- /dev/null +++ b/src/components/Upload/src/props.ts @@ -0,0 +1,83 @@ +import type { PropType } from 'vue'; +import { FileBasicColumn } from './typing'; + +export const basicProps = { + helpText: { + type: String as PropType, + default: '', + }, + // 文件最大多少MB + maxSize: { + type: Number as PropType, + default: 2, + }, + // 最大数量的文件,Infinity不限制 + maxNumber: { + type: Number as PropType, + default: Infinity, + }, + // 根据后缀,或者其他 + accept: { + type: Array as PropType, + default: () => [], + }, + multiple: { + type: Boolean as PropType, + default: true, + }, + uploadParams: { + type: Object as PropType, + default: () => ({}), + }, + api: { + type: Function as PropType, + default: null, + required: true, + }, + name: { + type: String as PropType, + default: 'file', + }, + filename: { + type: String as PropType, + default: null, + }, +}; + +export const uploadContainerProps = { + value: { + type: Array as PropType, + default: () => [], + }, + ...basicProps, + showPreviewNumber: { + type: Boolean as PropType, + default: true, + }, + emptyHidePreview: { + type: Boolean as PropType, + default: false, + }, +}; + +export const previewProps = { + value: { + type: Array as PropType, + default: () => [], + }, +}; + +export const fileListProps = { + columns: { + type: Array as PropType, + default: null, + }, + actionColumn: { + type: Object as PropType, + default: null, + }, + dataSource: { + type: Array as PropType, + default: null, + }, +}; diff --git a/src/components/Upload/src/typing.ts b/src/components/Upload/src/typing.ts new file mode 100644 index 0000000..c630110 --- /dev/null +++ b/src/components/Upload/src/typing.ts @@ -0,0 +1,55 @@ +import { UploadApiResult } from '/@/api/sys/model/uploadModel'; + +export enum UploadResultStatus { + SUCCESS = 'success', + ERROR = 'error', + UPLOADING = 'uploading', +} + +export interface FileItem { + thumbUrl?: string; + name: string; + size: string | number; + type?: string; + percent: number; + file: File; + status?: UploadResultStatus; + responseData?: UploadApiResult; + uuid: string; +} + +export interface PreviewFileItem { + url: string; + name: string; + type: string; +} + +export interface FileBasicColumn { + /** + * Renderer of the table cell. The return value should be a VNode, or an object for colSpan/rowSpan config + * @type Function | ScopedSlot + */ + customRender?: Function; + /** + * Title of this column + * @type any (string | slot) + */ + title: string; + + /** + * Width of this column + * @type string | number + */ + width?: number; + /** + * Display field of the data record, could be set like a.b.c + * @type string + */ + dataIndex: string; + /** + * specify how content is aligned + * @default 'left' + * @type string + */ + align?: 'left' | 'right' | 'center'; +} diff --git a/src/components/Upload/src/useUpload.ts b/src/components/Upload/src/useUpload.ts new file mode 100644 index 0000000..fb178d0 --- /dev/null +++ b/src/components/Upload/src/useUpload.ts @@ -0,0 +1,61 @@ +import { Ref, unref, computed } from 'vue'; +import { useI18n } from '/@/hooks/web/useI18n'; + +const { t } = useI18n(); +export function useUploadType({ + acceptRef, + helpTextRef, + maxNumberRef, + maxSizeRef, +}: { + acceptRef: Ref; + helpTextRef: Ref; + maxNumberRef: Ref; + maxSizeRef: Ref; +}) { + // 文件类型限制 + const getAccept = computed(() => { + const accept = unref(acceptRef); + if (accept && accept.length > 0) { + return accept; + } + return []; + }); + const getStringAccept = computed(() => { + return unref(getAccept) + .map((item) => { + if (item.indexOf('/') > 0 || item.startsWith('.')) { + return item; + } else { + return `.${item}`; + } + }) + .join(','); + }); + + // 支持jpg、jpeg、png格式,不超过2M,最多可选择10张图片,。 + const getHelpText = computed(() => { + const helpText = unref(helpTextRef); + if (helpText) { + return helpText; + } + const helpTexts: string[] = []; + + const accept = unref(acceptRef); + if (accept.length > 0) { + helpTexts.push(t('component.upload.accept', [accept.join(',')])); + } + + const maxSize = unref(maxSizeRef); + if (maxSize) { + helpTexts.push(t('component.upload.maxSize', [maxSize])); + } + + const maxNumber = unref(maxNumberRef); + if (maxNumber && maxNumber !== Infinity) { + helpTexts.push(t('component.upload.maxNumber', [maxNumber])); + } + return helpTexts.join(','); + }); + return { getAccept, getStringAccept, getHelpText }; +} diff --git a/src/components/VxeTable/index.ts b/src/components/VxeTable/index.ts new file mode 100644 index 0000000..bc24c39 --- /dev/null +++ b/src/components/VxeTable/index.ts @@ -0,0 +1,12 @@ +import { withInstall } from '/@/utils'; +import vxeBasicTable from './src/VxeBasicTable'; +import { VXETable } from 'vxe-table'; +import VXETablePluginAntd from './src/components'; +import VXETablePluginExportXLSX from 'vxe-table-plugin-export-xlsx'; +import './src/setting'; + +export const VxeBasicTable = withInstall(vxeBasicTable); +export * from 'vxe-table'; +export * from './src/types'; + +VXETable.use(VXETablePluginAntd).use(VXETablePluginExportXLSX); diff --git a/src/components/VxeTable/src/VxeBasicTable.tsx b/src/components/VxeTable/src/VxeBasicTable.tsx new file mode 100644 index 0000000..8133142 --- /dev/null +++ b/src/components/VxeTable/src/VxeBasicTable.tsx @@ -0,0 +1,116 @@ +import { defineComponent, computed, ref } from 'vue'; +import { BasicTableProps } from './types'; +import { basicProps } from './props'; +import { ignorePropKeys } from './const'; +import { basicEmits } from './emits'; +import XEUtils from 'xe-utils'; +import type { + VxeGridInstance, + VxeGridEventProps, + GridMethods, + TableMethods, + TableEditMethods, + TableValidatorMethods, +} from 'vxe-table'; +import { Grid as VxeGrid } from 'vxe-table'; + +import { extendSlots } from '/@/utils/helper/tsxHelper'; +import { gridComponentMethodKeys } from './methods'; +import { omit } from 'lodash-es'; + +export default defineComponent({ + name: 'VxeBasicTable', + props: basicProps, + emits: basicEmits, + setup(props, { emit, attrs }) { + const tableElRef = ref(); + const emitEvents: VxeGridEventProps = {}; + + const extendTableMethods = (methodKeys) => { + const funcs: any = {}; + methodKeys.forEach((name) => { + funcs[name] = (...args: any[]) => { + const $vxegrid: any = tableElRef.value; + if ($vxegrid && $vxegrid[name]) { + return $vxegrid[name](...args); + } + }; + }); + + return funcs; + }; + + const gridExtendTableMethods = extendTableMethods(gridComponentMethodKeys) as GridMethods & + TableMethods & + TableEditMethods & + TableValidatorMethods; + + basicEmits.forEach((name) => { + const type = XEUtils.camelCase(`on-${name}`) as keyof VxeGridEventProps; + + emitEvents[type] = (...args: any[]) => emit(name, ...args); + }); + + /** + * @description: 二次封装需要的所有属性 + * 1.部分属性需要和全局属性进行合并 + */ + const getBindValues = computed(() => { + const propsData: BasicTableProps = { + ...attrs, + ...props, + }; + + return propsData; + }); + + /** + * @description: Table 所有属性 + */ + const getBindGridValues = computed(() => { + const omitProps = omit(getBindValues.value, ignorePropKeys); + + return { + ...omitProps, + ...getBindGridEvent, + }; + }); + + /** + * @description: 组件外层class + */ + const getWrapperClass = computed(() => { + return [attrs.class]; + }); + + /** + * @description: 重写Vxe-table 方法 + */ + const getBindGridEvent: VxeGridEventProps = { + ...emitEvents, + }; + + return { + getWrapperClass, + getBindGridValues, + tableElRef, + ...gridExtendTableMethods, + }; + }, + render() { + const { tableClass, tableStyle } = this.$props; + + return ( +
    + + {extendSlots(this.$slots)} + +
    + ); + }, +}); diff --git a/src/components/VxeTable/src/componentMap.ts b/src/components/VxeTable/src/componentMap.ts new file mode 100644 index 0000000..d1ca62e --- /dev/null +++ b/src/components/VxeTable/src/componentMap.ts @@ -0,0 +1,59 @@ +import type { Component } from 'vue'; + +import type { ComponentType } from './componentType'; +import { ApiSelect, ApiTreeSelect } from '/@/components/Form'; +import { + Input, + Select, + Radio, + Checkbox, + AutoComplete, + Cascader, + DatePicker, + InputNumber, + Switch, + TimePicker, + TreeSelect, + Rate, + Empty, +} from 'ant-design-vue'; +import { Button } from '/@/components/Button'; + +const componentMap = new Map(); + +componentMap.set('AButton', Button); + +componentMap.set('AInput', Input); +componentMap.set('AInputSearch', Input.Search); +componentMap.set('AInputNumber', InputNumber); +componentMap.set('AAutoComplete', AutoComplete); + +componentMap.set('ASelect', Select); +componentMap.set('ATreeSelect', TreeSelect); +componentMap.set('ASwitch', Switch); +componentMap.set('ARadioGroup', Radio.Group); +componentMap.set('ACheckboxGroup', Checkbox.Group); +componentMap.set('ACascader', Cascader); +componentMap.set('ARate', Rate); + +componentMap.set('ADatePicker', DatePicker); +componentMap.set('AMonthPicker', DatePicker.MonthPicker); +componentMap.set('ARangePicker', DatePicker.RangePicker); +componentMap.set('AWeekPicker', DatePicker.WeekPicker); +componentMap.set('AYearPicker', DatePicker.YearPicker); +componentMap.set('ATimePicker', TimePicker); + +componentMap.set('AApiSelect', ApiSelect); +componentMap.set('AApiTreeSelect', ApiTreeSelect); + +componentMap.set('AEmpty', Empty); + +export function add(compName: ComponentType, component: Component) { + componentMap.set(compName, component); +} + +export function del(compName: ComponentType) { + componentMap.delete(compName); +} + +export { componentMap }; diff --git a/src/components/VxeTable/src/componentType.ts b/src/components/VxeTable/src/componentType.ts new file mode 100644 index 0000000..4a55e64 --- /dev/null +++ b/src/components/VxeTable/src/componentType.ts @@ -0,0 +1,22 @@ +export type ComponentType = + | 'AInput' + | 'AInputNumber' + | 'ASelect' + | 'AApiSelect' + | 'ATreeSelect' + | 'AApiTreeSelect' + | 'ARadioGroup' + | 'ACheckboxGroup' + | 'AAutoComplete' + | 'ACascader' + | 'ADatePicker' + | 'AMonthPicker' + | 'ARangePicker' + | 'AWeekPicker' + | 'ATimePicker' + | 'AYearPicker' + | 'ASwitch' + | 'ARate' + | 'AInputSearch' + | 'AButton' + | 'AEmpty'; diff --git a/src/components/VxeTable/src/components/AApiSelect.tsx b/src/components/VxeTable/src/components/AApiSelect.tsx new file mode 100644 index 0000000..8fb1d3d --- /dev/null +++ b/src/components/VxeTable/src/components/AApiSelect.tsx @@ -0,0 +1,20 @@ +import XEUtils from 'xe-utils'; +import { createDefaultRender, createEditRender, createFormItemRender } from './common'; + +export default { + renderDefault: createDefaultRender({}, (_, params) => { + return { + params: XEUtils.get(params, 'row'), + }; + }), + renderEdit: createEditRender({}, (_, params) => { + return { + params: XEUtils.get(params, 'row'), + }; + }), + renderItemContent: createFormItemRender({}, (_, params) => { + return { + params: XEUtils.get(params, 'row'), + }; + }), +}; diff --git a/src/components/VxeTable/src/components/AApiTreeSelect.tsx b/src/components/VxeTable/src/components/AApiTreeSelect.tsx new file mode 100644 index 0000000..8fb1d3d --- /dev/null +++ b/src/components/VxeTable/src/components/AApiTreeSelect.tsx @@ -0,0 +1,20 @@ +import XEUtils from 'xe-utils'; +import { createDefaultRender, createEditRender, createFormItemRender } from './common'; + +export default { + renderDefault: createDefaultRender({}, (_, params) => { + return { + params: XEUtils.get(params, 'row'), + }; + }), + renderEdit: createEditRender({}, (_, params) => { + return { + params: XEUtils.get(params, 'row'), + }; + }), + renderItemContent: createFormItemRender({}, (_, params) => { + return { + params: XEUtils.get(params, 'row'), + }; + }), +}; diff --git a/src/components/VxeTable/src/components/AAutoComplete.tsx b/src/components/VxeTable/src/components/AAutoComplete.tsx new file mode 100644 index 0000000..41ca4a4 --- /dev/null +++ b/src/components/VxeTable/src/components/AAutoComplete.tsx @@ -0,0 +1,16 @@ +import { + createEditRender, + createDefaultRender, + createFilterRender, + createDefaultFilterRender, + createFormItemRender, +} from './common'; + +export default { + autofocus: 'input.ant-input', + renderDefault: createDefaultRender(), + renderEdit: createEditRender(), + renderFilter: createFilterRender(), + defaultFilterMethod: createDefaultFilterRender(), + renderItemContent: createFormItemRender(), +}; diff --git a/src/components/VxeTable/src/components/AButton.tsx b/src/components/VxeTable/src/components/AButton.tsx new file mode 100644 index 0000000..67468d1 --- /dev/null +++ b/src/components/VxeTable/src/components/AButton.tsx @@ -0,0 +1,120 @@ +import { h } from 'vue'; +import { + FormItemContentRenderParams, + FormItemRenderOptions, + VxeGlobalRendererHandles, +} from 'vxe-table'; +import XEUtils from 'xe-utils'; +import { cellText, createEvents, createProps, getComponent } from './common'; + +const COMPONENT_NAME = 'AButton'; + +export function createEditRender() { + return function ( + renderOpts: VxeGlobalRendererHandles.RenderEditOptions, + params: VxeGlobalRendererHandles.RenderEditParams, + ) { + const { attrs } = renderOpts; + const Component = getComponent(COMPONENT_NAME); + + return [ + h(Component, { + ...attrs, + ...createProps(renderOpts, null), + ...createEvents(renderOpts, params), + }), + ]; + }; +} + +export function createDefaultRender() { + return function ( + renderOpts: VxeGlobalRendererHandles.RenderEditOptions, + params: VxeGlobalRendererHandles.RenderEditParams, + ) { + const { attrs } = renderOpts; + const Component = getComponent(COMPONENT_NAME); + + return [ + h( + Component, + { + ...attrs, + ...createProps(renderOpts, null), + ...createEvents(renderOpts, params), + }, + cellText(renderOpts.content), + ), + ]; + }; +} + +export function createFormItemRender() { + return function (renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) { + const { attrs, content } = renderOpts; + const { property, $form, data } = params; + const props = createProps(renderOpts, null); + const Component = getComponent(COMPONENT_NAME); + + return [ + h( + Component, + { + ...attrs, + ...props, + ...createEvents( + renderOpts, + params, + (value: any) => { + // 处理 model 值双向绑定 + XEUtils.set(data, property, value); + }, + () => { + // 处理 change 事件相关逻辑 + $form.updateStatus({ + ...params, + field: property, + }); + }, + ), + }, + { + default: () => cellText(content || props.content), + }, + ), + ]; + }; +} + +function createToolbarButtonRender() { + return function ( + renderOpts: VxeGlobalRendererHandles.RenderToolOptions, + params: VxeGlobalRendererHandles.RenderButtonParams, + ) { + const { attrs } = renderOpts; + const { button } = params; + const props = createProps(renderOpts, null); + const Component = getComponent(COMPONENT_NAME); + + return [ + h( + Component, + { + ...attrs, + ...props, + ...createEvents(renderOpts, params), + }, + { + default: () => cellText(button?.content || props.content), + }, + ), + ]; + }; +} + +export default { + renderEdit: createEditRender(), + renderDefault: createDefaultRender(), + renderItemContent: createFormItemRender(), + renderToolbarButton: createToolbarButtonRender(), +}; diff --git a/src/components/VxeTable/src/components/AButtonGroup.tsx b/src/components/VxeTable/src/components/AButtonGroup.tsx new file mode 100644 index 0000000..ed0fc84 --- /dev/null +++ b/src/components/VxeTable/src/components/AButtonGroup.tsx @@ -0,0 +1,59 @@ +import { + FormItemContentRenderParams, + FormItemRenderOptions, + VxeGlobalRendererHandles, +} from 'vxe-table'; +import { createDefaultRender, createEditRender, createFormItemRender } from './AButton'; + +function createEditButtonRender() { + return function ( + renderOpts: VxeGlobalRendererHandles.RenderEditOptions, + params: VxeGlobalRendererHandles.RenderEditParams, + ) { + const buttonEditRender = createEditRender(); + const { children } = renderOpts; + if (children) { + return children.map( + (childRenderOpts: VxeGlobalRendererHandles.RenderEditOptions) => + buttonEditRender(childRenderOpts, params)[0], + ); + } + return []; + }; +} + +function createDefaultButtonRender() { + return function ( + renderOpts: VxeGlobalRendererHandles.RenderDefaultOptions, + params: VxeGlobalRendererHandles.RenderDefaultParams, + ) { + const buttonDefaultRender = createDefaultRender(); + const { children } = renderOpts; + if (children) { + return children.map( + (childRenderOpts: VxeGlobalRendererHandles.RenderDefaultOptions) => + buttonDefaultRender(childRenderOpts, params)[0], + ); + } + return []; + }; +} + +function createButtonItemRender() { + return function (renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) { + const buttonItemRender = createFormItemRender(); + const { children } = renderOpts; + if (children) { + return children.map( + (childRenderOpts: FormItemRenderOptions) => buttonItemRender(childRenderOpts, params)[0], + ); + } + return []; + }; +} + +export default { + renderEdit: createEditButtonRender(), + renderDefault: createDefaultButtonRender(), + renderItemContent: createButtonItemRender(), +}; diff --git a/src/components/VxeTable/src/components/ACascader.tsx b/src/components/VxeTable/src/components/ACascader.tsx new file mode 100644 index 0000000..650f32f --- /dev/null +++ b/src/components/VxeTable/src/components/ACascader.tsx @@ -0,0 +1,42 @@ +import { VxeGlobalRendererHandles } from 'vxe-table'; +import XEUtils from 'xe-utils'; +import { + createEditRender, + createCellRender, + createFormItemRender, + createExportMethod, +} from './common'; + +function matchCascaderData(index: number, list: any[], values: any[], labels: any[]) { + const val = values[index]; + if (list && values.length > index) { + XEUtils.each(list, (item) => { + if (item.value === val) { + labels.push(item.label); + matchCascaderData(++index, item.children, values, labels); + } + }); + } +} + +function getCascaderCellValue( + renderOpts: VxeGlobalRendererHandles.RenderOptions, + params: VxeGlobalRendererHandles.RenderCellParams, +) { + const { props = {} } = renderOpts; + const { row, column } = params; + const cellValue = XEUtils.get(row, column.field as string); + const values = cellValue || []; + const labels: Array = []; + matchCascaderData(0, props.options, values, labels); + return ( + props.showAllLevels === false ? labels.slice(labels.length - 1, labels.length) : labels + ).join(` ${props.separator || '/'} `); +} + +export default { + renderEdit: createEditRender(), + renderCell: createCellRender(getCascaderCellValue), + renderItemContent: createFormItemRender(), + exportMethod: createExportMethod(getCascaderCellValue), +}; diff --git a/src/components/VxeTable/src/components/ACheckboxGroup.tsx b/src/components/VxeTable/src/components/ACheckboxGroup.tsx new file mode 100644 index 0000000..d01092a --- /dev/null +++ b/src/components/VxeTable/src/components/ACheckboxGroup.tsx @@ -0,0 +1,5 @@ +import { createFormItemRender } from './common'; + +export default { + renderItemContent: createFormItemRender(), +}; diff --git a/src/components/VxeTable/src/components/ADatePicker.tsx b/src/components/VxeTable/src/components/ADatePicker.tsx new file mode 100644 index 0000000..3e90638 --- /dev/null +++ b/src/components/VxeTable/src/components/ADatePicker.tsx @@ -0,0 +1,33 @@ +import { VxeGlobalRendererHandles } from 'vxe-table'; +import XEUtils from 'xe-utils'; +import { + createCellRender, + createEditRender, + createExportMethod, + createFormItemRender, +} from './common'; + +export function getDatePickerCellValue( + renderOpts: VxeGlobalRendererHandles.RenderOptions, + params: VxeGlobalRendererHandles.RenderCellParams | VxeGlobalRendererHandles.ExportMethodParams, + defaultFormat: string, +) { + const { props = {} } = renderOpts; + const { row, column } = params; + let cellValue = XEUtils.get(row, column.field as string); + if (cellValue) { + cellValue = cellValue.format(props.format || defaultFormat); + } + return cellValue; +} + +export default { + renderEdit: createEditRender(), + renderCell: createCellRender(getDatePickerCellValue, () => { + return ['YYYY-MM-DD']; + }), + renderItemContent: createFormItemRender(), + exportMethod: createExportMethod(getDatePickerCellValue, () => { + return ['YYYY-MM-DD']; + }), +}; diff --git a/src/components/VxeTable/src/components/AEmpty.tsx b/src/components/VxeTable/src/components/AEmpty.tsx new file mode 100644 index 0000000..aed5007 --- /dev/null +++ b/src/components/VxeTable/src/components/AEmpty.tsx @@ -0,0 +1,27 @@ +import { h } from 'vue'; +import { VxeGlobalRendererHandles } from 'vxe-table'; +import { getComponent } from './common'; + +function createEmptyRender() { + return function (renderOpts: VxeGlobalRendererHandles.RenderEmptyOptions) { + const { name, attrs, props } = renderOpts; + + const Component = getComponent(name); + return [ + h( + 'div', + { + class: 'flex items-center justify-center', + }, + h(Component, { + ...attrs, + ...props, + }), + ), + ]; + }; +} + +export default { + renderEmpty: createEmptyRender(), +}; diff --git a/src/components/VxeTable/src/components/AInput.tsx b/src/components/VxeTable/src/components/AInput.tsx new file mode 100644 index 0000000..41ca4a4 --- /dev/null +++ b/src/components/VxeTable/src/components/AInput.tsx @@ -0,0 +1,16 @@ +import { + createEditRender, + createDefaultRender, + createFilterRender, + createDefaultFilterRender, + createFormItemRender, +} from './common'; + +export default { + autofocus: 'input.ant-input', + renderDefault: createDefaultRender(), + renderEdit: createEditRender(), + renderFilter: createFilterRender(), + defaultFilterMethod: createDefaultFilterRender(), + renderItemContent: createFormItemRender(), +}; diff --git a/src/components/VxeTable/src/components/AInputNumber.tsx b/src/components/VxeTable/src/components/AInputNumber.tsx new file mode 100644 index 0000000..22f299e --- /dev/null +++ b/src/components/VxeTable/src/components/AInputNumber.tsx @@ -0,0 +1,16 @@ +import { + createEditRender, + createFilterRender, + createFormItemRender, + createDefaultFilterRender, + createDefaultRender, +} from './common'; + +export default { + autofocus: 'input.ant-input-number-input', + renderDefault: createDefaultRender(), + renderEdit: createEditRender(), + renderFilter: createFilterRender(), + defaultFilterMethod: createDefaultFilterRender(), + renderItemContent: createFormItemRender(), +}; diff --git a/src/components/VxeTable/src/components/AInputSearch.tsx b/src/components/VxeTable/src/components/AInputSearch.tsx new file mode 100644 index 0000000..e365ef3 --- /dev/null +++ b/src/components/VxeTable/src/components/AInputSearch.tsx @@ -0,0 +1,17 @@ +import { + createEditRender, + createDefaultRender, + createFilterRender, + createDefaultFilterRender, + createFormItemRender, + createToolbarToolRender, +} from './common'; + +export default { + renderDefault: createDefaultRender(), + renderEdit: createEditRender(), + renderFilter: createFilterRender(), + defaultFilterMethod: createDefaultFilterRender(), + renderItemContent: createFormItemRender(), + renderToolbarTool: createToolbarToolRender(), +}; diff --git a/src/components/VxeTable/src/components/AMonthPicker.tsx b/src/components/VxeTable/src/components/AMonthPicker.tsx new file mode 100644 index 0000000..f46bbae --- /dev/null +++ b/src/components/VxeTable/src/components/AMonthPicker.tsx @@ -0,0 +1,18 @@ +import { getDatePickerCellValue } from './ADatePicker'; +import { + createCellRender, + createEditRender, + createExportMethod, + createFormItemRender, +} from './common'; + +export default { + renderEdit: createEditRender(), + renderCell: createCellRender(getDatePickerCellValue, () => { + return ['YYYY-MM']; + }), + renderItemContent: createFormItemRender(), + exportMethod: createExportMethod(getDatePickerCellValue, () => { + return ['YYYY-MM']; + }), +}; diff --git a/src/components/VxeTable/src/components/ARadioGroup.tsx b/src/components/VxeTable/src/components/ARadioGroup.tsx new file mode 100644 index 0000000..d01092a --- /dev/null +++ b/src/components/VxeTable/src/components/ARadioGroup.tsx @@ -0,0 +1,5 @@ +import { createFormItemRender } from './common'; + +export default { + renderItemContent: createFormItemRender(), +}; diff --git a/src/components/VxeTable/src/components/ARangePicker.tsx b/src/components/VxeTable/src/components/ARangePicker.tsx new file mode 100644 index 0000000..ce0da2c --- /dev/null +++ b/src/components/VxeTable/src/components/ARangePicker.tsx @@ -0,0 +1,30 @@ +import { VxeColumnPropTypes, VxeGlobalRendererHandles } from 'vxe-table'; +import XEUtils from 'xe-utils'; +import { + createCellRender, + createEditRender, + createExportMethod, + createFormItemRender, +} from './common'; + +function getRangePickerCellValue( + renderOpts: VxeColumnPropTypes.EditRender, + params: VxeGlobalRendererHandles.RenderCellParams | VxeGlobalRendererHandles.ExportMethodParams, +) { + const { props = {} } = renderOpts; + const { row, column } = params; + let cellValue = XEUtils.get(row, column.field as string); + if (cellValue) { + cellValue = XEUtils.map(cellValue, (date: any) => + date.format(props.format || 'YYYY-MM-DD'), + ).join(' ~ '); + } + return cellValue; +} + +export default { + renderEdit: createEditRender(), + renderCell: createCellRender(getRangePickerCellValue), + renderItemContent: createFormItemRender(), + exportMethod: createExportMethod(getRangePickerCellValue), +}; diff --git a/src/components/VxeTable/src/components/ARate.tsx b/src/components/VxeTable/src/components/ARate.tsx new file mode 100644 index 0000000..3ec3f6b --- /dev/null +++ b/src/components/VxeTable/src/components/ARate.tsx @@ -0,0 +1,15 @@ +import { + createEditRender, + createDefaultRender, + createFilterRender, + createDefaultFilterRender, + createFormItemRender, +} from './common'; + +export default { + renderDefault: createDefaultRender(), + renderEdit: createEditRender(), + renderFilter: createFilterRender(), + defaultFilterMethod: createDefaultFilterRender(), + renderItemContent: createFormItemRender(), +}; diff --git a/src/components/VxeTable/src/components/ASelect.tsx b/src/components/VxeTable/src/components/ASelect.tsx new file mode 100644 index 0000000..2785fe7 --- /dev/null +++ b/src/components/VxeTable/src/components/ASelect.tsx @@ -0,0 +1,271 @@ +import { ComponentOptions, h, resolveComponent } from 'vue'; +import { VxeColumnPropTypes, VxeGlobalRendererHandles } from 'vxe-table'; +import XEUtils from 'xe-utils'; +import { + cellText, + createCellRender, + createEvents, + createProps, + isEmptyValue, + createExportMethod, + createFormItemRender, +} from './common'; + +function renderOptions(options: any[], optionProps: VxeGlobalRendererHandles.RenderOptionProps) { + const labelProp = optionProps.label || 'label'; + const valueProp = optionProps.value || 'value'; + return XEUtils.map(options, (item, oIndex) => { + return h( + resolveComponent('a-select-option') as ComponentOptions, + { + key: oIndex, + value: item[valueProp], + disabled: item.disabled, + }, + { + default: () => cellText(item[labelProp]), + }, + ); + }); +} + +function createEditRender() { + return function ( + renderOpts: VxeColumnPropTypes.EditRender, + params: VxeGlobalRendererHandles.RenderEditParams, + ) { + const { options = [], optionGroups, optionProps = {}, optionGroupProps = {} } = renderOpts; + const { row, column, $table } = params; + const { attrs } = renderOpts; + const cellValue = XEUtils.get(row, column.field as string); + const props = createProps(renderOpts, cellValue); + const ons = createEvents( + renderOpts, + params, + (value: any) => { + // 处理 model 值双向绑定 + XEUtils.set(row, column.field as string, value); + }, + () => { + // 处理 change 事件相关逻辑 + $table.updateStatus(params); + }, + ); + if (optionGroups) { + const groupOptions = optionGroupProps.options || 'options'; + const groupLabel = optionGroupProps.label || 'label'; + return [ + h( + resolveComponent('a-select') as ComponentOptions, + { + ...attrs, + ...props, + ...ons, + }, + { + default: () => { + return XEUtils.map(optionGroups, (group, gIndex) => { + return h( + resolveComponent('a-select-opt-group') as ComponentOptions, + { + key: gIndex, + }, + { + label: () => { + return h('span', {}, group[groupLabel]); + }, + default: () => renderOptions(group[groupOptions], optionProps), + }, + ); + }); + }, + }, + ), + ]; + } + return [ + h( + resolveComponent('a-select') as ComponentOptions, + { + ...props, + ...attrs, + ...ons, + }, + { + default: () => renderOptions(options, optionProps), + }, + ), + ]; + }; +} + +function getSelectCellValue( + renderOpts: VxeGlobalRendererHandles.RenderCellOptions, + params: VxeGlobalRendererHandles.RenderCellParams, +) { + const { + options = [], + optionGroups, + props = {}, + optionProps = {}, + optionGroupProps = {}, + } = renderOpts; + const { row, column } = params; + const labelProp = optionProps.label || 'label'; + const valueProp = optionProps.value || 'value'; + const groupOptions = optionGroupProps.options || 'options'; + const cellValue = XEUtils.get(row, column.field as string); + if (!isEmptyValue(cellValue)) { + return XEUtils.map( + props.mode === 'multiple' ? cellValue : [cellValue], + optionGroups + ? (value) => { + let selectItem; + for (let index = 0; index < optionGroups.length; index++) { + selectItem = XEUtils.find( + optionGroups[index][groupOptions], + (item) => item[valueProp] === value, + ); + if (selectItem) { + break; + } + } + return selectItem ? selectItem[labelProp] : value; + } + : (value) => { + const selectItem = XEUtils.find(options, (item) => item[valueProp] === value); + return selectItem ? selectItem[labelProp] : value; + }, + ).join(', '); + } + return ''; +} + +function createFilterRender() { + return function ( + renderOpts: VxeColumnPropTypes.FilterRender, + params: VxeGlobalRendererHandles.RenderFilterParams, + ) { + const { options = [], optionGroups, optionProps = {}, optionGroupProps = {} } = renderOpts; + const groupOptions = optionGroupProps.options || 'options'; + const groupLabel = optionGroupProps.label || 'label'; + const { column } = params; + const { attrs } = renderOpts; + + return [ + h( + 'div', + { + class: 'vxe-table--filter-antd-wrapper', + }, + optionGroups + ? column.filters.map((option, oIndex) => { + const optionValue = option.data; + const props = createProps(renderOpts, optionValue); + + return h( + resolveComponent('a-select') as ComponentOptions, + { + key: oIndex, + ...attrs, + ...props, + ...createEvents( + renderOpts, + params, + (value: any) => { + // 处理 model 值双向绑定 + option.data = value; + }, + () => { + // 处理 change 事件相关逻辑 + const { $panel } = params; + $panel.changeOption( + null, + props.mode === 'multiple' + ? option.data && option.data.length > 0 + : !XEUtils.eqNull(option.data), + option, + ); + }, + ), + }, + { + default: () => { + return XEUtils.map(optionGroups, (group, gIndex) => { + return h( + resolveComponent('a-select-opt-group') as ComponentOptions, + { + key: gIndex, + }, + { + label: () => { + return h('span', {}, group[groupLabel]); + }, + default: () => renderOptions(group[groupOptions], optionProps), + }, + ); + }); + }, + }, + ); + }) + : column.filters.map((option, oIndex) => { + const optionValue = option.data; + const props = createProps(renderOpts, optionValue); + return h( + resolveComponent('a-select') as ComponentOptions, + { + key: oIndex, + ...attrs, + ...props, + ...createEvents( + renderOpts, + params, + (value: any) => { + // 处理 model 值双向绑定 + option.data = value; + }, + () => { + // 处理 change 事件相关逻辑 + const { $panel } = params; + $panel.changeOption( + null, + props.mode === 'multiple' + ? option.data && option.data.length > 0 + : !XEUtils.eqNull(option.data), + option, + ); + }, + ), + }, + { + default: () => renderOptions(options, optionProps), + }, + ); + }), + ), + ]; + }; +} + +export default { + renderEdit: createEditRender(), + renderCell: createCellRender(getSelectCellValue), + renderFilter: createFilterRender(), + defaultFilterMethod(params) { + const { option, row, column } = params; + const { data } = option; + const { field, filterRender: renderOpts } = column; + const { props = {} } = renderOpts; + const cellValue = XEUtils.get(row, field); + if (props.mode === 'multiple') { + if (XEUtils.isArray(cellValue)) { + return XEUtils.includeArrays(cellValue, data); + } + return data.indexOf(cellValue) > -1; + } + return cellValue == data; + }, + renderItemContent: createFormItemRender(), + exportMethod: createExportMethod(getSelectCellValue), +}; diff --git a/src/components/VxeTable/src/components/ASwitch.tsx b/src/components/VxeTable/src/components/ASwitch.tsx new file mode 100644 index 0000000..634ab7f --- /dev/null +++ b/src/components/VxeTable/src/components/ASwitch.tsx @@ -0,0 +1,53 @@ +import { h } from 'vue'; +import XEUtils from 'xe-utils'; +import { + createEditRender, + createDefaultRender, + createProps, + createEvents, + createDefaultFilterRender, + createFormItemRender, + getComponent, +} from './common'; + +export default { + renderDefault: createDefaultRender(), + renderEdit: createEditRender(), + renderFilter(renderOpts, params) { + const { column } = params; + const { name, attrs } = renderOpts; + const Component = getComponent(name); + + return [ + h( + 'div', + { + class: 'vxe-table--filter-antd-wrapper', + }, + column.filters.map((option, oIndex) => { + const optionValue = option.data; + return h(Component, { + key: oIndex, + ...attrs, + ...createProps(renderOpts, optionValue), + ...createEvents( + renderOpts, + params, + (value: any) => { + // 处理 model 值双向绑定 + option.data = value; + }, + () => { + // 处理 change 事件相关逻辑 + const { $panel } = params; + $panel.changeOption(null, XEUtils.isBoolean(option.data), option); + }, + ), + }); + }), + ), + ]; + }, + defaultFilterMethod: createDefaultFilterRender(), + renderItemContent: createFormItemRender(), +}; diff --git a/src/components/VxeTable/src/components/ATimePicker.tsx b/src/components/VxeTable/src/components/ATimePicker.tsx new file mode 100644 index 0000000..7d2be54 --- /dev/null +++ b/src/components/VxeTable/src/components/ATimePicker.tsx @@ -0,0 +1,18 @@ +import { getDatePickerCellValue } from './ADatePicker'; +import { + createEditRender, + createCellRender, + createFormItemRender, + createExportMethod, +} from './common'; + +export default { + renderEdit: createEditRender(), + renderCell: createCellRender(getDatePickerCellValue, () => { + return ['HH:mm:ss']; + }), + renderItemContent: createFormItemRender(), + exportMethod: createExportMethod(getDatePickerCellValue, () => { + return ['HH:mm:ss']; + }), +}; diff --git a/src/components/VxeTable/src/components/ATreeSelect.tsx b/src/components/VxeTable/src/components/ATreeSelect.tsx new file mode 100644 index 0000000..5cb577a --- /dev/null +++ b/src/components/VxeTable/src/components/ATreeSelect.tsx @@ -0,0 +1,35 @@ +import { VxeGlobalRendererHandles } from 'vxe-table'; +import XEUtils from 'xe-utils'; +import { + createEditRender, + createCellRender, + isEmptyValue, + createFormItemRender, + createExportMethod, +} from './common'; + +function getTreeSelectCellValue( + renderOpts: VxeGlobalRendererHandles.RenderOptions, + params: VxeGlobalRendererHandles.RenderCellParams | VxeGlobalRendererHandles.ExportMethodParams, +) { + const { props = {} } = renderOpts; + const { treeData, treeCheckable } = props; + const { row, column } = params; + const cellValue = XEUtils.get(row, column.field as string); + if (!isEmptyValue(cellValue)) { + return XEUtils.map(treeCheckable ? cellValue : [cellValue], (value) => { + const matchObj = XEUtils.findTree(treeData, (item: any) => item.value === value, { + children: 'children', + }); + return matchObj ? matchObj.item.title : value; + }).join(', '); + } + return cellValue; +} + +export default { + renderEdit: createEditRender(), + renderCell: createCellRender(getTreeSelectCellValue), + renderItemContent: createFormItemRender(), + exportMethod: createExportMethod(getTreeSelectCellValue), +}; diff --git a/src/components/VxeTable/src/components/AWeekPicker.tsx b/src/components/VxeTable/src/components/AWeekPicker.tsx new file mode 100644 index 0000000..97b34e5 --- /dev/null +++ b/src/components/VxeTable/src/components/AWeekPicker.tsx @@ -0,0 +1,18 @@ +import { getDatePickerCellValue } from './ADatePicker'; +import { + createEditRender, + createCellRender, + createFormItemRender, + createExportMethod, +} from './common'; + +export default { + renderEdit: createEditRender(), + renderCell: createCellRender(getDatePickerCellValue, () => { + return ['YYYY-WW周']; + }), + renderItemContent: createFormItemRender(), + exportMethod: createExportMethod(getDatePickerCellValue, () => { + return ['YYYY-WW周']; + }), +}; diff --git a/src/components/VxeTable/src/components/AYearPicker.tsx b/src/components/VxeTable/src/components/AYearPicker.tsx new file mode 100644 index 0000000..6e73c19 --- /dev/null +++ b/src/components/VxeTable/src/components/AYearPicker.tsx @@ -0,0 +1,18 @@ +import { getDatePickerCellValue } from './ADatePicker'; +import { + createEditRender, + createCellRender, + createFormItemRender, + createExportMethod, +} from './common'; + +export default { + renderEdit: createEditRender(), + renderCell: createCellRender(getDatePickerCellValue, () => { + return ['YYYY']; + }), + renderItemContent: createFormItemRender(), + exportMethod: createExportMethod(getDatePickerCellValue, () => { + return ['YYYY']; + }), +}; diff --git a/src/components/VxeTable/src/components/common.tsx b/src/components/VxeTable/src/components/common.tsx new file mode 100644 index 0000000..f2ba1e3 --- /dev/null +++ b/src/components/VxeTable/src/components/common.tsx @@ -0,0 +1,427 @@ +import { ComponentOptions, h } from 'vue'; +import { + FormItemContentRenderParams, + FormItemRenderOptions, + VxeGlobalRendererHandles, +} from 'vxe-table'; +import XEUtils from 'xe-utils'; +import { componentMap } from '../componentMap'; +import { ComponentType } from '../componentType'; +import { createPlaceholderMessage } from '../helper'; + +/** + * @description: 获取组件 + */ +export function getComponent(componentName) { + const Component = componentMap.get(componentName as ComponentType); + if (!Component) throw `您还没注册此组件 ${componentName}`; + return Component as ComponentOptions; +} + +export function isEmptyValue(cellValue: any) { + return cellValue === null || cellValue === undefined || cellValue === ''; +} + +export function formatText(cellValue: any) { + return '' + (isEmptyValue(cellValue) ? '' : cellValue); +} + +export function cellText(cellValue: any): string[] { + return [formatText(cellValue)]; +} + +/** + * @description: 方法名转换 + */ +export function getOnName(type: string) { + return 'on' + type.substring(0, 1).toLocaleUpperCase() + type.substring(1); +} + +/** + * @description: 获取组件传值所接受的属性 + */ +function getModelKey(renderOpts: VxeGlobalRendererHandles.RenderOptions) { + let prop = 'value'; + switch (renderOpts.name) { + case 'ASwitch': + prop = 'checked'; + break; + } + return prop; +} + +/** + * @description: 回去双向更新的方法 + */ +function getModelEvent(renderOpts: VxeGlobalRendererHandles.RenderOptions) { + let type = 'update:value'; + switch (renderOpts.name) { + case 'ASwitch': + type = 'update:checked'; + break; + } + return type; +} + +/** + * @description: chang值改变方法 + * @param {} + * @return {*} + * @author: * + */ +function getChangeEvent() { + return 'change'; +} + +function getClickEvent() { + return 'click'; +} +/** + * @description: 获取方法 + * @param {} + * @return {*} + * @author: * + */ +export function createEvents( + renderOpts: VxeGlobalRendererHandles.RenderOptions, + params: VxeGlobalRendererHandles.RenderParams, + inputFunc?: Function, + changeFunc?: Function, + clickFunc?: Function, +) { + const { events } = renderOpts; + const modelEvent = getModelEvent(renderOpts); + const changeEvent = getChangeEvent(); + const clickEvent = getClickEvent(); + const isSameEvent = changeEvent === modelEvent; + const ons: { [type: string]: Function } = {}; + + XEUtils.objectEach(events, (func: Function, key: string) => { + ons[getOnName(key)] = function (...args: any[]) { + func(params, ...args); + }; + }); + if (inputFunc) { + ons[getOnName(modelEvent)] = function (targetEvnt: any) { + inputFunc(targetEvnt); + if (events && events[modelEvent]) { + events[modelEvent](params, targetEvnt); + } + if (isSameEvent && changeFunc) { + changeFunc(targetEvnt); + } + }; + } + if (!isSameEvent && changeFunc) { + ons[getOnName(changeEvent)] = function (...args: any[]) { + changeFunc(...args); + if (events && events[changeEvent]) { + events[changeEvent](params, ...args); + } + }; + } + if (clickFunc) { + ons[getOnName(clickEvent)] = function (...args: any[]) { + clickFunc(...args); + if (events && events[clickEvent]) { + events[clickEvent](params, ...args); + } + }; + } + return ons; +} + +/** + * @description: 获取属性 + */ +export function createProps( + renderOpts: VxeGlobalRendererHandles.RenderOptions, + value: any, + defaultProps?: { [prop: string]: any }, +) { + const name = renderOpts.name as ComponentType; + return XEUtils.assign( + { + placeholder: createPlaceholderMessage(name), + allowClear: true, + }, + defaultProps, + renderOpts.props, + { + [getModelKey(renderOpts)]: value, + }, + ); +} + +/** + * @description: 创建单元格默认显示内容 + */ +export function createDefaultRender( + defaultProps?: { [key: string]: any }, + callBack?: ( + renderOpts: VxeGlobalRendererHandles.RenderDefaultOptions, + params: VxeGlobalRendererHandles.RenderDefaultParams, + ) => Record, +) { + return function ( + renderOpts: VxeGlobalRendererHandles.RenderDefaultOptions, + params: VxeGlobalRendererHandles.RenderDefaultParams, + ) { + const { row, column, $table } = params; + const { name, attrs } = renderOpts; + const cellValue = XEUtils.get(row, column.field as string); + const args = (callBack && callBack(renderOpts, params)) ?? {}; + + const Component = getComponent(name); + return [ + h(Component, { + ...attrs, + ...createProps(renderOpts, cellValue, defaultProps), + ...args, + ...createEvents( + renderOpts, + params, + (value: any) => XEUtils.set(row, column.field as string, value), + () => $table.updateStatus(params), + ), + }), + ]; + }; +} + +/** + * @description: 创建编辑单元格 + */ +export function createEditRender( + defaultProps?: { [key: string]: any }, + callBack?: ( + renderOpts: VxeGlobalRendererHandles.RenderEditOptions, + params: VxeGlobalRendererHandles.RenderEditParams, + ) => Record, +) { + return function ( + renderOpts: VxeGlobalRendererHandles.RenderEditOptions, + params: VxeGlobalRendererHandles.RenderEditParams, + ) { + const { row, column, $table } = params; + const { name, attrs } = renderOpts; + const cellValue = XEUtils.get(row, column.field as string); + const args = (callBack && callBack(renderOpts, params)) ?? {}; + + const Component = getComponent(name); + return [ + h(Component, { + ...attrs, + ...createProps(renderOpts, cellValue, defaultProps), + ...args, + ...createEvents( + renderOpts, + params, + (value: any) => XEUtils.set(row, column.field as string, value), + () => $table.updateStatus(params), + ), + }), + ]; + }; +} + +/** + * @description: 创建筛选渲染内容 + */ +export function createFilterRender( + defaultProps?: { [key: string]: any }, + callBack?: ( + renderOpts: VxeGlobalRendererHandles.RenderFilterOptions, + params: VxeGlobalRendererHandles.RenderFilterParams, + ) => Record, +) { + return function ( + renderOpts: VxeGlobalRendererHandles.RenderFilterOptions, + params: VxeGlobalRendererHandles.RenderFilterParams, + ) { + const { column } = params; + const { name, attrs } = renderOpts; + const args = (callBack && callBack(renderOpts, params)) ?? {}; + + const Component = getComponent(name); + return [ + h( + 'div', + { + class: 'vxe-table--filter-antd-wrapper', + }, + column.filters.map((option, oIndex) => { + const optionValue = option.data; + const checked = !!option.data; + + return h(Component, { + key: oIndex, + ...attrs, + ...createProps(renderOpts, optionValue, defaultProps), + ...args, + ...createEvents( + renderOpts, + params, + (value: any) => { + // 处理 model 值双向绑定 + option.data = value; + }, + () => { + // 处理 change 事件相关逻辑 + const { $panel } = params; + $panel.changeOption(null, checked, option); + }, + ), + }); + }), + ), + ]; + }; +} + +/** + * @description: 默认过滤 + * @param {} + * @return {*} + * @author: * + */ + +export function createDefaultFilterRender() { + return function (params: VxeGlobalRendererHandles.FilterMethodParams) { + const { option, row, column } = params; + const { data } = option; + const cellValue = XEUtils.get(row, column.field as string); + return cellValue === data; + }; +} + +/** + * @description: 创建 form表单渲染 + */ +export function createFormItemRender( + defaultProps?: { [key: string]: any }, + callBack?: ( + renderOpts: FormItemRenderOptions, + params: FormItemContentRenderParams, + ) => Record, +) { + return function (renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) { + const args = (callBack && callBack(renderOpts, params)) ?? {}; + const { data, property, $form } = params; + const { name } = renderOpts; + const { attrs } = renderOpts; + const itemValue = XEUtils.get(data, property); + + const Component = getComponent(name); + return [ + h(Component, { + ...attrs, + ...createProps(renderOpts, itemValue, defaultProps), + ...args, + ...createEvents( + renderOpts, + params, + (value: any) => { + // 处理 model 值双向绑定 + XEUtils.set(data, property, value); + }, + () => { + // 处理 change 事件相关逻辑 + $form.updateStatus({ + ...params, + field: property, + }); + }, + ), + }), + ]; + }; +} + +/** + * @description: cell渲染 + */ +export function createCellRender( + getSelectCellValue: Function, + callBack?: ( + renderOpts: VxeGlobalRendererHandles.RenderCellOptions, + params: VxeGlobalRendererHandles.RenderCellParams, + ) => Array, +) { + return function ( + renderOpts: VxeGlobalRendererHandles.RenderCellOptions, + params: VxeGlobalRendererHandles.RenderCellParams, + ) { + const args = (callBack && callBack(renderOpts, params)) ?? []; + const cellLabel = getSelectCellValue && getSelectCellValue(renderOpts, params, ...args); + const { placeholder } = renderOpts; + + return [ + h( + 'span', + { + class: 'vxe-cell--label', + }, + placeholder && isEmptyValue(cellLabel) + ? [ + h( + 'span', + { + class: 'vxe-cell--placeholder', + }, + formatText(placeholder), + ), + ] + : formatText(cellLabel), + ), + ]; + }; +} + +/** + * @description: 创建 导出渲染 + * @param {} + * @return {*} + * @author: * + */ +export function createExportMethod( + getExportCellValue: Function, + callBack?: (params: VxeGlobalRendererHandles.ExportMethodParams) => Array, +) { + return function (params: VxeGlobalRendererHandles.ExportMethodParams) { + const { row, column, options } = params; + const args = (callBack && callBack(params)) ?? []; + return options && options.original + ? XEUtils.get(row, column.field as string) + : getExportCellValue(column.editRender || column.cellRender, params, ...args); + }; +} + +/** + * @description: 创建单元格默认显示内容 + */ +export function createToolbarToolRender( + defaultProps?: { [key: string]: any }, + callBack?: ( + renderOpts: VxeGlobalRendererHandles.RenderToolOptions, + params: VxeGlobalRendererHandles.RenderToolParams, + ) => Record, +) { + return function ( + renderOpts: VxeGlobalRendererHandles.RenderToolOptions, + params: VxeGlobalRendererHandles.RenderToolParams, + ) { + const { name, attrs } = renderOpts; + const args = (callBack && callBack(renderOpts, params)) ?? {}; + + const Component = getComponent(name); + return [ + h(Component, { + ...attrs, + ...createProps(renderOpts, null, defaultProps), + ...args, + ...createEvents(renderOpts, params), + }), + ]; + }; +} diff --git a/src/components/VxeTable/src/components/index.tsx b/src/components/VxeTable/src/components/index.tsx new file mode 100644 index 0000000..ba8c6d8 --- /dev/null +++ b/src/components/VxeTable/src/components/index.tsx @@ -0,0 +1,114 @@ +import { VXETableCore, VxeGlobalInterceptorHandles } from 'vxe-table'; +import AAutoComplete from './AAutoComplete'; +import AInput from './AInput'; +import AInputNumber from './AInputNumber'; +import ASelect from './ASelect'; +import ACascader from './ACascader'; +import ADatePicker from './ADatePicker'; +import AMonthPicker from './AMonthPicker'; +import ARangePicker from './ARangePicker'; +import AWeekPicker from './AWeekPicker'; +import ATreeSelect from './ATreeSelect'; +import ATimePicker from './ATimePicker'; +import ARate from './ARate'; +import ASwitch from './ASwitch'; +import ARadioGroup from './ARadioGroup'; +import ACheckboxGroup from './ACheckboxGroup'; +import AButton from './AButton'; +import AButtonGroup from './AButtonGroup'; +import AApiSelect from './AApiSelect'; +import AApiTreeSelect from './AApiTreeSelect'; +import AEmpty from './AEmpty'; +import AInputSearch from './AInputSearch'; +import AYearPicker from './AYearPicker'; + +/** + * 检查触发源是否属于目标节点 + */ +function getEventTargetNode(evnt: any, container: HTMLElement, className: string) { + let targetElem; + let target = evnt.target; + while (target && target.nodeType && target !== document) { + if ( + className && + target.className && + target.className.split && + target.className.split(' ').indexOf(className) > -1 + ) { + targetElem = target; + } else if (target === container) { + return { flag: className ? !!targetElem : true, container, targetElem: targetElem }; + } + target = target.parentNode; + } + return { flag: false }; +} + +/** + * 事件兼容性处理 + */ +function handleClearEvent( + params: + | VxeGlobalInterceptorHandles.InterceptorClearFilterParams + | VxeGlobalInterceptorHandles.InterceptorClearActivedParams + | VxeGlobalInterceptorHandles.InterceptorClearAreasParams, +) { + const { $event } = params; + const bodyElem = document.body; + if ( + // 下拉框 + getEventTargetNode($event, bodyElem, 'ant-select-dropdown').flag || + // 级联 + getEventTargetNode($event, bodyElem, 'ant-cascader-menus').flag || + // 日期 + getEventTargetNode($event, bodyElem, 'ant-calendar-picker-container').flag || + // 时间选择 + getEventTargetNode($event, bodyElem, 'ant-time-picker-panel').flag + ) { + return false; + } +} + +/** + * 基于 vxe-table 表格的适配插件,用于兼容 ant-design-vue 组件库 + */ +export const VXETablePluginAntd = { + install(vxetablecore: VXETableCore) { + const { interceptor, renderer } = vxetablecore; + + renderer.mixin({ + AAutoComplete, + AInput, + AInputNumber, + ASelect, + ACascader, + ADatePicker, + AMonthPicker, + ARangePicker, + AWeekPicker, + ATimePicker, + ATreeSelect, + ARate, + ASwitch, + ARadioGroup, + ACheckboxGroup, + AButton, + AButtonGroup, + AApiSelect, + AApiTreeSelect, + AEmpty, + AInputSearch, + AYearPicker, + }); + + interceptor.add('event.clearFilter', handleClearEvent); + interceptor.add('event.clearActived', handleClearEvent); + interceptor.add('event.clearAreas', handleClearEvent); + }, +}; + +if (typeof window !== 'undefined' && window.VXETable && window.VXETable.use) { + window.VXETable.use(VXETablePluginAntd); +} + +export default VXETablePluginAntd; diff --git a/src/components/VxeTable/src/const.ts b/src/components/VxeTable/src/const.ts new file mode 100644 index 0000000..6827bb4 --- /dev/null +++ b/src/components/VxeTable/src/const.ts @@ -0,0 +1,4 @@ +/** + * @description: 传给vxe-table 时需要忽略的prop + */ +export const ignorePropKeys = ['tableClass', 'tableStyle']; diff --git a/src/components/VxeTable/src/css/common.scss b/src/components/VxeTable/src/css/common.scss new file mode 100644 index 0000000..a8eb58e --- /dev/null +++ b/src/components/VxeTable/src/css/common.scss @@ -0,0 +1,8 @@ +*, +::before, +::after { + box-sizing: border-box; + border-width: 0; + border-style: solid; + border-color: initial; +} diff --git a/src/components/VxeTable/src/css/component.scss b/src/components/VxeTable/src/css/component.scss new file mode 100644 index 0000000..a9f7ba2 --- /dev/null +++ b/src/components/VxeTable/src/css/component.scss @@ -0,0 +1,123 @@ +/* stylelint-disable scss/percent-placeholder-pattern */ +%ResetBorder { + border: 0; + box-shadow: none; +} + +%CompWidth { + & > .ant-input, + & > .ant-input-number, + & > .ant-select, + & > .ant-cascader-picker, + & > .ant-calendar-picker, + & > .ant-time-picker { + width: 100%; + } +} + +.vxe-form { + .vxe-form--item-content { + @extend %CompWidth; + } +} + +.vxe-table--filter-antd-wrapper { + & > .ant-input, + & > .ant-input-number, + & > .ant-select, + & > .ant-rate { + width: 180px; + } +} + +.vxe-cell, +.vxe-tree-cell { + @extend %CompWidth; + + & > .ant-rate { + vertical-align: bottom; + + .anticon-star { + display: block; + } + } +} + +.col--valid-error { + & > .vxe-cell, + & > .vxe-tree-cell { + & > .ant-input, + & > .ant-select .ant-input, + & > .ant-select .ant-select-selection, + & > .ant-input-number, + & > .ant-cascader-picker .ant-cascader-input, + & > .ant-calendar-picker .ant-calendar-picker-input { + box-shadow: none; + } + } +} + +.vxe-table.cell--highlight { + .vxe-cell, + .vxe-tree-cell { + & > .ant-input, + & > .ant-input-number { + @extend %ResetBorder; + + padding: 0; + } + + & > .ant-select { + .ant-input { + @extend %ResetBorder; + + padding: 0; + } + + .ant-select-selection { + @extend %ResetBorder; + + .ant-select-selection__rendered { + margin: 0; + } + } + } + + & > .ant-input-number { + .ant-input-number-input { + padding: 0; + } + + .ant-input-number-handler-wrap, + .ant-input-number-handler-down { + @extend %ResetBorder; + } + } + + & > .ant-cascader-picker { + .ant-input { + @extend %ResetBorder; + } + + .ant-cascader-picker-label { + padding: 0; + } + } + + & > .ant-calendar-picker { + .ant-calendar-picker-input { + @extend %ResetBorder; + + padding: 0; + } + } + + & > .ant-time-picker { + .ant-time-picker-input { + @extend %ResetBorder; + + padding: 0; + } + } + } +} \ No newline at end of file diff --git a/src/components/VxeTable/src/css/index.scss b/src/components/VxeTable/src/css/index.scss new file mode 100644 index 0000000..7f34cab --- /dev/null +++ b/src/components/VxeTable/src/css/index.scss @@ -0,0 +1,5 @@ +@import './common'; +@import './variable'; +@import './toolbar'; +@import './component'; +@import 'vxe-table/styles/index'; \ No newline at end of file diff --git a/src/components/VxeTable/src/css/scrollbar.scss b/src/components/VxeTable/src/css/scrollbar.scss new file mode 100644 index 0000000..4464aa2 --- /dev/null +++ b/src/components/VxeTable/src/css/scrollbar.scss @@ -0,0 +1,29 @@ +.vxe-grid_scrollbar { + ::-webkit-scrollbar { + width: 8px; + height: 8px; + } + + ::-webkit-scrollbar-track { + background-color: #fff; + } + + ::-webkit-scrollbar-thumb { + border: 1px solid #f1f1f1; + border-radius: 5px; + background-color: rgb(0 0 0 / 10%); + box-shadow: inset 0 0 6px rgb(0 0 0 / 30%); + } + + ::-webkit-scrollbar-thumb:hover { + background-color: #a8a8a8; + } + + ::-webkit-scrollbar-thumb:active { + background-color: #a8a8a8; + } + + ::-webkit-scrollbar-corner { + background-color: #fff; + } +} \ No newline at end of file diff --git a/src/components/VxeTable/src/css/toolbar.scss b/src/components/VxeTable/src/css/toolbar.scss new file mode 100644 index 0000000..4a8897b --- /dev/null +++ b/src/components/VxeTable/src/css/toolbar.scss @@ -0,0 +1,26 @@ +.vxe-toolbar .vxe-custom--option-wrapper .vxe-custom--footer { + display: flex; +} + +.vxe-toolbar .vxe-tools--wrapper, +.vxe-toolbar .vxe-tools--operate button:first-child { + margin: 0; + margin-left: 10px; +} + +.vxe-toolbar .vxe-tools--wrapper, +.vxe-toolbar .vxe-tools--operate .vxe-button { + margin-left: 10px; + border-radius: 0 !important; +} + +.vxe-toolbar .vxe-tools--wrapper, +.vxe-toolbar .vxe-tools--operate .vxe-custom--wrapper { + margin-left: 1px; + border-radius: 0 !important; +} + +.vxe-toolbar .vxe-tools--wrapper, +.vxe-toolbar .vxe-tools--operate .vxe-custom--wrapper .vxe-button { + margin-left: 10px; +} \ No newline at end of file diff --git a/src/components/VxeTable/src/css/variable.scss b/src/components/VxeTable/src/css/variable.scss new file mode 100644 index 0000000..56bf213 --- /dev/null +++ b/src/components/VxeTable/src/css/variable.scss @@ -0,0 +1,54 @@ +/* stylelint-disable scss/no-global-function-names */ +html[data-theme='dark'] { + // $bg-color: #151515; + // $tooltip-bg-color: #303133; + // $text-color: #c9d1d9; + // $border-color: #303030; + // $selected-bg-color: #1e1e1e; + // $striped-bg-color: #1e1e1e; + + --vxe-form-background-color: #151515; + --vxe-toolbar-background-color: #151515; + --vxe-pager-background-color: #151515; + --vxe-button-default-background-color: lighten(#151515, 15%); + --vxe-table-header-background-color: lighten(#151515, 5%); + --vxe-font-color: darken(#c9d1d9, 12%); + --vxe-table-header-font-color: #c9d1d9; + --vxe-table-footer-font-color: #c9d1d9; + --vxe-table-body-background-color: #151515; + --vxe-table-footer-background-color: #151515; + --vxe-table-row-striped-background-color: #1e1e1e; + --vxe-table-border-color: #303030; + --vxe-table-row-hover-background-color: #1e1e1e; + --vxe-table-row-hover-striped-background-color: darken(#1e1e1e, 10%); + --vxe-table-row-current-background-color: fade(#1e1e1e, 20%); + --vxe-table-row-hover-current-background-color: fade(#1e1e1e, 20%); + --vxe-table-column-hover-background-color: fade(#1e1e1e, 20%); + --vxe-table-column-current-background-color: fade(#1e1e1e, 20%); + --vxe-table-row-checkbox-checked-background-color: fade(#1e1e1e, 15%); + --vxe-table-row-hover-checkbox-checked-background-color: fade(#1e1e1e, 20%); + --vxe-table-menu-background-color: lighten(#303133, 10%); + --vxe-table-filter-panel-background-color: lighten(#151515, 5%); + --vxe-grid-maximize-background-color: #151515; + --vxe-pager-perfect-background-color: #151515; + --vxe-pager-perfect-button-background-color: lighten(#151515, 15%); + --vxe-input-background-color: #151515; + --vxe-input-border-color: #303030; + --vxe-select-panel-background-color: #151515; + --vxe-table-popup-border-color: #303030; + --vxe-select-option-hover-background-color: lighten(#1e1e1e, 15%); + --vxe-pulldown-panel-background-color: #151515; + --vxe-table-fixed-left-scrolling-box-shadow: 8px 0px 10px -5px rgb(255 255 255 / 12%); + --vxe-table-fixed-right-scrolling-box-shadow: -8px 0px 10px -5px rgb(255 255 255 / 12%); + --vxe-loading-background-color: rgb(0 0 0 / 50%); + --vxe-tooltip-dark-background-color: lighten(#303133, 25%); + --vxe-modal-header-background-color: #1e1e1e; + --vxe-modal-body-background-color: #303133; + --vxe-modal-border-color: #303030; + --vxe-toolbar-panel-background-color: #151515; + --vxe-input-disabled-color: lighten(#1e1e1e, 20%); + --vxe-input-disabled-background-color: lighten(#1e1e1e, 25%); + --vxe-checkbox-icon-background-color: lighten(#1e1e1e, 15%); + --vxe-checkbox-checked-icon-border-color: #303030; + --vxe-checkbox-indeterminate-icon-background-color: lighten(#1e1e1e, 15%); +} \ No newline at end of file diff --git a/src/components/VxeTable/src/emits.ts b/src/components/VxeTable/src/emits.ts new file mode 100644 index 0000000..4920d73 --- /dev/null +++ b/src/components/VxeTable/src/emits.ts @@ -0,0 +1,17 @@ +import tableEmits from 'vxe-table/es/table/src/emits'; + +export const basicEmits = [ + ...tableEmits, + 'page-change', + 'form-submit', + 'form-submit-invalid', + 'form-reset', + 'form-collapse', + 'form-toggle-collapse', + 'toolbar-button-click', + 'toolbar-tool-click', + 'zoom', + + //... 如有缺少在此处追加 + // xxx +]; diff --git a/src/components/VxeTable/src/helper.ts b/src/components/VxeTable/src/helper.ts new file mode 100644 index 0000000..07aa8fd --- /dev/null +++ b/src/components/VxeTable/src/helper.ts @@ -0,0 +1,19 @@ +import { ComponentType } from './componentType'; +import { useI18n } from '/@/hooks/web/useI18n'; + +const { t } = useI18n(); + +/** + * @description: 生成placeholder + */ +export function createPlaceholderMessage(component: ComponentType) { + if (!component) return; + if (component.includes('RangePicker')) { + return [t('common.chooseText'), t('common.chooseText')]; + } + if (component.includes('Input') || component.includes('Complete') || component.includes('Rate')) { + return t('common.inputText'); + } else { + return t('common.chooseText'); + } +} diff --git a/src/components/VxeTable/src/methods.ts b/src/components/VxeTable/src/methods.ts new file mode 100644 index 0000000..78a81c2 --- /dev/null +++ b/src/components/VxeTable/src/methods.ts @@ -0,0 +1,160 @@ +import { GridMethods, TableMethods, TableEditMethods, TableValidatorMethods } from 'vxe-table'; + +export const gridComponentMethodKeys: ( + | keyof GridMethods + | keyof TableMethods + | keyof TableEditMethods + | keyof TableValidatorMethods +)[] = [ + // vxe-grid 部分 + 'dispatchEvent', + 'commitProxy', + 'getFormItems', + 'getPendingRecords', + 'zoom', + 'isMaximized', + 'maximize', + 'revert', + 'getProxyInfo', + + // vxe-table和vxe-grid公共部分 + 'clearAll', + 'syncData', + 'updateData', + 'loadData', + 'reloadData', + 'reloadRow', + 'loadColumn', + 'reloadColumn', + 'getRowNode', + 'getColumnNode', + 'getRowIndex', + 'getVTRowIndex', + 'getVMRowIndex', + 'getColumnIndex', + 'getVTColumnIndex', + 'getVMColumnIndex', + 'createData', + 'createRow', + 'revertData', + 'clearData', + 'isInsertByRow', + 'isUpdateByRow', + 'getColumns', + 'getColumnById', + 'getColumnByField', + 'getTableColumn', + 'getData', + 'getCheckboxRecords', + 'getParentRow', + 'getRowSeq', + 'getRowById', + 'getRowid', + 'getTableData', + 'hideColumn', + 'showColumn', + 'resetColumn', + 'refreshColumn', + 'refreshScroll', + 'recalculate', + 'closeTooltip', + 'isAllCheckboxChecked', + 'isAllCheckboxIndeterminate', + 'getCheckboxIndeterminateRecords', + 'setCheckboxRow', + 'isCheckedByCheckboxRow', + 'isIndeterminateByCheckboxRow', + 'toggleCheckboxRow', + 'setAllCheckboxRow', + 'getRadioReserveRecord', + 'clearRadioReserve', + 'getCheckboxReserveRecords', + 'clearCheckboxReserve', + 'toggleAllCheckboxRow', + 'clearCheckboxRow', + 'setCurrentRow', + 'isCheckedByRadioRow', + 'setRadioRow', + 'clearCurrentRow', + 'clearRadioRow', + 'getCurrentRecord', + 'getRadioRecord', + 'getCurrentColumn', + 'setCurrentColumn', + 'clearCurrentColumn', + 'sort', + 'clearSort', + 'isSort', + 'getSortColumns', + 'closeFilter', + 'isFilter', + 'isRowExpandLoaded', + 'clearRowExpandLoaded', + 'reloadRowExpand', + 'reloadRowExpand', + 'toggleRowExpand', + 'setAllRowExpand', + 'setRowExpand', + 'isExpandByRow', + 'clearRowExpand', + 'clearRowExpandReserve', + 'getRowExpandRecords', + 'getTreeExpandRecords', + 'isTreeExpandLoaded', + 'clearTreeExpandLoaded', + 'reloadTreeExpand', + 'reloadTreeChilds', + 'toggleTreeExpand', + 'setAllTreeExpand', + 'setTreeExpand', + 'isTreeExpandByRow', + 'clearTreeExpand', + 'clearTreeExpandReserve', + 'getScroll', + 'scrollTo', + 'scrollToRow', + 'scrollToColumn', + 'clearScroll', + 'updateFooter', + 'updateStatus', + 'setMergeCells', + 'removeInsertRow', + 'removeMergeCells', + 'getMergeCells', + 'clearMergeCells', + 'setMergeFooterItems', + 'removeMergeFooterItems', + 'getMergeFooterItems', + 'clearMergeFooterItems', + 'openTooltip', + 'focus', + 'blur', + 'connect', + + // vxe-table-edit部分 + 'insert', + 'insertAt', + 'remove', + 'removeCheckboxRow', + 'removeRadioRow', + 'removeCurrentRow', + 'getRecordset', + 'getInsertRecords', + 'getRemoveRecords', + 'getUpdateRecords', + 'getEditRecord', + 'getSelectedCell', + 'clearSelected', + 'isEditByRow', + 'setEditRow', + 'setEditCell', + 'setSelectCell', + + // vxe-table-validator + 'clearValidate', + 'fullValidate', + 'validate', + + //... 如有缺少在此处追加 + // xxx +]; diff --git a/src/components/VxeTable/src/props.ts b/src/components/VxeTable/src/props.ts new file mode 100644 index 0000000..fff29de --- /dev/null +++ b/src/components/VxeTable/src/props.ts @@ -0,0 +1,52 @@ +import { VxeGridPropTypes, VxeTablePropTypes } from 'vxe-table'; +import tableProps from 'vxe-table/es/table/src/props'; +import { CSSProperties } from 'vue'; + +/** + * @description: table二次开发需要后,需要接受的所有prop属性 + */ +export const basicProps = { + ...tableProps, + columns: Array as PropType, + pagerConfig: { + type: Object as PropType, + default: () => ({}), + }, + proxyConfig: { + type: Object as PropType, + default: () => ({}), + }, + toolbarConfig: { + type: Object as PropType, + default: () => ({}), + }, + formConfig: { + type: Object as PropType, + default: () => ({}), + }, + zoomConfig: { + type: Object as PropType, + default: () => ({}), + }, + printConfig: { + type: Object as PropType, + default: () => ({}), + }, + exportConfig: { + type: Object as PropType, + default: () => ({}), + }, + importConfig: { + type: Object as PropType, + default: () => ({}), + }, + size: String as PropType, + tableClass: { + type: String, + default: '', + }, + tableStyle: { + type: Object as PropType, + default: () => ({}), + }, +}; diff --git a/src/components/VxeTable/src/setting.ts b/src/components/VxeTable/src/setting.ts new file mode 100644 index 0000000..a1df882 --- /dev/null +++ b/src/components/VxeTable/src/setting.ts @@ -0,0 +1,4 @@ +import { VXETable } from '..'; +import componentSetting from '/@/settings/componentSetting'; + +VXETable.setup(componentSetting.vxeTable); diff --git a/src/components/VxeTable/src/types.ts b/src/components/VxeTable/src/types.ts new file mode 100644 index 0000000..1319e69 --- /dev/null +++ b/src/components/VxeTable/src/types.ts @@ -0,0 +1,7 @@ +import { CSSProperties } from 'vue'; +import { VxeGridProps } from 'vxe-table'; + +export type BasicTableProps = VxeGridProps & { + tableClass?: string; + tableStyle?: CSSProperties; +}; diff --git a/src/components/registerGlobComp.ts b/src/components/registerGlobComp.ts new file mode 100644 index 0000000..5a8e591 --- /dev/null +++ b/src/components/registerGlobComp.ts @@ -0,0 +1,8 @@ +import type { App } from 'vue'; +import { Button } from './Button'; +import { Input, Layout } from 'ant-design-vue'; +import VXETable from 'vxe-table'; + +export function registerGlobComp(app: App) { + app.use(Input).use(Button).use(Layout).use(VXETable); +} diff --git a/src/design/.DS_Store b/src/design/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..11025585cef1348c19250de5c71731074b2446a1 GIT binary patch literal 6148 zcmeHK%T2>T5S@*4FdrcwIc^E011B;SqyY$#AR>;V5IFll2NXaxoM?(S9|c>sIYua& zk#^sDKD*;*%i|%UFne82h%zEdF&IZ@n0kcmJUTKm%_T7K9+UY)Rczmt*~BEMVt2N z**o^{^&7}#z_&NEUf-TP6M93IyLM*jhupbX26C~uvg$qEtnKq|u&IkP;0!neM`Hjr znv1Lttg)kOws}X$54x4&AkN2M8n*$R)hr-G!&?z!CH)< z;m}9(%MEKq4X0quN3fHFbtpkj$No{=DddViI|I%@n}I|xGp_%)!~K6d$gi9MXW*n5 z2;*X2%y3IqTRS($wKihhVX&}Yt#}B*LP{}wxfEYxh(I5C0n80+MQ9-YBOo;R .ant-descriptions { + margin-left: 6px; + } +} + +.ant-image-preview-operations { + background-color: rgb(0 0 0 / 30%); +} + +.ant-popover { + &-content { + box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%); + } +} + +// ================================= +// ==============modal message====== +// ================================= +.modal-icon-warning { + color: @warning-color !important; +} + +.modal-icon-success { + color: @success-color !important; +} + +.modal-icon-error { + color: @error-color !important; +} + +.modal-icon-info { + color: @primary-color !important; +} + +.ant-checkbox-checked .ant-checkbox-inner::after, +.ant-tree-checkbox-checked .ant-tree-checkbox-inner::after { + border-top: 0 !important; + border-left: 0 !important; +} + +.ant-form-item-control-input-content { + > div { + > div { + max-width: 100%; + } + } +} diff --git a/src/design/ant/input.less b/src/design/ant/input.less new file mode 100644 index 0000000..8245fb7 --- /dev/null +++ b/src/design/ant/input.less @@ -0,0 +1,27 @@ +@import (reference) '../color.less'; + +// input +.ant-input { + &-number, + &-number-group-wrapper { + width: 100% !important; + min-width: 110px; + max-width: 100%; + } +} + +.ant-input-affix-wrapper .ant-input-suffix { + right: 9px; +} + +.ant-input-clear-icon { + margin-right: 5px; +} + +.ant-input-affix-wrapper-textarea-with-clear-btn { + padding: 0 !important; + + textarea.ant-input { + padding: 4px; + } +} diff --git a/src/design/ant/pagination.less b/src/design/ant/pagination.less new file mode 100644 index 0000000..0fb6711 --- /dev/null +++ b/src/design/ant/pagination.less @@ -0,0 +1,96 @@ +html[data-theme='dark'] { + .ant-pagination { + &.mini { + .ant-pagination-prev, + .ant-pagination-next, + .ant-pagination-item { + background-color: rgb(255 255 255 / 4%) !important; + + a { + color: #8b949e !important; + } + } + + .ant-select-arrow { + color: @text-color-secondary !important; + } + + .ant-pagination-item-active { + border: none; + border-radius: none !important; + background-color: @primary-color !important; + + a { + color: @white !important; + } + } + } + } +} + +.ant-pagination { + &.mini { + .ant-pagination-prev, + .ant-pagination-next { + border: 1px solid; + color: @text-color-base; + font-size: 12px; + } + + .ant-pagination-prev:hover, + .ant-pagination-next:hover, + .ant-pagination-item:focus, + .ant-pagination-item:hover { + a { + color: @primary-color; + } + } + + .ant-pagination-prev, + .ant-pagination-next, + .ant-pagination-item { + margin: 0 4px !important; + border: none; + border-radius: none !important; + background-color: #f4f4f5 !important; + + a { + margin-top: 1px; + color: #606266; + } + + &:last-child { + margin-right: 0 !important; + } + } + + .ant-pagination-item-active { + border: none; + border-radius: none !important; + background-color: @primary-color !important; + + a { + color: @white !important; + } + } + + .ant-pagination-options { + margin-left: 12px; + } + + .ant-pagination-options-quick-jumper input { + height: 22px; + margin: 0 6px; + line-height: 22px; + text-align: center; + } + + .ant-select-arrow { + color: @border-color-shallow-dark; + } + } + + &-disabled { + display: none !important; + } +} diff --git a/src/design/ant/table.less b/src/design/ant/table.less new file mode 100644 index 0000000..fd50da7 --- /dev/null +++ b/src/design/ant/table.less @@ -0,0 +1,72 @@ +@prefix-cls: ~'@{namespace}-basic-table'; + +// fix table unnecessary scrollbar +.@{prefix-cls} { + .hide-scrollbar-y { + .ant-spin-nested-loading { + .ant-spin-container { + .ant-table { + .ant-table-content { + .ant-table-scroll { + .ant-table-hide-scrollbar { + overflow-y: auto !important; + } + + .ant-table-body { + overflow-y: auto !important; + } + } + + .ant-table-fixed-right { + .ant-table-body-outer { + .ant-table-body-inner { + overflow-y: auto !important; + } + } + } + + .ant-table-fixed-left { + .ant-table-body-outer { + .ant-table-body-inner { + overflow-y: auto !important; + } + } + } + } + } + } + } + } + + .hide-scrollbar-x { + .ant-spin-nested-loading { + .ant-spin-container { + .ant-table { + .ant-table-content { + .ant-table-scroll { + .ant-table-body { + overflow: auto !important; + } + } + + .ant-table-fixed-right { + .ant-table-body-outer { + .ant-table-body-inner { + overflow-x: auto !important; + } + } + } + + .ant-table-fixed-left { + .ant-table-body-outer { + .ant-table-body-inner { + overflow-x: auto !important; + } + } + } + } + } + } + } + } +} diff --git a/src/design/color.less b/src/design/color.less new file mode 100644 index 0000000..bd17e18 --- /dev/null +++ b/src/design/color.less @@ -0,0 +1,160 @@ +html { + // text + --text-color: rgb(0 0 0 85%); + + // border + --border-color: #eee; + + // header + --header-bg-color: #394664; + --header-bg-hover-color: #273352; + --header-active-menu-bg-color: #273352; + + // sider + --sider-dark-bg-color: #273352; + --sider-dark-darken-bg-color: #273352; + --sider-dark-lighten-bg-color: #273352; + + // component + --component-background-color: #fff; + + // app + --app-content-background-color: #fafafa; +} + +@white: #fff; + +@content-bg: #f4f7f9; + +@border-color-base: var(--border-color); + +@text-color-secondary: #8b949e; + +@component-background: var(--component-background-color); + +// :export { +// name: "less"; +// mainColor: @mainColor; +// fontSize: @fontSize; +// } +@iconify-bg-color: #5551; + +// ================================= +// ==============border-color======= +// ================================= + +// Dark-dark +@border-color-dark: #b6b7b9; + +// Dark-light +@border-color-shallow-dark: #cececd; + +// Light-dark +@border-color-light: @border-color-base; + +// ================================= +// ==============message============== +// ================================= + +// success-bg-color +@success-background-color: #f1f9ec; +// info-bg-color +@info-background-color: #e8eff8; +// warn-bg-color +@warning-background-color: #fdf6ed; +// danger-bg-color +@danger-background-color: #fef0f0; + +// ================================= +// ==============Header============= +// ================================= +@header-dark-bg-color: var(--header-bg-color); +@header-dark-bg-hover-color: var(--header-bg-hover-color); +@header-light-bg-hover-color: #f6f6f6; +@header-light-desc-color: #7c8087; +@header-light-bottom-border-color: #eee; +// top-menu +@top-menu-active-bg-color: var(--header-active-menu-bg-color); + +// ================================= +// ==============Menu============ +// ================================= + +// let -menu +@sider-dark-bg-color: var(--sider-dark-bg-color); +@sider-dark-darken-bg-color: var(--sider-dark-darken-bg-color); +@sider-dark-lighten-bg-color: var(--sider-dark-lighten-bg-color); + +// trigger +@trigger-dark-hover-bg-color: rgba(255, 255, 255, 0.2); +@trigger-dark-bg-color: rgba(255, 255, 255, 0.1); + +// ================================= +// ==============tree============ +// ================================= +// tree item hover background +@tree-hover-background-color: #f5f7fa; +// tree item hover font color +@tree-hover-font-color: #f5f7fa; + +// ================================= +// ==============link============ +// ================================= +@link-hover-color: @primary-color; +@link-active-color: darken(@primary-color, 10%); + +// ================================= +// ==============Text color-============= +// ================================= + +// Main text color +@text-color-base: var(--text-color); + +// ================================= +// ==============app content color-============= +// ================================= +@app-content-background: var(--app-content-background-color); + +// Label color +@text-color-call-out: #606266; + +// Auxiliary information color-dark +@text-color-help-dark: #909399; + +// ================================= +// ==============breadcrumb========= +// ================================= +@breadcrumb-item-normal-color: #999; +// ================================= +// ==============button============= +// ================================= + +@button-primary-color: @primary-color; +@button-primary-hover-color: lighten(@primary-color, 5%); +@button-primary-active-color: darken(@primary-color, 5%); + +@button-ghost-color: @white; +@button-ghost-hover-color: lighten(@white, 10%); +@button-ghost-hover-bg-color: #e1ebf6; +@button-ghost-active-color: darken(@white, 10%); + +@button-success-color: @success-color; +@button-success-hover-color: lighten(@success-color, 10%); +@button-success-active-color: darken(@success-color, 10%); + +@button-warn-color: @warning-color; +@button-warn-hover-color: lighten(@warning-color, 10%); +@button-warn-active-color: darken(@warning-color, 10%); + +@button-error-color: @error-color; +@button-error-hover-color: lighten(@error-color, 10%); +@button-error-active-color: darken(@error-color, 10%); + +@button-cancel-color: @text-color-call-out; +@button-cancel-bg-color: @white; +@button-cancel-border-color: @border-color-shallow-dark; + +// Mouse over +@button-cancel-hover-color: @primary-color; +@button-cancel-hover-bg-color: @white; +@button-cancel-hover-border-color: @primary-color; diff --git a/src/design/config.less b/src/design/config.less new file mode 100644 index 0000000..64c33f6 --- /dev/null +++ b/src/design/config.less @@ -0,0 +1,2 @@ +@import (reference) 'color.less'; +@import (reference) 'var/index.less'; diff --git a/src/design/dark.less b/src/design/dark.less new file mode 100644 index 0000000..1c66c8e --- /dev/null +++ b/src/design/dark.less @@ -0,0 +1,110 @@ +[data-theme='dark'] { + body { + background-color: #000; + color: @text-color-base; + } + + .ant-btn { + &[disabled], + &[disabled]:hover, + &[disabled]:focus, + &[disabled]:active { + border-color: #303030; + background: rgb(255 255 255 / 8%); + color: rgb(255 255 255 / 30%); + } + + &-success.ant-btn-link.ant-btn-loading, + &-warning.ant-btn-link.ant-btn-loading, + &-error.ant-btn-link.ant-btn-loading, + &-background-ghost.ant-btn-link.ant-btn-loading, + &.ant-btn-link.ant-btn-loading { + &::before { + background: transparent; + } + } + + &:not( + .ant-btn-link, + .is-disabled, + .ant-btn-primary, + .ant-btn-success, + .ant-btn-warning, + .ant-btn-error, + .ant-btn-dangerous + ) { + background: transparent; + color: @text-color-base; + + &:hover { + color: @button-primary-hover-color; + } + } + + &-dangerous.ant-btn-primary { + &:focus { + background: @error-color !important; + } + } + + &-default.ant-btn-dangerous { + border-color: @error-color; + background: transparent !important; + color: @error-color; + + &:hover, + &:focus { + border-color: @button-error-hover-color !important; + color: @button-error-hover-color !important; + } + } + + &-default:not(.ant-btn-background-ghost) { + border-color: #303030; + + &:hover, + &:focus { + border-color: @button-cancel-hover-color; + color: @button-cancel-hover-color; + } + } + + &-default.is-disabled { + &:hover, + &:focus { + border-color: #303030; + color: rgb(255 255 255 / 30%); + } + } + + &-success:not(.is-disabled, .ant-btn-link, .ant-btn-background-ghost) { + &:hover, + &:focus, + &:active { + border-color: @button-success-active-color !important; + background-color: @button-success-active-color !important; + color: @white !important; + } + } + + &-warning:not(.is-disabled, .ant-btn-link, .ant-btn-background-ghost) { + &:hover, + &:focus, + &:active { + border-color: @button-warn-active-color !important; + background-color: @button-warn-active-color !important; + color: @white !important; + } + } + + &-error:not(.is-disabled, .ant-btn-link, .ant-btn-background-ghost) { + &:hover, + &:focus, + &:active { + border-color: @button-error-active-color !important; + background-color: @button-error-active-color !important; + color: @white !important; + } + } + } +} diff --git a/src/design/entry.css b/src/design/entry.css new file mode 100644 index 0000000..1d40f5d --- /dev/null +++ b/src/design/entry.css @@ -0,0 +1,168 @@ +* > .enter-x:nth-child(1) { + transform: translateX(50px); +} +* > .-enter-x:nth-child(1) { + transform: translateX(-50px); +} + +* > .enter-x:nth-child(1), +* > .-enter-x:nth-child(1) { + z-index: 9; + opacity: 0; + animation: enter-x-animation 0.4s ease-in-out 0.3s; + animation-fill-mode: forwards; + animation-delay: 0.1s; +} +* > .enter-x:nth-child(2) { + transform: translateX(50px); +} +* > .-enter-x:nth-child(2) { + transform: translateX(-50px); +} + +* > .enter-x:nth-child(2), +* > .-enter-x:nth-child(2) { + z-index: 8; + opacity: 0; + animation: enter-x-animation 0.4s ease-in-out 0.3s; + animation-fill-mode: forwards; + animation-delay: 0.2s; +} +* > .enter-x:nth-child(3) { + transform: translateX(50px); +} +* > .-enter-x:nth-child(3) { + transform: translateX(-50px); +} + +* > .enter-x:nth-child(3), +* > .-enter-x:nth-child(3) { + z-index: 7; + opacity: 0; + animation: enter-x-animation 0.4s ease-in-out 0.3s; + animation-fill-mode: forwards; + animation-delay: 0.3s; +} + +* > .enter-x:nth-child(4) { + transform: translateX(50px); +} +* > .-enter-x:nth-child(4) { + transform: translateX(-50px); +} + +* > .enter-x:nth-child(4), +* > .-enter-x:nth-child(4) { + z-index: 6; + opacity: 0; + animation: enter-x-animation 0.4s ease-in-out 0.3s; + animation-fill-mode: forwards; + animation-delay: 0.4s; +} + +* > .enter-x:nth-child(5) { + transform: translateX(50px); +} +* > .-enter-x:nth-child(5) { + transform: translateX(-50px); +} + +* > .enter-x:nth-child(5), +* > .-enter-x:nth-child(5) { + z-index: 5; + opacity: 0; + animation: enter-x-animation 0.4s ease-in-out 0.3s; + animation-fill-mode: forwards; + animation-delay: 0.5s; +} + +* > .enter-y:nth-child(1) { + transform: translateX(50px); +} +* > .-enter-y:nth-child(1) { + transform: translateX(-50px); +} + +* > .enter-y:nth-child(1), +* > .-enter-y:nth-child(1) { + z-index: 9; + opacity: 0; + animation: enter-y-animation 0.4s ease-in-out 0.3s; + animation-fill-mode: forwards; + animation-delay: 0.1s; +} +* > .enter-y:nth-child(2) { + transform: translateX(50px); +} +* > .-enter-y:nth-child(2) { + transform: translateX(-50px); +} + +* > .enter-y:nth-child(2), +* > .-enter-y:nth-child(2) { + z-index: 8; + opacity: 0; + animation: enter-y-animation 0.4s ease-in-out 0.3s; + animation-fill-mode: forwards; + animation-delay: 0.2s; +} +* > .enter-y:nth-child(3) { + transform: translateX(50px); +} +* > .-enter-y:nth-child(3) { + transform: translateX(-50px); +} + +* > .enter-y:nth-child(3), +* > .-enter-y:nth-child(3) { + z-index: 7; + opacity: 0; + animation: enter-y-animation 0.4s ease-in-out 0.3s; + animation-fill-mode: forwards; + animation-delay: 0.3s; +} + +* > .enter-y:nth-child(4) { + transform: translateX(50px); +} +* > .-enter-y:nth-child(4) { + transform: translateX(-50px); +} + +* > .enter-y:nth-child(4), +* > .-enter-y:nth-child(4) { + z-index: 6; + opacity: 0; + animation: enter-y-animation 0.4s ease-in-out 0.3s; + animation-fill-mode: forwards; + animation-delay: 0.4s; +} + +* > .enter-y:nth-child(5) { + transform: translateX(50px); +} +* > .-enter-y:nth-child(5) { + transform: translateX(-50px); +} + +* > .enter-y:nth-child(5), +* > .-enter-y:nth-child(5) { + z-index: 5; + opacity: 0; + animation: enter-y-animation 0.4s ease-in-out 0.3s; + animation-fill-mode: forwards; + animation-delay: 0.5s; +} + +@keyframes enter-x-animation { + to { + opacity: 1; + transform: translateX(0); + } +} +@keyframes enter-y-animation { + to { + opacity: 1; + transform: translateY(0); + } +} diff --git a/src/design/index.less b/src/design/index.less new file mode 100644 index 0000000..65307eb --- /dev/null +++ b/src/design/index.less @@ -0,0 +1,54 @@ +@import 'transition/index.less'; +@import 'var/index.less'; +@import 'public.less'; +@import 'ant/index.less'; +@import './theme.less'; +@import './entry.css'; +@import './dark.less'; + +input:-webkit-autofill { + box-shadow: 0 0 0 1000px white inset !important; +} + +:-webkit-autofill { + transition: background-color 5000s ease-in-out 0s !important; +} + +html { + overflow: hidden; + text-size-adjust: 100%; +} + +html, +body { + position: relative; + width: 100%; + height: 100%; + overflow: visible; + overflow-x: hidden; + + &.color-weak { + filter: invert(80%); + } + + &.gray-mode { + filter: grayscale(100%); + filter: progid:dximagetransform.microsoft.basicimage(grayscale=1); + } +} + +a:focus, +a:active, +button, +div, +svg, +span { + outline: none; +} + +// 保持 和 windi 一样的全局样式,减少升级带来的影响 +ul { + margin: 0; + padding: 0; + list-style: none; +} diff --git a/src/design/public.less b/src/design/public.less new file mode 100644 index 0000000..b8b3991 --- /dev/null +++ b/src/design/public.less @@ -0,0 +1,51 @@ +#app { + width: 100%; + height: 100%; +} + +// ================================= +// ==============scrollbar========== +// ================================= + +::-webkit-scrollbar { + width: 7px; + height: 8px; +} + +// ::-webkit-scrollbar-track { +// background: transparent; +// } + +::-webkit-scrollbar-track { + background-color: rgb(0 0 0 / 5%); +} + +::-webkit-scrollbar-thumb { + // background-color: rgba(144, 147, 153, 0.3); + border-radius: 2px; + // background: rgba(0, 0, 0, 0.6); + background-color: rgb(144 147 153 / 30%); + box-shadow: inset 0 0 6px rgb(0 0 0 / 20%); +} + +::-webkit-scrollbar-thumb:hover { + background-color: @border-color-dark; +} + +// ================================= +// ==============nprogress========== +// ================================= +#nprogress { + pointer-events: none; + + .bar { + position: fixed; + z-index: 99999; + top: 0; + left: 0; + width: 100%; + height: 2px; + opacity: 0.75; + background-color: @primary-color; + } +} diff --git a/src/design/theme.less b/src/design/theme.less new file mode 100644 index 0000000..22a139e --- /dev/null +++ b/src/design/theme.less @@ -0,0 +1,28 @@ +.bg-white { + background-color: @component-background !important; +} + +html[data-theme='light'] { + .text-secondary { + color: rgb(0 0 0 / 45%); + } + + .ant-alert-success { + border: 1px solid #b7eb8f; + background-color: #f6ffed; + } + + .ant-alert-error { + border: 1px solid #ffccc7; + background-color: #fff2f0; + } + + .ant-alert-warning { + border: 1px solid #ffe58f; + background-color: #fffbe6; + } + + :not(:root):fullscreen::backdrop { + background-color: @layout-body-background !important; + } +} diff --git a/src/design/transition/base.less b/src/design/transition/base.less new file mode 100644 index 0000000..7944c8b --- /dev/null +++ b/src/design/transition/base.less @@ -0,0 +1,18 @@ +.transition-default() { + &-enter-active, + &-leave-active { + transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1) !important; + } + + &-move { + transition: transform 0.4s; + } +} + +.expand-transition { + .transition-default(); +} + +.expand-x-transition { + .transition-default(); +} diff --git a/src/design/transition/fade.less b/src/design/transition/fade.less new file mode 100644 index 0000000..2df4c7f --- /dev/null +++ b/src/design/transition/fade.less @@ -0,0 +1,93 @@ +.fade-transition { + &-enter-active, + &-leave-active { + transition: opacity 0.2s ease-in-out; + } + + &-enter-from, + &-leave-to { + opacity: 0; + } +} + +.fade-enter-active, +.fade-leave-active { + transition: opacity 0.2s ease-in-out; +} + +.fade-enter-from, +.fade-leave-to { + opacity: 0; +} + +/* fade-slide */ +.fade-slide-leave-active, +.fade-slide-enter-active { + transition: all 0.3s; +} + +.fade-slide-enter-from { + transform: translateX(-30px); + opacity: 0; +} + +.fade-slide-leave-to { + transform: translateX(30px); + opacity: 0; +} + +// /////////////////////////////////////////////// +// Fade Bottom +// /////////////////////////////////////////////// + +// Speed: 1x +.fade-bottom-enter-active, +.fade-bottom-leave-active { + transition: opacity 0.25s, transform 0.3s; +} + +.fade-bottom-enter-from { + transform: translateY(-10%); + opacity: 0; +} + +.fade-bottom-leave-to { + transform: translateY(10%); + opacity: 0; +} + +// fade-scale +.fade-scale-leave-active, +.fade-scale-enter-active { + transition: all 0.28s; +} + +.fade-scale-enter-from { + transform: scale(1.2); + opacity: 0; +} + +.fade-scale-leave-to { + transform: scale(0.8); + opacity: 0; +} + +// /////////////////////////////////////////////// +// Fade Top +// /////////////////////////////////////////////// + +// Speed: 1x +.fade-top-enter-active, +.fade-top-leave-active { + transition: opacity 0.2s, transform 0.25s; +} + +.fade-top-enter-from { + transform: translateY(8%); + opacity: 0; +} + +.fade-top-leave-to { + transform: translateY(-8%); + opacity: 0; +} diff --git a/src/design/transition/index.less b/src/design/transition/index.less new file mode 100644 index 0000000..e372b25 --- /dev/null +++ b/src/design/transition/index.less @@ -0,0 +1,10 @@ +@import './base.less'; +@import './fade.less'; +@import './scale.less'; +@import './slide.less'; +@import './scroll.less'; +@import './zoom.less'; + +.collapse-transition { + transition: 0.2s height ease-in-out, 0.2s padding-top ease-in-out, 0.2s padding-bottom ease-in-out; +} diff --git a/src/design/transition/scale.less b/src/design/transition/scale.less new file mode 100644 index 0000000..521fce3 --- /dev/null +++ b/src/design/transition/scale.less @@ -0,0 +1,21 @@ +.scale-transition { + .transition-default(); + + &-enter-from, + &-leave, + &-leave-to { + transform: scale(0); + opacity: 0; + } +} + +.scale-rotate-transition { + .transition-default(); + + &-enter-from, + &-leave, + &-leave-to { + transform: scale(0) rotate(-45deg); + opacity: 0; + } +} diff --git a/src/design/transition/scroll.less b/src/design/transition/scroll.less new file mode 100644 index 0000000..a5f45e4 --- /dev/null +++ b/src/design/transition/scroll.less @@ -0,0 +1,67 @@ +.scroll-y-transition { + .transition-default(); + + &-enter-from, + &-leave-to { + opacity: 0; + } + + &-enter-from { + transform: translateY(-15px); + } + + &-leave-to { + transform: translateY(15px); + } +} + +.scroll-y-reverse-transition { + .transition-default(); + + &-enter-from, + &-leave-to { + opacity: 0; + } + + &-enter-from { + transform: translateY(15px); + } + + &-leave-to { + transform: translateY(-15px); + } +} + +.scroll-x-transition { + .transition-default(); + + &-enter-from, + &-leave-to { + opacity: 0; + } + + &-enter-from { + transform: translateX(-15px); + } + + &-leave-to { + transform: translateX(15px); + } +} + +.scroll-x-reverse-transition { + .transition-default(); + + &-enter-from, + &-leave-to { + opacity: 0; + } + + &-enter-from { + transform: translateX(15px); + } + + &-leave-to { + transform: translateX(-15px); + } +} diff --git a/src/design/transition/slide.less b/src/design/transition/slide.less new file mode 100644 index 0000000..fe1be22 --- /dev/null +++ b/src/design/transition/slide.less @@ -0,0 +1,39 @@ +.slide-y-transition { + .transition-default(); + + &-enter-from, + &-leave-to { + transform: translateY(-15px); + opacity: 0; + } +} + +.slide-y-reverse-transition { + .transition-default(); + + &-enter-from, + &-leave-to { + transform: translateY(15px); + opacity: 0; + } +} + +.slide-x-transition { + .transition-default(); + + &-enter-from, + &-leave-to { + transform: translateX(-15px); + opacity: 0; + } +} + +.slide-x-reverse-transition { + .transition-default(); + + &-enter-from, + &-leave-to { + transform: translateX(15px); + opacity: 0; + } +} diff --git a/src/design/transition/zoom.less b/src/design/transition/zoom.less new file mode 100644 index 0000000..2cfdada --- /dev/null +++ b/src/design/transition/zoom.less @@ -0,0 +1,27 @@ +// zoom-out +.zoom-out-enter-active, +.zoom-out-leave-active { + transition: opacity 0.1 ease-in-out, transform 0.15s ease-out; +} + +.zoom-out-enter-from, +.zoom-out-leave-to { + transform: scale(0); + opacity: 0; +} + +// zoom-fade +.zoom-fade-enter-active, +.zoom-fade-leave-active { + transition: transform 0.2s, opacity 0.3s ease-out; +} + +.zoom-fade-enter-from { + transform: scale(0.92); + opacity: 0; +} + +.zoom-fade-leave-to { + transform: scale(1.06); + opacity: 0; +} diff --git a/src/design/var/breakpoint.less b/src/design/var/breakpoint.less new file mode 100644 index 0000000..793e826 --- /dev/null +++ b/src/design/var/breakpoint.less @@ -0,0 +1,33 @@ +// ================================= +// ==============屏幕断点============ +// ================================= + +// Extra small screen / phone +@screen-xs: 480px; +@screen-xs-min: @screen-xs; + +// Small screen / tablet +@screen-sm: 576px; +@screen-sm-min: @screen-sm; + +// Medium screen / desktop +@screen-md: 768px; +@screen-md-min: @screen-md; + +// Large screen / wide desktop +@screen-lg: 992px; +@screen-lg-min: @screen-lg; + +// Extra large screen / full hd +@screen-xl: 1200px; +@screen-xl-min: @screen-xl; + +// Extra extra large screen / large desktop +@screen-2xl: 1600px; +@screen-2xl-min: @screen-2xl; + +@screen-xs-max: (@screen-sm-min - 1px); +@screen-sm-max: (@screen-md-min - 1px); +@screen-md-max: (@screen-lg-min - 1px); +@screen-lg-max: (@screen-xl-min - 1px); +@screen-xl-max: (@screen-2xl-min - 1px); diff --git a/src/design/var/easing.less b/src/design/var/easing.less new file mode 100644 index 0000000..e19735f --- /dev/null +++ b/src/design/var/easing.less @@ -0,0 +1,18 @@ +// ================================= +// ==============动画函数-=========== +// ================================= + +@ease-base-out: cubic-bezier(0.7, 0.3, 0.1, 1); +@ease-base-in: cubic-bezier(0.9, 0, 0.3, 0.7); +@ease-out: cubic-bezier(0.215, 0.61, 0.355, 1); +@ease-in: cubic-bezier(0.55, 0.055, 0.675, 0.19); +@ease-in-out: cubic-bezier(0.645, 0.045, 0.355, 1); +@ease-out-back: cubic-bezier(0.12, 0.4, 0.29, 1.46); +@ease-in-back: cubic-bezier(0.71, -0.46, 0.88, 0.6); +@ease-in-out-back: cubic-bezier(0.71, -0.46, 0.29, 1.46); +@ease-out-circ: cubic-bezier(0.08, 0.82, 0.17, 1); +@ease-in-circ: cubic-bezier(0.6, 0.04, 0.98, 0.34); +@ease-in-out-circ: cubic-bezier(0.78, 0.14, 0.15, 0.86); +@ease-out-quint: cubic-bezier(0.23, 1, 0.32, 1); +@ease-in-quint: cubic-bezier(0.755, 0.05, 0.855, 0.06); +@ease-in-out-quint: cubic-bezier(0.86, 0, 0.07, 1); diff --git a/src/design/var/index.less b/src/design/var/index.less new file mode 100644 index 0000000..1689f76 --- /dev/null +++ b/src/design/var/index.less @@ -0,0 +1,39 @@ +@import (reference) '../color.less'; +@import 'easing'; +@import 'breakpoint'; + +@namespace: vben; + +// tabs +@multiple-height: 30px; + +// headers +@header-height: 48px; + +// logo width +@logo-width: 32px; + +// +@side-drag-z-index: 200; + +@page-loading-z-index: 10000; + +@lock-page-z-index: 3000; + +@layout-header-fixed-z-index: 500; + +@multiple-tab-fixed-z-index: 505; + +@layout-sider-fixed-z-index: 510; + +@layout-mix-sider-fixed-z-index: 550; + +@preview-comp-z-index: 1000; + +@page-footer-z-index: 99; + +.bem(@n; @content) { + @{namespace}-@{n} { + @content(); + } +} diff --git a/src/directives/clickOutside.ts b/src/directives/clickOutside.ts new file mode 100644 index 0000000..f6f3051 --- /dev/null +++ b/src/directives/clickOutside.ts @@ -0,0 +1,86 @@ +import { on } from '/@/utils/domUtils'; +import { isServer } from '/@/utils/is'; +import type { ComponentPublicInstance, DirectiveBinding, ObjectDirective } from 'vue'; + +type DocumentHandler = (mouseup: T, mousedown: T) => void; + +type FlushList = Map< + HTMLElement, + { + documentHandler: DocumentHandler; + bindingFn: (...args: unknown[]) => unknown; + } +>; + +const nodeList: FlushList = new Map(); + +let startClick: MouseEvent; + +if (!isServer) { + on(document, 'mousedown', (e: MouseEvent) => (startClick = e)); + on(document, 'mouseup', (e: MouseEvent) => { + for (const { documentHandler } of nodeList.values()) { + documentHandler(e, startClick); + } + }); +} + +function createDocumentHandler(el: HTMLElement, binding: DirectiveBinding): DocumentHandler { + let excludes: HTMLElement[] = []; + if (Array.isArray(binding.arg)) { + excludes = binding.arg; + } else { + // due to current implementation on binding type is wrong the type casting is necessary here + excludes.push(binding.arg as unknown as HTMLElement); + } + return function (mouseup, mousedown) { + const popperRef = ( + binding.instance as ComponentPublicInstance<{ + popperRef: Nullable; + }> + ).popperRef; + const mouseUpTarget = mouseup.target as Node; + const mouseDownTarget = mousedown.target as Node; + const isBound = !binding || !binding.instance; + const isTargetExists = !mouseUpTarget || !mouseDownTarget; + const isContainedByEl = el.contains(mouseUpTarget) || el.contains(mouseDownTarget); + const isSelf = el === mouseUpTarget; + + const isTargetExcluded = + (excludes.length && excludes.some((item) => item?.contains(mouseUpTarget))) || + (excludes.length && excludes.includes(mouseDownTarget as HTMLElement)); + const isContainedByPopper = + popperRef && (popperRef.contains(mouseUpTarget) || popperRef.contains(mouseDownTarget)); + if ( + isBound || + isTargetExists || + isContainedByEl || + isSelf || + isTargetExcluded || + isContainedByPopper + ) { + return; + } + binding.value(); + }; +} + +const ClickOutside: ObjectDirective = { + beforeMount(el, binding) { + nodeList.set(el, { + documentHandler: createDocumentHandler(el, binding), + bindingFn: binding.value, + }); + }, + updated(el, binding) { + nodeList.set(el, { + documentHandler: createDocumentHandler(el, binding), + bindingFn: binding.value, + }); + }, + unmounted(el) { + nodeList.delete(el); + }, +}; + +export default ClickOutside; diff --git a/src/directives/ellipsis.ts b/src/directives/ellipsis.ts new file mode 100644 index 0000000..2370f4e --- /dev/null +++ b/src/directives/ellipsis.ts @@ -0,0 +1,42 @@ +import type { CSSProperties, DirectiveBinding, ObjectDirective, App } from 'vue'; + +interface IValue { + width?: number; + line?: number; +} + +interface IOptions { + [key: string]: CSSProperties; +} + +const cssProperties: IOptions = { + single: { + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }, + multiple: { + display: '-webkit-box', + overflow: 'hidden', + wordBreak: 'break-all', + }, +}; + +const Ellipsis: ObjectDirective = { + mounted(el: HTMLElement, binding: DirectiveBinding>) { + const { value = [100, 1], arg = 'single' } = binding; + const [width, line] = value; + Object.entries(cssProperties[arg]).forEach(([key, value]) => { + el.style[key] = value; + }); + el.style.width = `${width}px`; + if (arg === 'multiple') { + el.style.webkitLineClamp = `${line}`; + el.style.webkitBoxOrient = 'vertical'; + } + }, +}; +export function setupEllipsisDirective(app: App) { + app.directive('ellipsis', Ellipsis); +} +export default Ellipsis; diff --git a/src/directives/index.ts b/src/directives/index.ts new file mode 100644 index 0000000..ad58631 --- /dev/null +++ b/src/directives/index.ts @@ -0,0 +1,13 @@ +/** + * Configure and register global directives + */ +import type { App } from 'vue'; +import { setupPermissionDirective } from './permission'; +import { setupLoadingDirective } from './loading'; +import { setupEllipsisDirective } from './ellipsis'; + +export function setupGlobDirectives(app: App) { + setupPermissionDirective(app); + setupLoadingDirective(app); + setupEllipsisDirective(app); +} diff --git a/src/directives/loading.ts b/src/directives/loading.ts new file mode 100644 index 0000000..712b71c --- /dev/null +++ b/src/directives/loading.ts @@ -0,0 +1,39 @@ +import { createLoading } from '/@/components/Loading'; +import type { Directive, App } from 'vue'; + +const loadingDirective: Directive = { + mounted(el, binding) { + const tip = el.getAttribute('loading-tip'); + const background = el.getAttribute('loading-background'); + const size = el.getAttribute('loading-size'); + const fullscreen = !!binding.modifiers.fullscreen; + const instance = createLoading( + { + tip, + background, + size: size || 'large', + loading: !!binding.value, + absolute: !fullscreen, + }, + fullscreen ? document.body : el, + ); + el.instance = instance; + }, + updated(el, binding) { + const instance = el.instance; + if (!instance) return; + instance.setTip(el.getAttribute('loading-tip')); + if (binding.oldValue !== binding.value) { + instance.setLoading?.(binding.value && !instance.loading); + } + }, + unmounted(el) { + el?.instance?.close(); + }, +}; + +export function setupLoadingDirective(app: App) { + app.directive('loading', loadingDirective); +} + +export default loadingDirective; diff --git a/src/directives/permission.ts b/src/directives/permission.ts new file mode 100644 index 0000000..ca5d0fc --- /dev/null +++ b/src/directives/permission.ts @@ -0,0 +1,32 @@ +/** + * Global authority directive + * Used for fine-grained control of component permissions + * @Example v-auth="RoleEnum.TEST" + */ +import type { App, Directive, DirectiveBinding } from 'vue'; + +import { usePermission } from '/@/hooks/web/usePermission'; + +function isAuth(el: Element, binding: any) { + const { hasPermission } = usePermission(); + + const value = binding.value; + if (!value) return; + if (!hasPermission(value)) { + el.parentNode?.removeChild(el); + } +} + +const mounted = (el: Element, binding: DirectiveBinding) => { + isAuth(el, binding); +}; + +const authDirective: Directive = { + mounted, +}; + +export function setupPermissionDirective(app: App) { + app.directive('auth', authDirective); +} + +export default authDirective; diff --git a/src/directives/ripple/index.less b/src/directives/ripple/index.less new file mode 100644 index 0000000..70a1c3f --- /dev/null +++ b/src/directives/ripple/index.less @@ -0,0 +1,21 @@ +.ripple-container { + position: absolute; + top: 0; + left: 0; + width: 0; + height: 0; + overflow: hidden; + pointer-events: none; +} + +.ripple-effect { + position: relative; + z-index: 9999; + width: 1px; + height: 1px; + margin-top: 0; + margin-left: 0; + transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1); + border-radius: 50%; + pointer-events: none; +} diff --git a/src/directives/ripple/index.ts b/src/directives/ripple/index.ts new file mode 100644 index 0000000..3da8014 --- /dev/null +++ b/src/directives/ripple/index.ts @@ -0,0 +1,192 @@ +import type { Directive } from 'vue'; +import './index.less'; + +export interface RippleOptions { + event: string; + transition: number; +} + +export interface RippleProto { + background?: string; + zIndex?: string; +} + +export type EventType = Event & MouseEvent & TouchEvent; + +const options: RippleOptions = { + event: 'mousedown', + transition: 400, +}; + +const RippleDirective: Directive & RippleProto = { + beforeMount: (el: HTMLElement, binding) => { + if (binding.value === false) return; + + const bg = el.getAttribute('ripple-background'); + setProps(Object.keys(binding.modifiers), options); + + const background = bg || RippleDirective.background; + const zIndex = RippleDirective.zIndex; + + el.addEventListener(options.event, (event: EventType) => { + rippler({ + event, + el, + background, + zIndex, + }); + }); + }, + updated(el, binding) { + if (!binding.value) { + el?.clearRipple?.(); + return; + } + const bg = el.getAttribute('ripple-background'); + el?.setBackground?.(bg); + }, +}; + +function rippler({ + event, + el, + zIndex, + background, +}: { event: EventType; el: HTMLElement } & RippleProto) { + const targetBorder = parseInt(getComputedStyle(el).borderWidth.replace('px', '')); + const clientX = event.clientX || event.touches[0].clientX; + const clientY = event.clientY || event.touches[0].clientY; + + const rect = el.getBoundingClientRect(); + const { left, top } = rect; + const { offsetWidth: width, offsetHeight: height } = el; + const { transition } = options; + const dx = clientX - left; + const dy = clientY - top; + const maxX = Math.max(dx, width - dx); + const maxY = Math.max(dy, height - dy); + const style = window.getComputedStyle(el); + const radius = Math.sqrt(maxX * maxX + maxY * maxY); + const border = targetBorder > 0 ? targetBorder : 0; + + const ripple = document.createElement('div'); + const rippleContainer = document.createElement('div'); + + // Styles for ripple + ripple.className = 'ripple'; + + Object.assign(ripple.style ?? {}, { + marginTop: '0px', + marginLeft: '0px', + width: '1px', + height: '1px', + transition: `all ${transition}ms cubic-bezier(0.4, 0, 0.2, 1)`, + borderRadius: '50%', + pointerEvents: 'none', + position: 'relative', + zIndex: zIndex ?? '9999', + backgroundColor: background ?? 'rgba(0, 0, 0, 0.12)', + }); + + // Styles for rippleContainer + rippleContainer.className = 'ripple-container'; + Object.assign(rippleContainer.style ?? {}, { + position: 'absolute', + left: `${0 - border}px`, + top: `${0 - border}px`, + height: '0', + width: '0', + pointerEvents: 'none', + overflow: 'hidden', + }); + + const storedTargetPosition = + el.style.position.length > 0 ? el.style.position : getComputedStyle(el).position; + + if (storedTargetPosition !== 'relative') { + el.style.position = 'relative'; + } + + rippleContainer.appendChild(ripple); + el.appendChild(rippleContainer); + + Object.assign(ripple.style, { + marginTop: `${dy}px`, + marginLeft: `${dx}px`, + }); + + const { + borderTopLeftRadius, + borderTopRightRadius, + borderBottomLeftRadius, + borderBottomRightRadius, + } = style; + Object.assign(rippleContainer.style, { + width: `${width}px`, + height: `${height}px`, + direction: 'ltr', + borderTopLeftRadius, + borderTopRightRadius, + borderBottomLeftRadius, + borderBottomRightRadius, + }); + + setTimeout(() => { + const wh = `${radius * 2}px`; + Object.assign(ripple.style ?? {}, { + width: wh, + height: wh, + marginLeft: `${dx - radius}px`, + marginTop: `${dy - radius}px`, + }); + }, 0); + + function clearRipple() { + setTimeout(() => { + ripple.style.backgroundColor = 'rgba(0, 0, 0, 0)'; + }, 250); + + setTimeout(() => { + rippleContainer?.parentNode?.removeChild(rippleContainer); + }, 850); + el.removeEventListener('mouseup', clearRipple, false); + el.removeEventListener('mouseleave', clearRipple, false); + el.removeEventListener('dragstart', clearRipple, false); + setTimeout(() => { + let clearPosition = true; + for (let i = 0; i < el.childNodes.length; i++) { + if ((el.childNodes[i] as Recordable).className === 'ripple-container') { + clearPosition = false; + } + } + + if (clearPosition) { + el.style.position = storedTargetPosition !== 'static' ? storedTargetPosition : ''; + } + }, options.transition + 260); + } + + if (event.type === 'mousedown') { + el.addEventListener('mouseup', clearRipple, false); + el.addEventListener('mouseleave', clearRipple, false); + el.addEventListener('dragstart', clearRipple, false); + } else { + clearRipple(); + } + + (el as Recordable).setBackground = (bgColor: string) => { + if (!bgColor) { + return; + } + ripple.style.backgroundColor = bgColor; + }; +} + +function setProps(modifiers: Recordable, props: Recordable) { + modifiers.forEach((item: Recordable) => { + if (isNaN(Number(item))) props.event = item; + else props.transition = item; + }); +} + +export default RippleDirective; diff --git a/src/enums/appEnum.ts b/src/enums/appEnum.ts new file mode 100644 index 0000000..def8027 --- /dev/null +++ b/src/enums/appEnum.ts @@ -0,0 +1,56 @@ +export const SIDE_BAR_MINI_WIDTH = 48; +export const SIDE_BAR_SHOW_TIT_MINI_WIDTH = 80; + +export enum ContentEnum { + // auto width + FULL = 'full', + // fixed width + FIXED = 'fixed', +} + +// menu theme enum +export enum ThemeEnum { + DARK = 'dark', + LIGHT = 'light', +} + +export enum SettingButtonPositionEnum { + AUTO = 'auto', + HEADER = 'header', + FIXED = 'fixed', +} + +export enum SessionTimeoutProcessingEnum { + ROUTE_JUMP, + PAGE_COVERAGE, +} + +/** + * 权限模式 + */ +export enum PermissionModeEnum { + // role + // 角色权限 + ROLE = 'ROLE', + // black + // 后端 + BACK = 'BACK', + // route mapping + // 路由映射 + ROUTE_MAPPING = 'ROUTE_MAPPING', +} + +// Route switching animation +// 路由切换动画 +export enum RouterTransitionEnum { + ZOOM_FADE = 'zoom-fade', + ZOOM_OUT = 'zoom-out', + FADE_SIDE = 'fade-slide', + FADE = 'fade', + FADE_BOTTOM = 'fade-bottom', + FADE_SCALE = 'fade-scale', +} + +export enum ParentIdEnum { + DEFAULT = 0, +} \ No newline at end of file diff --git a/src/enums/breakpointEnum.ts b/src/enums/breakpointEnum.ts new file mode 100644 index 0000000..93acc1a --- /dev/null +++ b/src/enums/breakpointEnum.ts @@ -0,0 +1,28 @@ +export enum sizeEnum { + XS = 'XS', + SM = 'SM', + MD = 'MD', + LG = 'LG', + XL = 'XL', + XXL = 'XXL', +} + +export enum screenEnum { + XS = 480, + SM = 576, + MD = 768, + LG = 992, + XL = 1200, + XXL = 1600, +} + +const screenMap = new Map(); + +screenMap.set(sizeEnum.XS, screenEnum.XS); +screenMap.set(sizeEnum.SM, screenEnum.SM); +screenMap.set(sizeEnum.MD, screenEnum.MD); +screenMap.set(sizeEnum.LG, screenEnum.LG); +screenMap.set(sizeEnum.XL, screenEnum.XL); +screenMap.set(sizeEnum.XXL, screenEnum.XXL); + +export { screenMap }; diff --git a/src/enums/cacheEnum.ts b/src/enums/cacheEnum.ts new file mode 100644 index 0000000..7cfe28f --- /dev/null +++ b/src/enums/cacheEnum.ts @@ -0,0 +1,33 @@ +// token key +export const TOKEN_KEY = 'TOKEN__'; + +export const LOCALE_KEY = 'LOCALE__'; + +// user info key +export const USER_INFO_KEY = 'USER__INFO__'; + +// role info key +export const ROLES_KEY = 'ROLES__KEY__'; + +// project config key +export const PROJ_CFG_KEY = 'PROJ__CFG__KEY__'; + +export const ROLES_NAME_KEY = 'ROLES__NAME__KEY__'; + +// lock info +export const LOCK_INFO_KEY = 'LOCK__INFO__KEY__'; + +export const MULTIPLE_TABS_KEY = 'MULTIPLE_TABS__KEY__'; + +export const APP_DARK_MODE_KEY = '__APP__DARK__MODE__'; + +// base global local key +export const APP_LOCAL_CACHE_KEY = 'COMMON__LOCAL__KEY__'; + +// base global session key +export const APP_SESSION_CACHE_KEY = 'COMMON__SESSION__KEY__'; + +export enum CacheTypeEnum { + SESSION, + LOCAL, +} diff --git a/src/enums/exceptionEnum.ts b/src/enums/exceptionEnum.ts new file mode 100644 index 0000000..d28f4d0 --- /dev/null +++ b/src/enums/exceptionEnum.ts @@ -0,0 +1,27 @@ +/** + * @description: Exception related enumeration + */ +export enum ExceptionEnum { + // page not access + PAGE_NOT_ACCESS = 403, + + // page not found + PAGE_NOT_FOUND = 404, + + // error + ERROR = 500, + + // net work error + NET_WORK_ERROR = 10000, + + // No data on the page. In fact, it is not an exception page + PAGE_NOT_DATA = 10100, +} + +export enum ErrorTypeEnum { + VUE = 'vue', + SCRIPT = 'script', + RESOURCE = 'resource', + AJAX = 'ajax', + PROMISE = 'promise', +} diff --git a/src/enums/httpEnum.ts b/src/enums/httpEnum.ts new file mode 100644 index 0000000..e1fbd69 --- /dev/null +++ b/src/enums/httpEnum.ts @@ -0,0 +1,31 @@ +/** + * @description: Request result set + */ +export enum ResultEnum { + SUCCESS = '00000', + ERROR = 'A0500', + TIMEOUT = 'A0501', + TYPE = 'success', +} + +/** + * @description: request method + */ +export enum RequestEnum { + GET = 'GET', + POST = 'POST', + PUT = 'PUT', + DELETE = 'DELETE', +} + +/** + * @description: contentType + */ +export enum ContentTypeEnum { + // json + JSON = 'application/json;charset=UTF-8', + // form-data qs + FORM_URLENCODED = 'application/x-www-form-urlencoded;charset=UTF-8', + // form-data upload + FORM_DATA = 'multipart/form-data;charset=UTF-8', +} diff --git a/src/enums/menuEnum.ts b/src/enums/menuEnum.ts new file mode 100644 index 0000000..89cfa9f --- /dev/null +++ b/src/enums/menuEnum.ts @@ -0,0 +1,50 @@ +/** + * @description: menu type + */ +export enum MenuTypeEnum { + // left menu + SIDEBAR = 'sidebar', + + MIX_SIDEBAR = 'mix-sidebar', + // mixin menu + MIX = 'mix', + // top menu + TOP_MENU = 'top-menu', +} + +// 折叠触发器位置 +export enum TriggerEnum { + // 不显示 + NONE = 'NONE', + // 菜单底部 + FOOTER = 'FOOTER', + // 头部 + HEADER = 'HEADER', +} + +export type Mode = 'vertical' | 'vertical-right' | 'horizontal' | 'inline'; + +// menu mode +export enum MenuModeEnum { + VERTICAL = 'vertical', + HORIZONTAL = 'horizontal', + VERTICAL_RIGHT = 'vertical-right', + INLINE = 'inline', +} + +export enum MenuSplitTyeEnum { + NONE, + TOP, + LEFT, +} + +export enum TopMenuAlignEnum { + CENTER = 'center', + START = 'start', + END = 'end', +} + +export enum MixSidebarTriggerEnum { + HOVER = 'hover', + CLICK = 'click', +} diff --git a/src/enums/pageEnum.ts b/src/enums/pageEnum.ts new file mode 100644 index 0000000..8ac2274 --- /dev/null +++ b/src/enums/pageEnum.ts @@ -0,0 +1,11 @@ +export enum PageEnum { + // basic login path + BASE_LOGIN = '/login', + // basic home path + BASE_HOME = '/dashboard', + // error page path + ERROR_PAGE = '/exception', + // error log page path + ERROR_LOG_PAGE = '/error-log/list', +} +export const PageWrapperFixedHeightKey = 'PageWrapperFixedHeight'; diff --git a/src/enums/sizeEnum.ts b/src/enums/sizeEnum.ts new file mode 100644 index 0000000..cbbc152 --- /dev/null +++ b/src/enums/sizeEnum.ts @@ -0,0 +1,5 @@ +export enum SizeEnum { + DEFAULT = 'default', + SMALL = 'small', + LARGE = 'large', +} diff --git a/src/hooks/.DS_Store b/src/hooks/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b49e1c1bb8e3287f9a09f0ee990d9a96850310a1 GIT binary patch literal 6148 zcmeHK%}&EG40c%223&SPh+|#=i5)m1m8m?zUI6V!1+mfz23&jNAvo|foH+4Dd`?Vh z)<)t2Ldc%%uZ!*2`KBfd5t;G*d_*)Pq5+gK*@fv4_OrHROGfsA#?4XE4K1MSW!{R` z0cAiL_-hRCySqa(Dyg6qZ2kU@CbP0w`F8uW?x>>7vgxv%!pj@P+x5%qSuAq?&B)bd zv$Dl>l(_zGX|c?kzQKFb7wM(WEy~UgYJW%FZR}+apZi&}^1%@*H@uPBK}2WuMnqWu znAhE>J5*oebA{g}4_ANk+>VI!u`y4CiH)eRpNjkG(IfhqhJ8Gpet9DGB`;D}yg@zV z*3UInevSd0*(`%Sk7|_xWk4CI8Q}fFLK#!R%A?ylVB8e|m|)lmp7}1pIaV+gtUSU4 zF+LUOQ;l3Pj8Dh7mAF)}^61ma$mPRGWg|Bf%z&T9@Q!X%0S3K&wm~A`F|e2 z|A$HXO&L%I{uKiz$tKwtOOms-wKzU&E%XA)!f};HmjWZlv3ua7_z>y@KFbflRIu`h Q5s3Z~a5Sh<27Z-+4_rT+dH?_b literal 0 HcmV?d00001 diff --git a/src/hooks/component/useFormItem.ts b/src/hooks/component/useFormItem.ts new file mode 100644 index 0000000..fbd7037 --- /dev/null +++ b/src/hooks/component/useFormItem.ts @@ -0,0 +1,60 @@ +import type { UnwrapRef, Ref, WritableComputedRef, DeepReadonly } from 'vue'; +import { + reactive, + readonly, + computed, + getCurrentInstance, + watchEffect, + unref, + toRaw, + nextTick, +} from 'vue'; + +import { isEqual } from 'lodash-es'; + +export function useRuleFormItem>( + props: T, + key?: K, + changeEvent?, + emitData?: Ref, +): [WritableComputedRef, (val: V) => void, DeepReadonly]; + +export function useRuleFormItem( + props: T, + key: keyof T = 'value', + changeEvent = 'change', + emitData?: Ref, +) { + const instance = getCurrentInstance(); + const emit = instance?.emit; + + const innerState = reactive({ + value: props[key], + }); + + const defaultState = readonly(innerState); + + const setState = (val: UnwrapRef): void => { + innerState.value = val as T[keyof T]; + }; + + watchEffect(() => { + innerState.value = props[key]; + }); + + const state: any = computed({ + get() { + return innerState.value; + }, + set(value) { + if (isEqual(value, defaultState.value)) return; + + innerState.value = value as T[keyof T]; + nextTick(() => { + emit?.(changeEvent, value, ...(toRaw(unref(emitData)) || [])); + }); + }, + }); + + return [state, setState, defaultState]; +} diff --git a/src/hooks/component/usePageContext.ts b/src/hooks/component/usePageContext.ts new file mode 100644 index 0000000..12cc160 --- /dev/null +++ b/src/hooks/component/usePageContext.ts @@ -0,0 +1,18 @@ +import type { InjectionKey, ComputedRef, Ref } from 'vue'; +import { createContext, useContext } from '/@/hooks/core/useContext'; + +export interface PageContextProps { + contentHeight: ComputedRef; + pageHeight: Ref; + setPageHeight: (height: number) => Promise; +} + +const key: InjectionKey = Symbol(); + +export function createPageContext(context: PageContextProps) { + return createContext(context, key, { native: true }); +} + +export function usePageContext() { + return useContext(key); +} diff --git a/src/hooks/core/useAttrs.ts b/src/hooks/core/useAttrs.ts new file mode 100644 index 0000000..7de9296 --- /dev/null +++ b/src/hooks/core/useAttrs.ts @@ -0,0 +1,41 @@ +import { getCurrentInstance, reactive, shallowRef, watchEffect } from 'vue'; +import type { Ref } from 'vue'; + +interface Params { + excludeListeners?: boolean; + excludeKeys?: string[]; + excludeDefaultKeys?: boolean; +} + +const DEFAULT_EXCLUDE_KEYS = ['class', 'style']; +const LISTENER_PREFIX = /^on[A-Z]/; + +export function entries(obj: Recordable): [string, T][] { + return Object.keys(obj).map((key: string) => [key, obj[key]]); +} + +export function useAttrs(params: Params = {}): Ref | {} { + const instance = getCurrentInstance(); + if (!instance) return {}; + + const { excludeListeners = false, excludeKeys = [], excludeDefaultKeys = true } = params; + const attrs = shallowRef({}); + const allExcludeKeys = excludeKeys.concat(excludeDefaultKeys ? DEFAULT_EXCLUDE_KEYS : []); + + // Since attrs are not reactive, make it reactive instead of doing in `onUpdated` hook for better performance + instance.attrs = reactive(instance.attrs); + + watchEffect(() => { + const res = entries(instance.attrs).reduce((acm, [key, val]) => { + if (!allExcludeKeys.includes(key) && !(excludeListeners && LISTENER_PREFIX.test(key))) { + acm[key] = val; + } + + return acm; + }, {} as Recordable); + + attrs.value = res; + }); + + return attrs; +} \ No newline at end of file diff --git a/src/hooks/core/useContext.ts b/src/hooks/core/useContext.ts new file mode 100644 index 0000000..04a9433 --- /dev/null +++ b/src/hooks/core/useContext.ts @@ -0,0 +1,43 @@ +import { + InjectionKey, + provide, + inject, + reactive, + readonly as defineReadonly, + UnwrapRef, +} from 'vue'; + +export interface CreateContextOptions { + readonly?: boolean; + createProvider?: boolean; + native?: boolean; +} + +type ShallowUnwrap = { + [P in keyof T]: UnwrapRef; +}; + +export function createContext( + context: any, + key: InjectionKey = Symbol(), + options: CreateContextOptions = {}, +) { + const { readonly = true, createProvider = true, native = false } = options; + + const state = reactive(context); + const provideData = readonly ? defineReadonly(state) : state; + createProvider && provide(key, native ? context : provideData); + + return { + state, + }; +} + +export function useContext(key: InjectionKey, native?: boolean): T; + +export function useContext( + key: InjectionKey = Symbol(), + defaultValue?: any, +): ShallowUnwrap { + return inject(key, defaultValue || {}); +} diff --git a/src/hooks/event/useBreakpoint.ts b/src/hooks/event/useBreakpoint.ts new file mode 100644 index 0000000..0ca3a6b --- /dev/null +++ b/src/hooks/event/useBreakpoint.ts @@ -0,0 +1,93 @@ +import { ref, computed, ComputedRef, unref } from 'vue'; +import { useEventListener } from '/@/hooks/event/useEventListener'; +import { screenMap, sizeEnum, screenEnum } from '/@/enums/breakpointEnum'; + +// 可以用这个替换,优化项 +// import { Grid } from 'ant-design-vue'; +// const { useBreakpoint } = Grid; + +let globalScreenRef: ComputedRef; +let globalWidthRef: ComputedRef; +let globalRealWidthRef: ComputedRef; + +export interface CreateCallbackParams { + screen: ComputedRef; + width: ComputedRef; + realWidth: ComputedRef; + screenEnum: typeof screenEnum; + screenMap: Map; + sizeEnum: typeof sizeEnum; +} + +export function useBreakpoint() { + return { + screenRef: computed(() => unref(globalScreenRef)), + widthRef: globalWidthRef, + screenEnum, + realWidthRef: globalRealWidthRef, + }; +} + +// Just call it once +export function createBreakpointListen(fn?: (opt: CreateCallbackParams) => void) { + const screenRef = ref(sizeEnum.XL); + const realWidthRef = ref(window.innerWidth); + + function getWindowWidth() { + const width = document.body.clientWidth; + const xs = screenMap.get(sizeEnum.XS)!; + const sm = screenMap.get(sizeEnum.SM)!; + const md = screenMap.get(sizeEnum.MD)!; + const lg = screenMap.get(sizeEnum.LG)!; + const xl = screenMap.get(sizeEnum.XL)!; + if (width < xs) { + screenRef.value = sizeEnum.XS; + } else if (width < sm) { + screenRef.value = sizeEnum.SM; + } else if (width < md) { + screenRef.value = sizeEnum.MD; + } else if (width < lg) { + screenRef.value = sizeEnum.LG; + } else if (width < xl) { + screenRef.value = sizeEnum.XL; + } else { + screenRef.value = sizeEnum.XXL; + } + realWidthRef.value = width; + } + + useEventListener({ + el: window, + name: 'resize', + + listener: () => { + getWindowWidth(); + resizeFn(); + }, + // wait: 100, + }); + + getWindowWidth(); + globalScreenRef = computed(() => unref(screenRef)); + globalWidthRef = computed((): number => screenMap.get(unref(screenRef)!)!); + globalRealWidthRef = computed((): number => unref(realWidthRef)); + + function resizeFn() { + fn?.({ + screen: globalScreenRef, + width: globalWidthRef, + realWidth: globalRealWidthRef, + screenEnum, + screenMap, + sizeEnum, + }); + } + + resizeFn(); + return { + screenRef: globalScreenRef, + screenEnum, + widthRef: globalWidthRef, + realWidthRef: globalRealWidthRef, + }; +} diff --git a/src/hooks/event/useEventListener.ts b/src/hooks/event/useEventListener.ts new file mode 100644 index 0000000..892cd92 --- /dev/null +++ b/src/hooks/event/useEventListener.ts @@ -0,0 +1,58 @@ +import type { Ref } from 'vue'; +import { ref, watch, unref } from 'vue'; +import { useThrottleFn, useDebounceFn } from '@vueuse/core'; + +export type RemoveEventFn = () => void; +export interface UseEventParams { + el?: Element | Ref | Window | any; + name: string; + listener: EventListener; + options?: boolean | AddEventListenerOptions; + autoRemove?: boolean; + isDebounce?: boolean; + wait?: number; +} +export function useEventListener({ + el = window, + name, + listener, + options, + autoRemove = true, + isDebounce = true, + wait = 80, +}: UseEventParams): { removeEvent: RemoveEventFn } { + /* eslint-disable-next-line */ + let remove: RemoveEventFn = () => {}; + const isAddRef = ref(false); + + if (el) { + const element = ref(el as Element) as Ref; + + const handler = isDebounce ? useDebounceFn(listener, wait) : useThrottleFn(listener, wait); + const realHandler = wait ? handler : listener; + const removeEventListener = (e: Element) => { + isAddRef.value = true; + e.removeEventListener(name, realHandler, options); + }; + const addEventListener = (e: Element) => e.addEventListener(name, realHandler, options); + + const removeWatch = watch( + element, + (v, _ov, cleanUp) => { + if (v) { + !unref(isAddRef) && addEventListener(v); + cleanUp(() => { + autoRemove && removeEventListener(v); + }); + } + }, + { immediate: true }, + ); + + remove = () => { + removeEventListener(element.value); + removeWatch(); + }; + } + return { removeEvent: remove }; +} diff --git a/src/hooks/event/useScroll.ts b/src/hooks/event/useScroll.ts new file mode 100644 index 0000000..cc60f9b --- /dev/null +++ b/src/hooks/event/useScroll.ts @@ -0,0 +1,65 @@ +import type { Ref } from 'vue'; + +import { ref, onMounted, watch, onUnmounted } from 'vue'; +import { isWindow, isObject } from '/@/utils/is'; +import { useThrottleFn } from '@vueuse/core'; + +export function useScroll( + refEl: Ref, + options?: { + wait?: number; + leading?: boolean; + trailing?: boolean; + }, +) { + const refX = ref(0); + const refY = ref(0); + let handler = () => { + if (isWindow(refEl.value)) { + refX.value = refEl.value.scrollX; + refY.value = refEl.value.scrollY; + } else if (refEl.value) { + refX.value = (refEl.value as Element).scrollLeft; + refY.value = (refEl.value as Element).scrollTop; + } + }; + + if (isObject(options)) { + let wait = 0; + if (options.wait && options.wait > 0) { + wait = options.wait; + Reflect.deleteProperty(options, 'wait'); + } + + handler = useThrottleFn(handler, wait); + } + + let stopWatch: () => void; + onMounted(() => { + stopWatch = watch( + refEl, + (el, prevEl, onCleanup) => { + if (el) { + el.addEventListener('scroll', handler); + } else if (prevEl) { + prevEl.removeEventListener('scroll', handler); + } + onCleanup(() => { + refX.value = refY.value = 0; + el && el.removeEventListener('scroll', handler); + }); + }, + { immediate: true }, + ); + }); + + onUnmounted(() => { + refEl.value && refEl.value.removeEventListener('scroll', handler); + }); + + function stop() { + stopWatch && stopWatch(); + } + + return { refX, refY, stop }; +} diff --git a/src/hooks/setting/index.ts b/src/hooks/setting/index.ts new file mode 100644 index 0000000..2f0db3a --- /dev/null +++ b/src/hooks/setting/index.ts @@ -0,0 +1,18 @@ +import type { GlobConfig } from '/#/config'; + +import { getAppEnvConfig } from '/@/utils/env'; + +export const useGlobSetting = (): Readonly => { + const { VITE_GLOB_APP_TITLE, VITE_GLOB_API_URL, VITE_GLOB_API_URL_PREFIX, VITE_GLOB_UPLOAD_URL } = + getAppEnvConfig(); + + // Take global configuration + const glob: Readonly = { + title: VITE_GLOB_APP_TITLE, + apiUrl: VITE_GLOB_API_URL, + shortName: VITE_GLOB_APP_TITLE.replace(/\s/g, '_').replace(/-/g, '_'), + urlPrefix: VITE_GLOB_API_URL_PREFIX, + uploadUrl: VITE_GLOB_UPLOAD_URL, + }; + return glob as Readonly; +}; diff --git a/src/hooks/setting/useDarkModeTheme.ts b/src/hooks/setting/useDarkModeTheme.ts new file mode 100644 index 0000000..abad5c9 --- /dev/null +++ b/src/hooks/setting/useDarkModeTheme.ts @@ -0,0 +1,18 @@ +import { computed } from 'vue'; +import { theme } from 'ant-design-vue'; +import { useRootSetting } from '/@/hooks/setting/useRootSetting'; +import { ThemeEnum } from '/@/enums/appEnum'; + +export function useDarkModeTheme() { + const { getDarkMode } = useRootSetting(); + const { darkAlgorithm } = theme; + const isDark = computed(() => getDarkMode.value === ThemeEnum.DARK); + const darkTheme = { + algorithm: [darkAlgorithm], + }; + + return { + isDark, + darkTheme, + }; +} diff --git a/src/hooks/setting/useHeaderSetting.ts b/src/hooks/setting/useHeaderSetting.ts new file mode 100644 index 0000000..d590be8 --- /dev/null +++ b/src/hooks/setting/useHeaderSetting.ts @@ -0,0 +1,105 @@ +import type { HeaderSetting } from '/#/config'; + +import { computed, unref } from 'vue'; + +import { useAppStore } from '/@/store/modules/app'; + +import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; +import { useRootSetting } from '/@/hooks/setting/useRootSetting'; +import { useFullContent } from '/@/hooks/web/useFullContent'; +import { MenuModeEnum } from '/@/enums/menuEnum'; + +export function useHeaderSetting() { + const { getFullContent } = useFullContent(); + const appStore = useAppStore(); + + const getShowFullHeaderRef = computed(() => { + return ( + !unref(getFullContent) && + unref(getShowMixHeaderRef) && + unref(getShowHeader) && + !unref(getIsTopMenu) && + !unref(getIsMixSidebar) + ); + }); + + const getUnFixedAndFull = computed(() => !unref(getFixed) && !unref(getShowFullHeaderRef)); + + const getShowInsetHeaderRef = computed(() => { + const need = !unref(getFullContent) && unref(getShowHeader); + return ( + (need && !unref(getShowMixHeaderRef)) || + (need && unref(getIsTopMenu)) || + (need && unref(getIsMixSidebar)) + ); + }); + + const { + getMenuMode, + getSplit, + getShowHeaderTrigger, + getIsSidebarType, + getIsMixSidebar, + getIsTopMenu, + } = useMenuSetting(); + const { getShowBreadCrumb, getShowLogo } = useRootSetting(); + + const getShowMixHeaderRef = computed(() => !unref(getIsSidebarType) && unref(getShowHeader)); + + const getShowDoc = computed(() => appStore.getHeaderSetting.showDoc); + + const getHeaderTheme = computed(() => appStore.getHeaderSetting.theme); + + const getShowHeader = computed(() => appStore.getHeaderSetting.show); + + const getFixed = computed(() => appStore.getHeaderSetting.fixed); + + const getHeaderBgColor = computed(() => appStore.getHeaderSetting.bgColor); + + const getShowSearch = computed(() => appStore.getHeaderSetting.showSearch); + + const getUseLockPage = computed(() => appStore.getHeaderSetting.useLockPage); + + const getShowFullScreen = computed(() => appStore.getHeaderSetting.showFullScreen); + + const getShowNotice = computed(() => appStore.getHeaderSetting.showNotice); + + const getShowBread = computed(() => { + return ( + unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && unref(getShowBreadCrumb) && !unref(getSplit) + ); + }); + + const getShowHeaderLogo = computed(() => { + return unref(getShowLogo) && !unref(getIsSidebarType) && !unref(getIsMixSidebar); + }); + + const getShowContent = computed(() => { + return unref(getShowBread) || unref(getShowHeaderTrigger); + }); + + // Set header configuration + function setHeaderSetting(headerSetting: Partial) { + appStore.setProjectConfig({ headerSetting }); + } + return { + setHeaderSetting, + + getShowDoc, + getShowSearch, + getHeaderTheme, + getUseLockPage, + getShowFullScreen, + getShowNotice, + getShowBread, + getShowContent, + getShowHeaderLogo, + getShowHeader, + getFixed, + getShowMixHeaderRef, + getShowFullHeaderRef, + getShowInsetHeaderRef, + getUnFixedAndFull, + getHeaderBgColor, + }; +} diff --git a/src/hooks/setting/useMenuSetting.ts b/src/hooks/setting/useMenuSetting.ts new file mode 100644 index 0000000..e3c62ed --- /dev/null +++ b/src/hooks/setting/useMenuSetting.ts @@ -0,0 +1,168 @@ +import type { MenuSetting } from '/#/config'; + +import { computed, unref, ref } from 'vue'; + +import { useAppStore } from '/@/store/modules/app'; + +import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum'; +import { MenuModeEnum, MenuTypeEnum, TriggerEnum } from '/@/enums/menuEnum'; +import { useFullContent } from '/@/hooks/web/useFullContent'; + +const mixSideHasChildren = ref(false); + +export function useMenuSetting() { + const { getFullContent: fullContent } = useFullContent(); + const appStore = useAppStore(); + + const getShowSidebar = computed(() => { + return ( + unref(getSplit) || + (unref(getShowMenu) && unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && !unref(fullContent)) + ); + }); + + const getCollapsed = computed(() => appStore.getMenuSetting.collapsed); + + const getMenuType = computed(() => appStore.getMenuSetting.type); + + const getMenuMode = computed(() => appStore.getMenuSetting.mode); + + const getMenuFixed = computed(() => appStore.getMenuSetting.fixed); + + const getShowMenu = computed(() => appStore.getMenuSetting.show); + + const getMenuHidden = computed(() => appStore.getMenuSetting.hidden); + + const getMenuWidth = computed(() => appStore.getMenuSetting.menuWidth); + + const getTrigger = computed(() => appStore.getMenuSetting.trigger); + + const getMenuTheme = computed(() => appStore.getMenuSetting.theme); + + const getSplit = computed(() => appStore.getMenuSetting.split); + + const getMenuBgColor = computed(() => appStore.getMenuSetting.bgColor); + + const getMixSideTrigger = computed(() => appStore.getMenuSetting.mixSideTrigger); + + const getCanDrag = computed(() => appStore.getMenuSetting.canDrag); + + const getAccordion = computed(() => appStore.getMenuSetting.accordion); + + const getMixSideFixed = computed(() => appStore.getMenuSetting.mixSideFixed); + + const getTopMenuAlign = computed(() => appStore.getMenuSetting.topMenuAlign); + + const getCloseMixSidebarOnChange = computed( + () => appStore.getMenuSetting.closeMixSidebarOnChange, + ); + + const getIsSidebarType = computed(() => unref(getMenuType) === MenuTypeEnum.SIDEBAR); + + const getIsTopMenu = computed(() => unref(getMenuType) === MenuTypeEnum.TOP_MENU); + + const getCollapsedShowTitle = computed(() => appStore.getMenuSetting.collapsedShowTitle); + + const getShowTopMenu = computed(() => { + return unref(getMenuMode) === MenuModeEnum.HORIZONTAL || unref(getSplit); + }); + + const getShowHeaderTrigger = computed(() => { + if ( + unref(getMenuType) === MenuTypeEnum.TOP_MENU || + !unref(getShowMenu) || + unref(getMenuHidden) + ) { + return false; + } + + return unref(getTrigger) === TriggerEnum.HEADER; + }); + + const getIsHorizontal = computed(() => { + return unref(getMenuMode) === MenuModeEnum.HORIZONTAL; + }); + + const getIsMixSidebar = computed(() => { + return unref(getMenuType) === MenuTypeEnum.MIX_SIDEBAR; + }); + + const getIsMixMode = computed(() => { + return unref(getMenuMode) === MenuModeEnum.INLINE && unref(getMenuType) === MenuTypeEnum.MIX; + }); + + const getRealWidth = computed(() => { + if (unref(getIsMixSidebar)) { + return unref(getCollapsed) && !unref(getMixSideFixed) + ? unref(getMiniWidthNumber) + : unref(getMenuWidth); + } + return unref(getCollapsed) ? unref(getMiniWidthNumber) : unref(getMenuWidth); + }); + + const getMiniWidthNumber = computed(() => { + const { collapsedShowTitle, siderHidden } = appStore.getMenuSetting; + return siderHidden + ? 0 + : collapsedShowTitle + ? SIDE_BAR_SHOW_TIT_MINI_WIDTH + : SIDE_BAR_MINI_WIDTH; + }); + + const getCalcContentWidth = computed(() => { + const width = + unref(getIsTopMenu) || !unref(getShowMenu) || (unref(getSplit) && unref(getMenuHidden)) + ? 0 + : unref(getIsMixSidebar) + ? (unref(getCollapsed) ? SIDE_BAR_MINI_WIDTH : SIDE_BAR_SHOW_TIT_MINI_WIDTH) + + (unref(getMixSideFixed) && unref(mixSideHasChildren) ? unref(getRealWidth) : 0) + : unref(getRealWidth); + + return `calc(100% - ${unref(width)}px)`; + }); + + // Set menu configuration + function setMenuSetting(menuSetting: Partial): void { + appStore.setMenuSetting(menuSetting); + } + + function toggleCollapsed() { + setMenuSetting({ + collapsed: !unref(getCollapsed), + }); + } + return { + setMenuSetting, + toggleCollapsed, + getMenuFixed, + getRealWidth, + getMenuType, + getMenuMode, + getShowMenu, + getCollapsed, + getMiniWidthNumber, + getCalcContentWidth, + getMenuWidth, + getTrigger, + getSplit, + getMenuTheme, + getCanDrag, + getCollapsedShowTitle, + getIsHorizontal, + getIsSidebarType, + getAccordion, + getShowTopMenu, + getShowHeaderTrigger, + getTopMenuAlign, + getMenuHidden, + getIsTopMenu, + getMenuBgColor, + getShowSidebar, + getIsMixMode, + getIsMixSidebar, + getCloseMixSidebarOnChange, + getMixSideTrigger, + getMixSideFixed, + mixSideHasChildren, + }; +} diff --git a/src/hooks/setting/useMultipleTabSetting.ts b/src/hooks/setting/useMultipleTabSetting.ts new file mode 100644 index 0000000..7caa753 --- /dev/null +++ b/src/hooks/setting/useMultipleTabSetting.ts @@ -0,0 +1,28 @@ +import type { MultiTabsSetting } from '/#/config'; + +import { computed } from 'vue'; + +import { useAppStore } from '/@/store/modules/app'; + +export function useMultipleTabSetting() { + const appStore = useAppStore(); + + const getShowMultipleTab = computed(() => appStore.getMultiTabsSetting.show); + + const getShowQuick = computed(() => appStore.getMultiTabsSetting.showQuick); + + const getShowRedo = computed(() => appStore.getMultiTabsSetting.showRedo); + + const getShowFold = computed(() => appStore.getMultiTabsSetting.showFold); + + function setMultipleTabSetting(multiTabsSetting: Partial) { + appStore.setProjectConfig({ multiTabsSetting }); + } + return { + setMultipleTabSetting, + getShowMultipleTab, + getShowQuick, + getShowRedo, + getShowFold, + }; +} diff --git a/src/hooks/setting/useRootSetting.ts b/src/hooks/setting/useRootSetting.ts new file mode 100644 index 0000000..4976e40 --- /dev/null +++ b/src/hooks/setting/useRootSetting.ts @@ -0,0 +1,95 @@ +import type { ProjectConfig } from '/#/config'; + +import { computed } from 'vue'; + +import { useAppStore } from '/@/store/modules/app'; +import { ContentEnum, ThemeEnum } from '/@/enums/appEnum'; + +type RootSetting = Omit< + ProjectConfig, + 'locale' | 'headerSetting' | 'menuSetting' | 'multiTabsSetting' +>; + +export function useRootSetting() { + const appStore = useAppStore(); + + const getPageLoading = computed(() => appStore.getPageLoading); + + const getOpenKeepAlive = computed(() => appStore.getProjectConfig.openKeepAlive); + + const getSettingButtonPosition = computed(() => appStore.getProjectConfig.settingButtonPosition); + + const getCanEmbedIFramePage = computed(() => appStore.getProjectConfig.canEmbedIFramePage); + + const getPermissionMode = computed(() => appStore.getProjectConfig.permissionMode); + + const getShowLogo = computed(() => appStore.getProjectConfig.showLogo); + + const getContentMode = computed(() => appStore.getProjectConfig.contentMode); + + const getUseOpenBackTop = computed(() => appStore.getProjectConfig.useOpenBackTop); + + const getShowSettingButton = computed(() => appStore.getProjectConfig.showSettingButton); + + const getUseErrorHandle = computed(() => appStore.getProjectConfig.useErrorHandle); + + const getShowFooter = computed(() => appStore.getProjectConfig.showFooter); + + const getShowBreadCrumb = computed(() => appStore.getProjectConfig.showBreadCrumb); + + const getThemeColor = computed(() => appStore.getProjectConfig.themeColor); + + const getShowBreadCrumbIcon = computed(() => appStore.getProjectConfig.showBreadCrumbIcon); + + const getFullContent = computed(() => appStore.getProjectConfig.fullContent); + + const getColorWeak = computed(() => appStore.getProjectConfig.colorWeak); + + const getGrayMode = computed(() => appStore.getProjectConfig.grayMode); + + const getLockTime = computed(() => appStore.getProjectConfig.lockTime); + + const getShowDarkModeToggle = computed(() => appStore.getProjectConfig.showDarkModeToggle); + + const getDarkMode = computed(() => appStore.getDarkMode); + + const getLayoutContentMode = computed(() => + appStore.getProjectConfig.contentMode === ContentEnum.FULL + ? ContentEnum.FULL + : ContentEnum.FIXED, + ); + + function setRootSetting(setting: Partial) { + appStore.setProjectConfig(setting); + } + + function setDarkMode(mode: ThemeEnum) { + appStore.setDarkMode(mode); + } + return { + setRootSetting, + + getSettingButtonPosition, + getFullContent, + getColorWeak, + getGrayMode, + getLayoutContentMode, + getPageLoading, + getOpenKeepAlive, + getCanEmbedIFramePage, + getPermissionMode, + getShowLogo, + getUseErrorHandle, + getShowBreadCrumb, + getShowBreadCrumbIcon, + getUseOpenBackTop, + getShowSettingButton, + getShowFooter, + getContentMode, + getLockTime, + getThemeColor, + getDarkMode, + setDarkMode, + getShowDarkModeToggle, + }; +} diff --git a/src/hooks/setting/useTransitionSetting.ts b/src/hooks/setting/useTransitionSetting.ts new file mode 100644 index 0000000..b6d421a --- /dev/null +++ b/src/hooks/setting/useTransitionSetting.ts @@ -0,0 +1,31 @@ +import type { TransitionSetting } from '/#/config'; + +import { computed } from 'vue'; + +import { useAppStore } from '/@/store/modules/app'; + +export function useTransitionSetting() { + const appStore = useAppStore(); + + const getEnableTransition = computed(() => appStore.getTransitionSetting?.enable); + + const getOpenNProgress = computed(() => appStore.getTransitionSetting?.openNProgress); + + const getOpenPageLoading = computed((): boolean => { + return !!appStore.getTransitionSetting?.openPageLoading; + }); + + const getBasicTransition = computed(() => appStore.getTransitionSetting?.basicTransition); + + function setTransitionSetting(transitionSetting: Partial) { + appStore.setProjectConfig({ transitionSetting }); + } + return { + setTransitionSetting, + + getEnableTransition, + getOpenNProgress, + getOpenPageLoading, + getBasicTransition, + }; +} diff --git a/src/hooks/web/useAppInject.ts b/src/hooks/web/useAppInject.ts new file mode 100644 index 0000000..7d6efb2 --- /dev/null +++ b/src/hooks/web/useAppInject.ts @@ -0,0 +1,10 @@ +import { useAppProviderContext } from '/@/components/Application'; +import { computed, unref } from 'vue'; + +export function useAppInject() { + const values = useAppProviderContext(); + + return { + getIsMobile: computed(() => unref(values.isMobile)), + }; +} diff --git a/src/hooks/web/useContentHeight.ts b/src/hooks/web/useContentHeight.ts new file mode 100644 index 0000000..558cd51 --- /dev/null +++ b/src/hooks/web/useContentHeight.ts @@ -0,0 +1,189 @@ +import { ComputedRef, isRef, nextTick, Ref, ref, unref, watch } from 'vue'; +import { onMountedOrActivated, useWindowSizeFn } from '@vben/hooks'; +import { useLayoutHeight } from '/@/layouts/default/content/useContentViewHeight'; +import { getViewportOffset } from '/@/utils/domUtils'; +import { isNumber, isString } from '/@/utils/is'; + +export interface CompensationHeight { + // 使用 layout Footer 高度作为判断补偿高度的条件 + useLayoutFooter: boolean; + // refs HTMLElement + elements?: Ref[]; +} + +type Upward = number | string | null | undefined; + +/** + * 动态计算内容高度,根据锚点dom最下坐标到屏幕最下坐标,根据传入dom的高度、padding、margin等值进行动态计算 + * 最终获取合适的内容高度 + * + * @param flag 用于开启计算的响应式标识 + * @param anchorRef 锚点组件 Ref + * @param subtractHeightRefs 待减去高度的组件列表 Ref + * @param substractSpaceRefs 待减去空闲空间(margins/paddings)的组件列表 Ref + * @param offsetHeightRef 计算偏移的响应式高度,计算高度时将直接减去此值 + * @param upwardSpace 向上递归减去空闲空间的 层级 或 直到指定class为止 数值为2代表向上递归两次|数值为ant-layout表示向上递归直到碰见.ant-layout为止 + * @returns 响应式高度 + */ +export function useContentHeight( + flag: ComputedRef, + anchorRef: Ref, + subtractHeightRefs: Ref[], + substractSpaceRefs: Ref[], + upwardSpace: Ref | ComputedRef | Upward = 0, + offsetHeightRef: Ref = ref(0), +) { + const contentHeight: Ref> = ref(null); + const { footerHeightRef: layoutFooterHeightRef } = useLayoutHeight(); + let compensationHeight: CompensationHeight = { + useLayoutFooter: true, + }; + + const setCompensation = (params: CompensationHeight) => { + compensationHeight = params; + }; + + function redoHeight() { + nextTick(() => { + calcContentHeight(); + }); + } + + function calcSubtractSpace( + element: Element | null | undefined, + direction: 'all' | 'top' | 'bottom' = 'all', + ): number { + function numberPx(px: string) { + return Number(px.replace(/[^\d]/g, '')); + } + let subtractHeight = 0; + const ZERO_PX = '0px'; + if (element) { + const cssStyle = getComputedStyle(element); + const marginTop = numberPx(cssStyle?.marginTop ?? ZERO_PX); + const marginBottom = numberPx(cssStyle?.marginBottom ?? ZERO_PX); + const paddingTop = numberPx(cssStyle?.paddingTop ?? ZERO_PX); + const paddingBottom = numberPx(cssStyle?.paddingBottom ?? ZERO_PX); + if (direction === 'all') { + subtractHeight += marginTop; + subtractHeight += marginBottom; + subtractHeight += paddingTop; + subtractHeight += paddingBottom; + } else if (direction === 'top') { + subtractHeight += marginTop; + subtractHeight += paddingTop; + } else { + subtractHeight += marginBottom; + subtractHeight += paddingBottom; + } + } + return subtractHeight; + } + + function getEl(element: any): Nullable { + if (element == null) { + return null; + } + return (element instanceof HTMLDivElement ? element : element.$el) as HTMLDivElement; + } + + async function calcContentHeight() { + if (!flag.value) { + return; + } + // Add a delay to get the correct height + await nextTick(); + + const anchorEl = getEl(unref(anchorRef)); + if (!anchorEl) { + return; + } + const { bottomIncludeBody } = getViewportOffset(anchorEl); + + // substract elements height + let substractHeight = 0; + subtractHeightRefs.forEach((item) => { + substractHeight += getEl(unref(item))?.offsetHeight ?? 0; + }); + + // subtract margins / paddings + let substractSpaceHeight = calcSubtractSpace(anchorEl) ?? 0; + substractSpaceRefs.forEach((item) => { + substractSpaceHeight += calcSubtractSpace(getEl(unref(item))); + }); + + // upwardSpace + let upwardSpaceHeight = 0; + function upward(element: Element | null, upwardLvlOrClass: number | string | null | undefined) { + if (element && upwardLvlOrClass) { + const parent = element.parentElement; + if (parent) { + if (isString(upwardLvlOrClass)) { + if (!parent.classList.contains(upwardLvlOrClass)) { + upwardSpaceHeight += calcSubtractSpace(parent, 'bottom'); + upward(parent, upwardLvlOrClass); + } else { + upwardSpaceHeight += calcSubtractSpace(parent, 'bottom'); + } + } else if (isNumber(upwardLvlOrClass)) { + if (upwardLvlOrClass > 0) { + upwardSpaceHeight += calcSubtractSpace(parent, 'bottom'); + upward(parent, --upwardLvlOrClass); + } + } + } + } + } + if (isRef(upwardSpace)) { + upward(anchorEl, unref(upwardSpace)); + } else { + upward(anchorEl, upwardSpace); + } + + let height = + bottomIncludeBody - + unref(layoutFooterHeightRef) - + unref(offsetHeightRef) - + substractHeight - + substractSpaceHeight - + upwardSpaceHeight; + + // compensation height + const calcCompensationHeight = () => { + compensationHeight.elements?.forEach((item) => { + height += getEl(unref(item))?.offsetHeight ?? 0; + }); + }; + if (compensationHeight.useLayoutFooter && unref(layoutFooterHeightRef) > 0) { + calcCompensationHeight(); + } else { + calcCompensationHeight(); + } + + contentHeight.value = height; + } + + onMountedOrActivated(() => { + nextTick(() => { + calcContentHeight(); + }); + }); + useWindowSizeFn( + () => { + calcContentHeight(); + }, + { wait: 50, immediate: true }, + ); + watch( + () => [layoutFooterHeightRef.value], + () => { + calcContentHeight(); + }, + { + flush: 'post', + immediate: true, + }, + ); + + return { redoHeight, setCompensation, contentHeight }; +} diff --git a/src/hooks/web/useContextMenu.ts b/src/hooks/web/useContextMenu.ts new file mode 100644 index 0000000..3237d35 --- /dev/null +++ b/src/hooks/web/useContextMenu.ts @@ -0,0 +1,13 @@ +import { onUnmounted, getCurrentInstance } from 'vue'; +import { createContextMenu, destroyContextMenu } from '/@/components/ContextMenu'; +import type { ContextMenuItem } from '/@/components/ContextMenu'; + +export type { ContextMenuItem }; +export function useContextMenu(authRemove = true) { + if (getCurrentInstance() && authRemove) { + onUnmounted(() => { + destroyContextMenu(); + }); + } + return [createContextMenu, destroyContextMenu]; +} diff --git a/src/hooks/web/useCopyToClipboard.ts b/src/hooks/web/useCopyToClipboard.ts new file mode 100644 index 0000000..5072f9c --- /dev/null +++ b/src/hooks/web/useCopyToClipboard.ts @@ -0,0 +1,70 @@ +import { ref, watch } from 'vue'; + +import { isDef } from '/@/utils/is'; + +interface Options { + target?: HTMLElement; +} +export function useCopyToClipboard(initial?: string) { + const clipboardRef = ref(initial || ''); + const isSuccessRef = ref(false); + const copiedRef = ref(false); + + watch( + clipboardRef, + (str?: string) => { + if (isDef(str)) { + copiedRef.value = true; + isSuccessRef.value = copyTextToClipboard(str); + } + }, + { immediate: !!initial, flush: 'sync' }, + ); + + return { clipboardRef, isSuccessRef, copiedRef }; +} + +export function copyTextToClipboard(input: string, { target = document.body }: Options = {}) { + const element = document.createElement('textarea'); + const previouslyFocusedElement = document.activeElement; + + element.value = input; + + element.setAttribute('readonly', ''); + + (element.style as any).contain = 'strict'; + element.style.position = 'absolute'; + element.style.left = '-9999px'; + element.style.fontSize = '12pt'; + + const selection = document.getSelection(); + let originalRange; + if (selection && selection.rangeCount > 0) { + originalRange = selection.getRangeAt(0); + } + + target.append(element); + element.select(); + + element.selectionStart = 0; + element.selectionEnd = input.length; + + let isSuccess = false; + try { + isSuccess = document.execCommand('copy'); + } catch (e: any) { + throw new Error(e); + } + + element.remove(); + + if (originalRange && selection) { + selection.removeAllRanges(); + selection.addRange(originalRange); + } + + if (previouslyFocusedElement) { + (previouslyFocusedElement as HTMLElement).focus(); + } + return isSuccess; +} diff --git a/src/hooks/web/useDesign.ts b/src/hooks/web/useDesign.ts new file mode 100644 index 0000000..046674b --- /dev/null +++ b/src/hooks/web/useDesign.ts @@ -0,0 +1,22 @@ +import { useAppProviderContext } from '/@/components/Application'; +// import { computed } from 'vue'; +// import { lowerFirst } from 'lodash-es'; +export function useDesign(scope: string) { + const values = useAppProviderContext(); + // const $style = cssModule ? useCssModule() : {}; + + // const style: Record = {}; + // if (cssModule) { + // Object.keys($style).forEach((key) => { + // // const moduleCls = $style[key]; + // const k = key.replace(new RegExp(`^${values.prefixCls}-?`, 'ig'), ''); + // style[lowerFirst(k)] = $style[key]; + // }); + // } + return { + // prefixCls: computed(() => `${values.prefixCls}-${scope}`), + prefixCls: `${values.prefixCls}-${scope}`, + prefixVar: values.prefixCls, + // style, + }; +} diff --git a/src/hooks/web/useECharts.ts b/src/hooks/web/useECharts.ts new file mode 100644 index 0000000..643ce60 --- /dev/null +++ b/src/hooks/web/useECharts.ts @@ -0,0 +1,131 @@ +import type { EChartsOption } from 'echarts'; +import type { Ref } from 'vue'; +import { useTimeoutFn } from '@vben/hooks'; +import { tryOnUnmounted, useDebounceFn } from '@vueuse/core'; +import { unref, nextTick, watch, computed, ref } from 'vue'; +import { useEventListener } from '/@/hooks/event/useEventListener'; +import { useBreakpoint } from '/@/hooks/event/useBreakpoint'; +import echarts from '/@/utils/lib/echarts'; +import { useRootSetting } from '/@/hooks/setting/useRootSetting'; +import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; + +export function useECharts( + elRef: Ref, + theme: 'light' | 'dark' | 'default' = 'default', +) { + const { getDarkMode: getSysDarkMode } = useRootSetting(); + const { getCollapsed } = useMenuSetting(); + + const getDarkMode = computed(() => { + return theme === 'default' ? getSysDarkMode.value : theme; + }); + let chartInstance: echarts.ECharts | null = null; + let resizeFn: Fn = resize; + const cacheOptions = ref({}) as Ref; + let removeResizeFn: Fn = () => {}; + + resizeFn = useDebounceFn(resize, 200); + + const getOptions = computed(() => { + if (getDarkMode.value !== 'dark') { + return cacheOptions.value as EChartsOption; + } + return { + backgroundColor: 'transparent', + ...cacheOptions.value, + } as EChartsOption; + }); + + function initCharts(t = theme) { + const el = unref(elRef); + if (!el || !unref(el)) { + return; + } + + chartInstance = echarts.init(el, t); + const { removeEvent } = useEventListener({ + el: window, + name: 'resize', + listener: resizeFn, + }); + removeResizeFn = removeEvent; + const { widthRef, screenEnum } = useBreakpoint(); + if (unref(widthRef) <= screenEnum.MD || el.offsetHeight === 0) { + useTimeoutFn(() => { + resizeFn(); + }, 30); + } + } + + function setOptions(options: EChartsOption, clear = true) { + cacheOptions.value = options; + return new Promise((resolve) => { + if (unref(elRef)?.offsetHeight === 0) { + useTimeoutFn(() => { + setOptions(unref(getOptions)); + resolve(null); + }, 30); + } + nextTick(() => { + useTimeoutFn(() => { + if (!chartInstance) { + initCharts(getDarkMode.value as 'default'); + + if (!chartInstance) return; + } + clear && chartInstance?.clear(); + + chartInstance?.setOption(unref(getOptions)); + resolve(null); + }, 30); + }); + }); + } + + function resize() { + chartInstance?.resize({ + animation: { + duration: 300, + easing: 'quadraticIn', + }, + }); + } + + watch( + () => getDarkMode.value, + (theme) => { + if (chartInstance) { + chartInstance.dispose(); + initCharts(theme as 'default'); + setOptions(cacheOptions.value); + } + }, + ); + + watch(getCollapsed, (_) => { + useTimeoutFn(() => { + resizeFn(); + }, 300); + }); + + tryOnUnmounted(() => { + if (!chartInstance) return; + removeResizeFn(); + chartInstance.dispose(); + chartInstance = null; + }); + + function getInstance(): echarts.ECharts | null { + if (!chartInstance) { + initCharts(getDarkMode.value as 'default'); + } + return chartInstance; + } + + return { + setOptions, + resize, + echarts, + getInstance, + }; +} diff --git a/src/hooks/web/useFullContent.ts b/src/hooks/web/useFullContent.ts new file mode 100644 index 0000000..7dea077 --- /dev/null +++ b/src/hooks/web/useFullContent.ts @@ -0,0 +1,28 @@ +import { computed, unref } from 'vue'; + +import { useAppStore } from '/@/store/modules/app'; + +import { useRouter } from 'vue-router'; + +/** + * @description: Full screen display content + */ +export const useFullContent = () => { + const appStore = useAppStore(); + const router = useRouter(); + const { currentRoute } = router; + + // Whether to display the content in full screen without displaying the menu + const getFullContent = computed(() => { + // Query parameters, the full screen is displayed when the address bar has a full parameter + const route = unref(currentRoute); + const query = route.query; + if (query && Reflect.has(query, '__full__')) { + return true; + } + // Return to the configuration in the configuration file + return appStore.getProjectConfig.fullContent; + }); + + return { getFullContent }; +}; diff --git a/src/hooks/web/useI18n.ts b/src/hooks/web/useI18n.ts new file mode 100644 index 0000000..2a777b7 --- /dev/null +++ b/src/hooks/web/useI18n.ts @@ -0,0 +1,55 @@ +import { i18n } from '/@/locales/setupI18n'; + +type I18nGlobalTranslation = { + (key: string): string; + (key: string, locale: string): string; + (key: string, locale: string, list: unknown[]): string; + (key: string, locale: string, named: Record): string; + (key: string, list: unknown[]): string; + (key: string, named: Record): string; +}; + +type I18nTranslationRestParameters = [string, any]; + +function getKey(namespace: string | undefined, key: string) { + if (!namespace) { + return key; + } + if (key.startsWith(namespace)) { + return key; + } + return `${namespace}.${key}`; +} + +export function useI18n(namespace?: string): { + t: I18nGlobalTranslation; +} { + const normalFn = { + t: (key: string) => { + return getKey(namespace, key); + }, + }; + + if (!i18n) { + return normalFn; + } + + const { t, ...methods } = i18n.global; + + const tFn: I18nGlobalTranslation = (key: string, ...arg: any[]) => { + if (!key) return ''; + if (!key.includes('.') && !namespace) return key; + return t(getKey(namespace, key), ...(arg as I18nTranslationRestParameters)); + }; + return { + ...methods, + t: tFn, + }; +} + +// Why write this function? +// Mainly to configure the vscode i18nn ally plugin. This function is only used for routing and menus. Please use useI18n for other places + +// 为什么要编写此函数? +// 主要用于配合vscode i18nn ally插件。此功能仅用于路由和菜单。请在其他地方使用useI18n +export const t = (key: string) => key; diff --git a/src/hooks/web/useLockPage.ts b/src/hooks/web/useLockPage.ts new file mode 100644 index 0000000..c543be9 --- /dev/null +++ b/src/hooks/web/useLockPage.ts @@ -0,0 +1,72 @@ +import { computed, onUnmounted, unref, watchEffect } from 'vue'; +import { useThrottleFn } from '@vueuse/core'; + +import { useAppStore } from '/@/store/modules/app'; +import { useLockStore } from '/@/store/modules/lock'; + +import { useUserStore } from '/@/store/modules/user'; +import { useRootSetting } from '../setting/useRootSetting'; + +export function useLockPage() { + const { getLockTime } = useRootSetting(); + const lockStore = useLockStore(); + const userStore = useUserStore(); + const appStore = useAppStore(); + + let timeId: TimeoutHandle; + + function clear(): void { + window.clearTimeout(timeId); + } + + function resetCalcLockTimeout(): void { + // not login + if (!userStore.getToken) { + clear(); + return; + } + const lockTime = appStore.getProjectConfig.lockTime; + if (!lockTime || lockTime < 1) { + clear(); + return; + } + clear(); + + timeId = setTimeout(() => { + lockPage(); + }, lockTime * 60 * 1000); + } + + function lockPage(): void { + lockStore.setLockInfo({ + isLock: true, + pwd: undefined, + }); + } + + watchEffect((onClean) => { + if (userStore.getToken) { + resetCalcLockTimeout(); + } else { + clear(); + } + onClean(() => { + clear(); + }); + }); + + onUnmounted(() => { + clear(); + }); + + const keyupFn = useThrottleFn(resetCalcLockTimeout, 2000); + + return computed(() => { + if (unref(getLockTime)) { + return { onKeyup: keyupFn, onMousemove: keyupFn }; + } else { + clear(); + return {}; + } + }); +} diff --git a/src/hooks/web/useMessage.tsx b/src/hooks/web/useMessage.tsx new file mode 100644 index 0000000..2de8a38 --- /dev/null +++ b/src/hooks/web/useMessage.tsx @@ -0,0 +1,121 @@ +import type { ModalFunc, ModalFuncProps } from 'ant-design-vue/lib/modal/Modal'; +import { Modal, message as Message, notification } from 'ant-design-vue'; +import { InfoCircleFilled, CheckCircleFilled, CloseCircleFilled } from '@ant-design/icons-vue'; +import { NotificationArgsProps, ConfigProps } from 'ant-design-vue/lib/notification'; +import { useI18n } from './useI18n'; +import { isString } from '/@/utils/is'; + +export interface NotifyApi { + info(config: NotificationArgsProps): void; + success(config: NotificationArgsProps): void; + error(config: NotificationArgsProps): void; + warn(config: NotificationArgsProps): void; + warning(config: NotificationArgsProps): void; + open(args: NotificationArgsProps): void; + close(key: String): void; + config(options: ConfigProps): void; + destroy(): void; +} + +export declare type NotificationPlacement = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight'; +export declare type IconType = 'success' | 'info' | 'error' | 'warning'; +export interface ModalOptionsEx extends Omit { + iconType: 'warning' | 'success' | 'error' | 'info'; +} +export type ModalOptionsPartial = Partial & Pick; + +interface ConfirmOptions { + info: ModalFunc; + success: ModalFunc; + error: ModalFunc; + warn: ModalFunc; + warning: ModalFunc; +} + +function getIcon(iconType: string) { + if (iconType === 'warning') { + return ; + } else if (iconType === 'success') { + return ; + } else if (iconType === 'info') { + return ; + } else { + return ; + } +} + +function renderContent({ content }: Pick) { + if (isString(content)) { + return
    ${content as string}
    `}>; + } else { + return content; + } +} + +/** + * @description: Create confirmation box + */ +function createConfirm(options: ModalOptionsEx): ConfirmOptions { + const iconType = options.iconType || 'warning'; + Reflect.deleteProperty(options, 'iconType'); + const opt: ModalFuncProps = { + centered: true, + icon: getIcon(iconType), + ...options, + content: renderContent(options), + }; + return Modal.confirm(opt) as unknown as ConfirmOptions; +} + +const getBaseOptions = () => { + const { t } = useI18n(); + return { + okText: t('common.okText'), + centered: true, + }; +}; + +function createModalOptions(options: ModalOptionsPartial, icon: string): ModalOptionsPartial { + return { + ...getBaseOptions(), + ...options, + content: renderContent(options), + icon: getIcon(icon), + }; +} + +function createSuccessModal(options: ModalOptionsPartial) { + return Modal.success(createModalOptions(options, 'success')); +} + +function createErrorModal(options: ModalOptionsPartial) { + return Modal.error(createModalOptions(options, 'error')); +} + +function createInfoModal(options: ModalOptionsPartial) { + return Modal.info(createModalOptions(options, 'info')); +} + +function createWarningModal(options: ModalOptionsPartial) { + return Modal.warning(createModalOptions(options, 'warning')); +} + +notification.config({ + placement: 'topRight', + duration: 3, +}); + +/** + * @description: message + */ +export function useMessage() { + return { + createMessage: Message, + notification: notification as NotifyApi, + createConfirm: createConfirm, + createSuccessModal, + createErrorModal, + createInfoModal, + createWarningModal, + }; +} diff --git a/src/hooks/web/usePage.ts b/src/hooks/web/usePage.ts new file mode 100644 index 0000000..a4a5c73 --- /dev/null +++ b/src/hooks/web/usePage.ts @@ -0,0 +1,54 @@ +import type { RouteLocationRaw, Router } from 'vue-router'; + +import { PageEnum } from '/@/enums/pageEnum'; +import { unref } from 'vue'; + +import { useRouter } from 'vue-router'; +import { REDIRECT_NAME } from '/@/router/constant'; + +export type PathAsPageEnum = T extends { path: string } ? T & { path: PageEnum } : T; +export type RouteLocationRawEx = PathAsPageEnum; + +function handleError(e: Error) { + console.error(e); +} + +/** + * page switch + */ +export function useGo(_router?: Router) { + const { push, replace } = _router || useRouter(); + function go(opt: RouteLocationRawEx = PageEnum.BASE_HOME, isReplace = false) { + if (!opt) { + return; + } + isReplace ? replace(opt).catch(handleError) : push(opt).catch(handleError); + } + return go; +} + +/** + * @description: redo current page + */ +export const useRedo = (_router?: Router) => { + const { replace, currentRoute } = _router || useRouter(); + const { query, params = {}, name, fullPath } = unref(currentRoute.value); + function redo(): Promise { + return new Promise((resolve) => { + if (name === REDIRECT_NAME) { + resolve(false); + return; + } + if (name && Object.keys(params).length > 0) { + params['_origin_params'] = JSON.stringify(params ?? {}); + params['_redirect_type'] = 'name'; + params['path'] = String(name); + } else { + params['_redirect_type'] = 'path'; + params['path'] = fullPath; + } + replace({ name: REDIRECT_NAME, params, query }).then(() => resolve(true)); + }); + } + return redo; +}; diff --git a/src/hooks/web/usePagination.ts b/src/hooks/web/usePagination.ts new file mode 100644 index 0000000..1e19913 --- /dev/null +++ b/src/hooks/web/usePagination.ts @@ -0,0 +1,34 @@ +import type { Ref } from 'vue'; +import { ref, unref, computed } from 'vue'; + +function pagination(list: T[], pageNo: number, pageSize: number): T[] { + const offset = (pageNo - 1) * Number(pageSize); + const ret = + offset + Number(pageSize) >= list.length + ? list.slice(offset, list.length) + : list.slice(offset, offset + Number(pageSize)); + return ret; +} + +export function usePagination(list: Ref, pageSize: number) { + const currentPage = ref(1); + const pageSizeRef = ref(pageSize); + + const getPaginationList = computed(() => { + return pagination(unref(list), unref(currentPage), unref(pageSizeRef)); + }); + + const getTotal = computed(() => { + return unref(list).length; + }); + + function setCurrentPage(page: number) { + currentPage.value = page; + } + + function setPageSize(pageSize: number) { + pageSizeRef.value = pageSize; + } + + return { setCurrentPage, getTotal, setPageSize, getPaginationList }; +} diff --git a/src/hooks/web/usePermission.ts b/src/hooks/web/usePermission.ts new file mode 100644 index 0000000..8a82d46 --- /dev/null +++ b/src/hooks/web/usePermission.ts @@ -0,0 +1,119 @@ +import type { RouteRecordRaw } from 'vue-router'; + +import { useAppStore } from '/@/store/modules/app'; +import { usePermissionStore } from '/@/store/modules/permission'; +import { useUserStore } from '/@/store/modules/user'; + +import { useTabs } from './useTabs'; + +import { router, resetRouter } from '/@/router'; +// import { RootRoute } from '/@/router/routes'; + +import projectSetting from '/@/settings/projectSetting'; +import { PermissionModeEnum } from '/@/enums/appEnum'; +import { RoleEnum } from '/@/enums/roleEnum'; + +import { intersection } from 'lodash-es'; +import { isArray } from '/@/utils/is'; +import { useMultipleTabStore } from '/@/store/modules/multipleTab'; + +// User permissions related operations +export function usePermission() { + const userStore = useUserStore(); + const appStore = useAppStore(); + const permissionStore = usePermissionStore(); + const { closeAll } = useTabs(router); + + /** + * Change permission mode + */ + async function togglePermissionMode() { + appStore.setProjectConfig({ + permissionMode: + appStore.projectConfig?.permissionMode === PermissionModeEnum.BACK + ? PermissionModeEnum.ROUTE_MAPPING + : PermissionModeEnum.BACK, + }); + location.reload(); + } + + /** + * Reset and regain authority resource information + * 重置和重新获得权限资源信息 + * @param id + */ + async function resume() { + const tabStore = useMultipleTabStore(); + tabStore.clearCacheTabs(); + resetRouter(); + const routes = await permissionStore.buildRoutesAction(); + routes.forEach((route) => { + router.addRoute(route as unknown as RouteRecordRaw); + }); + permissionStore.setLastBuildMenuTime(); + closeAll(); + } + + /** + * Determine whether there is permission + */ + function hasPermission(value?: RoleEnum | RoleEnum[] | string | string[], def = true): boolean { + // Visible by default + if (!value) { + return def; + } + + const permMode = projectSetting.permissionMode; + + if ([PermissionModeEnum.ROUTE_MAPPING, PermissionModeEnum.ROLE].includes(permMode)) { + if (!isArray(value)) { + return userStore.getRoleList?.includes(value as RoleEnum); + } + return (intersection(value, userStore.getRoleList) as RoleEnum[]).length > 0; + } + + if (PermissionModeEnum.BACK === permMode) { + const allCodeList = permissionStore.getPermCodeList as string[]; + if (!isArray(value)) { + const splits = ['||', '&&']; + const splitName = splits.find((item) => value.includes(item)); + if (splitName) { + const splitCodes = value.split(splitName); + return splitName === splits[0] + ? intersection(splitCodes, allCodeList).length > 0 + : intersection(splitCodes, allCodeList).length === splitCodes.length; + } + return allCodeList.includes(value); + } + return (intersection(value, allCodeList) as string[]).length > 0; + } + return true; + } + + /** + * Change roles + * @param roles + */ + async function changeRole(roles: RoleEnum | RoleEnum[]): Promise { + if (projectSetting.permissionMode !== PermissionModeEnum.ROUTE_MAPPING) { + throw new Error( + 'Please switch PermissionModeEnum to ROUTE_MAPPING mode in the configuration to operate!', + ); + } + + if (!isArray(roles)) { + roles = [roles]; + } + userStore.setRoleList(roles); + await resume(); + } + + /** + * refresh menu data + */ + async function refreshMenu() { + resume(); + } + + return { changeRole, hasPermission, togglePermissionMode, refreshMenu }; +} diff --git a/src/hooks/web/useScript.ts b/src/hooks/web/useScript.ts new file mode 100644 index 0000000..9707116 --- /dev/null +++ b/src/hooks/web/useScript.ts @@ -0,0 +1,46 @@ +import { onMounted, onUnmounted, ref } from 'vue'; + +interface ScriptOptions { + src: string; +} + +export function useScript(opts: ScriptOptions) { + const isLoading = ref(false); + const error = ref(false); + const success = ref(false); + let script: HTMLScriptElement; + + const promise = new Promise((resolve, reject) => { + onMounted(() => { + script = document.createElement('script'); + script.type = 'text/javascript'; + script.onload = function () { + isLoading.value = false; + success.value = true; + error.value = false; + resolve(''); + }; + + script.onerror = function (err) { + isLoading.value = false; + success.value = false; + error.value = true; + reject(err); + }; + + script.src = opts.src; + document.head.appendChild(script); + }); + }); + + onUnmounted(() => { + script && script.remove(); + }); + + return { + isLoading, + error, + success, + toPromise: () => promise, + }; +} diff --git a/src/hooks/web/useSortable.ts b/src/hooks/web/useSortable.ts new file mode 100644 index 0000000..4c66b6a --- /dev/null +++ b/src/hooks/web/useSortable.ts @@ -0,0 +1,21 @@ +import { nextTick, unref } from 'vue'; +import type { Ref } from 'vue'; +import type { Options } from 'sortablejs'; + +export function useSortable(el: HTMLElement | Ref, options?: Options) { + function initSortable() { + nextTick(async () => { + if (!el) return; + + const Sortable = (await import('sortablejs')).default; + Sortable.create(unref(el), { + animation: 500, + delay: 400, + delayOnTouchOnly: true, + ...options, + }); + }); + } + + return { initSortable }; +} diff --git a/src/hooks/web/useTabs.ts b/src/hooks/web/useTabs.ts new file mode 100644 index 0000000..51f3fce --- /dev/null +++ b/src/hooks/web/useTabs.ts @@ -0,0 +1,103 @@ +import type { RouteLocationNormalized, Router } from 'vue-router'; + +import { useRouter } from 'vue-router'; +import { unref } from 'vue'; + +import { useMultipleTabStore } from '/@/store/modules/multipleTab'; +import { useAppStore } from '/@/store/modules/app'; + +enum TableActionEnum { + REFRESH, + CLOSE_ALL, + CLOSE_LEFT, + CLOSE_RIGHT, + CLOSE_OTHER, + CLOSE_CURRENT, + CLOSE, +} + +export function useTabs(_router?: Router) { + const appStore = useAppStore(); + + function canIUseTabs(): boolean { + const { show } = appStore.getMultiTabsSetting; + if (!show) { + throw new Error('The multi-tab page is currently not open, please open it in the settings!'); + } + return show; + } + + const tabStore = useMultipleTabStore(); + const router = _router || useRouter(); + + const { currentRoute } = router; + + function getCurrentTab() { + const route = unref(currentRoute); + return tabStore.getTabList.find((item) => item.fullPath === route.fullPath)!; + } + + async function updateTabTitle(title: string, tab?: RouteLocationNormalized) { + const canIUse = canIUseTabs; + if (!canIUse) { + return; + } + const targetTab = tab || getCurrentTab(); + await tabStore.setTabTitle(title, targetTab); + } + + async function updateTabPath(path: string, tab?: RouteLocationNormalized) { + const canIUse = canIUseTabs; + if (!canIUse) { + return; + } + const targetTab = tab || getCurrentTab(); + await tabStore.updateTabPath(path, targetTab); + } + + async function handleTabAction(action: TableActionEnum, tab?: RouteLocationNormalized) { + const canIUse = canIUseTabs; + if (!canIUse) { + return; + } + const currentTab = getCurrentTab(); + switch (action) { + case TableActionEnum.REFRESH: + await tabStore.refreshPage(router); + break; + + case TableActionEnum.CLOSE_ALL: + await tabStore.closeAllTab(router); + break; + + case TableActionEnum.CLOSE_LEFT: + await tabStore.closeLeftTabs(currentTab, router); + break; + + case TableActionEnum.CLOSE_RIGHT: + await tabStore.closeRightTabs(currentTab, router); + break; + + case TableActionEnum.CLOSE_OTHER: + await tabStore.closeOtherTabs(currentTab, router); + break; + + case TableActionEnum.CLOSE_CURRENT: + case TableActionEnum.CLOSE: + await tabStore.closeTab(tab || currentTab, router); + break; + } + } + + return { + refreshPage: () => handleTabAction(TableActionEnum.REFRESH), + closeAll: () => handleTabAction(TableActionEnum.CLOSE_ALL), + closeLeft: () => handleTabAction(TableActionEnum.CLOSE_LEFT), + closeRight: () => handleTabAction(TableActionEnum.CLOSE_RIGHT), + closeOther: () => handleTabAction(TableActionEnum.CLOSE_OTHER), + closeCurrent: () => handleTabAction(TableActionEnum.CLOSE_CURRENT), + close: (tab?: RouteLocationNormalized) => handleTabAction(TableActionEnum.CLOSE, tab), + setTitle: (title: string, tab?: RouteLocationNormalized) => updateTabTitle(title, tab), + updatePath: (fullPath: string, tab?: RouteLocationNormalized) => updateTabPath(fullPath, tab), + }; +} diff --git a/src/hooks/web/useTitle.ts b/src/hooks/web/useTitle.ts new file mode 100644 index 0000000..675a5db --- /dev/null +++ b/src/hooks/web/useTitle.ts @@ -0,0 +1,34 @@ +import { watch, unref } from 'vue'; +import { useI18n } from '/@/hooks/web/useI18n'; +import { useTitle as usePageTitle } from '@vueuse/core'; +import { useGlobSetting } from '/@/hooks/setting'; +import { useRouter } from 'vue-router'; +import { useLocaleStore } from '/@/store/modules/locale'; +import { REDIRECT_NAME } from '/@/router/constant'; + +/** + * Listening to page changes and dynamically changing site titles + */ +export function useTitle() { + const { title } = useGlobSetting(); + const { t } = useI18n(); + const { currentRoute } = useRouter(); + const localeStore = useLocaleStore(); + + const pageTitle = usePageTitle(); + + watch( + [() => currentRoute.value.path, () => localeStore.getLocale], + () => { + const route = unref(currentRoute); + + if (route.name === REDIRECT_NAME) { + return; + } + + const tTitle = t(route?.meta?.title as string); + pageTitle.value = tTitle ? ` ${tTitle} - ${title} ` : `${title}`; + }, + { immediate: true }, + ); +} diff --git a/src/hooks/web/useWatermark.ts b/src/hooks/web/useWatermark.ts new file mode 100644 index 0000000..5840c14 --- /dev/null +++ b/src/hooks/web/useWatermark.ts @@ -0,0 +1,106 @@ +import { getCurrentInstance, onBeforeUnmount, ref, Ref, shallowRef, unref } from 'vue'; +import { useRafThrottle } from '/@/utils/domUtils'; +import { addResizeListener, removeResizeListener } from '/@/utils/event'; +import { isDef } from '/@/utils/is'; + +const domSymbol = Symbol('watermark-dom'); +const sourceMap = new WeakMap(); + +export function useWatermark( + appendEl: Ref = ref(document.body) as Ref, +) { + const appendElRaw = unref(appendEl); + if (appendElRaw && sourceMap.has(appendElRaw)) { + return sourceMap.get(appendElRaw); + } + const func = useRafThrottle(function () { + const el = unref(appendEl); + if (!el) return; + const { clientHeight: height, clientWidth: width } = el; + updateWatermark({ height, width }); + }); + const id = domSymbol.toString(); + const watermarkEl = shallowRef(); + + const clear = () => { + const domId = unref(watermarkEl); + watermarkEl.value = undefined; + const el = unref(appendEl); + if (!el) return; + domId && el.removeChild(domId); + removeResizeListener(el, func); + }; + + function createBase64(str: string) { + const can = document.createElement('canvas'); + const width = 300; + const height = 240; + Object.assign(can, { width, height }); + + const cans = can.getContext('2d'); + if (cans) { + cans.rotate((-20 * Math.PI) / 120); + cans.font = '15px Vedana'; + cans.fillStyle = 'rgba(0, 0, 0, 0.15)'; + cans.textAlign = 'left'; + cans.textBaseline = 'middle'; + cans.fillText(str, width / 20, height); + } + return can.toDataURL('image/png'); + } + + function updateWatermark( + options: { + width?: number; + height?: number; + str?: string; + } = {}, + ) { + const el = unref(watermarkEl); + if (!el) return; + if (isDef(options.width)) { + el.style.width = `${options.width}px`; + } + if (isDef(options.height)) { + el.style.height = `${options.height}px`; + } + if (isDef(options.str)) { + el.style.background = `url(${createBase64(options.str)}) left top repeat`; + } + } + + const createWatermark = (str: string) => { + if (unref(watermarkEl)) { + updateWatermark({ str }); + return id; + } + const div = document.createElement('div'); + watermarkEl.value = div; + div.id = id; + div.style.pointerEvents = 'none'; + div.style.top = '0px'; + div.style.left = '0px'; + div.style.position = 'absolute'; + div.style.zIndex = '100000'; + const el = unref(appendEl); + if (!el) return id; + const { clientHeight: height, clientWidth: width } = el; + updateWatermark({ str, width, height }); + el.appendChild(div); + sourceMap.set(el, { setWatermark, clear }); + return id; + }; + + function setWatermark(str: string) { + createWatermark(str); + addResizeListener(document.documentElement, func); + const instance = getCurrentInstance(); + if (instance) { + onBeforeUnmount(() => { + clear(); + }); + } + } + + return { setWatermark, clear }; +} diff --git a/src/layouts/.DS_Store b/src/layouts/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..319577c31122da71d90971560edd0d1246c265b9 GIT binary patch literal 6148 zcmeHKJ5Iwu5S?`_2!tXf<+hY5(omVmoFEr~;3S~fvV}!5~=0_=)xL%%IPKF&Xx~l$J-Qt zkpX^prrs?xy2{HHEW9y3cCYU@eO}o&ysAguEt+lgiDl@7 zo>0v*>M3X~yGiYIetm2osHL?=QTA5S@@dsUp6iIILJiyF8YWkVwt@Uj>_G0u-jkPe zn-~MefHCls4B*UW8BYXlHU^9VW1wMxzYiXRF;T1q!>0pNXaRsR)Io5~y#&X2#YC|d zgazUx6eyuiTMQ@R(0lbu6l*~VC#TJa)67mg6c@5%eIMM(C4x2^1I9p`fsx!!`TV~f z?*H3Cc4rJ21OJKv7pKc~fk)D_wexU%)_ROP3>NmQ1)C6DgrgX~d=y_|1cBc31u#*p S1)+i1k3gWoCS%}N8TbO)eqw$A literal 0 HcmV?d00001 diff --git a/src/layouts/default/content/index.vue b/src/layouts/default/content/index.vue new file mode 100644 index 0000000..00cad20 --- /dev/null +++ b/src/layouts/default/content/index.vue @@ -0,0 +1,53 @@ + + + diff --git a/src/layouts/default/content/useContentContext.ts b/src/layouts/default/content/useContentContext.ts new file mode 100644 index 0000000..f12e77b --- /dev/null +++ b/src/layouts/default/content/useContentContext.ts @@ -0,0 +1,17 @@ +import type { InjectionKey, ComputedRef } from 'vue'; +import { createContext, useContext } from '/@/hooks/core/useContext'; + +export interface ContentContextProps { + contentHeight: ComputedRef; + setPageHeight: (height: number) => Promise; +} + +const key: InjectionKey = Symbol(); + +export function createContentContext(context: ContentContextProps) { + return createContext(context, key, { native: true }); +} + +export function useContentContext() { + return useContext(key); +} diff --git a/src/layouts/default/content/useContentViewHeight.ts b/src/layouts/default/content/useContentViewHeight.ts new file mode 100644 index 0000000..8dd63fa --- /dev/null +++ b/src/layouts/default/content/useContentViewHeight.ts @@ -0,0 +1,41 @@ +import { ref, computed, unref } from 'vue'; +import { createPageContext } from '/@/hooks/component/usePageContext'; +import { useWindowSizeFn } from '@vben/hooks'; + +const headerHeightRef = ref(0); +const footerHeightRef = ref(0); + +export function useLayoutHeight() { + function setHeaderHeight(val) { + headerHeightRef.value = val; + } + function setFooterHeight(val) { + footerHeightRef.value = val; + } + return { headerHeightRef, footerHeightRef, setHeaderHeight, setFooterHeight }; +} + +export function useContentViewHeight() { + const contentHeight = ref(window.innerHeight); + const pageHeight = ref(window.innerHeight); + const getViewHeight = computed(() => { + return unref(contentHeight) - unref(headerHeightRef) - unref(footerHeightRef) || 0; + }); + + useWindowSizeFn( + () => { + contentHeight.value = window.innerHeight; + }, + { wait: 100, immediate: true }, + ); + + async function setPageHeight(height: number) { + pageHeight.value = height; + } + + createPageContext({ + contentHeight: getViewHeight, + setPageHeight, + pageHeight, + }); +} diff --git a/src/layouts/default/feature/index.vue b/src/layouts/default/feature/index.vue new file mode 100644 index 0000000..3595848 --- /dev/null +++ b/src/layouts/default/feature/index.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/src/layouts/default/footer/index.vue b/src/layouts/default/footer/index.vue new file mode 100644 index 0000000..c687fa3 --- /dev/null +++ b/src/layouts/default/footer/index.vue @@ -0,0 +1,95 @@ + + + + diff --git a/src/layouts/default/header/MultipleHeader.vue b/src/layouts/default/header/MultipleHeader.vue new file mode 100644 index 0000000..7244221 --- /dev/null +++ b/src/layouts/default/header/MultipleHeader.vue @@ -0,0 +1,126 @@ + + + diff --git a/src/layouts/default/header/components/Breadcrumb.vue b/src/layouts/default/header/components/Breadcrumb.vue new file mode 100644 index 0000000..1869d18 --- /dev/null +++ b/src/layouts/default/header/components/Breadcrumb.vue @@ -0,0 +1,204 @@ + + + diff --git a/src/layouts/default/header/components/ErrorAction.vue b/src/layouts/default/header/components/ErrorAction.vue new file mode 100644 index 0000000..086f2ff --- /dev/null +++ b/src/layouts/default/header/components/ErrorAction.vue @@ -0,0 +1,47 @@ + + diff --git a/src/layouts/default/header/components/FullScreen.vue b/src/layouts/default/header/components/FullScreen.vue new file mode 100644 index 0000000..2e124b5 --- /dev/null +++ b/src/layouts/default/header/components/FullScreen.vue @@ -0,0 +1,45 @@ + + diff --git a/src/layouts/default/header/components/index.ts b/src/layouts/default/header/components/index.ts new file mode 100644 index 0000000..09e767e --- /dev/null +++ b/src/layouts/default/header/components/index.ts @@ -0,0 +1,14 @@ +import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; +import FullScreen from './FullScreen.vue'; + +export const UserDropDown = createAsyncComponent(() => import('./user-dropdown/index.vue'), { + loading: true, +}); + +export const LayoutBreadcrumb = createAsyncComponent(() => import('./Breadcrumb.vue')); + +export const Notify = createAsyncComponent(() => import('./notify/index.vue')); + +export const ErrorAction = createAsyncComponent(() => import('./ErrorAction.vue')); + +export { FullScreen }; diff --git a/src/layouts/default/header/components/lock/LockModal.vue b/src/layouts/default/header/components/lock/LockModal.vue new file mode 100644 index 0000000..daca092 --- /dev/null +++ b/src/layouts/default/header/components/lock/LockModal.vue @@ -0,0 +1,127 @@ + + + diff --git a/src/layouts/default/header/components/notify/NoticeList.vue b/src/layouts/default/header/components/notify/NoticeList.vue new file mode 100644 index 0000000..022feea --- /dev/null +++ b/src/layouts/default/header/components/notify/NoticeList.vue @@ -0,0 +1,190 @@ + + + diff --git a/src/layouts/default/header/components/notify/data.ts b/src/layouts/default/header/components/notify/data.ts new file mode 100644 index 0000000..15d524d --- /dev/null +++ b/src/layouts/default/header/components/notify/data.ts @@ -0,0 +1,193 @@ +export interface ListItem { + id: string; + avatar: string; + // 通知的标题内容 + title: string; + // 是否在标题上显示删除线 + titleDelete?: boolean; + datetime: string; + type: string; + read?: boolean; + description: string; + clickClose?: boolean; + extra?: string; + color?: string; +} + +export interface TabItem { + key: string; + name: string; + list: ListItem[]; + unreadlist?: ListItem[]; +} + +export const tabListData: TabItem[] = [ + { + key: '1', + name: '通知', + list: [ + { + id: '000000001', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', + title: '你收到了 14 份新周报', + description: '', + datetime: '2017-08-09', + type: '1', + }, + { + id: '000000002', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png', + title: '你推荐的 曲妮妮 已通过第三轮面试', + description: '', + datetime: '2017-08-08', + type: '1', + }, + { + id: '000000003', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png', + title: '这种模板可以区分多种通知类型', + description: '', + datetime: '2017-08-07', + // read: true, + type: '1', + }, + { + id: '000000004', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', + title: '左侧图标用于区分不同的类型', + description: '', + datetime: '2017-08-07', + type: '1', + }, + { + id: '000000005', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', + title: + '标题可以设置自动显示省略号,本例中标题行数已设为1行,如果内容超过1行将自动截断并支持tooltip显示完整标题。', + description: '', + datetime: '2017-08-07', + type: '1', + }, + { + id: '000000006', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', + title: '左侧图标用于区分不同的类型', + description: '', + datetime: '2017-08-07', + type: '1', + }, + { + id: '000000007', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', + title: '左侧图标用于区分不同的类型', + description: '', + datetime: '2017-08-07', + type: '1', + }, + { + id: '000000008', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', + title: '左侧图标用于区分不同的类型', + description: '', + datetime: '2017-08-07', + type: '1', + }, + { + id: '000000009', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', + title: '左侧图标用于区分不同的类型', + description: '', + datetime: '2017-08-07', + type: '1', + }, + { + id: '000000010', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', + title: '左侧图标用于区分不同的类型', + description: '', + datetime: '2017-08-07', + type: '1', + }, + ], + }, + { + key: '2', + name: '消息', + list: [ + { + id: '000000006', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', + title: '曲丽丽 评论了你', + description: '描述信息描述信息描述信息', + datetime: '2017-08-07', + type: '2', + clickClose: true, + }, + { + id: '000000007', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', + title: '朱偏右 回复了你', + description: '这种模板用于提醒谁与你发生了互动', + datetime: '2017-08-07', + type: '2', + clickClose: true, + }, + { + id: '000000008', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', + title: '标题', + description: + '请将鼠标移动到此处,以便测试超长的消息在此处将如何处理。本例中设置的描述最大行数为2,超过2行的描述内容将被省略并且可以通过tooltip查看完整内容', + datetime: '2017-08-07', + type: '2', + clickClose: true, + }, + ], + }, + { + key: '3', + name: '待办', + list: [ + { + id: '000000009', + avatar: '', + title: '任务名称', + description: '任务需要在 2017-01-12 20:00 前启动', + datetime: '', + extra: '未开始', + color: '', + type: '3', + }, + { + id: '000000010', + avatar: '', + title: '第三方紧急代码变更', + description: '冠霖 需在 2017-01-07 前完成代码变更任务', + datetime: '', + extra: '马上到期', + color: 'red', + type: '3', + }, + { + id: '000000011', + avatar: '', + title: '信息安全考试', + description: '指派竹尔于 2017-01-09 前完成更新并发布', + datetime: '', + extra: '已耗时 8 天', + color: 'gold', + type: '3', + }, + { + id: '000000012', + avatar: '', + title: 'ABCD 版本发布', + description: '指派竹尔于 2017-01-09 前完成更新并发布', + datetime: '', + extra: '进行中', + color: 'blue', + type: '3', + }, + ], + }, +]; diff --git a/src/layouts/default/header/components/notify/index.vue b/src/layouts/default/header/components/notify/index.vue new file mode 100644 index 0000000..e6883bb --- /dev/null +++ b/src/layouts/default/header/components/notify/index.vue @@ -0,0 +1,93 @@ + + + diff --git a/src/layouts/default/header/components/user-dropdown/DropMenuItem.vue b/src/layouts/default/header/components/user-dropdown/DropMenuItem.vue new file mode 100644 index 0000000..6f2b903 --- /dev/null +++ b/src/layouts/default/header/components/user-dropdown/DropMenuItem.vue @@ -0,0 +1,32 @@ + + diff --git a/src/layouts/default/header/components/user-dropdown/index.vue b/src/layouts/default/header/components/user-dropdown/index.vue new file mode 100644 index 0000000..11f9318 --- /dev/null +++ b/src/layouts/default/header/components/user-dropdown/index.vue @@ -0,0 +1,191 @@ + + + diff --git a/src/layouts/default/header/index.less b/src/layouts/default/header/index.less new file mode 100644 index 0000000..bfa2e90 --- /dev/null +++ b/src/layouts/default/header/index.less @@ -0,0 +1,196 @@ +@header-trigger-prefix-cls: ~'@{namespace}-layout-header-trigger'; +@header-prefix-cls: ~'@{namespace}-layout-header'; +@breadcrumb-prefix-cls: ~'@{namespace}-layout-breadcrumb'; +@logo-prefix-cls: ~'@{namespace}-app-logo'; + +.ant-layout .@{header-prefix-cls} { + display: flex; + align-items: center; + justify-content: space-between; + height: @header-height; + margin-left: -1px; + padding: 0; + background-color: @white; + color: @white; + line-height: @header-height; + + &--mobile { + .@{breadcrumb-prefix-cls}, + .error-action, + .notify-item, + .fullscreen-item { + display: none; + } + + .@{logo-prefix-cls} { + min-width: unset; + padding-right: 0; + + &__title { + display: none; + } + } + .@{header-trigger-prefix-cls} { + padding: 0 4px 0 8px !important; + } + .@{header-prefix-cls}-action { + padding-right: 4px; + } + } + + &--fixed { + position: fixed; + z-index: @layout-header-fixed-z-index; + top: 0; + left: 0; + width: 100%; + } + + &-logo { + min-width: 192px; + height: @header-height; + padding: 0 10px; + font-size: 14px; + + img { + width: @logo-width; + height: @logo-width; + margin-right: 2px; + } + } + + &-left { + display: flex; + align-items: center; + height: 100%; + + .@{header-trigger-prefix-cls} { + display: flex; + align-items: center; + height: 100%; + padding: 1px 10px 0; + cursor: pointer; + + .anticon { + font-size: 16px; + } + + &.light { + &:hover { + background-color: @header-light-bg-hover-color; + } + + svg { + fill: #000; + } + } + + &.dark { + &:hover { + background-color: @header-dark-bg-hover-color; + } + } + } + } + + &-menu { + flex: 1; + align-items: center; + min-width: 0; + height: 100%; + } + + &-action { + display: flex; + // padding-right: 12px; + align-items: center; + min-width: 180px; + + &__item { + display: flex !important; + align-items: center; + height: @header-height; + padding: 0 2px; + font-size: 1.2em; + cursor: pointer; + + .ant-badge { + height: @header-height; + line-height: @header-height; + } + + .ant-badge-dot { + top: 14px; + right: 2px; + } + } + + span[role='img'] { + padding: 0 8px; + } + } + + &--light { + border-bottom: 1px solid @header-light-bottom-border-color; + border-left: 1px solid @header-light-bottom-border-color; + background-color: @white !important; + + .@{header-prefix-cls}-logo { + color: @text-color-base; + + &:hover { + background-color: @header-light-bg-hover-color; + } + } + + .@{header-prefix-cls}-action { + &__item { + color: @text-color-base; + + .app-iconify { + padding: 0 10px; + font-size: 16px !important; + } + + &:hover { + background-color: @header-light-bg-hover-color; + } + } + + &-icon, + span[role='img'] { + color: @text-color-base; + } + } + } + + &--dark { + border-bottom: 1px solid #303030; + border-left: 1px solid @border-color-base; + background-color: @header-dark-bg-color !important; + .@{header-prefix-cls}-logo { + &:hover { + background-color: @header-dark-bg-hover-color; + } + } + + .@{header-prefix-cls}-action { + &__item { + .app-iconify { + padding: 0 10px; + font-size: 16px !important; + } + + .ant-badge { + span { + color: @white; + } + } + + &:hover { + background-color: @header-dark-bg-hover-color; + } + } + } + } +} \ No newline at end of file diff --git a/src/layouts/default/header/index.vue b/src/layouts/default/header/index.vue new file mode 100644 index 0000000..2ffd43c --- /dev/null +++ b/src/layouts/default/header/index.vue @@ -0,0 +1,153 @@ + + + diff --git a/src/layouts/default/index.vue b/src/layouts/default/index.vue new file mode 100644 index 0000000..de7fcae --- /dev/null +++ b/src/layouts/default/index.vue @@ -0,0 +1,92 @@ + + + + diff --git a/src/layouts/default/menu/index.vue b/src/layouts/default/menu/index.vue new file mode 100644 index 0000000..35f8fcf --- /dev/null +++ b/src/layouts/default/menu/index.vue @@ -0,0 +1,197 @@ + + diff --git a/src/layouts/default/menu/useLayoutMenu.ts b/src/layouts/default/menu/useLayoutMenu.ts new file mode 100644 index 0000000..33c7768 --- /dev/null +++ b/src/layouts/default/menu/useLayoutMenu.ts @@ -0,0 +1,109 @@ +import type { Menu } from '/@/router/types'; +import type { Ref } from 'vue'; +import { watch, unref, ref, computed } from 'vue'; +import { useRouter } from 'vue-router'; +import { MenuSplitTyeEnum } from '/@/enums/menuEnum'; +import { useThrottleFn } from '@vueuse/core'; +import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; +import { getChildrenMenus, getCurrentParentPath, getMenus, getShallowMenus } from '/@/router/menus'; +import { usePermissionStore } from '/@/store/modules/permission'; +import { useAppInject } from '/@/hooks/web/useAppInject'; + +export function useSplitMenu(splitType: Ref) { + // Menu array + const menusRef = ref([]); + const { currentRoute } = useRouter(); + const { getIsMobile } = useAppInject(); + const permissionStore = usePermissionStore(); + const { setMenuSetting, getIsHorizontal, getSplit } = useMenuSetting(); + + const throttleHandleSplitLeftMenu = useThrottleFn(handleSplitLeftMenu, 50); + + const splitNotLeft = computed( + () => unref(splitType) !== MenuSplitTyeEnum.LEFT && !unref(getIsHorizontal), + ); + + const getSplitLeft = computed( + () => !unref(getSplit) || unref(splitType) !== MenuSplitTyeEnum.LEFT, + ); + + const getSpiltTop = computed(() => unref(splitType) === MenuSplitTyeEnum.TOP); + + const normalType = computed(() => { + return unref(splitType) === MenuSplitTyeEnum.NONE || !unref(getSplit); + }); + + watch( + [() => unref(currentRoute).path, () => unref(splitType)], + async ([path]: [string, MenuSplitTyeEnum]) => { + if (unref(splitNotLeft) || unref(getIsMobile)) return; + + const { meta } = unref(currentRoute); + const currentActiveMenu = meta.currentActiveMenu as string; + let parentPath = await getCurrentParentPath(path); + if (!parentPath) { + parentPath = await getCurrentParentPath(currentActiveMenu); + } + parentPath && throttleHandleSplitLeftMenu(parentPath); + }, + { + immediate: true, + }, + ); + + // Menu changes + watch( + [() => permissionStore.getLastBuildMenuTime, () => permissionStore.getBackMenuList], + () => { + genMenus(); + }, + { + immediate: true, + }, + ); + + // split Menu changes + watch( + () => getSplit.value, + () => { + if (unref(splitNotLeft)) return; + genMenus(); + }, + ); + + // Handle left menu split + async function handleSplitLeftMenu(parentPath: string) { + if (unref(getSplitLeft) || unref(getIsMobile)) return; + + // spilt mode left + const children = await getChildrenMenus(parentPath); + + if (!children || !children.length) { + setMenuSetting({ hidden: true }); + menusRef.value = []; + return; + } + + setMenuSetting({ hidden: false }); + menusRef.value = children; + } + + // get menus + async function genMenus() { + // normal mode + if (unref(normalType) || unref(getIsMobile)) { + menusRef.value = await getMenus(); + return; + } + + // split-top + if (unref(getSpiltTop)) { + const shallowMenus = await getShallowMenus(); + + menusRef.value = shallowMenus; + return; + } + } + + return { menusRef }; +} diff --git a/src/layouts/default/setting/SettingDrawer.tsx b/src/layouts/default/setting/SettingDrawer.tsx new file mode 100644 index 0000000..e924e7f --- /dev/null +++ b/src/layouts/default/setting/SettingDrawer.tsx @@ -0,0 +1,427 @@ +import { defineComponent, computed, unref } from 'vue'; +import { BasicDrawer } from '/@/components/Drawer/index'; +import { Divider } from 'ant-design-vue'; +import { + TypePicker, + ThemeColorPicker, + SettingFooter, + SwitchItem, + SelectItem, + InputNumberItem, +} from './components'; + +import { AppDarkModeToggle } from '/@/components/Application'; + +import { MenuTypeEnum, TriggerEnum } from '/@/enums/menuEnum'; + +import { useRootSetting } from '/@/hooks/setting/useRootSetting'; +import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; +import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting'; +import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting'; +import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting'; +import { useI18n } from '/@/hooks/web/useI18n'; + +import { baseHandler } from './handler'; + +import { + HandlerEnum, + contentModeOptions, + topMenuAlignOptions, + getMenuTriggerOptions, + routerTransitionOptions, + menuTypeList, + mixSidebarTriggerOptions, +} from './enum'; + +import { +// HEADER_PRESET_BG_COLOR_LIST, +// SIDE_BAR_BG_COLOR_LIST, + APP_PRESET_COLOR_LIST, + } from '/@/settings/designSetting'; + +const { t } = useI18n(); + +export default defineComponent({ + name: 'SettingDrawer', + setup(_, { attrs }) { + const { + getContentMode, + getShowFooter, + getShowBreadCrumb, + getShowBreadCrumbIcon, + getShowLogo, + getFullContent, + getColorWeak, + getGrayMode, + getLockTime, + getShowDarkModeToggle, + getThemeColor, + } = useRootSetting(); + + const { getOpenPageLoading, getBasicTransition, getEnableTransition, getOpenNProgress } = + useTransitionSetting(); + + const { + getIsHorizontal, + getShowMenu, + getMenuType, + getTrigger, + getCollapsedShowTitle, + getMenuFixed, + getCollapsed, + getCanDrag, + getTopMenuAlign, + getAccordion, + getMenuWidth, + // getMenuBgColor, + getIsTopMenu, + getSplit, + getIsMixSidebar, + getCloseMixSidebarOnChange, + getMixSideTrigger, + getMixSideFixed, + } = useMenuSetting(); + + const { + getShowHeader, + getFixed: getHeaderFixed, + // getHeaderBgColor, + getShowSearch, + } = useHeaderSetting(); + + const { getShowMultipleTab, getShowQuick, getShowRedo, getShowFold } = useMultipleTabSetting(); + + const getShowMenuRef = computed(() => { + return unref(getShowMenu) && !unref(getIsHorizontal); + }); + + function renderSidebar() { + return ( + <> + { + baseHandler(HandlerEnum.CHANGE_LAYOUT, { + mode: item.mode, + type: item.type, + split: unref(getIsHorizontal) ? false : undefined, + }); + }} + def={unref(getMenuType)} + /> + + ); + } + + // function renderHeaderTheme() { + // return ( + // + // ); + // } + + // function renderSiderTheme() { + // return ( + // + // ); + // } + + function renderMainTheme() { + return ( + + ); + } + + /** + * @description: + */ + function renderFeatures() { + let triggerDef = unref(getTrigger); + + const triggerOptions = getMenuTriggerOptions(unref(getSplit)); + const some = triggerOptions.some((item) => item.value === triggerDef); + if (!some) { + triggerDef = TriggerEnum.FOOTER; + } + + return ( + <> + + + + + + + + + + + + + + + + + + + { + return parseInt(value) === 0 + ? `0(${t('layout.setting.notAutoScreenLock')})` + : `${value}${t('layout.setting.minute')}`; + }} + /> + `${parseInt(value)}px`} + /> + + ); + } + + function renderContent() { + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + ); + } + + function renderTransition() { + return ( + <> + + + + + + + + ); + } + + return () => ( + + {unref(getShowDarkModeToggle) && {() => t('layout.setting.darkMode')}} + {unref(getShowDarkModeToggle) && } + {() => t('layout.setting.navMode')} + {renderSidebar()} + {/*{ {() => t('layout.setting.sysTheme')} }*/} + {/*{renderMainTheme()}*/} + {/*{() => t('layout.setting.headerTheme')}*/} + {/*{renderHeaderTheme()}*/} + {/*{() => t('layout.setting.sidebarTheme')}*/} + {/*{renderSiderTheme()}*/} + {/*{() => t('layout.setting.interfaceFunction')}*/} + {/*{renderFeatures()}*/} + {() => t('layout.setting.interfaceDisplay')} + {renderContent()} + {/*{() => t('layout.setting.animation')}*/} + {/*{renderTransition()}*/} + + + + ); + }, +}); diff --git a/src/layouts/default/setting/components/InputNumberItem.vue b/src/layouts/default/setting/components/InputNumberItem.vue new file mode 100644 index 0000000..9f350ef --- /dev/null +++ b/src/layouts/default/setting/components/InputNumberItem.vue @@ -0,0 +1,56 @@ + + + diff --git a/src/layouts/default/setting/components/SelectItem.vue b/src/layouts/default/setting/components/SelectItem.vue new file mode 100644 index 0000000..676ca91 --- /dev/null +++ b/src/layouts/default/setting/components/SelectItem.vue @@ -0,0 +1,75 @@ + + + diff --git a/src/layouts/default/setting/components/SettingFooter.vue b/src/layouts/default/setting/components/SettingFooter.vue new file mode 100644 index 0000000..d243795 --- /dev/null +++ b/src/layouts/default/setting/components/SettingFooter.vue @@ -0,0 +1,100 @@ + + + diff --git a/src/layouts/default/setting/components/SwitchItem.vue b/src/layouts/default/setting/components/SwitchItem.vue new file mode 100644 index 0000000..ff27477 --- /dev/null +++ b/src/layouts/default/setting/components/SwitchItem.vue @@ -0,0 +1,66 @@ + + + diff --git a/src/layouts/default/setting/components/ThemeColorPicker.vue b/src/layouts/default/setting/components/ThemeColorPicker.vue new file mode 100644 index 0000000..95c73a0 --- /dev/null +++ b/src/layouts/default/setting/components/ThemeColorPicker.vue @@ -0,0 +1,88 @@ + + + diff --git a/src/layouts/default/setting/components/TypePicker.vue b/src/layouts/default/setting/components/TypePicker.vue new file mode 100644 index 0000000..d13f7d7 --- /dev/null +++ b/src/layouts/default/setting/components/TypePicker.vue @@ -0,0 +1,179 @@ + + + diff --git a/src/layouts/default/setting/components/index.ts b/src/layouts/default/setting/components/index.ts new file mode 100644 index 0000000..bd24888 --- /dev/null +++ b/src/layouts/default/setting/components/index.ts @@ -0,0 +1,8 @@ +import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; + +export const TypePicker = createAsyncComponent(() => import('./TypePicker.vue')); +export const ThemeColorPicker = createAsyncComponent(() => import('./ThemeColorPicker.vue')); +export const SettingFooter = createAsyncComponent(() => import('./SettingFooter.vue')); +export const SwitchItem = createAsyncComponent(() => import('./SwitchItem.vue')); +export const SelectItem = createAsyncComponent(() => import('./SelectItem.vue')); +export const InputNumberItem = createAsyncComponent(() => import('./InputNumberItem.vue')); diff --git a/src/layouts/default/setting/enum.ts b/src/layouts/default/setting/enum.ts new file mode 100644 index 0000000..1e9633a --- /dev/null +++ b/src/layouts/default/setting/enum.ts @@ -0,0 +1,156 @@ +import { ContentEnum, RouterTransitionEnum } from '/@/enums/appEnum'; +import { + MenuModeEnum, + MenuTypeEnum, + TopMenuAlignEnum, + TriggerEnum, + MixSidebarTriggerEnum, +} from '/@/enums/menuEnum'; + +import { useI18n } from '/@/hooks/web/useI18n'; + +const { t } = useI18n(); + +export enum HandlerEnum { + CHANGE_LAYOUT, + CHANGE_THEME_COLOR, + CHANGE_THEME, + // menu + MENU_HAS_DRAG, + MENU_ACCORDION, + MENU_TRIGGER, + MENU_TOP_ALIGN, + MENU_COLLAPSED, + MENU_COLLAPSED_SHOW_TITLE, + MENU_WIDTH, + MENU_SHOW_SIDEBAR, + MENU_THEME, + MENU_SPLIT, + MENU_FIXED, + MENU_CLOSE_MIX_SIDEBAR_ON_CHANGE, + MENU_TRIGGER_MIX_SIDEBAR, + MENU_FIXED_MIX_SIDEBAR, + + // header + HEADER_SHOW, + HEADER_THEME, + HEADER_FIXED, + + HEADER_SEARCH, + + TABS_SHOW_QUICK, + TABS_SHOW_REDO, + TABS_SHOW, + TABS_SHOW_FOLD, + + LOCK_TIME, + FULL_CONTENT, + CONTENT_MODE, + SHOW_BREADCRUMB, + SHOW_BREADCRUMB_ICON, + GRAY_MODE, + COLOR_WEAK, + SHOW_LOGO, + SHOW_FOOTER, + + ROUTER_TRANSITION, + OPEN_PROGRESS, + OPEN_PAGE_LOADING, + OPEN_ROUTE_TRANSITION, +} + +export const contentModeOptions = [ + { + value: ContentEnum.FULL, + label: t('layout.setting.contentModeFull'), + }, + { + value: ContentEnum.FIXED, + label: t('layout.setting.contentModeFixed'), + }, +]; + +export const topMenuAlignOptions = [ + { + value: TopMenuAlignEnum.CENTER, + label: t('layout.setting.topMenuAlignRight'), + }, + { + value: TopMenuAlignEnum.START, + label: t('layout.setting.topMenuAlignLeft'), + }, + { + value: TopMenuAlignEnum.END, + label: t('layout.setting.topMenuAlignCenter'), + }, +]; + +export const getMenuTriggerOptions = (hideTop: boolean) => { + return [ + { + value: TriggerEnum.NONE, + label: t('layout.setting.menuTriggerNone'), + }, + { + value: TriggerEnum.FOOTER, + label: t('layout.setting.menuTriggerBottom'), + }, + ...(hideTop + ? [] + : [ + { + value: TriggerEnum.HEADER, + label: t('layout.setting.menuTriggerTop'), + }, + ]), + ]; +}; + +export const routerTransitionOptions = [ + RouterTransitionEnum.ZOOM_FADE, + RouterTransitionEnum.FADE, + RouterTransitionEnum.ZOOM_OUT, + RouterTransitionEnum.FADE_SIDE, + RouterTransitionEnum.FADE_BOTTOM, + RouterTransitionEnum.FADE_SCALE, +].map((item) => { + return { + label: item, + value: item, + }; +}); + +export const menuTypeList = [ + { + title: t('layout.setting.menuTypeSidebar'), + mode: MenuModeEnum.INLINE, + type: MenuTypeEnum.SIDEBAR, + }, + { + title: t('layout.setting.menuTypeMix'), + mode: MenuModeEnum.INLINE, + type: MenuTypeEnum.MIX, + }, + + { + title: t('layout.setting.menuTypeTopMenu'), + mode: MenuModeEnum.HORIZONTAL, + type: MenuTypeEnum.TOP_MENU, + }, + { + title: t('layout.setting.menuTypeMixSidebar'), + mode: MenuModeEnum.INLINE, + type: MenuTypeEnum.MIX_SIDEBAR, + }, +]; + +export const mixSidebarTriggerOptions = [ + { + value: MixSidebarTriggerEnum.HOVER, + label: t('layout.setting.triggerHover'), + }, + { + value: MixSidebarTriggerEnum.CLICK, + label: t('layout.setting.triggerClick'), + }, +]; diff --git a/src/layouts/default/setting/handler.ts b/src/layouts/default/setting/handler.ts new file mode 100644 index 0000000..e541081 --- /dev/null +++ b/src/layouts/default/setting/handler.ts @@ -0,0 +1,172 @@ +import { HandlerEnum } from './enum'; +import { updateHeaderBgColor, updateSidebarBgColor } from '/@/logics/theme/updateBackground'; +import { updateColorWeak } from '/@/logics/theme/updateColorWeak'; +import { updateGrayMode } from '/@/logics/theme/updateGrayMode'; + +import { useAppStore } from '/@/store/modules/app'; +import { ProjectConfig } from '/#/config'; +import { updateDarkTheme } from '/@/logics/theme/dark'; +import { useRootSetting } from '/@/hooks/setting/useRootSetting'; + +export function baseHandler(event: HandlerEnum, value: any) { + const appStore = useAppStore(); + const config = handler(event, value); + appStore.setProjectConfig(config); + if (event === HandlerEnum.CHANGE_THEME) { + updateHeaderBgColor(); + updateSidebarBgColor(); + } +} + +export function handler(event: HandlerEnum, value: any): DeepPartial { + const appStore = useAppStore(); + + const { getThemeColor, getDarkMode } = useRootSetting(); + switch (event) { + case HandlerEnum.CHANGE_LAYOUT: + const { mode, type, split } = value; + const splitOpt = split === undefined ? { split } : {}; + + return { + menuSetting: { + mode, + type, + collapsed: false, + show: true, + hidden: false, + ...splitOpt, + }, + }; + + case HandlerEnum.CHANGE_THEME_COLOR: + if (getThemeColor.value === value) { + return {}; + } + + return { themeColor: value }; + + case HandlerEnum.CHANGE_THEME: + if (getDarkMode.value === value) { + return {}; + } + updateDarkTheme(value); + + return {}; + + case HandlerEnum.MENU_HAS_DRAG: + return { menuSetting: { canDrag: value } }; + + case HandlerEnum.MENU_ACCORDION: + return { menuSetting: { accordion: value } }; + + case HandlerEnum.MENU_TRIGGER: + return { menuSetting: { trigger: value } }; + + case HandlerEnum.MENU_TOP_ALIGN: + return { menuSetting: { topMenuAlign: value } }; + + case HandlerEnum.MENU_COLLAPSED: + return { menuSetting: { collapsed: value } }; + + case HandlerEnum.MENU_WIDTH: + return { menuSetting: { menuWidth: value } }; + + case HandlerEnum.MENU_SHOW_SIDEBAR: + return { menuSetting: { show: value } }; + + case HandlerEnum.MENU_COLLAPSED_SHOW_TITLE: + return { menuSetting: { collapsedShowTitle: value } }; + + case HandlerEnum.MENU_THEME: + updateSidebarBgColor(value); + return { menuSetting: { bgColor: value } }; + + case HandlerEnum.MENU_SPLIT: + return { menuSetting: { split: value } }; + + case HandlerEnum.MENU_CLOSE_MIX_SIDEBAR_ON_CHANGE: + return { menuSetting: { closeMixSidebarOnChange: value } }; + + case HandlerEnum.MENU_FIXED: + return { menuSetting: { fixed: value } }; + + case HandlerEnum.MENU_TRIGGER_MIX_SIDEBAR: + return { menuSetting: { mixSideTrigger: value } }; + + case HandlerEnum.MENU_FIXED_MIX_SIDEBAR: + return { menuSetting: { mixSideFixed: value } }; + + // ============transition================== + case HandlerEnum.OPEN_PAGE_LOADING: + appStore.setPageLoading(false); + return { transitionSetting: { openPageLoading: value } }; + + case HandlerEnum.ROUTER_TRANSITION: + return { transitionSetting: { basicTransition: value } }; + + case HandlerEnum.OPEN_ROUTE_TRANSITION: + return { transitionSetting: { enable: value } }; + + case HandlerEnum.OPEN_PROGRESS: + return { transitionSetting: { openNProgress: value } }; + // ============root================== + + case HandlerEnum.LOCK_TIME: + return { lockTime: value }; + + case HandlerEnum.FULL_CONTENT: + return { fullContent: value }; + + case HandlerEnum.CONTENT_MODE: + return { contentMode: value }; + + case HandlerEnum.SHOW_BREADCRUMB: + return { showBreadCrumb: value }; + + case HandlerEnum.SHOW_BREADCRUMB_ICON: + return { showBreadCrumbIcon: value }; + + case HandlerEnum.GRAY_MODE: + updateGrayMode(value); + return { grayMode: value }; + + case HandlerEnum.SHOW_FOOTER: + return { showFooter: value }; + + case HandlerEnum.COLOR_WEAK: + updateColorWeak(value); + return { colorWeak: value }; + + case HandlerEnum.SHOW_LOGO: + return { showLogo: value }; + + // ============tabs================== + case HandlerEnum.TABS_SHOW_QUICK: + return { multiTabsSetting: { showQuick: value } }; + + case HandlerEnum.TABS_SHOW: + return { multiTabsSetting: { show: value } }; + + case HandlerEnum.TABS_SHOW_REDO: + return { multiTabsSetting: { showRedo: value } }; + + case HandlerEnum.TABS_SHOW_FOLD: + return { multiTabsSetting: { showFold: value } }; + + // ============header================== + case HandlerEnum.HEADER_THEME: + updateHeaderBgColor(value); + return { headerSetting: { bgColor: value } }; + + case HandlerEnum.HEADER_SEARCH: + return { headerSetting: { showSearch: value } }; + + case HandlerEnum.HEADER_FIXED: + return { headerSetting: { fixed: value } }; + + case HandlerEnum.HEADER_SHOW: + return { headerSetting: { show: value } }; + default: + return {}; + } +} diff --git a/src/layouts/default/setting/index.vue b/src/layouts/default/setting/index.vue new file mode 100644 index 0000000..dd52c37 --- /dev/null +++ b/src/layouts/default/setting/index.vue @@ -0,0 +1,26 @@ + + diff --git a/src/layouts/default/sider/DragBar.vue b/src/layouts/default/sider/DragBar.vue new file mode 100644 index 0000000..ce74d85 --- /dev/null +++ b/src/layouts/default/sider/DragBar.vue @@ -0,0 +1,66 @@ + + + diff --git a/src/layouts/default/sider/LayoutSider.vue b/src/layouts/default/sider/LayoutSider.vue new file mode 100644 index 0000000..7fd712f --- /dev/null +++ b/src/layouts/default/sider/LayoutSider.vue @@ -0,0 +1,157 @@ + + + diff --git a/src/layouts/default/sider/MixSider.vue b/src/layouts/default/sider/MixSider.vue new file mode 100644 index 0000000..da05e97 --- /dev/null +++ b/src/layouts/default/sider/MixSider.vue @@ -0,0 +1,591 @@ + + + diff --git a/src/layouts/default/sider/index.vue b/src/layouts/default/sider/index.vue new file mode 100644 index 0000000..1f73fd7 --- /dev/null +++ b/src/layouts/default/sider/index.vue @@ -0,0 +1,59 @@ + + + + diff --git a/src/layouts/default/sider/useLayoutSider.ts b/src/layouts/default/sider/useLayoutSider.ts new file mode 100644 index 0000000..66656b2 --- /dev/null +++ b/src/layouts/default/sider/useLayoutSider.ts @@ -0,0 +1,143 @@ +import type { Ref } from 'vue'; + +import { computed, unref, onMounted, nextTick } from 'vue'; + +import { TriggerEnum } from '/@/enums/menuEnum'; + +import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; +import { useDebounceFn } from '@vueuse/core'; +import { useAppStore } from '/@/store/modules/app'; + +/** + * Handle related operations of menu events + */ +export function useSiderEvent() { + const appStore = useAppStore(); + const { getMiniWidthNumber } = useMenuSetting(); + + const getCollapsedWidth = computed(() => { + return unref(getMiniWidthNumber); + }); + + function onBreakpointChange(broken: boolean) { + appStore.setProjectConfig({ + menuSetting: { + siderHidden: broken, + }, + }); + } + + return { getCollapsedWidth, onBreakpointChange }; +} + +/** + * Handle related operations of menu folding + */ +export function useTrigger(getIsMobile: Ref) { + const { getTrigger, getSplit } = useMenuSetting(); + + const getShowTrigger = computed(() => { + const trigger = unref(getTrigger); + + return ( + trigger !== TriggerEnum.NONE && + !unref(getIsMobile) && + (trigger === TriggerEnum.FOOTER || unref(getSplit)) + ); + }); + + const getTriggerAttr = computed(() => { + if (unref(getShowTrigger)) { + return {}; + } + return { + trigger: null, + }; + }); + + return { getTriggerAttr, getShowTrigger }; +} + +/** + * Handle menu drag and drop related operations + * @param siderRef + * @param dragBarRef + */ +export function useDragLine(siderRef: Ref, dragBarRef: Ref, mix = false) { + const { getMiniWidthNumber, getCollapsed, setMenuSetting } = useMenuSetting(); + + onMounted(() => { + nextTick(() => { + const exec = useDebounceFn(changeWrapWidth, 80); + exec(); + }); + }); + + function getEl(elRef: Ref): any { + const el = unref(elRef); + if (!el) return null; + if (Reflect.has(el, '$el')) { + return (unref(elRef) as ComponentRef)?.$el; + } + return unref(elRef); + } + + function handleMouseMove(ele: HTMLElement, wrap: HTMLElement, clientX: number) { + document.onmousemove = function (innerE) { + let iT = (ele as any).left + (innerE.clientX - clientX); + innerE = innerE || window.event; + const maxT = 800; + const minT = unref(getMiniWidthNumber); + iT < 0 && (iT = 0); + iT > maxT && (iT = maxT); + iT < minT && (iT = minT); + ele.style.left = wrap.style.width = iT + 'px'; + return false; + }; + } + + // Drag and drop in the menu area-release the mouse + function removeMouseup(ele: any) { + const wrap = getEl(siderRef); + document.onmouseup = function () { + document.onmousemove = null; + document.onmouseup = null; + wrap.style.transition = 'width 0.2s'; + const width = parseInt(wrap.style.width); + + if (!mix) { + const miniWidth = unref(getMiniWidthNumber); + if (!unref(getCollapsed)) { + width > miniWidth + 20 + ? setMenuSetting({ menuWidth: width }) + : setMenuSetting({ collapsed: true }); + } else { + width > miniWidth && setMenuSetting({ collapsed: false, menuWidth: width }); + } + } else { + setMenuSetting({ menuWidth: width }); + } + + ele.releaseCapture?.(); + }; + } + + function changeWrapWidth() { + const ele = getEl(dragBarRef); + if (!ele) return; + const wrap = getEl(siderRef); + if (!wrap) return; + + ele.onmousedown = (e: any) => { + wrap.style.transition = 'unset'; + const clientX = e?.clientX; + ele.left = ele.offsetLeft; + handleMouseMove(ele, wrap, clientX); + removeMouseup(ele); + ele.setCapture?.(); + return false; + }; + } + + return {}; +} diff --git a/src/layouts/default/tabs/components/FoldButton.vue b/src/layouts/default/tabs/components/FoldButton.vue new file mode 100644 index 0000000..2deb1c0 --- /dev/null +++ b/src/layouts/default/tabs/components/FoldButton.vue @@ -0,0 +1,42 @@ + + diff --git a/src/layouts/default/tabs/components/TabContent.vue b/src/layouts/default/tabs/components/TabContent.vue new file mode 100644 index 0000000..431cbb1 --- /dev/null +++ b/src/layouts/default/tabs/components/TabContent.vue @@ -0,0 +1,76 @@ + + diff --git a/src/layouts/default/tabs/components/TabRedo.vue b/src/layouts/default/tabs/components/TabRedo.vue new file mode 100644 index 0000000..9c038aa --- /dev/null +++ b/src/layouts/default/tabs/components/TabRedo.vue @@ -0,0 +1,38 @@ + + + diff --git a/src/layouts/default/tabs/index.less b/src/layouts/default/tabs/index.less new file mode 100644 index 0000000..12523a0 --- /dev/null +++ b/src/layouts/default/tabs/index.less @@ -0,0 +1,199 @@ +@prefix-cls: ~'@{namespace}-multiple-tabs'; + +html[data-theme='light'] { + .@{prefix-cls} { + .ant-tabs-tab:not(.ant-tabs-tab-active) { + border: 1px solid #d9d9d9 !important; + } + } +} + +.@{prefix-cls} { + z-index: 10; + height: @multiple-height + 2; + border-bottom: 1px solid @border-color-base; + background-color: @component-background; + line-height: @multiple-height + 2; + + .ant-tabs-small { + height: @multiple-height; + } + + .ant-tabs.ant-tabs-card { + .ant-tabs-nav { + height: @multiple-height; + margin: 0; + padding-top: 2px; + border: 0; + background-color: @component-background; + box-shadow: none; + + .ant-tabs-nav-container { + height: @multiple-height; + padding-top: 2px; + } + + .ant-tabs-tab { + height: calc(@multiple-height - 2px); + padding-right: 12px; + transition: none; + background-color: @component-background; + color: @text-color-base; + line-height: calc(@multiple-height - 2px); + + &:hover { + .ant-tabs-tab-remove { + opacity: 1; + } + } + + .ant-tabs-tab-remove { + width: 8px; + height: 28px; + margin-right: -4px; + margin-left: 2px; + transition: none; + opacity: 0; + color: inherit; + font-size: 12px; + + &:hover { + svg { + width: 0.8em; + } + } + } + + // > div { + // display: flex; + // justify-content: center; + // align-items: center; + // } + + svg { + fill: @text-color-base; + } + } + + .ant-tabs-tab:not(.ant-tabs-tab-active) { + &:hover { + color: @primary-color; + } + } + + .ant-tabs-tab-active { + position: relative; + padding-left: 18px; + transition: none; + border: 0; + background: @primary-color; + + span { + color: @white !important; + } + + .ant-tabs-tab-remove { + opacity: 1; + } + + svg { + width: 0.7em; + fill: @white; + } + } + } + + .ant-tabs-nav > div:nth-child(1) { + padding: 0 6px; + + .ant-tabs-tab { + margin-right: 3px !important; + } + } + } + + .ant-tabs-tab:not(.ant-tabs-tab-active) { + .anticon-close { + font-size: 12px; + + svg { + width: 0.6em; + } + } + } + + .ant-dropdown-trigger { + display: inline-flex; + } + + &--hide-close { + .ant-tabs-tab-remove { + opacity: 0 !important; + } + } + + &-content { + &__extra-quick, + &__extra-redo, + &__extra-fold { + display: inline-block; + width: 36px; + height: @multiple-height; + border-left: 1px solid @border-color-base; + color: @text-color-secondary; + line-height: @multiple-height; + text-align: center; + cursor: pointer; + + &:hover { + color: @text-color-base; + } + + span[role='img'] { + transform: rotate(90deg); + } + } + + &__extra-redo { + span[role='img'] { + transform: rotate(0deg); + } + } + + &__info { + display: inline-block; + width: 100%; + height: @multiple-height - 2; + margin-left: -10px; + padding-left: 0; + font-size: 12px; + cursor: pointer; + user-select: none; + } + } +} + +.ant-tabs-dropdown-menu { + &-title-content { + display: flex; + align-items: center; + + .@{prefix-cls} { + &-content__info { + width: auto; + margin-left: 0; + line-height: 28px; + } + } + } + + &-item-remove { + margin-left: auto; + } +} + +.multiple-tabs__dropdown { + .ant-dropdown-content { + width: 172px; + } +} \ No newline at end of file diff --git a/src/layouts/default/tabs/index.vue b/src/layouts/default/tabs/index.vue new file mode 100644 index 0000000..3b487bb --- /dev/null +++ b/src/layouts/default/tabs/index.vue @@ -0,0 +1,144 @@ + + + diff --git a/src/layouts/default/tabs/types.ts b/src/layouts/default/tabs/types.ts new file mode 100644 index 0000000..3a8cfd9 --- /dev/null +++ b/src/layouts/default/tabs/types.ts @@ -0,0 +1,25 @@ +import type { DropMenu } from '/@/components/Dropdown/index'; +import type { RouteLocationNormalized } from 'vue-router'; + +export enum TabContentEnum { + TAB_TYPE, + EXTRA_TYPE, +} + +export type { DropMenu }; + +export interface TabContentProps { + tabItem: RouteLocationNormalized; + type?: TabContentEnum; + trigger?: ('click' | 'hover' | 'contextmenu')[]; +} + +export enum MenuEventEnum { + REFRESH_PAGE, + CLOSE_CURRENT, + CLOSE_LEFT, + CLOSE_RIGHT, + CLOSE_OTHER, + CLOSE_ALL, + SCALE, +} diff --git a/src/layouts/default/tabs/useMultipleTabs.ts b/src/layouts/default/tabs/useMultipleTabs.ts new file mode 100644 index 0000000..71b9029 --- /dev/null +++ b/src/layouts/default/tabs/useMultipleTabs.ts @@ -0,0 +1,80 @@ +import { toRaw, ref, nextTick } from 'vue'; +import type { RouteLocationNormalized } from 'vue-router'; +import { useDesign } from '/@/hooks/web/useDesign'; +import { useSortable } from '/@/hooks/web/useSortable'; +import { useMultipleTabStore } from '/@/store/modules/multipleTab'; +import { isNullAndUnDef } from '/@/utils/is'; +import projectSetting from '/@/settings/projectSetting'; +import { useRouter } from 'vue-router'; + +export function initAffixTabs(): string[] { + const affixList = ref([]); + + const tabStore = useMultipleTabStore(); + const router = useRouter(); + /** + * @description: Filter all fixed routes + */ + function filterAffixTabs(routes: RouteLocationNormalized[]) { + const tabs: RouteLocationNormalized[] = []; + routes && + routes.forEach((route) => { + if (route.meta && route.meta.affix) { + tabs.push(toRaw(route)); + } + }); + return tabs; + } + + /** + * @description: Set fixed tabs + */ + function addAffixTabs(): void { + const affixTabs = filterAffixTabs(router.getRoutes() as unknown as RouteLocationNormalized[]); + affixList.value = affixTabs; + for (const tab of affixTabs) { + tabStore.addTab({ + meta: tab.meta, + name: tab.name, + path: tab.path, + } as unknown as RouteLocationNormalized); + } + } + + let isAddAffix = false; + + if (!isAddAffix) { + addAffixTabs(); + isAddAffix = true; + } + return affixList.value.map((item) => item.meta?.title).filter(Boolean) as string[]; +} + +export function useTabsDrag(affixTextList: string[]) { + const tabStore = useMultipleTabStore(); + const { multiTabsSetting } = projectSetting; + const { prefixCls } = useDesign('multiple-tabs'); + nextTick(() => { + if (!multiTabsSetting.canDrag) return; + const el = document.querySelectorAll( + `.${prefixCls} .ant-tabs-nav-wrap > div`, + )?.[0] as HTMLElement; + const { initSortable } = useSortable(el, { + filter: (e: ChangeEvent) => { + const text = e?.target?.innerText; + if (!text) return false; + return affixTextList.includes(text); + }, + onEnd: (evt) => { + const { oldIndex, newIndex } = evt; + + if (isNullAndUnDef(oldIndex) || isNullAndUnDef(newIndex) || oldIndex === newIndex) { + return; + } + + tabStore.sortTabs(oldIndex, newIndex); + }, + }); + initSortable(); + }); +} diff --git a/src/layouts/default/tabs/useTabDropdown.ts b/src/layouts/default/tabs/useTabDropdown.ts new file mode 100644 index 0000000..016ce8c --- /dev/null +++ b/src/layouts/default/tabs/useTabDropdown.ts @@ -0,0 +1,140 @@ +import type { TabContentProps } from './types'; +import type { DropMenu } from '/@/components/Dropdown'; +import type { ComputedRef } from 'vue'; + +import { computed, unref, reactive } from 'vue'; +import { MenuEventEnum } from './types'; +import { useMultipleTabStore } from '/@/store/modules/multipleTab'; +import { RouteLocationNormalized, useRouter } from 'vue-router'; +import { useTabs } from '/@/hooks/web/useTabs'; +import { useI18n } from '/@/hooks/web/useI18n'; + +export function useTabDropdown(tabContentProps: TabContentProps, getIsTabs: ComputedRef) { + const state = reactive({ + current: null as Nullable, + currentIndex: 0, + }); + + const { t } = useI18n(); + const tabStore = useMultipleTabStore(); + const { currentRoute } = useRouter(); + const { refreshPage, closeAll, close, closeLeft, closeOther, closeRight } = useTabs(); + + const getTargetTab = computed((): RouteLocationNormalized => { + return unref(getIsTabs) ? tabContentProps.tabItem : unref(currentRoute); + }); + + /** + * @description: drop-down list + */ + const getDropMenuList = computed(() => { + if (!unref(getTargetTab)) { + return; + } + const { meta } = unref(getTargetTab); + const { path } = unref(currentRoute); + + const curItem = state.current; + + const isCurItem = curItem ? curItem.path === path : false; + + // Refresh button + const index = state.currentIndex; + const refreshDisabled = !isCurItem; + // Close left + const closeLeftDisabled = index === 0 || !isCurItem; + + const disabled = tabStore.getTabList.length === 1; + + // Close right + const closeRightDisabled = + !isCurItem || (index === tabStore.getTabList.length - 1 && tabStore.getLastDragEndIndex >= 0); + const dropMenuList: DropMenu[] = [ + { + icon: 'ion:reload-sharp', + event: MenuEventEnum.REFRESH_PAGE, + text: t('layout.multipleTab.reload'), + disabled: refreshDisabled, + }, + { + icon: 'clarity:close-line', + event: MenuEventEnum.CLOSE_CURRENT, + text: t('layout.multipleTab.close'), + disabled: !!meta?.affix || disabled, + divider: true, + }, + { + icon: 'line-md:arrow-close-left', + event: MenuEventEnum.CLOSE_LEFT, + text: t('layout.multipleTab.closeLeft'), + disabled: closeLeftDisabled, + divider: false, + }, + { + icon: 'line-md:arrow-close-right', + event: MenuEventEnum.CLOSE_RIGHT, + text: t('layout.multipleTab.closeRight'), + disabled: closeRightDisabled, + divider: true, + }, + { + icon: 'dashicons:align-center', + event: MenuEventEnum.CLOSE_OTHER, + text: t('layout.multipleTab.closeOther'), + disabled: disabled || !isCurItem, + }, + { + icon: 'clarity:minus-line', + event: MenuEventEnum.CLOSE_ALL, + text: t('layout.multipleTab.closeAll'), + disabled: disabled, + }, + ]; + + return dropMenuList; + }); + + function handleContextMenu(tabItem: RouteLocationNormalized) { + return (e: Event) => { + if (!tabItem) { + return; + } + e?.preventDefault(); + const index = tabStore.getTabList.findIndex((tab) => tab.path === tabItem.path); + state.current = tabItem; + state.currentIndex = index; + }; + } + + // Handle right click event + function handleMenuEvent(menu: DropMenu): void { + const { event } = menu; + switch (event) { + case MenuEventEnum.REFRESH_PAGE: + // refresh page + refreshPage(); + break; + // Close current + case MenuEventEnum.CLOSE_CURRENT: + close(tabContentProps.tabItem); + break; + // Close left + case MenuEventEnum.CLOSE_LEFT: + closeLeft(); + break; + // Close right + case MenuEventEnum.CLOSE_RIGHT: + closeRight(); + break; + // Close other + case MenuEventEnum.CLOSE_OTHER: + closeOther(); + break; + // Close all + case MenuEventEnum.CLOSE_ALL: + closeAll(); + break; + } + } + return { getDropMenuList, handleMenuEvent, handleContextMenu }; +} diff --git a/src/layouts/default/trigger/HeaderTrigger.vue b/src/layouts/default/trigger/HeaderTrigger.vue new file mode 100644 index 0000000..391b7fc --- /dev/null +++ b/src/layouts/default/trigger/HeaderTrigger.vue @@ -0,0 +1,17 @@ + + diff --git a/src/layouts/default/trigger/SiderTrigger.vue b/src/layouts/default/trigger/SiderTrigger.vue new file mode 100644 index 0000000..ab0d057 --- /dev/null +++ b/src/layouts/default/trigger/SiderTrigger.vue @@ -0,0 +1,12 @@ + + diff --git a/src/layouts/default/trigger/index.vue b/src/layouts/default/trigger/index.vue new file mode 100644 index 0000000..5a070e1 --- /dev/null +++ b/src/layouts/default/trigger/index.vue @@ -0,0 +1,15 @@ + + + diff --git a/src/layouts/iframe/index.vue b/src/layouts/iframe/index.vue new file mode 100644 index 0000000..d9ee7e5 --- /dev/null +++ b/src/layouts/iframe/index.vue @@ -0,0 +1,29 @@ + + diff --git a/src/layouts/iframe/useFrameKeepAlive.ts b/src/layouts/iframe/useFrameKeepAlive.ts new file mode 100644 index 0000000..e84c49f --- /dev/null +++ b/src/layouts/iframe/useFrameKeepAlive.ts @@ -0,0 +1,59 @@ +import type { AppRouteRecordRaw } from '/@/router/types'; + +import { computed, toRaw, unref } from 'vue'; + +import { useMultipleTabStore } from '/@/store/modules/multipleTab'; + +import { uniqBy } from 'lodash-es'; + +import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting'; + +import { useRouter } from 'vue-router'; + +export function useFrameKeepAlive() { + const router = useRouter(); + const { currentRoute } = router; + const { getShowMultipleTab } = useMultipleTabSetting(); + const tabStore = useMultipleTabStore(); + const getFramePages = computed(() => { + const ret = getAllFramePages(toRaw(router.getRoutes()) as unknown as AppRouteRecordRaw[]) || []; + return ret; + }); + + const getOpenTabList = computed((): string[] => { + return tabStore.getTabList.reduce((prev: string[], next) => { + if (next.meta && Reflect.has(next.meta, 'frameSrc')) { + prev.push(next.name as string); + } + return prev; + }, []); + }); + + function getAllFramePages(routes: AppRouteRecordRaw[]): AppRouteRecordRaw[] { + let res: AppRouteRecordRaw[] = []; + for (const route of routes) { + const { meta: { frameSrc } = {}, children } = route; + if (frameSrc) { + res.push(route); + } + if (children && children.length) { + res.push(...getAllFramePages(children)); + } + } + res = uniqBy(res, 'name'); + return res; + } + + function showIframe(item: AppRouteRecordRaw) { + return item.name === unref(currentRoute).name; + } + + function hasRenderFrame(name: string) { + if (!unref(getShowMultipleTab)) { + return router.currentRoute.value.name === name; + } + return unref(getOpenTabList).includes(name); + } + + return { hasRenderFrame, getFramePages, showIframe, getAllFramePages }; +} diff --git a/src/layouts/page/index.vue b/src/layouts/page/index.vue new file mode 100644 index 0000000..72fe90f --- /dev/null +++ b/src/layouts/page/index.vue @@ -0,0 +1,70 @@ + + + diff --git a/src/layouts/page/transition.ts b/src/layouts/page/transition.ts new file mode 100644 index 0000000..9e93009 --- /dev/null +++ b/src/layouts/page/transition.ts @@ -0,0 +1,33 @@ +import type { FunctionalComponent } from 'vue'; +import type { RouteLocation } from 'vue-router'; + +export interface DefaultContext { + Component: FunctionalComponent & { type: Recordable }; + route: RouteLocation; +} + +export function getTransitionName({ + route, + openCache, + cacheTabs, + enableTransition, + def, +}: Pick & { + enableTransition: boolean; + openCache: boolean; + def: string; + cacheTabs: string[]; +}): string | undefined { + if (!enableTransition) { + return undefined; + } + + const isInCache = cacheTabs.includes(route.name as string); + const transitionName = 'fade-slide'; + let name: string | undefined = transitionName; + + if (openCache) { + name = isInCache && route.meta.loaded ? transitionName : undefined; + } + return name || (route.meta.transitionName as string) || def; +} diff --git a/src/locales/helper.ts b/src/locales/helper.ts new file mode 100644 index 0000000..4f78439 --- /dev/null +++ b/src/locales/helper.ts @@ -0,0 +1,37 @@ +import type { LocaleType } from '/#/config'; + +import { set } from 'lodash-es'; + +export const loadLocalePool: LocaleType[] = []; + +export function setHtmlPageLang(locale: LocaleType) { + document.querySelector('html')?.setAttribute('lang', locale); +} + +export function setLoadLocalePool(cb: (loadLocalePool: LocaleType[]) => void) { + cb(loadLocalePool); +} + +export function genMessage(langs: Record>, prefix = 'lang') { + const obj: Recordable = {}; + + Object.keys(langs).forEach((key) => { + const langFileModule = langs[key].default; + let fileName = key.replace(`./${prefix}/`, '').replace(/^\.\//, ''); + const lastIndex = fileName.lastIndexOf('.'); + fileName = fileName.substring(0, lastIndex); + const keyList = fileName.split('/'); + const moduleName = keyList.shift(); + const objKey = keyList.join('.'); + + if (moduleName) { + if (objKey) { + set(obj, moduleName, obj[moduleName] || {}); + set(obj[moduleName], objKey, langFileModule); + } else { + set(obj, moduleName, langFileModule || {}); + } + } + }); + return obj; +} diff --git a/src/locales/lang/en.ts b/src/locales/lang/en.ts new file mode 100644 index 0000000..98bebd5 --- /dev/null +++ b/src/locales/lang/en.ts @@ -0,0 +1,12 @@ +import { genMessage } from '../helper'; +import antdLocale from 'ant-design-vue/es/locale/en_US'; + +const modules = import.meta.glob('./en/**/*.ts', { eager: true }); +export default { + message: { + ...genMessage(modules as Recordable, 'en'), + antdLocale, + }, + dateLocale: null, + dateLocaleName: 'en', +}; diff --git a/src/locales/lang/en/common.ts b/src/locales/lang/en/common.ts new file mode 100644 index 0000000..ba2d0f2 --- /dev/null +++ b/src/locales/lang/en/common.ts @@ -0,0 +1,35 @@ +export default { + okText: 'OK', + closeText: 'Close', + cancelText: 'Cancel', + loadingText: 'Loading...', + saveText: 'Save', + delText: 'Delete', + resetText: 'Reset', + searchText: 'Search', + queryText: 'Search', + + inputText: 'Please enter ', + chooseText: 'Please choose ', + + redo: 'Refresh', + back: 'Back', + + light: 'Light', + dark: 'Dark', + + action: 'Action', + + successful: 'Success', + failed: 'Failed', + warning: 'Warning', + on: 'On', + off: 'Off', + delete: 'Delete', + deleteConfirm: 'Confirm Delete', + createTime: 'Create Time', + updateTime: 'Update Time', + notAllowEditAdminData: 'Disallow edit of administrator data', + notAllowDeleteAdminData: 'Disallow deletion of administrator data', + notAllowResetAdmin: 'Disallow reset password of administrator' +}; diff --git a/src/locales/lang/en/component.ts b/src/locales/lang/en/component.ts new file mode 100644 index 0000000..ba66fa5 --- /dev/null +++ b/src/locales/lang/en/component.ts @@ -0,0 +1,130 @@ +export default { + app: { + searchNotData: 'No search results yet', + toSearch: 'to search', + toNavigate: 'to navigate', + }, + countdown: { + normalText: 'Get SMS code', + sendText: 'Reacquire in {0}s', + }, + cropper: { + selectImage: 'Select Image', + uploadSuccess: 'Uploaded success!', + imageTooBig: 'Image too big', + modalTitle: 'Avatar upload', + okText: 'Confirm and upload', + btn_reset: 'Reset', + btn_rotate_left: 'Counterclockwise rotation', + btn_rotate_right: 'Clockwise rotation', + btn_scale_x: 'Flip horizontal', + btn_scale_y: 'Flip vertical', + btn_zoom_in: 'Zoom in', + btn_zoom_out: 'Zoom out', + preview: 'Preivew', + }, + drawer: { + loadingText: 'Loading...', + cancelText: 'Close', + okText: 'Confirm', + }, + excel: { + exportModalTitle: 'Export data', + fileType: 'File type', + fileName: 'File name', + }, + form: { + putAway: 'Put away', + unfold: 'Unfold', + maxTip: 'The number of characters should be less than {0}', + apiSelectNotFound: 'Wait for data loading to complete...', + }, + icon: { + placeholder: 'Click the select icon', + search: 'Search icon', + copy: 'Copy icon successfully!', + }, + menu: { + search: 'Menu search', + }, + modal: { + cancelText: 'Close', + okText: 'Confirm', + close: 'Close', + maximize: 'Maximize', + restore: 'Restore', + }, + table: { + settingDens: 'Density', + settingDensDefault: 'Default', + settingDensMiddle: 'Middle', + settingDensSmall: 'Compact', + settingColumn: 'Column settings', + settingColumnShow: 'Column display', + settingIndexColumnShow: 'Index Column', + settingSelectColumnShow: 'Selection Column', + settingFixedLeft: 'Fixed Left', + settingFixedRight: 'Fixed Right', + settingFullScreen: 'Full Screen', + index: 'Index', + total: 'total of {total}', + }, + time: { + before: ' ago', + after: ' after', + just: 'just now', + seconds: ' seconds', + minutes: ' minutes', + hours: ' hours', + days: ' days', + }, + tree: { + selectAll: 'Select All', + unSelectAll: 'Cancel Select', + expandAll: 'Expand All', + unExpandAll: 'Collapse all', + + checkStrictly: 'Hierarchical association', + checkUnStrictly: 'Hierarchical independence', + }, + upload: { + save: 'Save', + upload: 'Upload', + imgUpload: 'ImageUpload', + uploaded: 'Uploaded', + + operating: 'Operating', + del: 'Delete', + download: 'download', + saveWarn: 'Please wait for the file to upload and save!', + saveError: 'There is no file successfully uploaded and cannot be saved!', + + preview: 'Preview', + choose: 'Select the file', + + accept: 'Support {0} format', + acceptUpload: 'Only upload files in {0} format', + maxSize: 'A single file does not exceed {0}MB ', + maxSizeMultiple: 'Only upload files up to {0}MB!', + maxNumber: 'Only upload up to {0} files', + + legend: 'Legend', + fileName: 'File name', + fileSize: 'File size', + fileStatue: 'File status', + + startUpload: 'Start upload', + uploadSuccess: 'Upload successfully', + uploadError: 'Upload failed', + uploading: 'Uploading', + uploadWait: 'Please wait for the file upload to finish', + reUploadFailed: 'Re-upload failed files', + }, + verify: { + error: 'verification failed!', + time: 'The verification is successful and it takes {time} seconds!', + redoTip: 'Click the picture to refresh', + dragText: 'Hold down the slider and drag', + successText: 'Verified', + }, +}; diff --git a/src/locales/lang/en/layout.ts b/src/locales/lang/en/layout.ts new file mode 100644 index 0000000..8ba9ff6 --- /dev/null +++ b/src/locales/lang/en/layout.ts @@ -0,0 +1,116 @@ +export default { + footer: { onlinePreview: 'Preview', onlineDocument: 'Document' }, + header: { + // user dropdown + dropdownItemSetting: 'Personal Setting', + dropdownItemDoc: 'Document', + dropdownItemLoginOut: 'Log Out', + + tooltipErrorLog: 'Error log', + tooltipLock: 'Lock screen', + tooltipNotify: 'Notification', + + tooltipEntryFull: 'Full Screen', + tooltipExitFull: 'Exit Full Screen', + + // lock + lockScreenPassword: 'Lock screen password', + lockScreen: 'Lock screen', + lockScreenBtn: 'Locking', + + home: 'Home', + }, + multipleTab: { + reload: 'Refresh current', + close: 'Close current', + closeLeft: 'Close Left', + closeRight: 'Close Right', + closeOther: 'Close Other', + closeAll: 'Close All', + }, + setting: { + // content mode + contentModeFull: 'Full', + contentModeFixed: 'Fixed width', + // topMenu align + topMenuAlignLeft: 'Left', + topMenuAlignRight: 'Center', + topMenuAlignCenter: 'Right', + // menu trigger + menuTriggerNone: 'Not Show', + menuTriggerBottom: 'Bottom', + menuTriggerTop: 'Top', + // menu type + menuTypeSidebar: 'Left menu mode', + menuTypeMixSidebar: 'Left menu mixed mode', + menuTypeMix: 'Top Menu Mix mode', + menuTypeTopMenu: 'Top menu mode', + + on: 'On', + off: 'Off', + minute: 'Minute', + + operatingTitle: 'Successful!', + operatingContent: + 'The copy is successful, please go to src/settings/projectSetting.ts to modify the configuration!', + resetSuccess: 'Successfully reset!', + + copyBtn: 'Copy', + clearBtn: 'Clear cache and to the login page', + + drawerTitle: 'Configuration', + + darkMode: 'Dark mode', + navMode: 'Navigation mode', + interfaceFunction: 'Interface function', + interfaceDisplay: 'Interface display', + animation: 'Animation', + splitMenu: 'Split menu', + closeMixSidebarOnChange: 'Switch page to close menu', + + sysTheme: 'System theme', + headerTheme: 'Header theme', + sidebarTheme: 'Menu theme', + + menuDrag: 'Drag Sidebar', + menuSearch: 'Menu search', + menuAccordion: 'Sidebar accordion', + menuCollapse: 'Collapse menu', + collapseMenuDisplayName: 'Collapse menu display name', + topMenuLayout: 'Top menu layout', + menuCollapseButton: 'Menu collapse button', + contentMode: 'Content area width', + expandedMenuWidth: 'Expanded menu width', + + breadcrumb: 'Breadcrumbs', + breadcrumbIcon: 'Breadcrumbs Icon', + tabs: 'Tabs', + tabDetail: 'Tab Detail', + tabsQuickBtn: 'Tabs quick button', + tabsRedoBtn: 'Tabs redo button', + tabsFoldBtn: 'Tabs flod button', + sidebar: 'Sidebar', + header: 'Header', + footer: 'Footer', + fullContent: 'Full content', + grayMode: 'Gray mode', + colorWeak: 'Color Weak Mode', + + progress: 'Progress', + switchLoading: 'Switch Loading', + switchAnimation: 'Switch animation', + animationType: 'Animation type', + + autoScreenLock: 'Auto screen lock', + notAutoScreenLock: 'Not auto lock', + + fixedHeader: 'Fixed header', + fixedSideBar: 'Fixed Sidebar', + + mixSidebarTrigger: 'Mixed menu Trigger', + triggerHover: 'Hover', + triggerClick: 'Click', + + mixSidebarFixed: 'Fixed expanded menu', + }, +}; diff --git a/src/locales/lang/en/routes/basic.ts b/src/locales/lang/en/routes/basic.ts new file mode 100644 index 0000000..b6faa00 --- /dev/null +++ b/src/locales/lang/en/routes/basic.ts @@ -0,0 +1,4 @@ +export default { + login: 'Login', + errorLogList: 'Error Log', +}; diff --git a/src/locales/lang/en/routes/dashboard.ts b/src/locales/lang/en/routes/dashboard.ts new file mode 100644 index 0000000..6d047b5 --- /dev/null +++ b/src/locales/lang/en/routes/dashboard.ts @@ -0,0 +1,6 @@ +export default { + dashboard: 'Dashboard', + about: 'About', + workbench: 'Workbench', + analysis: 'Analysis', +}; diff --git a/src/locales/lang/en/routes/demo.ts b/src/locales/lang/en/routes/demo.ts new file mode 100644 index 0000000..1cc82d0 --- /dev/null +++ b/src/locales/lang/en/routes/demo.ts @@ -0,0 +1,199 @@ +export default { + charts: { + baiduMap: 'Baidu map', + aMap: 'A map', + googleMap: 'Google map', + charts: 'Chart', + map: 'Map', + line: 'Line', + pie: 'Pie', + }, + comp: { + comp: 'Component', + basic: 'Basic', + transition: 'Animation', + countTo: 'Count To', + + scroll: 'Scroll', + scrollBasic: 'Basic', + scrollAction: 'Scroll Function', + virtualScroll: 'Virtual Scroll', + + tree: 'Tree', + + treeBasic: 'Basic', + editTree: 'Searchable/toolbar', + actionTree: 'Function operation', + + modal: 'Modal', + drawer: 'Drawer', + desc: 'Desc', + + verify: 'Verify', + verifyDrag: 'Drag ', + verifyRotate: 'Picture Restore', + + qrcode: 'QR code', + strength: 'Password strength', + upload: 'Upload', + + loading: 'Loading', + + time: 'Relative Time', + cropperImage: 'Cropper Image', + cardList: 'Card List', + }, + editor: { + editor: 'Editor', + jsonEditor: 'Json editor', + markdown: 'Markdown editor', + + tinymce: 'Rich text', + tinymceBasic: 'Basic', + tinymceForm: 'embedded form', + }, + excel: { + excel: 'Excel', + customExport: 'Select export format', + jsonExport: 'JSON data export', + arrayExport: 'Array data export', + importExcel: 'Import', + }, + feat: { + feat: 'Page Function', + icon: 'Icon', + tabs: 'Tabs', + tabDetail: 'Tab Detail', + sessionTimeout: 'Session Timeout', + print: 'Print', + contextMenu: 'Context Menu', + download: 'Download', + clickOutSide: 'ClickOutSide', + imgPreview: 'Picture Preview', + copy: 'Clipboard', + msg: 'Message prompt', + watermark: 'Watermark', + ripple: 'Ripple', + fullScreen: 'Full Screen', + errorLog: 'Error Log', + tab: 'Tab with parameters', + tab1: 'Tab with parameter 1', + tab2: 'Tab with parameter 2', + menu: 'Menu with parameters', + menu1: 'Menu with parameters 1', + menu2: 'Menu with parameters 2', + + ws: 'Websocket test', + + breadcrumb: 'Breadcrumbs', + breadcrumbFlat: 'Flat Mode', + breadcrumbFlatDetail: 'Flat mode details', + requestDemo: 'Retry request demo', + + breadcrumbChildren: 'Level mode', + breadcrumbChildrenDetail: 'Level mode detail', + }, + flow: { + name: 'Graphics editor', + flowChart: 'FlowChart', + }, + form: { + form: 'Form', + basic: 'Basic', + useForm: 'useForm', + refForm: 'RefForm', + advancedForm: 'Shrinkable', + ruleForm: 'Form validation', + dynamicForm: 'Dynamic', + customerForm: 'Custom', + appendForm: 'Append', + tabsForm: 'TabsForm', + }, + iframe: { + frame: 'External', + antv: 'antVue doc (embedded)', + doc: 'Project doc (embedded)', + docExternal: 'Project doc (external)', + }, + level: { level: 'MultiMenu' }, + page: { + page: 'Page', + + form: 'Form', + formBasic: 'Basic Form', + formStep: 'Step Form', + formHigh: 'Advanced Form', + + desc: 'Details', + descBasic: 'Basic Details', + descHigh: 'Advanced Details', + + result: 'Result', + resultSuccess: 'Success', + resultFail: 'Failed', + + account: 'Personal', + accountCenter: 'Personal Center', + accountSetting: 'Personal Settings', + + exception: 'Exception', + netWorkError: 'Network Error', + notData: 'No data', + + list: 'List page', + listCard: 'Card list', + basic: 'Basic list', + listBasic: 'Basic list', + listSearch: 'Search list', + }, + permission: { + permission: 'Permission', + + front: 'front-end', + frontPage: 'Page', + frontBtn: 'Button', + frontTestA: 'Test page A', + frontTestB: 'Test page B', + + back: 'background', + backPage: 'Page', + backBtn: 'Button', + }, + setup: { + page: 'Intro page', + }, + system: { + moduleName: 'System management', + + account: 'Account management', + account_detail: 'Account detail', + password: 'Change password', + + dept: 'Department management', + + menu: 'Menu management', + role: 'Role management', + }, + table: { + table: 'Table', + + basic: 'Basic', + treeTable: 'Tree', + fetchTable: 'Remote loading', + fixedColumn: 'Fixed column', + customerCell: 'Custom column', + formTable: 'Open search', + useTable: 'UseTable', + refTable: 'RefTable', + multipleHeader: 'MultiLevel header', + mergeHeader: 'Merge cells', + expandTable: 'Expandable table', + fixedHeight: 'Fixed height', + footerTable: 'Footer', + editCellTable: 'Editable cell', + editRowTable: 'Editable row', + authColumn: 'Auth column', + resizeParentHeightTable: 'resizeParentHeightTable', + vxeTable: 'VxeTable', + }, +}; diff --git a/src/locales/lang/en/sys.ts b/src/locales/lang/en/sys.ts new file mode 100644 index 0000000..0d68c38 --- /dev/null +++ b/src/locales/lang/en/sys.ts @@ -0,0 +1,127 @@ +export default { + api: { + operationSuccess: 'Operation Success', + operationFailed: 'Operation failed', + errorTip: 'Error Tip', + successTip: 'Success Tip', + errorMessage: 'The operation failed, the system is abnormal!', + timeoutMessage: 'Login timed out, please log in again!', + apiTimeoutMessage: 'The interface request timed out, please refresh the page and try again!', + apiRequestFailed: 'The interface request failed, please try again later!', + networkException: 'network anomaly', + networkExceptionMsg: + 'Please check if your network connection is normal! The network is abnormal', + + errMsg401: 'The user does not have permission (token, user name, password error)!', + errMsg403: 'The user is authorized, but access is forbidden!', + errMsg404: 'Network request error, the resource was not found!', + errMsg405: 'Network request error, request method not allowed!', + errMsg408: 'Network request timed out!', + errMsg500: 'Server error, please contact the administrator!', + errMsg501: 'The network is not implemented!', + errMsg502: 'Network Error!', + errMsg503: 'The service is unavailable, the server is temporarily overloaded or maintained!', + errMsg504: 'Network timeout!', + errMsg505: 'The http version does not support the request!', + }, + app: { + logoutTip: 'Reminder', + logoutMessage: 'Confirm to exit the system?', + menuLoading: 'Menu loading...', + }, + errorLog: { + tableTitle: 'Error log list', + tableColumnType: 'Type', + tableColumnDate: 'Time', + tableColumnFile: 'File', + tableColumnMsg: 'Error message', + tableColumnStackMsg: 'Stack info', + + tableActionDesc: 'Details', + + modalTitle: 'Error details', + + fireVueError: 'Fire vue error', + fireResourceError: 'Fire resource error', + fireAjaxError: 'Fire ajax error', + + enableMessage: 'Only effective when useErrorHandle=true in `/src/settings/projectSetting.ts`.', + }, + exception: { + backLogin: 'Back Login', + backHome: 'Back Home', + subTitle403: "Sorry, you don't have access to this page.", + subTitle404: 'Sorry, the page you visited does not exist.', + subTitle500: 'Sorry, the server is reporting an error.', + noDataTitle: 'No data on the current page.', + networkErrorTitle: 'Network Error', + networkErrorSubTitle: + 'Sorry,Your network connection has been disconnected, please check your network!', + }, + lock: { + unlock: 'Click to unlock', + alert: 'Lock screen password error', + backToLogin: 'Back to login', + entry: 'Enter the system', + placeholder: 'Please enter the lock screen password or user password', + }, + login: { + captcha: 'Verification code', + backSignIn: 'Back sign in', + mobileSignInFormTitle: 'Mobile sign in', + qrSignInFormTitle: 'Qr code sign in', + signInFormTitle: 'Sign in', + signUpFormTitle: 'Sign up', + forgetFormTitle: 'Reset password', + + signInTitle: 'Provide next-generation intelligent ERP system software for enterprises', + signInDesc: '© 2023-2033 Wan Sen ERP - All Right Reserved', + policy: 'I agree, to the WanSer ERP System Privacy Policy', + scanSign: `scanning the code to complete the login`, + + loginButton: 'Sign in', + registerButton: 'Sign up', + rememberMe: 'Remember me', + forgetPassword: 'Forget Password?', + otherSignIn: 'Sign in with', + + // notify + loginSuccessTitle: 'Login successful', + loginSuccessDesc: 'Welcome back', + + // placeholder + accountPlaceholder: 'Please input username', + passwordPlaceholder: 'Please input password', + captchaPlaceholder: 'Please input verification code', + smsPlaceholder: 'Please input sms code', + mobilePlaceholder: 'Please input mobile', + policyPlaceholder: 'Register after checking', + diffPwd: 'The two passwords are inconsistent', + + userName: 'Username', + password: 'Password', + confirmPassword: 'Confirm Password', + newPassword: 'New Password', + updatePassword: 'Change Password', + email: 'Email', + smsCode: 'SMS code', + mobile: 'Mobile', + }, + user: { + userList: 'User Table', + name: 'Nick Name', + status: 'Status', + roleName: 'Role Name', + department: 'Department', + remake: 'Remark', + addAccount: 'Add Account', + editAccount: 'Edit Account', + + // user table list action + viewUserDetails: 'View User Details', + editUserProfile: 'Edit User Profile', + resetUserPassword: 'Reset User Password', + confirmPasswordReset: 'Are you sure to reset the password to 123456', + deleteUserAccount: 'Delete User Account' + } +}; diff --git a/src/locales/lang/zh-CN/antdLocale/DatePicker.ts b/src/locales/lang/zh-CN/antdLocale/DatePicker.ts new file mode 100644 index 0000000..452dff0 --- /dev/null +++ b/src/locales/lang/zh-CN/antdLocale/DatePicker.ts @@ -0,0 +1,19 @@ +export default { + lang: { + shortWeekDays: ['一', '二', '三', '四', '五', '六', '日'], + shortMonths: [ + '1月', + '2月', + '3月', + '4月', + '5月', + '6月', + '7月', + '8月', + '9月', + '10月', + '11月', + '12月', + ], + }, +}; diff --git a/src/locales/lang/zh-CN/common.ts b/src/locales/lang/zh-CN/common.ts new file mode 100644 index 0000000..70e6c55 --- /dev/null +++ b/src/locales/lang/zh-CN/common.ts @@ -0,0 +1,37 @@ +export default { + okText: '确认', + closeText: '关闭', + cancelText: '取消', + loadingText: '加载中...', + saveText: '保存', + delText: '删除', + resetText: '重置', + searchText: '搜索', + queryText: '查询', + + inputText: '请输入', + chooseText: '请选择', + + redo: '刷新', + back: '返回', + + notice: '提示', + + light: '亮色主题', + dark: '黑暗主题', + + action: '操作', + + successful: '成功', + warning: '警告', + failed: '失败', + on: '启用', + off: '停用', + delete: '删除', + deleteConfirm: '确认删除', + createTime: '创建时间', + updateTime: '修改时间', + notAllowEditAdminData: '禁止编辑管理员数据', + notAllowDeleteAdminData: '禁止删除管理员数据', + notAllowResetAdmin: '禁止重置管理员密码' +}; diff --git a/src/locales/lang/zh-CN/component.ts b/src/locales/lang/zh-CN/component.ts new file mode 100644 index 0000000..a29c59b --- /dev/null +++ b/src/locales/lang/zh-CN/component.ts @@ -0,0 +1,135 @@ +export default { + app: { + searchNotData: '暂无搜索结果', + toSearch: '确认', + toNavigate: '切换', + }, + countdown: { + normalText: '获取验证码', + sendText: '{0}秒后重新获取', + }, + cropper: { + selectImage: '选择图片', + uploadSuccess: '上传成功', + imageTooBig: '图片超限', + modalTitle: '头像上传', + okText: '确认并上传', + btn_reset: '重置', + btn_rotate_left: '逆时针旋转', + btn_rotate_right: '顺时针旋转', + btn_scale_x: '水平翻转', + btn_scale_y: '垂直翻转', + btn_zoom_in: '放大', + btn_zoom_out: '缩小', + preview: '预览', + }, + drawer: { + loadingText: '加载中...', + cancelText: '关闭', + okText: '确认', + }, + excel: { + exportModalTitle: '导出数据', + fileType: '文件类型', + fileName: '文件名', + }, + form: { + putAway: '收起', + unfold: '展开', + + maxTip: '字符数应小于{0}位', + + apiSelectNotFound: '请等待数据加载完成...', + }, + icon: { + placeholder: '点击选择图标', + search: '搜索图标', + copy: '复制图标成功!', + }, + menu: { + search: '菜单搜索', + }, + modal: { + cancelText: '关闭', + okText: '确认', + close: '关闭', + maximize: '最大化', + restore: '还原', + }, + table: { + settingDens: '密度', + settingDensDefault: '默认', + settingDensMiddle: '中等', + settingDensSmall: '紧凑', + settingColumn: '列设置', + settingColumnShow: '列展示', + settingIndexColumnShow: '序号列', + settingSelectColumnShow: '勾选列', + settingFixedLeft: '固定到左侧', + settingFixedRight: '固定到右侧', + settingFullScreen: '全屏', + + index: '序号', + + total: '共 {total} 条数据', + }, + time: { + before: '前', + after: '后', + just: '刚刚', + seconds: '秒', + minutes: '分钟', + hours: '小时', + days: '天', + }, + tree: { + selectAll: '选择全部', + unSelectAll: '取消选择', + expandAll: '展开全部', + unExpandAll: '折叠全部', + checkStrictly: '层级关联', + checkUnStrictly: '层级独立', + }, + upload: { + save: '保存', + upload: '上传', + imgUpload: '图片上传', + uploaded: '已上传', + + operating: '操作', + del: '删除', + download: '下载', + saveWarn: '请等待文件上传后,保存!', + saveError: '没有上传成功的文件,无法保存!', + + preview: '预览', + choose: '选择文件', + + accept: '支持{0}格式', + acceptUpload: '只能上传{0}格式文件', + maxSize: '单个文件不超过{0}MB', + maxSizeMultiple: '只能上传不超过{0}MB的文件!', + maxNumber: '最多只能上传{0}个文件', + + legend: '略缩图', + fileName: '文件名', + fileSize: '文件大小', + fileStatue: '状态', + + startUpload: '开始上传', + uploadSuccess: '上传成功', + uploadError: '上传失败', + uploading: '上传中', + uploadWait: '请等待文件上传结束后操作', + reUploadFailed: '重新上传失败文件', + }, + verify: { + error: '验证失败!', + time: '验证校验成功,耗时{time}秒!', + + redoTip: '点击图片可刷新', + + dragText: '请按住滑块拖动', + successText: '验证通过', + }, +}; diff --git a/src/locales/lang/zh-CN/layout.ts b/src/locales/lang/zh-CN/layout.ts new file mode 100644 index 0000000..f60a117 --- /dev/null +++ b/src/locales/lang/zh-CN/layout.ts @@ -0,0 +1,116 @@ +export default { + footer: { onlinePreview: '在线预览', onlineDocument: '在线文档' }, + header: { + // user dropdown + dropdownItemSetting: '个人设置', + dropdownItemDoc: '文档', + dropdownItemLoginOut: '退出系统', + + // tooltip + tooltipErrorLog: '错误日志', + tooltipLock: '锁定屏幕', + tooltipNotify: '消息通知', + + tooltipEntryFull: '全屏', + tooltipExitFull: '退出全屏', + + // lock + lockScreenPassword: '锁屏密码', + lockScreen: '锁定屏幕', + lockScreenBtn: '锁定', + + home: '首页', + }, + multipleTab: { + reload: '重新加载', + close: '关闭标签页', + closeLeft: '关闭左侧标签页', + closeRight: '关闭右侧标签页', + closeOther: '关闭其它标签页', + closeAll: '关闭全部标签页', + }, + setting: { + // content mode + contentModeFull: '流式', + contentModeFixed: '定宽', + // topMenu align + topMenuAlignLeft: '居左', + topMenuAlignRight: '居中', + topMenuAlignCenter: '居右', + // menu trigger + menuTriggerNone: '不显示', + menuTriggerBottom: '底部', + menuTriggerTop: '顶部', + // menu type + menuTypeSidebar: '左侧菜单模式', + menuTypeMixSidebar: '左侧菜单混合模式', + menuTypeMix: '顶部菜单混合模式', + menuTypeTopMenu: '顶部菜单模式', + + on: '开', + off: '关', + minute: '分钟', + + operatingTitle: '操作成功', + operatingContent: '复制成功,请到 src/settings/projectSetting.ts 中修改配置!', + resetSuccess: '重置成功!', + + copyBtn: '拷贝', + clearBtn: '清空缓存并返回登录页', + + drawerTitle: '项目配置', + + darkMode: '主题', + navMode: '导航栏模式', + interfaceFunction: '界面功能', + interfaceDisplay: '界面显示', + animation: '动画', + splitMenu: '分割菜单', + closeMixSidebarOnChange: '切换页面关闭菜单', + + sysTheme: '系统主题', + headerTheme: '顶栏主题', + sidebarTheme: '菜单主题', + + menuDrag: '侧边菜单拖拽', + menuSearch: '菜单搜索', + menuAccordion: '侧边菜单手风琴模式', + menuCollapse: '折叠菜单', + collapseMenuDisplayName: '折叠菜单显示名称', + topMenuLayout: '顶部菜单布局', + menuCollapseButton: '菜单折叠按钮', + contentMode: '内容区域宽度', + expandedMenuWidth: '菜单展开宽度', + + breadcrumb: '面包屑', + breadcrumbIcon: '面包屑图标', + tabs: '标签页', + tabDetail: '标签详情页', + tabsQuickBtn: '标签页快捷按钮', + tabsRedoBtn: '标签页刷新按钮', + tabsFoldBtn: '标签页折叠按钮', + sidebar: '左侧菜单', + header: '顶栏', + footer: '页脚', + fullContent: '全屏内容', + grayMode: '灰色模式', + colorWeak: '色弱模式', + + progress: '顶部进度条', + switchLoading: '切换loading', + switchAnimation: '切换动画', + animationType: '动画类型', + + autoScreenLock: '自动锁屏', + notAutoScreenLock: '不自动锁屏', + + fixedHeader: '固定header', + fixedSideBar: '固定Sidebar', + + mixSidebarTrigger: '混合菜单触发方式', + triggerHover: '悬停', + triggerClick: '点击', + + mixSidebarFixed: '固定展开菜单', + }, +}; diff --git a/src/locales/lang/zh-CN/routes/basic.ts b/src/locales/lang/zh-CN/routes/basic.ts new file mode 100644 index 0000000..3d03e8e --- /dev/null +++ b/src/locales/lang/zh-CN/routes/basic.ts @@ -0,0 +1,4 @@ +export default { + login: '登录', + errorLogList: '错误日志列表', +}; diff --git a/src/locales/lang/zh-CN/routes/dashboard.ts b/src/locales/lang/zh-CN/routes/dashboard.ts new file mode 100644 index 0000000..04b1b19 --- /dev/null +++ b/src/locales/lang/zh-CN/routes/dashboard.ts @@ -0,0 +1,6 @@ +export default { + dashboard: 'Dashboard', + about: '关于', + workbench: '工作台', + analysis: '分析页', +}; diff --git a/src/locales/lang/zh-CN/routes/demo.ts b/src/locales/lang/zh-CN/routes/demo.ts new file mode 100644 index 0000000..54f6482 --- /dev/null +++ b/src/locales/lang/zh-CN/routes/demo.ts @@ -0,0 +1,190 @@ +export default { + charts: { + baiduMap: '百度地图', + aMap: '高德地图', + googleMap: '谷歌地图', + charts: '图表', + map: '地图', + line: '折线图', + pie: '饼图', + }, + comp: { + comp: '组件', + basic: '基础组件', + transition: '动画组件', + countTo: '数字动画', + + scroll: '滚动组件', + scrollBasic: '基础滚动', + scrollAction: '滚动函数', + virtualScroll: '虚拟滚动', + + tree: 'Tree', + treeBasic: '基础树', + editTree: '可搜索/工具栏', + actionTree: '函数操作示例', + + modal: '弹窗扩展', + drawer: '抽屉扩展', + desc: '详情组件', + + verify: '验证组件', + verifyDrag: '拖拽校验', + verifyRotate: '图片还原', + + qrcode: '二维码组件', + strength: '密码强度组件', + upload: '上传组件', + + loading: 'Loading', + + time: '相对时间', + cropperImage: '图片裁剪', + cardList: '卡片列表', + }, + editor: { + editor: '编辑器', + jsonEditor: 'Json编辑器', + markdown: 'markdown编辑器', + + tinymce: '富文本', + tinymceBasic: '基础使用', + tinymceForm: '嵌入form', + }, + excel: { + excel: 'Excel', + customExport: '选择导出格式', + jsonExport: 'JSON数据导出', + arrayExport: 'Array数据导出', + importExcel: '导入', + }, + feat: { + feat: '功能', + icon: '图标', + sessionTimeout: '登录过期', + tabs: '标签页操作', + tabDetail: '标签详情页', + print: '打印', + contextMenu: '右键菜单', + download: '文件下载', + clickOutSide: 'ClickOutSide组件', + imgPreview: '图片预览', + copy: '剪切板', + msg: '消息提示', + watermark: '水印', + ripple: '水波纹', + fullScreen: '全屏', + errorLog: '错误日志', + tab: 'Tab带参', + tab1: 'Tab带参1', + tab2: 'Tab带参2', + menu: 'Menu带参', + menu1: 'Menu带参1', + menu2: 'Menu带参2', + ws: 'websocket测试', + breadcrumb: '面包屑导航', + breadcrumbFlat: '平级模式', + requestDemo: '测试请求重试', + breadcrumbFlatDetail: '平级详情', + breadcrumbChildren: '层级模式', + breadcrumbChildrenDetail: '层级详情', + }, + flow: { + name: '图形编辑器', + flowChart: '流程图', + }, + form: { + form: 'Form', + basic: '基础表单', + useForm: 'useForm', + refForm: 'RefForm', + advancedForm: '可收缩表单', + ruleForm: '表单验证', + dynamicForm: '动态表单', + customerForm: '自定义组件', + appendForm: '表单增删示例', + tabsForm: '标签页+多级field', + }, + iframe: { + frame: '外部页面', + antv: 'antVue文档(内嵌)', + doc: '项目文档(内嵌)', + docExternal: '项目文档(外链)', + }, + level: { level: '多级菜单' }, + page: { + page: '页面', + + form: '表单页', + formBasic: '基础表单', + formStep: '分步表单', + formHigh: '高级表单', + + desc: '详情页', + descBasic: '基础详情页', + descHigh: '高级详情页', + + result: '结果页', + resultSuccess: '成功页', + resultFail: '失败页', + + account: '个人页', + accountCenter: '个人中心', + accountSetting: '个人设置', + + exception: '异常页', + netWorkError: '网络错误', + notData: '无数据', + + list: '列表页', + listCard: '卡片列表', + listBasic: '标准列表', + listSearch: '搜索列表', + }, + permission: { + permission: '权限管理', + + front: '基于前端权限', + frontPage: '页面权限', + frontBtn: '按钮权限', + frontTestA: '权限测试页A', + frontTestB: '权限测试页B', + + back: '基于后台权限', + backPage: '页面权限', + backBtn: '按钮权限', + }, + setup: { + page: '引导页', + }, + system: { + moduleName: '系统管理', + account: '账号管理', + account_detail: '账号详情', + password: '修改密码', + dept: '部门管理', + menu: '菜单管理', + role: '角色管理', + }, + table: { + table: 'Table', + basic: '基础表格', + treeTable: '树形表格', + fetchTable: '远程加载示例', + fixedColumn: '固定列', + customerCell: '自定义列', + formTable: '开启搜索区域', + useTable: 'UseTable', + refTable: 'RefTable', + multipleHeader: '多级表头', + mergeHeader: '合并单元格', + expandTable: '可展开表格', + fixedHeight: '定高/头部自定义', + footerTable: '表尾行合计', + editCellTable: '可编辑单元格', + editRowTable: '可编辑行', + authColumn: '权限列', + resizeParentHeightTable: '继承父元素高度', + vxeTable: 'VxeTable', + }, +}; diff --git a/src/locales/lang/zh-CN/sys.ts b/src/locales/lang/zh-CN/sys.ts new file mode 100644 index 0000000..39a6d93 --- /dev/null +++ b/src/locales/lang/zh-CN/sys.ts @@ -0,0 +1,121 @@ +export default { + api: { + operationSuccess: '操作成功', + operationFailed: '操作失败', + errorTip: '错误提示', + successTip: '成功提示', + errorMessage: '操作失败,系统异常!', + timeoutMessage: '登录超时,请重新登录!', + apiTimeoutMessage: '接口请求超时,请刷新页面重试!', + apiRequestFailed: '请求出错,请稍候重试', + networkException: '网络异常', + networkExceptionMsg: '网络异常,请检查您的网络连接是否正常!', + + errMsg401: '用户没有权限(令牌、用户名、密码错误)!', + errMsg403: '用户得到授权,但是访问是被禁止的。!', + errMsg404: '网络请求错误,未找到该资源!', + errMsg405: '网络请求错误,请求方法未允许!', + errMsg408: '网络请求超时!', + errMsg500: '服务器错误,请联系管理员!', + errMsg501: '网络未实现!', + errMsg502: '网络错误!', + errMsg503: '服务不可用,服务器暂时过载或维护!', + errMsg504: '网络超时!', + errMsg505: 'http版本不支持该请求!', + }, + app: { logoutTip: '温馨提醒', logoutMessage: '是否确认退出系统?', menuLoading: '菜单加载中...' }, + errorLog: { + tableTitle: '错误日志列表', + tableColumnType: '类型', + tableColumnDate: '时间', + tableColumnFile: '文件', + tableColumnMsg: '错误信息', + tableColumnStackMsg: 'stack信息', + + tableActionDesc: '详情', + + modalTitle: '错误详情', + + fireVueError: '点击触发vue错误', + fireResourceError: '点击触发资源加载错误', + fireAjaxError: '点击触发ajax错误', + + enableMessage: '只在`/src/settings/projectSetting.ts` 内的useErrorHandle=true时生效.', + }, + exception: { + backLogin: '返回登录', + backHome: '返回首页', + subTitle403: '抱歉,您无权访问此页面。', + subTitle404: '抱歉,您访问的页面不存在。', + subTitle500: '抱歉,服务器报告错误。', + noDataTitle: '当前页无数据', + networkErrorTitle: '网络错误', + networkErrorSubTitle: '抱歉,您的网络连接已断开,请检查您的网络!', + }, + lock: { + unlock: '点击解锁', + alert: '锁屏密码错误', + backToLogin: '返回登录', + entry: '进入系统', + placeholder: '请输入锁屏密码或者用户密码', + }, + login: { + captcha: '验证码', + backSignIn: '返回', + signInFormTitle: '登录', + mobileSignInFormTitle: '手机登录', + qrSignInFormTitle: '二维码登录', + signUpFormTitle: '注册租户', + forgetFormTitle: '重置密码', + + signInTitle: '为企业提供下一代智能ERP系统软件', + signInDesc: '© 2015-2030 Wan Sen ERP - All Right Reserved 版权所有', + policy: '我同意,《万森ERP系统》隐私政策', + scanSign: `扫码后点击"确认",即可完成登录`, + + loginButton: '登录', + registerButton: '注册租户', + rememberMe: '记住我', + forgetPassword: '忘记密码?', + otherSignIn: '其他登录方式', + + // notify + loginSuccessTitle: '登录成功', + loginSuccessDesc: '欢迎回来', + + // placeholder + accountPlaceholder: '请输入账号', + passwordPlaceholder: '请输入密码', + captchaPlaceholder: '请输入验证码', + smsPlaceholder: '请输入验证码', + mobilePlaceholder: '请输入手机号码', + policyPlaceholder: '勾选后才能注册', + diffPwd: '两次输入密码不一致', + + userName: '账号', + password: '密码', + confirmPassword: '确认密码', + newPassword: '新密码', + updatePassword: '修改密码', + email: '邮箱', + smsCode: '短信验证码', + mobile: '手机号码', + }, + user: { + userList: '用户列表', + name: '昵称', + status: '用户状态', + roleName: '角色', + department: '所属部门', + remake: '备注', + addAccount: '新增账户', + editAccount: '编辑账户', + + // 用户数据表格操作 + viewUserDetails: '查看用户详情', + editUserProfile: '编辑用户资料', + resetUserPassword: '重置密码', + confirmPasswordReset: '确定重置密码为123456吗', + deleteUserAccount: '删除账号' + } +}; diff --git a/src/locales/lang/zh_CN.ts b/src/locales/lang/zh_CN.ts new file mode 100644 index 0000000..8fc3305 --- /dev/null +++ b/src/locales/lang/zh_CN.ts @@ -0,0 +1,10 @@ +import { genMessage } from '../helper'; +import antdLocale from 'ant-design-vue/es/locale/zh_CN'; + +const modules = import.meta.glob('./zh-CN/**/*.ts', { eager: true }); +export default { + message: { + ...genMessage(modules as Recordable, 'zh-CN'), + antdLocale, + }, +}; diff --git a/src/locales/setupI18n.ts b/src/locales/setupI18n.ts new file mode 100644 index 0000000..405fb0c --- /dev/null +++ b/src/locales/setupI18n.ts @@ -0,0 +1,44 @@ +import type { App } from 'vue'; +import type { I18n, I18nOptions } from 'vue-i18n'; + +import { createI18n } from 'vue-i18n'; +import { setHtmlPageLang, setLoadLocalePool } from './helper'; +import { localeSetting } from '/@/settings/localeSetting'; +import { useLocaleStoreWithOut } from '/@/store/modules/locale'; + +const { fallback, availableLocales } = localeSetting; + +export let i18n: ReturnType; + +async function createI18nOptions(): Promise { + const localeStore = useLocaleStoreWithOut(); + const locale = localeStore.getLocale; + const defaultLocal = await import(`./lang/${locale}.ts`); + const message = defaultLocal.default?.message ?? {}; + + setHtmlPageLang(locale); + setLoadLocalePool((loadLocalePool) => { + loadLocalePool.push(locale); + }); + + return { + legacy: false, + locale, + fallbackLocale: fallback, + messages: { + [locale]: message, + }, + availableLocales: availableLocales, + sync: true, //If you don’t want to inherit locale from global scope, you need to set sync of i18n component option to false. + silentTranslationWarn: true, // true - warning off + missingWarn: false, + silentFallbackWarn: true, + }; +} + +// setup i18n instance with glob +export async function setupI18n(app: App) { + const options = await createI18nOptions(); + i18n = createI18n(options) as I18n; + app.use(i18n); +} diff --git a/src/locales/useLocale.ts b/src/locales/useLocale.ts new file mode 100644 index 0000000..64bd4a1 --- /dev/null +++ b/src/locales/useLocale.ts @@ -0,0 +1,69 @@ +/** + * Multi-language related operations + */ +import type { LocaleType } from '/#/config'; + +import { i18n } from './setupI18n'; +import { useLocaleStoreWithOut } from '/@/store/modules/locale'; +import { unref, computed } from 'vue'; +import { loadLocalePool, setHtmlPageLang } from './helper'; + +interface LangModule { + message: Recordable; + dateLocale: Recordable; + dateLocaleName: string; +} + +function setI18nLanguage(locale: LocaleType) { + const localeStore = useLocaleStoreWithOut(); + + if (i18n.mode === 'legacy') { + i18n.global.locale = locale; + } else { + (i18n.global.locale as any).value = locale; + } + localeStore.setLocaleInfo({ locale }); + setHtmlPageLang(locale); +} + +export function useLocale() { + const localeStore = useLocaleStoreWithOut(); + const getLocale = computed(() => localeStore.getLocale); + const getShowLocalePicker = computed(() => localeStore.getShowPicker); + + const getAntdLocale = computed((): any => { + return i18n.global.getLocaleMessage(unref(getLocale))?.antdLocale ?? {}; + }); + + // Switching the language will change the locale of useI18n + // And submit to configuration modification + async function changeLocale(locale: LocaleType) { + const globalI18n = i18n.global; + const currentLocale = unref(globalI18n.locale); + if (currentLocale === locale) { + return locale; + } + + if (loadLocalePool.includes(locale)) { + setI18nLanguage(locale); + return locale; + } + const langModule = ((await import(`./lang/${locale}.ts`)) as any).default as LangModule; + if (!langModule) return; + + const { message } = langModule; + + globalI18n.setLocaleMessage(locale, message); + loadLocalePool.push(locale); + + setI18nLanguage(locale); + return locale; + } + + return { + getLocale, + getShowLocalePicker, + changeLocale, + getAntdLocale, + }; +} diff --git a/src/logics/.DS_Store b/src/logics/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..6338d5093106f4bfcddb496bf4cf8ed3f0530a3b GIT binary patch literal 6148 zcmeHKK~BRk5FEEfDx!yq6XN6#aOe+06<*K}KuJXr38|`b&rf&&-+&XJV%BSggfx}l zfDqcP*5j;qz0Nqz#sJ*>DVqUP0As4);F!%Gk#W(E45DR1bYYGyF0jT89+7pt&F~i) zkiDB=g)M(2^>hDntn$0r;sePFTa=#oi~(cdUoqfD=^~x;mSSz~+?>=}Pras!h+m~xhp-b$F@2>JpHYL*?xjOa UB36pDQ0zk>&|r-*@T&}b0LbHK?EnA( literal 0 HcmV?d00001 diff --git a/src/logics/error-handle/index.ts b/src/logics/error-handle/index.ts new file mode 100644 index 0000000..e04c009 --- /dev/null +++ b/src/logics/error-handle/index.ts @@ -0,0 +1,184 @@ +/** + * Used to configure the global error handling function, which can monitor vue errors, script errors, static resource errors and Promise errors + */ + +import type { ErrorLogInfo } from '/#/store'; + +import { useErrorLogStoreWithOut } from '/@/store/modules/errorLog'; + +import { ErrorTypeEnum } from '/@/enums/exceptionEnum'; +import { App } from 'vue'; +import projectSetting from '/@/settings/projectSetting'; + +/** + * Handling error stack information + * @param error + */ +function processStackMsg(error: Error) { + if (!error.stack) { + return ''; + } + let stack = error.stack + .replace(/\n/gi, '') // Remove line breaks to save the size of the transmitted content + .replace(/\bat\b/gi, '@') // At in chrome, @ in ff + .split('@') // Split information with @ + .slice(0, 9) // The maximum stack length (Error.stackTraceLimit = 10), so only take the first 10 + .map((v) => v.replace(/^\s*|\s*$/g, '')) // Remove extra spaces + .join('~') // Manually add separators for later display + .replace(/\?[^:]+/gi, ''); // Remove redundant parameters of js file links (?x=1 and the like) + const msg = error.toString(); + if (stack.indexOf(msg) < 0) { + stack = msg + '@' + stack; + } + return stack; +} + +/** + * get comp name + * @param vm + */ +function formatComponentName(vm: any) { + if (vm.$root === vm) { + return { + name: 'root', + path: 'root', + }; + } + + const options = vm.$options as any; + if (!options) { + return { + name: 'anonymous', + path: 'anonymous', + }; + } + const name = options.name || options._componentTag; + return { + name: name, + path: options.__file, + }; +} + +/** + * Configure Vue error handling function + */ + +function vueErrorHandler(err: Error, vm: any, info: string) { + const errorLogStore = useErrorLogStoreWithOut(); + const { name, path } = formatComponentName(vm); + errorLogStore.addErrorLogInfo({ + type: ErrorTypeEnum.VUE, + name, + file: path, + message: err.message, + stack: processStackMsg(err), + detail: info, + url: window.location.href, + }); +} + +/** + * Configure script error handling function + */ +export function scriptErrorHandler( + event: Event | string, + source?: string, + lineno?: number, + colno?: number, + error?: Error, +) { + if (event === 'Script error.' && !source) { + return false; + } + const errorInfo: Partial = {}; + colno = colno || (window.event && (window.event as any).errorCharacter) || 0; + errorInfo.message = event as string; + if (error?.stack) { + errorInfo.stack = error.stack; + } else { + errorInfo.stack = ''; + } + const name = source ? source.substr(source.lastIndexOf('/') + 1) : 'script'; + const errorLogStore = useErrorLogStoreWithOut(); + errorLogStore.addErrorLogInfo({ + type: ErrorTypeEnum.SCRIPT, + name: name, + file: source as string, + detail: 'lineno' + lineno, + url: window.location.href, + ...(errorInfo as Pick), + }); + return true; +} + +/** + * Configure Promise error handling function + */ +function registerPromiseErrorHandler() { + window.addEventListener( + 'unhandledrejection', + function (event) { + const errorLogStore = useErrorLogStoreWithOut(); + errorLogStore.addErrorLogInfo({ + type: ErrorTypeEnum.PROMISE, + name: 'Promise Error!', + file: 'none', + detail: 'promise error!', + url: window.location.href, + stack: 'promise error!', + message: event.reason, + }); + }, + true, + ); +} + +/** + * Configure monitoring resource loading error handling function + */ +function registerResourceErrorHandler() { + // Monitoring resource loading error(img,script,css,and jsonp) + window.addEventListener( + 'error', + function (e: Event) { + const target = e.target ? e.target : (e.srcElement as any); + const errorLogStore = useErrorLogStoreWithOut(); + errorLogStore.addErrorLogInfo({ + type: ErrorTypeEnum.RESOURCE, + name: 'Resource Error!', + file: (e.target || ({} as any)).currentSrc, + detail: JSON.stringify({ + tagName: target.localName, + html: target.outerHTML, + type: e.type, + }), + url: window.location.href, + stack: 'resource is not found', + message: (e.target || ({} as any)).localName + ' is load error', + }); + }, + true, + ); +} + +/** + * Configure global error handling + * @param app + */ +export function setupErrorHandle(app: App) { + const { useErrorHandle } = projectSetting; + if (!useErrorHandle) { + return; + } + // Vue exception monitoring; + app.config.errorHandler = vueErrorHandler; + + // script error + window.onerror = scriptErrorHandler; + + // promise exception + registerPromiseErrorHandler(); + + // Static resource exception + registerResourceErrorHandler(); +} diff --git a/src/logics/initAppConfig.ts b/src/logics/initAppConfig.ts new file mode 100644 index 0000000..644066d --- /dev/null +++ b/src/logics/initAppConfig.ts @@ -0,0 +1,88 @@ +/** + * Application configuration + */ +import type { ProjectConfig } from '/#/config'; + +import { PROJ_CFG_KEY } from '/@/enums/cacheEnum'; +import projectSetting from '/@/settings/projectSetting'; + +import { + updateTextColor, + updateBorderColor, + updateHeaderBgColor, + updateSidebarBgColor, + updateComponentBgColor, + updateAppContentBgColor, +} from '/@/logics/theme/updateBackground'; +import { updateColorWeak } from '/@/logics/theme/updateColorWeak'; +import { updateGrayMode } from '/@/logics/theme/updateGrayMode'; +import { updateDarkTheme } from '/@/logics/theme/dark'; + +import { useAppStore } from '/@/store/modules/app'; +import { useLocaleStore } from '/@/store/modules/locale'; + +import { getCommonStoragePrefix, getStorageShortName } from '/@/utils/env'; + +import { Persistent } from '/@/utils/cache/persistent'; +import { deepMerge } from '/@/utils'; +import { ThemeEnum } from '/@/enums/appEnum'; + +// Initial project configuration +export function initAppConfigStore() { + const localeStore = useLocaleStore(); + const appStore = useAppStore(); + let projCfg: ProjectConfig = Persistent.getLocal(PROJ_CFG_KEY) as ProjectConfig; + projCfg = deepMerge(projectSetting, projCfg || {}); + const darkMode = appStore.getDarkMode; + const { + colorWeak, + grayMode, + + headerSetting: { bgColor: headerBgColor } = {}, + menuSetting: { bgColor } = {}, + } = projCfg; + try { + grayMode && updateGrayMode(grayMode); + colorWeak && updateColorWeak(colorWeak); + } catch (error) { + console.log(error); + } + appStore.setProjectConfig(projCfg); + + // init dark mode + updateDarkTheme(darkMode); + updateTextColor(); + updateBorderColor(); + updateComponentBgColor(); + updateAppContentBgColor(); + if (darkMode === ThemeEnum.DARK) { + updateHeaderBgColor(); + updateSidebarBgColor(); + } else { + headerBgColor && updateHeaderBgColor(headerBgColor); + bgColor && updateSidebarBgColor(bgColor); + } + // init store + localeStore.initLocale(); + + setTimeout(() => { + clearObsoleteStorage(); + }, 16); +} + +/** + * As the version continues to iterate, there will be more and more cache keys stored in localStorage. + * This method is used to delete useless keys + */ +export function clearObsoleteStorage() { + const commonPrefix = getCommonStoragePrefix(); + const shortPrefix = getStorageShortName(); + + [localStorage, sessionStorage].forEach((item: Storage) => { + Object.keys(item).forEach((key) => { + if (key && key.startsWith(commonPrefix) && !key.startsWith(shortPrefix)) { + item.removeItem(key); + } + }); + }); +} \ No newline at end of file diff --git a/src/logics/mitt/routeChange.ts b/src/logics/mitt/routeChange.ts new file mode 100644 index 0000000..a985fe2 --- /dev/null +++ b/src/logics/mitt/routeChange.ts @@ -0,0 +1,31 @@ +/** + * Used to monitor routing changes to change the status of menus and tabs. There is no need to monitor the route, because the route status change is affected by the page rendering time, which will be slow + */ + +import { mitt } from '/@/utils/mitt'; +import type { RouteLocationNormalized } from 'vue-router'; +import { getRawRoute } from '/@/utils'; + +const emitter = mitt(); + +const key = Symbol(); + +let lastChangeTab: RouteLocationNormalized; + +export function setRouteChange(lastChangeRoute: RouteLocationNormalized) { + const r = getRawRoute(lastChangeRoute); + emitter.emit(key, r); + lastChangeTab = r; +} + +export function listenerRouteChange( + callback: (route: RouteLocationNormalized) => void, + immediate = true, +) { + emitter.on(key, callback); + immediate && lastChangeTab && callback(lastChangeTab); +} + +export function removeTabChangeListener() { + emitter.clear(); +} diff --git a/src/logics/theme/dark.ts b/src/logics/theme/dark.ts new file mode 100644 index 0000000..bf6c34a --- /dev/null +++ b/src/logics/theme/dark.ts @@ -0,0 +1,20 @@ +import { addClass, hasClass, removeClass } from '/@/utils/domUtils'; + +export async function updateDarkTheme(mode: string | null = 'light') { + const htmlRoot = document.getElementById('htmlRoot'); + if (!htmlRoot) { + return; + } + const hasDarkClass = hasClass(htmlRoot, 'dark'); + if (mode === 'dark') { + htmlRoot.setAttribute('data-theme', 'dark'); + if (!hasDarkClass) { + addClass(htmlRoot, 'dark'); + } + } else { + htmlRoot.setAttribute('data-theme', 'light'); + if (hasDarkClass) { + removeClass(htmlRoot, 'dark'); + } + } +} diff --git a/src/logics/theme/index.ts b/src/logics/theme/index.ts new file mode 100644 index 0000000..d8e80b7 --- /dev/null +++ b/src/logics/theme/index.ts @@ -0,0 +1 @@ +export async function changeTheme(_color: string) {} diff --git a/src/logics/theme/updateBackground.ts b/src/logics/theme/updateBackground.ts new file mode 100644 index 0000000..eea1997 --- /dev/null +++ b/src/logics/theme/updateBackground.ts @@ -0,0 +1,198 @@ +import { colorIsDark, lighten, darken } from '/@/utils/color'; +import { useAppStore } from '/@/store/modules/app'; +import { ThemeEnum } from '/@/enums/appEnum'; +import { setCssVar } from './util'; + +const TEXT_COLOR_VAR = '--text-color'; + +const BORDER_COLOR_VAR = '--border-color'; + +const HEADER_BG_COLOR_VAR = '--header-bg-color'; +const HEADER_BG_HOVER_COLOR_VAR = '--header-bg-hover-color'; +const HEADER_MENU_ACTIVE_BG_COLOR_VAR = '--header-active-menu-bg-color'; + +const SIDER_DARK_BG_COLOR = '--sider-dark-bg-color'; +const SIDER_DARK_DARKEN_BG_COLOR = '--sider-dark-darken-bg-color'; +const SIDER_LIGHTEN_BG_COLOR = '--sider-dark-lighten-bg-color'; + +const COMPONENT_BACKGROUND_COLOR = '--component-background-color'; + +const APP_CONTENT_BACKGROUND_COLOR = '--app-content-background-color'; + +/** + * Change the text color of the html + * @param color + */ +export function updateTextColor(color?: string) { + const appStore = useAppStore(); + const darkMode = appStore.getDarkMode === ThemeEnum.DARK; + if (!color) { + if (darkMode) { + color = '#c9d1d9'; + } else { + color = 'rgb(0, 0, 0, 0.85)'; + } + } + + // text color + setCssVar(TEXT_COLOR_VAR, color); + + // only #ffffff is light + // Only when the background color is #fff, the theme of the menu will be changed to light + const isLight = ['#fff', '#ffffff'].includes(color!.toLowerCase()); + + appStore.setProjectConfig({ + menuSetting: { + theme: isLight && !darkMode ? ThemeEnum.LIGHT : ThemeEnum.DARK, + }, + }); +} + +/** + * Change the border color of the border + * @param color + */ +export function updateBorderColor(color?: string) { + const appStore = useAppStore(); + const darkMode = appStore.getDarkMode === ThemeEnum.DARK; + if (!color) { + if (darkMode) { + color = '#303030'; + } else { + color = '#eee'; + } + } + + // text color + setCssVar(BORDER_COLOR_VAR, color); + + // only #ffffff is light + // Only when the background color is #fff, the theme of the menu will be changed to light + const isLight = ['#fff', '#ffffff'].includes(color!.toLowerCase()); + + appStore.setProjectConfig({ + menuSetting: { + theme: isLight && !darkMode ? ThemeEnum.LIGHT : ThemeEnum.DARK, + }, + }); +} + +/** + * Change the background color of the top header + * @param color + */ +export function updateHeaderBgColor(color?: string) { + const appStore = useAppStore(); + const darkMode = appStore.getDarkMode === ThemeEnum.DARK; + if (!color) { + if (darkMode) { + color = '#151515'; + } else { + color = appStore.getHeaderSetting.bgColor; + } + } + + // bg color + setCssVar(HEADER_BG_COLOR_VAR, color); + + // hover color + const hoverColor = lighten(color!, 6); + setCssVar(HEADER_BG_HOVER_COLOR_VAR, hoverColor); + setCssVar(HEADER_MENU_ACTIVE_BG_COLOR_VAR, hoverColor); + + // Determine the depth of the color value and automatically switch the theme + const isDark = colorIsDark(color!); + + appStore.setProjectConfig({ + headerSetting: { + theme: isDark || darkMode ? ThemeEnum.DARK : ThemeEnum.LIGHT, + }, + }); +} + +/** + * Change the background color of the left menu + * @param color bg color + */ +export function updateSidebarBgColor(color?: string) { + const appStore = useAppStore(); + + // if (!isHexColor(color)) return; + const darkMode = appStore.getDarkMode === ThemeEnum.DARK; + if (!color) { + if (darkMode) { + color = '#212121'; + } else { + color = appStore.getMenuSetting.bgColor; + } + } + setCssVar(SIDER_DARK_BG_COLOR, color); + setCssVar(SIDER_DARK_DARKEN_BG_COLOR, darken(color!, 6)); + setCssVar(SIDER_LIGHTEN_BG_COLOR, lighten(color!, 5)); + + // only #ffffff is light + // Only when the background color is #fff, the theme of the menu will be changed to light + const isLight = ['#fff', '#ffffff'].includes(color!.toLowerCase()); + + appStore.setProjectConfig({ + menuSetting: { + theme: isLight && !darkMode ? ThemeEnum.LIGHT : ThemeEnum.DARK, + }, + }); +} + +/** + * Change the background color of the componet + * @param color + */ +export function updateComponentBgColor(color?: string) { + const appStore = useAppStore(); + const darkMode = appStore.getDarkMode === ThemeEnum.DARK; + if (!color) { + if (darkMode) { + color = '#151515'; + } else { + color = '#fff'; + } + } + // component color + setCssVar(COMPONENT_BACKGROUND_COLOR, color); + + // only #ffffff is light + // Only when the background color is #fff, the theme of the menu will be changed to light + const isLight = ['#fff', '#ffffff'].includes(color!.toLowerCase()); + + appStore.setProjectConfig({ + menuSetting: { + theme: isLight && !darkMode ? ThemeEnum.LIGHT : ThemeEnum.DARK, + }, + }); +} + +/** + * Change the background color of the app content + * @param color + */ +export function updateAppContentBgColor(color?: string) { + const appStore = useAppStore(); + const darkMode = appStore.getDarkMode === ThemeEnum.DARK; + if (!color) { + if (darkMode) { + color = '#1e1e1e'; + } else { + color = '#fafafa'; + } + } + // app content color + setCssVar(APP_CONTENT_BACKGROUND_COLOR, color); + + // only #ffffff is light + // Only when the background color is #fff, the theme of the menu will be changed to light + const isLight = ['#fff', '#ffffff'].includes(color!.toLowerCase()); + + appStore.setProjectConfig({ + menuSetting: { + theme: isLight && !darkMode ? ThemeEnum.LIGHT : ThemeEnum.DARK, + }, + }); +} \ No newline at end of file diff --git a/src/logics/theme/updateColorWeak.ts b/src/logics/theme/updateColorWeak.ts new file mode 100644 index 0000000..8a0e64a --- /dev/null +++ b/src/logics/theme/updateColorWeak.ts @@ -0,0 +1,9 @@ +import { toggleClass } from './util'; + +/** + * Change the status of the project's color weakness mode + * @param colorWeak + */ +export function updateColorWeak(colorWeak: boolean) { + toggleClass(colorWeak, 'color-weak', document.documentElement); +} diff --git a/src/logics/theme/updateGrayMode.ts b/src/logics/theme/updateGrayMode.ts new file mode 100644 index 0000000..0fd16fe --- /dev/null +++ b/src/logics/theme/updateGrayMode.ts @@ -0,0 +1,9 @@ +import { toggleClass } from './util'; + +/** + * Change project gray mode status + * @param gray + */ +export function updateGrayMode(gray: boolean) { + toggleClass(gray, 'gray-mode', document.documentElement); +} diff --git a/src/logics/theme/util.ts b/src/logics/theme/util.ts new file mode 100644 index 0000000..30aef37 --- /dev/null +++ b/src/logics/theme/util.ts @@ -0,0 +1,11 @@ +const docEle = document.documentElement; +export function toggleClass(flag: boolean, clsName: string, target?: HTMLElement) { + const targetEl = target || document.body; + let { className } = targetEl; + className = className.replace(clsName, ''); + targetEl.className = flag ? `${className} ${clsName} ` : className; +} + +export function setCssVar(prop: string, val: any, dom = docEle) { + dom.style.setProperty(prop, val); +} diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..1c4c808 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,64 @@ +import 'uno.css'; +import '@/design/index.less'; +import '@/components/VxeTable/src/css/index.scss'; +import 'ant-design-vue/dist/reset.css'; +// Register icon sprite +import 'virtual:svg-icons-register'; + +import { createApp } from 'vue'; + +import { registerGlobComp } from '@/components/registerGlobComp'; +import { setupGlobDirectives } from '@/directives'; +import { setupI18n } from '@/locales/setupI18n'; +import { setupErrorHandle } from '@/logics/error-handle'; +import { initAppConfigStore } from '@/logics/initAppConfig'; +import { router, setupRouter } from '@/router'; +import { setupRouterGuard } from '@/router/guard'; +import { setupStore } from '@/store'; + +import App from './App.vue'; + +async function bootstrap() { + const app = createApp(App); + + // Configure store + // 配置 store + setupStore(app); + + // Initialize internal system configuration + // 初始化内部系统配置 + initAppConfigStore(); + + // Register global components + // 注册全局组件 + registerGlobComp(app); + + // Multilingual configuration + // 多语言配置 + // Asynchronous case: language files may be obtained from the server side + // 异步案例:语言文件可能从服务器端获取 + await setupI18n(app); + + // Configure routing + // 配置路由 + setupRouter(app); + + // router-guard + // 路由守卫 + setupRouterGuard(router); + + // Register global directive + // 注册全局指令 + setupGlobDirectives(app); + + // Configure global error handling + // 配置全局错误处理 + setupErrorHandle(app); + + // https://next.router.vuejs.org/api/#isready + // await router.isReady(); + + app.mount('#app'); +} + +bootstrap(); diff --git a/src/router/.DS_Store b/src/router/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..0b0080ca060008ee7160849e5bc5c0a9e1a50270 GIT binary patch literal 6148 zcmeHKK~BRk5L`owDte$tj=sQ|{vcH0j?@o8DQYDW5(Rn>FX0_LfD3$z*|mkTNh59* zf?dfTXT57rri!;FA~)ZzW<*mW8ly2L$LMw#&vWb9LG*C4lQmZPdbYSLi>eoE4pYDs z_zRWZRwV3>U_WFOFdhZS+>ke_VR)7`SALF*^OBJ5K(Q~C&V?<>4-LTPdQcS zYkh*8y>;gYIH)y>awiKFqj_8~j}aAM@CYrQG>elDJv+dml|R6s6`}X%p8-15RATpM zu;?(DymaRWIH)xSSg07y!!r-F|DgbCHrsd-(0WtA6fgz872xy1qcNrtn}Bk3ppz>A zFo9bPW2t38&kkT3u?Ywd%!O27NOkdw;X*q6KE|aHn}8vmoa~Hs;?6GKP@L=zzn5@w zX+Y~u0aHLLa2Ot^T>r0z@BccicitRFz0yyOd~b{;epv70g=HvQ(&(Od;wFJe;fb+ literal 0 HcmV?d00001 diff --git a/src/router/constant.ts b/src/router/constant.ts new file mode 100644 index 0000000..fb967d8 --- /dev/null +++ b/src/router/constant.ts @@ -0,0 +1,24 @@ +export const REDIRECT_NAME = 'Redirect'; + +export const PARENT_LAYOUT_NAME = 'ParentLayout'; + +export const PAGE_NOT_FOUND_NAME = 'PageNotFound'; + +export const EXCEPTION_COMPONENT = () => import('/@/views/sys/exception/Exception.vue'); + +/** + * @description: default layout + */ +export const LAYOUT = () => import('/@/layouts/default/index.vue'); + +/** + * @description: parent-layout + */ +export const getParentLayout = (_name?: string) => { + return () => + new Promise((resolve) => { + resolve({ + name: _name || PARENT_LAYOUT_NAME, + }); + }); +}; diff --git a/src/router/guard/index.ts b/src/router/guard/index.ts new file mode 100644 index 0000000..c567749 --- /dev/null +++ b/src/router/guard/index.ts @@ -0,0 +1,147 @@ +import type { Router, RouteLocationNormalized } from 'vue-router'; +import { useAppStoreWithOut } from '/@/store/modules/app'; +import { useUserStoreWithOut } from '/@/store/modules/user'; +import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting'; +import { AxiosCanceler } from '/@/utils/http/axios/axiosCancel'; +import { Modal, notification } from 'ant-design-vue'; +import { warn } from '/@/utils/log'; +import { unref } from 'vue'; +import { setRouteChange } from '/@/logics/mitt/routeChange'; +import { createPermissionGuard } from './permissionGuard'; +import { createStateGuard } from './stateGuard'; +import nProgress from 'nprogress'; +import projectSetting from '/@/settings/projectSetting'; +import { createParamMenuGuard } from './paramMenuGuard'; + +// Don't change the order of creation +export function setupRouterGuard(router: Router) { + createPageGuard(router); + createPageLoadingGuard(router); + createHttpGuard(router); + createScrollGuard(router); + createMessageGuard(router); + createProgressGuard(router); + createPermissionGuard(router); + createParamMenuGuard(router); // must after createPermissionGuard (menu has been built.) + createStateGuard(router); +} + +/** + * Hooks for handling page state + */ +function createPageGuard(router: Router) { + const loadedPageMap = new Map(); + + router.beforeEach(async (to) => { + // The page has already been loaded, it will be faster to open it again, you don’t need to do loading and other processing + to.meta.loaded = !!loadedPageMap.get(to.path); + // Notify routing changes + setRouteChange(to); + + return true; + }); + + router.afterEach((to) => { + loadedPageMap.set(to.path, true); + }); +} + +// Used to handle page loading status +function createPageLoadingGuard(router: Router) { + const userStore = useUserStoreWithOut(); + const appStore = useAppStoreWithOut(); + const { getOpenPageLoading } = useTransitionSetting(); + router.beforeEach(async (to) => { + if (!userStore.getToken) { + return true; + } + if (to.meta.loaded) { + return true; + } + + if (unref(getOpenPageLoading)) { + appStore.setPageLoadingAction(true); + return true; + } + + return true; + }); + router.afterEach(async () => { + if (unref(getOpenPageLoading)) { + // TODO Looking for a better way + // The timer simulates the loading time to prevent flashing too fast, + setTimeout(() => { + appStore.setPageLoading(false); + }, 220); + } + return true; + }); +} + +/** + * The interface used to close the current page to complete the request when the route is switched + * @param router + */ +function createHttpGuard(router: Router) { + const { removeAllHttpPending } = projectSetting; + let axiosCanceler: Nullable; + if (removeAllHttpPending) { + axiosCanceler = new AxiosCanceler(); + } + router.beforeEach(async () => { + // Switching the route will delete the previous request + axiosCanceler?.removeAllPending(); + return true; + }); +} + +// Routing switch back to the top +function createScrollGuard(router: Router) { + const isHash = (href: string) => { + return /^#/.test(href); + }; + + const body = document.body; + + router.afterEach(async (to) => { + // scroll top + isHash((to as RouteLocationNormalized & { href: string })?.href) && body.scrollTo(0, 0); + return true; + }); +} + +/** + * Used to close the message instance when the route is switched + * @param router + */ +export function createMessageGuard(router: Router) { + const { closeMessageOnSwitch } = projectSetting; + + router.beforeEach(async () => { + try { + if (closeMessageOnSwitch) { + Modal.destroyAll(); + notification.destroy(); + } + } catch (error) { + warn('message guard error:' + error); + } + return true; + }); +} + +export function createProgressGuard(router: Router) { + const { getOpenNProgress } = useTransitionSetting(); + router.beforeEach(async (to) => { + if (to.meta.loaded) { + return true; + } + unref(getOpenNProgress) && nProgress.start(); + return true; + }); + + router.afterEach(async () => { + unref(getOpenNProgress) && nProgress.done(); + return true; + }); +} diff --git a/src/router/guard/paramMenuGuard.ts b/src/router/guard/paramMenuGuard.ts new file mode 100644 index 0000000..1c75157 --- /dev/null +++ b/src/router/guard/paramMenuGuard.ts @@ -0,0 +1,47 @@ +import type { Router } from 'vue-router'; +import { configureDynamicParamsMenu } from '../helper/menuHelper'; +import { Menu } from '../types'; +import { PermissionModeEnum } from '/@/enums/appEnum'; +import { useAppStoreWithOut } from '/@/store/modules/app'; + +import { usePermissionStoreWithOut } from '/@/store/modules/permission'; + +export function createParamMenuGuard(router: Router) { + const permissionStore = usePermissionStoreWithOut(); + router.beforeEach(async (to, _, next) => { + // filter no name route + if (!to.name) { + next(); + return; + } + + // menu has been built. + if (!permissionStore.getIsDynamicAddedRoute) { + next(); + return; + } + + let menus: Menu[] = []; + if (isBackMode()) { + menus = permissionStore.getBackMenuList; + } else if (isRouteMappingMode()) { + menus = permissionStore.getFrontMenuList; + } + menus.forEach((item) => configureDynamicParamsMenu(item, to.params)); + + next(); + }); +} + +const getPermissionMode = () => { + const appStore = useAppStoreWithOut(); + return appStore.getProjectConfig.permissionMode; +}; + +const isBackMode = () => { + return getPermissionMode() === PermissionModeEnum.BACK; +}; + +const isRouteMappingMode = () => { + return getPermissionMode() === PermissionModeEnum.ROUTE_MAPPING; +}; diff --git a/src/router/guard/permissionGuard.ts b/src/router/guard/permissionGuard.ts new file mode 100644 index 0000000..5b1acde --- /dev/null +++ b/src/router/guard/permissionGuard.ts @@ -0,0 +1,119 @@ +import type { Router, RouteRecordRaw } from 'vue-router'; + +import { usePermissionStoreWithOut } from '/@/store/modules/permission'; + +import { PageEnum } from '/@/enums/pageEnum'; +import { useUserStoreWithOut } from '/@/store/modules/user'; + +import { PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic'; + +import { RootRoute } from '/@/router/routes'; + +const LOGIN_PATH = PageEnum.BASE_LOGIN; + +const ROOT_PATH = RootRoute.path; + +const whitePathList: PageEnum[] = [LOGIN_PATH]; + +export function createPermissionGuard(router: Router) { + const userStore = useUserStoreWithOut(); + const permissionStore = usePermissionStoreWithOut(); + router.beforeEach(async (to, from, next) => { + if ( + from.path === ROOT_PATH && + to.path === PageEnum.BASE_HOME && + userStore.getUserInfo.homePath && + userStore.getUserInfo.homePath !== PageEnum.BASE_HOME + ) { + next(userStore.getUserInfo.homePath); + return; + } + + const token = userStore.getToken; + + // Whitelist can be directly entered + if (whitePathList.includes(to.path as PageEnum)) { + if (to.path === LOGIN_PATH && token) { + const isSessionTimeout = userStore.getSessionTimeout; + try { + await userStore.afterLoginAction(); + if (!isSessionTimeout) { + next((to.query?.redirect as string) || '/'); + return; + } + } catch { + // + } + } + next(); + return; + } + // token or user does not exist + if (!token) { + // You can access without permission. You need to set the routing meta.ignoreAuth to true + if (to.meta.ignoreAuth) { + next(); + return; + } + + // redirect login page + const redirectData: { path: string; replace: boolean; query?: Recordable } = { + path: LOGIN_PATH, + replace: true, + }; + if (to.path) { + redirectData.query = { + ...redirectData.query, + redirect: to.path, + }; + } + next(redirectData); + return; + } + + // Jump to the 404 page after processing the login + if ( + from.path === LOGIN_PATH && + to.name === PAGE_NOT_FOUND_ROUTE.name && + to.fullPath !== (userStore.getUserInfo.homePath || PageEnum.BASE_HOME) + ) { + next(userStore.getUserInfo.homePath || PageEnum.BASE_HOME); + return; + } + + // get userinfo while last fetch time is empty + if (userStore.getLastUpdateTime === 0) { + try { + await userStore.getUserInfoAction(); + } catch (err) { + next(); + return; + } + } + + if (permissionStore.getIsDynamicAddedRoute) { + next(); + return; + } + + const routes = await permissionStore.buildRoutesAction(); + + routes.forEach((route) => { + router.addRoute(route as unknown as RouteRecordRaw); + }); + + router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw); + + permissionStore.setDynamicAddedRoute(true); + + if (to.name === PAGE_NOT_FOUND_ROUTE.name) { + // 动态添加路由后,此处应当重定向到fullPath,否则会加载404页面内容 + next({ path: to.fullPath, replace: true, query: to.query }); + } else { + const redirectPath = (from.query.redirect || to.path) as string; + const redirect = decodeURIComponent(redirectPath); + const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect }; + next(nextData); + } + }); +} diff --git a/src/router/guard/stateGuard.ts b/src/router/guard/stateGuard.ts new file mode 100644 index 0000000..c34513c --- /dev/null +++ b/src/router/guard/stateGuard.ts @@ -0,0 +1,24 @@ +import type { Router } from 'vue-router'; +import { useAppStore } from '/@/store/modules/app'; +import { useMultipleTabStore } from '/@/store/modules/multipleTab'; +import { useUserStore } from '/@/store/modules/user'; +import { usePermissionStore } from '/@/store/modules/permission'; +import { PageEnum } from '/@/enums/pageEnum'; +import { removeTabChangeListener } from '/@/logics/mitt/routeChange'; + +export function createStateGuard(router: Router) { + router.afterEach((to) => { + // Just enter the login page and clear the authentication information + if (to.path === PageEnum.BASE_LOGIN) { + const tabStore = useMultipleTabStore(); + const userStore = useUserStore(); + const appStore = useAppStore(); + const permissionStore = usePermissionStore(); + appStore.resetAllState(); + permissionStore.resetState(); + tabStore.resetState(); + userStore.resetState(); + removeTabChangeListener(); + } + }); +} diff --git a/src/router/helper/menuHelper.ts b/src/router/helper/menuHelper.ts new file mode 100644 index 0000000..f0767b2 --- /dev/null +++ b/src/router/helper/menuHelper.ts @@ -0,0 +1,106 @@ +import { AppRouteModule } from '/@/router/types'; +import type { MenuModule, Menu, AppRouteRecordRaw } from '/@/router/types'; +import { findPath, treeMap } from '/@/utils/helper/treeHelper'; +import { cloneDeep } from 'lodash-es'; +import { isUrl } from '/@/utils/is'; +import { RouteParams } from 'vue-router'; +import { toRaw } from 'vue'; + +export function getAllParentPath(treeData: T[], path: string) { + const menuList = findPath(treeData, (n) => n.path === path) as Menu[]; + return (menuList || []).map((item) => item.path); +} + +// 路径处理 +function joinParentPath(menus: Menu[], parentPath = '') { + for (let index = 0; index < menus.length; index++) { + const menu = menus[index]; + // https://next.router.vuejs.org/guide/essentials/nested-routes.html + // Note that nested paths that start with / will be treated as a root path. + // 请注意,以 / 开头的嵌套路径将被视为根路径。 + // This allows you to leverage the component nesting without having to use a nested URL. + // 这允许你利用组件嵌套,而无需使用嵌套 URL。 + if (!(menu.path.startsWith('/') || isUrl(menu.path))) { + // path doesn't start with /, nor is it a url, join parent path + // 路径不以 / 开头,也不是 url,加入父路径 + menu.path = `${parentPath}/${menu.path}`; + } + if (menu?.children?.length) { + joinParentPath(menu.children, menu.meta?.hidePathForChildren ? parentPath : menu.path); + } + } +} + +// Parsing the menu module +export function transformMenuModule(menuModule: MenuModule): Menu { + const { menu } = menuModule; + + const menuList = [menu]; + + joinParentPath(menuList); + return menuList[0]; +} + +// 将路由转换成菜单 +export function transformRouteToMenu(routeModList: AppRouteModule[], routerMapping = false) { + // 借助 lodash 深拷贝 + const cloneRouteModList = cloneDeep(routeModList); + const routeList: AppRouteRecordRaw[] = []; + + // 对路由项进行修改 + cloneRouteModList.forEach((item) => { + if (routerMapping && item.meta.hideChildrenInMenu && typeof item.redirect === 'string') { + item.path = item.redirect; + } + + if (item.meta?.single) { + const realItem = item?.children?.[0]; + realItem && routeList.push(realItem); + } else { + routeList.push(item); + } + }); + // 提取树指定结构 + const list = treeMap(routeList, { + conversion: (node: AppRouteRecordRaw) => { + const { meta: { title, hideMenu = false } = {} } = node; + + return { + ...(node.meta || {}), + meta: node.meta, + name: title, + hideMenu, + path: node.path, + ...(node.redirect ? { redirect: node.redirect } : {}), + }; + }, + }); + // 路径处理 + joinParentPath(list); + return cloneDeep(list); +} + +/** + * config menu with given params + */ +const menuParamRegex = /(?::)([\s\S]+?)((?=\/)|$)/g; + +export function configureDynamicParamsMenu(menu: Menu, params: RouteParams) { + const { path, paramPath } = toRaw(menu); + let realPath = paramPath ? paramPath : path; + const matchArr = realPath.match(menuParamRegex); + + matchArr?.forEach((it) => { + const realIt = it.substr(1); + if (params[realIt]) { + realPath = realPath.replace(`:${realIt}`, params[realIt] as string); + } + }); + // save original param path. + if (!paramPath && matchArr && matchArr.length > 0) { + menu.paramPath = path; + } + menu.path = realPath; + // children + menu.children?.forEach((item) => configureDynamicParamsMenu(item, params)); +} diff --git a/src/router/helper/routeHelper.ts b/src/router/helper/routeHelper.ts new file mode 100644 index 0000000..d133209 --- /dev/null +++ b/src/router/helper/routeHelper.ts @@ -0,0 +1,178 @@ +import type { AppRouteModule, AppRouteRecordRaw } from '/@/router/types'; +import type { Router, RouteRecordNormalized } from 'vue-router'; + +import { getParentLayout, LAYOUT, EXCEPTION_COMPONENT } from '/@/router/constant'; +import { cloneDeep, omit } from 'lodash-es'; +import { warn } from '/@/utils/log'; +import { createRouter, createWebHashHistory } from 'vue-router'; + +export type LayoutMapKey = 'LAYOUT'; +const IFRAME = () => import('/@/views/sys/iframe/FrameBlank.vue'); + +const LayoutMap = new Map Promise>(); + +LayoutMap.set('LAYOUT', LAYOUT); +LayoutMap.set('IFRAME', IFRAME); + +let dynamicViewsModules: Record Promise>; + +// Dynamic introduction +function asyncImportRoute(routes: AppRouteRecordRaw[] | undefined) { + dynamicViewsModules = dynamicViewsModules || import.meta.glob('../../views/**/*.{vue,tsx}'); + if (!routes) return; + routes.forEach((item) => { + if (!item.component && item.meta?.frameSrc) { + item.component = 'IFRAME'; + } + const { component, name } = item; + const { children } = item; + if (component) { + const layoutFound = LayoutMap.get(component.toUpperCase()); + if (layoutFound) { + item.component = layoutFound; + } else { + item.component = dynamicImport(dynamicViewsModules, component as string); + } + } else if (name) { + item.component = getParentLayout(); + } + children && asyncImportRoute(children); + }); +} + +function dynamicImport( + dynamicViewsModules: Record Promise>, + component: string, +) { + const keys = Object.keys(dynamicViewsModules); + const matchKeys = keys.filter((key) => { + const k = key.replace('../../views', ''); + const startFlag = component.startsWith('/'); + const endFlag = component.endsWith('.vue') || component.endsWith('.tsx'); + const startIndex = startFlag ? 0 : 1; + const lastIndex = endFlag ? k.length : k.lastIndexOf('.'); + return k.substring(startIndex, lastIndex) === component; + }); + if (matchKeys?.length === 1) { + const matchKey = matchKeys[0]; + return dynamicViewsModules[matchKey]; + } else if (matchKeys?.length > 1) { + warn( + 'Please do not create `.vue` and `.TSX` files with the same file name in the same hierarchical directory under the views folder. This will cause dynamic introduction failure', + ); + return; + } else { + warn('在src/views/下找不到`' + component + '.vue` 或 `' + component + '.tsx`, 请自行创建!'); + return EXCEPTION_COMPONENT; + } +} + +// Turn background objects into routing objects +// 将背景对象变成路由对象 +export function transformObjToRoute(routeList: AppRouteModule[]): T[] { + routeList.forEach((route) => { + const component = route.component as string; + if (component) { + if (component.toUpperCase() === 'LAYOUT') { + route.component = LayoutMap.get(component.toUpperCase()); + } else { + route.children = [cloneDeep(route)]; + route.component = LAYOUT; + route.name = `${route.name}Parent`; + route.path = ''; + const meta = route.meta || {}; + meta.single = true; + meta.affix = false; + route.meta = meta; + } + } else { + warn('请正确配置路由:' + route?.name + '的component属性'); + } + route.children && asyncImportRoute(route.children); + }); + return routeList as unknown as T[]; +} + +/** + * Convert multi-level routing to level 2 routing + * 将多级路由转换为 2 级路由 + */ +export function flatMultiLevelRoutes(routeModules: AppRouteModule[]) { + const modules: AppRouteModule[] = cloneDeep(routeModules); + + for (let index = 0; index < modules.length; index++) { + const routeModule = modules[index]; + // 判断级别是否 多级 路由 + if (!isMultipleRoute(routeModule)) { + // 声明终止当前循环, 即跳过此次循环,进行下一轮 + continue; + } + // 路由等级提升 + promoteRouteLevel(routeModule); + } + return modules; +} + +// Routing level upgrade +// 路由等级提升 +function promoteRouteLevel(routeModule: AppRouteModule) { + // Use vue-router to splice menus + // 使用vue-router拼接菜单 + // createRouter 创建一个可以被 Vue 应用程序使用的路由实例 + let router: Router | null = createRouter({ + routes: [routeModule as unknown as RouteRecordNormalized], + history: createWebHashHistory(), + }); + // getRoutes: 获取所有 路由记录的完整列表。 + const routes = router.getRoutes(); + // 将所有子路由添加到二级路由 + addToChildren(routes, routeModule.children || [], routeModule); + router = null; + + // omit lodash的函数 对传入的item对象的children进行删除 + routeModule.children = routeModule.children?.map((item) => omit(item, 'children')); +} + +// Add all sub-routes to the secondary route +// 将所有子路由添加到二级路由 +function addToChildren( + routes: RouteRecordNormalized[], + children: AppRouteRecordRaw[], + routeModule: AppRouteModule, +) { + for (let index = 0; index < children.length; index++) { + const child = children[index]; + const route = routes.find((item) => item.name === child.name); + if (!route) { + continue; + } + routeModule.children = routeModule.children || []; + if (!routeModule.children.find((item) => item.name === route.name)) { + routeModule.children?.push(route as unknown as AppRouteModule); + } + if (child.children?.length) { + addToChildren(routes, child.children, routeModule); + } + } +} + +// Determine whether the level exceeds 2 levels +// 判断级别是否超过2级 +function isMultipleRoute(routeModule: AppRouteModule) { + // Reflect.has 与 in 操作符 相同, 用于检查一个对象(包括它原型链上)是否拥有某个属性 + if (!routeModule || !Reflect.has(routeModule, 'children') || !routeModule.children?.length) { + return false; + } + + const children = routeModule.children; + + let flag = false; + for (let index = 0; index < children.length; index++) { + const child = children[index]; + if (child.children?.length) { + flag = true; + break; + } + } + return flag; +} diff --git a/src/router/index.ts b/src/router/index.ts new file mode 100644 index 0000000..bcfc17f --- /dev/null +++ b/src/router/index.ts @@ -0,0 +1,42 @@ +import type { RouteRecordRaw } from 'vue-router'; +import type { App } from 'vue'; + +import { createRouter, createWebHashHistory } from 'vue-router'; +import { basicRoutes } from './routes'; + +// 白名单应该包含基本静态路由 +const WHITE_NAME_LIST: string[] = []; +const getRouteNames = (array: any[]) => + array.forEach((item) => { + WHITE_NAME_LIST.push(item.name); + getRouteNames(item.children || []); + }); +getRouteNames(basicRoutes); + +// app router +// 创建一个可以被 Vue 应用程序使用的路由实例 +export const router = createRouter({ + // 创建一个 hash 历史记录。 + history: createWebHashHistory(import.meta.env.VITE_PUBLIC_PATH), + // 应该添加到路由的初始路由列表。 + routes: basicRoutes as unknown as RouteRecordRaw[], + // 是否应该禁止尾部斜杠。默认为假 + strict: true, + scrollBehavior: () => ({ left: 0, top: 0 }), +}); + +// reset router +export function resetRouter() { + router.getRoutes().forEach((route) => { + const { name } = route; + if (name && !WHITE_NAME_LIST.includes(name as string)) { + router.hasRoute(name) && router.removeRoute(name); + } + }); +} + +// config router +// 配置路由器 +export function setupRouter(app: App) { + app.use(router); +} diff --git a/src/router/menus/index.ts b/src/router/menus/index.ts new file mode 100644 index 0000000..c9124b7 --- /dev/null +++ b/src/router/menus/index.ts @@ -0,0 +1,136 @@ +import type { Menu, MenuModule } from '/@/router/types'; +import type { RouteRecordNormalized } from 'vue-router'; + +import { useAppStoreWithOut } from '/@/store/modules/app'; +import { usePermissionStore } from '/@/store/modules/permission'; +import { transformMenuModule, getAllParentPath } from '/@/router/helper/menuHelper'; +import { filter } from '/@/utils/helper/treeHelper'; +import { isUrl } from '/@/utils/is'; +import { router } from '/@/router'; +import { PermissionModeEnum } from '/@/enums/appEnum'; +import { pathToRegexp } from 'path-to-regexp'; + +const modules = import.meta.glob('./modules/**/*.ts', { eager: true }); + +const menuModules: MenuModule[] = []; + +Object.keys(modules).forEach((key) => { + const mod = (modules as Recordable)[key].default || {}; + const modList = Array.isArray(mod) ? [...mod] : [mod]; + menuModules.push(...modList); +}); + +// =========================== +// ==========Helper=========== +// =========================== + +const getPermissionMode = () => { + const appStore = useAppStoreWithOut(); + return appStore.getProjectConfig.permissionMode; +}; +const isBackMode = () => { + return getPermissionMode() === PermissionModeEnum.BACK; +}; + +const isRouteMappingMode = () => { + return getPermissionMode() === PermissionModeEnum.ROUTE_MAPPING; +}; + +const isRoleMode = () => { + return getPermissionMode() === PermissionModeEnum.ROLE; +}; + +const staticMenus: Menu[] = []; +(() => { + menuModules.sort((a, b) => { + return (a.orderNo || 0) - (b.orderNo || 0); + }); + + for (const menu of menuModules) { + staticMenus.push(transformMenuModule(menu)); + } +})(); + +async function getAsyncMenus() { + const permissionStore = usePermissionStore(); + //递归过滤所有隐藏的菜单 + const menuFilter = (items) => { + return items.filter((item) => { + const show = !item.meta?.hideMenu && !item.hideMenu; + if (show && item.children) { + item.children = menuFilter(item.children); + } + return show; + }); + }; + if (isBackMode()) { + return menuFilter(permissionStore.getBackMenuList); + } + if (isRouteMappingMode()) { + return menuFilter(permissionStore.getFrontMenuList); + } + return staticMenus; +} + +export const getMenus = async (): Promise => { + const menus = await getAsyncMenus(); + if (isRoleMode()) { + const routes = router.getRoutes(); + return filter(menus, basicFilter(routes)); + } + return menus; +}; + +export async function getCurrentParentPath(currentPath: string) { + const menus = await getAsyncMenus(); + const allParentPath = await getAllParentPath(menus, currentPath); + return allParentPath?.[0]; +} + +// Get the level 1 menu, delete children +export async function getShallowMenus(): Promise { + const menus = await getAsyncMenus(); + const shallowMenuList = menus.map((item) => ({ ...item, children: undefined })); + if (isRoleMode()) { + const routes = router.getRoutes(); + return shallowMenuList.filter(basicFilter(routes)); + } + return shallowMenuList; +} + +// Get the children of the menu +export async function getChildrenMenus(parentPath: string) { + const menus = await getMenus(); + const parent = menus.find((item) => item.path === parentPath); + if (!parent || !parent.children || !!parent?.meta?.hideChildrenInMenu) { + return [] as Menu[]; + } + if (isRoleMode()) { + const routes = router.getRoutes(); + return filter(parent.children, basicFilter(routes)); + } + return parent.children; +} + +function basicFilter(routes: RouteRecordNormalized[]) { + return (menu: Menu) => { + const matchRoute = routes.find((route) => { + if (isUrl(menu.path)) return true; + + if (route.meta?.carryParam) { + return pathToRegexp(route.path).test(menu.path); + } + const isSame = route.path === menu.path; + if (!isSame) return false; + + if (route.meta?.ignoreAuth) return true; + + return isSame || pathToRegexp(route.path).test(menu.path); + }); + + if (!matchRoute) return false; + menu.icon = (menu.icon || matchRoute.meta.icon) as string; + menu.meta = matchRoute.meta; + return true; + }; +} diff --git a/src/router/routes/basic.ts b/src/router/routes/basic.ts new file mode 100644 index 0000000..573ce2b --- /dev/null +++ b/src/router/routes/basic.ts @@ -0,0 +1,78 @@ +import type { AppRouteRecordRaw } from '/@/router/types'; +import { t } from '/@/hooks/web/useI18n'; +import { + REDIRECT_NAME, + LAYOUT, + EXCEPTION_COMPONENT, + PAGE_NOT_FOUND_NAME, +} from '/@/router/constant'; + +// 404 on a page +export const PAGE_NOT_FOUND_ROUTE: AppRouteRecordRaw = { + path: '/:path(.*)*', + name: PAGE_NOT_FOUND_NAME, + component: LAYOUT, + meta: { + title: 'ErrorPage', + hideBreadcrumb: true, + hideMenu: true, + }, + children: [ + { + path: '/:path(.*)*', + name: PAGE_NOT_FOUND_NAME, + component: EXCEPTION_COMPONENT, + meta: { + title: 'ErrorPage', + hideBreadcrumb: true, + hideMenu: true, + }, + }, + ], +}; + +export const REDIRECT_ROUTE: AppRouteRecordRaw = { + path: '/redirect', + component: LAYOUT, + name: 'RedirectTo', + meta: { + title: REDIRECT_NAME, + hideBreadcrumb: true, + hideMenu: true, + }, + children: [ + { + path: '/redirect/:path(.*)/:_redirect_type(.*)/:_origin_params(.*)?', + name: REDIRECT_NAME, + component: () => import('/@/views/sys/redirect/index.vue'), + meta: { + title: REDIRECT_NAME, + hideBreadcrumb: true, + }, + }, + ], +}; + +export const ERROR_LOG_ROUTE: AppRouteRecordRaw = { + path: '/error-log', + name: 'ErrorLog', + component: LAYOUT, + redirect: '/error-log/list', + meta: { + title: 'ErrorLog', + hideBreadcrumb: true, + hideChildrenInMenu: true, + }, + children: [ + { + path: 'list', + name: 'ErrorLogList', + component: () => import('/@/views/sys/error-log/index.vue'), + meta: { + title: t('routes.basic.errorLogList'), + hideBreadcrumb: true, + currentActiveMenu: '/error-log', + }, + }, + ], +}; diff --git a/src/router/routes/index.ts b/src/router/routes/index.ts new file mode 100644 index 0000000..8c3758d --- /dev/null +++ b/src/router/routes/index.ts @@ -0,0 +1,42 @@ +import type { AppRouteRecordRaw, AppRouteModule } from '/@/router/types'; + +import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '/@/router/routes/basic'; + +import { PageEnum } from '/@/enums/pageEnum'; +import { t } from '/@/hooks/web/useI18n'; + +// import.meta.glob() 直接引入所有的模块 Vite 独有的功能 +const modules = import.meta.glob('./modules/**/*.ts', { eager: true }); +const routeModuleList: AppRouteModule[] = []; + +// 加入到路由集合中 +Object.keys(modules).forEach((key) => { + const mod = (modules as Recordable)[key].default || {}; + const modList = Array.isArray(mod) ? [...mod] : [mod]; + routeModuleList.push(...modList); +}); + +export const asyncRoutes = [PAGE_NOT_FOUND_ROUTE, ...routeModuleList]; + +// 根路由 +export const RootRoute: AppRouteRecordRaw = { + path: '/', + name: 'Root', + redirect: PageEnum.BASE_HOME, + meta: { + title: 'Root', + }, +}; + +export const LoginRoute: AppRouteRecordRaw = { + path: '/login', + name: 'Login', + component: () => import('/@/views/sys/login/Login.vue'), + meta: { + title: t('routes.basic.login'), + }, +}; + +// Basic routing without permission +// 未经许可的基本路由 +export const basicRoutes = [LoginRoute, RootRoute, REDIRECT_ROUTE, PAGE_NOT_FOUND_ROUTE]; diff --git a/src/router/types.ts b/src/router/types.ts new file mode 100644 index 0000000..082d208 --- /dev/null +++ b/src/router/types.ts @@ -0,0 +1,58 @@ +import type { RouteRecordRaw, RouteMeta } from 'vue-router'; +import { RoleEnum } from '/@/enums/roleEnum'; +import { defineComponent } from 'vue'; + +export type Component = + | ReturnType + | (() => Promise) + | (() => Promise); + +// @ts-ignore +export interface AppRouteRecordRaw extends Omit { + name: string; + meta: RouteMeta; + component?: Component | string; + components?: Component; + children?: AppRouteRecordRaw[]; + props?: Recordable; + fullPath?: string; +} + +export interface MenuTag { + type?: 'primary' | 'error' | 'warn' | 'success'; + content?: string; + dot?: boolean; +} + +export interface Menu { + name: string; + + icon?: string; + + path: string; + + // path contains param, auto assignment. + paramPath?: string; + + disabled?: boolean; + + children?: Menu[]; + + orderNo?: number; + + roles?: RoleEnum[]; + + meta?: Partial; + + tag?: MenuTag; + + hideMenu?: boolean; +} + +export interface MenuModule { + orderNo?: number; + menu: Menu; +} + +// export type AppRouteModule = RouteModule | AppRouteRecordRaw; +export type AppRouteModule = AppRouteRecordRaw; diff --git a/src/settings/componentSetting.ts b/src/settings/componentSetting.ts new file mode 100644 index 0000000..e718e1a --- /dev/null +++ b/src/settings/componentSetting.ts @@ -0,0 +1,51 @@ +// Used to configure the general configuration of some components without modifying the components + +import type { SorterResult } from '../components/Table'; + +export default { + // basic-table setting + table: { + // Form interface request general configuration + // support xxx.xxx.xxx + fetchSetting: { + // The field name of the current page passed to the background + pageField: 'page', + // The number field name of each page displayed in the background + sizeField: 'pageSize', + // Field name of the form data returned by the interface + listField: 'records', + // Total number of tables returned by the interface field name + totalField: 'total', + }, + // Number of pages that can be selected + pageSizeOptions: ['10', '50', '80', '100'], + // Default display quantity on one page + defaultPageSize: 10, + // Default Size + defaultSize: 'middle', + // Custom general sort function + defaultSortFn: (sortInfo: SorterResult) => { + const { field, order } = sortInfo; + if (field && order) { + return { + // The sort field passed to the backend you + field, + // Sorting method passed to the background asc/desc + order, + }; + } else { + return {}; + } + }, + // Custom general filter function + defaultFilterFn: (data: Partial>) => { + return data; + }, + }, + // scrollbar setting + scrollbar: { + // Whether to use native scroll bar + // After opening, the menu, modal, drawer will change the pop-up scroll bar to native + native: false, + }, +}; diff --git a/src/settings/designSetting.ts b/src/settings/designSetting.ts new file mode 100644 index 0000000..a81b576 --- /dev/null +++ b/src/settings/designSetting.ts @@ -0,0 +1,48 @@ +import { ThemeEnum } from '../enums/appEnum'; + +export const prefixCls = 'vben'; + +export const darkMode = ThemeEnum.LIGHT; + +// app theme preset color +export const APP_PRESET_COLOR_LIST: string[] = [ + '#0960bd', + '#0084f4', + '#009688', + '#536dfe', + '#ff5c93', + '#ee4f12', + '#0096c7', + '#9c27b0', + '#ff9800', +]; + +// header preset color +export const HEADER_PRESET_BG_COLOR_LIST: string[] = [ + '#ffffff', + '#151515', + '#009688', + '#5172DC', + '#018ffb', + '#409eff', + '#e74c3c', + '#24292e', + '#394664', + '#001529', + '#383f45', +]; + +// sider preset color +export const SIDE_BAR_BG_COLOR_LIST: string[] = [ + '#001529', + '#212121', + '#273352', + '#ffffff', + '#191b24', + '#191a23', + '#304156', + '#001628', + '#28333E', + '#344058', + '#383f45', +]; diff --git a/src/settings/encryptionSetting.ts b/src/settings/encryptionSetting.ts new file mode 100644 index 0000000..df3c7d5 --- /dev/null +++ b/src/settings/encryptionSetting.ts @@ -0,0 +1,13 @@ +import { isDevMode } from '/@/utils/env'; + +// System default cache time, in seconds +export const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 1; + +// aes encryption key +export const cacheCipher = { + key: '_11111000001111@', + iv: '@11111000001111_', +}; + +// Whether the system cache is encrypted using aes +export const enableStorageEncryption = !isDevMode(); diff --git a/src/settings/localeSetting.ts b/src/settings/localeSetting.ts new file mode 100644 index 0000000..5452568 --- /dev/null +++ b/src/settings/localeSetting.ts @@ -0,0 +1,29 @@ +import type { DropMenu } from '../components/Dropdown'; +import type { LocaleSetting, LocaleType } from '/#/config'; + +export const LOCALE: { [key: string]: LocaleType } = { + ZH_CN: 'zh_CN', + EN_US: 'en', +}; + +export const localeSetting: LocaleSetting = { + showPicker: true, + // Locale + locale: LOCALE.ZH_CN, + // Default locale + fallback: LOCALE.ZH_CN, + // available Locales + availableLocales: [LOCALE.ZH_CN, LOCALE.EN_US], +}; + +// locale list +export const localeList: DropMenu[] = [ + { + text: '简体中文', + event: LOCALE.ZH_CN, + }, + { + text: 'English', + event: LOCALE.EN_US, + }, +]; diff --git a/src/settings/projectSetting.ts b/src/settings/projectSetting.ts new file mode 100644 index 0000000..860c669 --- /dev/null +++ b/src/settings/projectSetting.ts @@ -0,0 +1,183 @@ +import type { ProjectConfig } from '/#/config'; +import { MenuTypeEnum, MenuModeEnum, TriggerEnum, MixSidebarTriggerEnum } from '/@/enums/menuEnum'; +import { CacheTypeEnum } from '/@/enums/cacheEnum'; +import { + ContentEnum, + PermissionModeEnum, + ThemeEnum, + RouterTransitionEnum, + SettingButtonPositionEnum, + SessionTimeoutProcessingEnum, +} from '/@/enums/appEnum'; +import { SIDE_BAR_BG_COLOR_LIST, HEADER_PRESET_BG_COLOR_LIST } from './designSetting'; + +const primaryColor = '#0960bd'; + +// ! You need to clear the browser cache after the change +const setting: ProjectConfig = { + // Whether to show the configuration button + showSettingButton: true, + + // Whether to show the theme switch button + showDarkModeToggle: true, + + // `Settings` button position + settingButtonPosition: SettingButtonPositionEnum.AUTO, + + // Permission mode + permissionMode: PermissionModeEnum.BACK, + + // Permission-related cache is stored in sessionStorage or localStorage + permissionCacheType: CacheTypeEnum.LOCAL, + + // Session timeout processing + sessionTimeoutProcessing: SessionTimeoutProcessingEnum.ROUTE_JUMP, + + // color + themeColor: primaryColor, + + // Website gray mode, open for possible mourning dates + grayMode: false, + + // Color Weakness Mode + colorWeak: false, + + // Whether to cancel the menu, the top, the multi-tab page display, for possible embedded in other systems + fullContent: false, + + // content mode + contentMode: ContentEnum.FULL, + + // Whether to display the logo + showLogo: true, + + // Whether to show footer + showFooter: false, + + // Header configuration + headerSetting: { + // header bg color + bgColor: HEADER_PRESET_BG_COLOR_LIST[0], + // Fixed at the top + fixed: true, + // Whether to show top + show: true, + // theme + theme: ThemeEnum.LIGHT, + // Whether to enable the lock screen function + useLockPage: true, + // Whether to show the full screen button + showFullScreen: true, + // Whether to show the document button + showDoc: true, + // Whether to show the notification button + showNotice: true, + // Whether to display the menu search + showSearch: true, + }, + + // Menu configuration + menuSetting: { + // sidebar menu bg color + bgColor: SIDE_BAR_BG_COLOR_LIST[0], + // Whether to fix the left menu + fixed: true, + // Menu collapse + collapsed: false, + // When sider hide because of the responsive layout + siderHidden: false, + // Whether to display the menu name when folding the menu + collapsedShowTitle: false, + // Whether it can be dragged + // Only limited to the opening of the left menu, the mouse has a drag bar on the right side of the menu + canDrag: false, + // Whether to show no dom + show: true, + // Whether to show dom + hidden: false, + // Menu width + menuWidth: 210, + // Menu mode + mode: MenuModeEnum.INLINE, + // Menu type + type: MenuTypeEnum.SIDEBAR, + // Menu theme + theme: ThemeEnum.DARK, + // Split menu + split: false, + // Top menu layout + topMenuAlign: 'center', + // Fold trigger position + trigger: TriggerEnum.HEADER, + // Turn on accordion mode, only show a menu + accordion: true, + // Switch page to close menu + closeMixSidebarOnChange: false, + // Module opening method ‘click’ |'hover' + mixSideTrigger: MixSidebarTriggerEnum.CLICK, + // Fixed expanded menu + mixSideFixed: false, + }, + + // Multi-label + multiTabsSetting: { + cache: false, + // Turn on + show: true, + // Is it possible to drag and drop sorting tabs + canDrag: true, + // Turn on quick actions + showQuick: true, + // Whether to show the refresh button + showRedo: true, + // Whether to show the collapse button + showFold: true, + }, + + // Transition Setting + transitionSetting: { + // Whether to open the page switching animation + // The disabled state will also disable pageLoading + enable: true, + + // Route basic switching animation + basicTransition: RouterTransitionEnum.FADE_SIDE, + + // Whether to open page switching loading + // Only open when enable=true + openPageLoading: true, + + // Whether to open the top progress bar + openNProgress: false, + }, + + // Whether to enable KeepAlive cache is best to close during development, otherwise the cache needs to be cleared every time + openKeepAlive: true, + + // Automatic screen lock time, 0 does not lock the screen. Unit minute default 0 + lockTime: 0, + + // Whether to show breadcrumbs + showBreadCrumb: true, + + // Whether to show the breadcrumb icon + showBreadCrumbIcon: false, + + // Use error-handler-plugin + useErrorHandle: false, + + // Whether to open back to top + useOpenBackTop: true, + + // Is it possible to embed iframe pages + canEmbedIFramePage: true, + + // Whether to delete unclosed messages and notify when switching the interface + closeMessageOnSwitch: true, + + // Whether to cancel the http request that has been sent but not responded when switching the interface. + // If it is enabled, I want to overwrite a single interface. Can be set in a separate interface + removeAllHttpPending: false, +}; + +export default setting; diff --git a/src/settings/siteSetting.ts b/src/settings/siteSetting.ts new file mode 100644 index 0000000..c2ea4d6 --- /dev/null +++ b/src/settings/siteSetting.ts @@ -0,0 +1,8 @@ +// github repo url +export const GITHUB_URL = 'https://github.com/wansenai'; + +// doc +export const DOC_URL = 'https://wansenai.com'; + +// site url +export const SITE_URL = 'https://wansenai.com'; diff --git a/src/store/index.ts b/src/store/index.ts new file mode 100644 index 0000000..efaf6c9 --- /dev/null +++ b/src/store/index.ts @@ -0,0 +1,10 @@ +import type { App } from 'vue'; +import { createPinia } from 'pinia'; + +const store = createPinia(); + +export function setupStore(app: App) { + app.use(store); +} + +export { store }; diff --git a/src/store/modules/app.ts b/src/store/modules/app.ts new file mode 100644 index 0000000..06df314 --- /dev/null +++ b/src/store/modules/app.ts @@ -0,0 +1,112 @@ +import type { + ProjectConfig, + HeaderSetting, + MenuSetting, + TransitionSetting, + MultiTabsSetting, +} from '/#/config'; +import type { BeforeMiniState } from '/#/store'; + +import { defineStore } from 'pinia'; +import { store } from '/@/store'; + +import { ThemeEnum } from '/@/enums/appEnum'; +import { APP_DARK_MODE_KEY, PROJ_CFG_KEY } from '/@/enums/cacheEnum'; +import { Persistent } from '/@/utils/cache/persistent'; +import { darkMode } from '/@/settings/designSetting'; +import { resetRouter } from '/@/router'; +import { deepMerge } from '/@/utils'; + +interface AppState { + darkMode?: ThemeEnum; + // Page loading status + pageLoading: boolean; + // project config + projectConfig: ProjectConfig | null; + // When the window shrinks, remember some states, and restore these states when the window is restored + beforeMiniInfo: BeforeMiniState; +} +let timeId: TimeoutHandle; +export const useAppStore = defineStore({ + id: 'app', + state: (): AppState => ({ + darkMode: undefined, + pageLoading: false, + projectConfig: Persistent.getLocal(PROJ_CFG_KEY), + beforeMiniInfo: {}, + }), + getters: { + getPageLoading(state): boolean { + return state.pageLoading; + }, + getDarkMode(state): 'light' | 'dark' | string { + return state.darkMode || localStorage.getItem(APP_DARK_MODE_KEY) || darkMode; + }, + + getBeforeMiniInfo(state): BeforeMiniState { + return state.beforeMiniInfo; + }, + + getProjectConfig(state): ProjectConfig { + return state.projectConfig || ({} as ProjectConfig); + }, + + getHeaderSetting(): HeaderSetting { + return this.getProjectConfig.headerSetting; + }, + getMenuSetting(): MenuSetting { + return this.getProjectConfig.menuSetting; + }, + getTransitionSetting(): TransitionSetting { + return this.getProjectConfig.transitionSetting; + }, + getMultiTabsSetting(): MultiTabsSetting { + return this.getProjectConfig.multiTabsSetting; + }, + }, + actions: { + setPageLoading(loading: boolean): void { + this.pageLoading = loading; + }, + + setDarkMode(mode: ThemeEnum): void { + this.darkMode = mode; + localStorage.setItem(APP_DARK_MODE_KEY, mode); + }, + + setBeforeMiniInfo(state: BeforeMiniState): void { + this.beforeMiniInfo = state; + }, + + setProjectConfig(config: DeepPartial): void { + this.projectConfig = deepMerge(this.projectConfig || {}, config) as ProjectConfig; + Persistent.setLocal(PROJ_CFG_KEY, this.projectConfig); + }, + setMenuSetting(setting: Partial): void { + this.projectConfig!.menuSetting = deepMerge(this.projectConfig!.menuSetting, setting); + Persistent.setLocal(PROJ_CFG_KEY, this.projectConfig); + }, + + async resetAllState() { + resetRouter(); + Persistent.clearAll(); + }, + async setPageLoadingAction(loading: boolean): Promise { + if (loading) { + clearTimeout(timeId); + // Prevent flicker + timeId = setTimeout(() => { + this.setPageLoading(loading); + }, 50); + } else { + this.setPageLoading(loading); + clearTimeout(timeId); + } + }, + }, +}); + +// Need to be used outside the setup +export function useAppStoreWithOut() { + return useAppStore(store); +} diff --git a/src/store/modules/errorLog.ts b/src/store/modules/errorLog.ts new file mode 100644 index 0000000..ffbdc0b --- /dev/null +++ b/src/store/modules/errorLog.ts @@ -0,0 +1,77 @@ +import type { ErrorLogInfo } from '/#/store'; + +import { defineStore } from 'pinia'; +import { store } from '/@/store'; + +import { formatToDateTime } from '/@/utils/dateUtil'; +import projectSetting from '/@/settings/projectSetting'; + +import { ErrorTypeEnum } from '/@/enums/exceptionEnum'; + +export interface ErrorLogState { + errorLogInfoList: Nullable; + errorLogListCount: number; +} + +export const useErrorLogStore = defineStore({ + id: 'app-error-log', + state: (): ErrorLogState => ({ + errorLogInfoList: null, + errorLogListCount: 0, + }), + getters: { + getErrorLogInfoList(state): ErrorLogInfo[] { + return state.errorLogInfoList || []; + }, + getErrorLogListCount(state): number { + return state.errorLogListCount; + }, + }, + actions: { + addErrorLogInfo(info: ErrorLogInfo) { + const item = { + ...info, + time: formatToDateTime(new Date()), + }; + this.errorLogInfoList = [item, ...(this.errorLogInfoList || [])]; + this.errorLogListCount += 1; + }, + + setErrorLogListCount(count: number): void { + this.errorLogListCount = count; + }, + + /** + * Triggered after ajax request error + * @param error + * @returns + */ + addAjaxErrorInfo(error) { + const { useErrorHandle } = projectSetting; + if (!useErrorHandle) { + return; + } + const errInfo: Partial = { + message: error.message, + type: ErrorTypeEnum.AJAX, + }; + if (error.response) { + const { + config: { url = '', data: params = '', method = 'get', headers = {} } = {}, + data = {}, + } = error.response; + errInfo.url = url; + errInfo.name = 'Ajax Error!'; + errInfo.file = '-'; + errInfo.stack = JSON.stringify(data); + errInfo.detail = JSON.stringify({ params, method, headers }); + } + this.addErrorLogInfo(errInfo as ErrorLogInfo); + }, + }, +}); + +// Need to be used outside the setup +export function useErrorLogStoreWithOut() { + return useErrorLogStore(store); +} diff --git a/src/store/modules/locale.ts b/src/store/modules/locale.ts new file mode 100644 index 0000000..78202ea --- /dev/null +++ b/src/store/modules/locale.ts @@ -0,0 +1,55 @@ +import type { LocaleSetting, LocaleType } from '/#/config'; + +import { defineStore } from 'pinia'; +import { store } from '/@/store'; + +import { LOCALE_KEY } from '/@/enums/cacheEnum'; +import { createLocalStorage } from '/@/utils/cache'; +import { localeSetting } from '/@/settings/localeSetting'; + +const ls = createLocalStorage(); + +const lsLocaleSetting = (ls.get(LOCALE_KEY) || localeSetting) as LocaleSetting; + +interface LocaleState { + localInfo: LocaleSetting; +} + +export const useLocaleStore = defineStore({ + id: 'app-locale', + state: (): LocaleState => ({ + localInfo: lsLocaleSetting, + }), + getters: { + getShowPicker(state): boolean { + return !!state.localInfo?.showPicker; + }, + getLocale(state): LocaleType { + return state.localInfo?.locale ?? 'zh_CN'; + }, + }, + actions: { + /** + * Set up multilingual information and cache + * @param info multilingual info + */ + setLocaleInfo(info: Partial) { + this.localInfo = { ...this.localInfo, ...info }; + ls.set(LOCALE_KEY, this.localInfo); + }, + /** + * Initialize multilingual information and load the existing configuration from the local cache + */ + initLocale() { + this.setLocaleInfo({ + ...localeSetting, + ...this.localInfo, + }); + }, + }, +}); + +// Need to be used outside the setup +export function useLocaleStoreWithOut() { + return useLocaleStore(store); +} diff --git a/src/store/modules/lock.ts b/src/store/modules/lock.ts new file mode 100644 index 0000000..da5ea00 --- /dev/null +++ b/src/store/modules/lock.ts @@ -0,0 +1,59 @@ +import type { LockInfo } from '/#/store'; + +import { defineStore } from 'pinia'; + +import { LOCK_INFO_KEY } from '/@/enums/cacheEnum'; +import { Persistent } from '/@/utils/cache/persistent'; +import { useUserStore } from './user'; + +interface LockState { + lockInfo: Nullable; +} + +export const useLockStore = defineStore({ + id: 'app-lock', + state: (): LockState => ({ + lockInfo: Persistent.getLocal(LOCK_INFO_KEY), + }), + getters: { + getLockInfo(state): Nullable { + return state.lockInfo; + }, + }, + actions: { + setLockInfo(info: LockInfo) { + this.lockInfo = Object.assign({}, this.lockInfo, info); + Persistent.setLocal(LOCK_INFO_KEY, this.lockInfo, true); + }, + resetLockInfo() { + Persistent.removeLocal(LOCK_INFO_KEY, true); + this.lockInfo = null; + }, + // Unlock + async unLock(password?: string) { + const userStore = useUserStore(); + if (this.lockInfo?.pwd === password) { + this.resetLockInfo(); + return true; + } + const tryLogin = async () => { + try { + const username = userStore.getUserInfo?.username; + const res = await userStore.login({ + username, + password: password!, + goHome: false, + mode: 'none', + }); + if (res) { + this.resetLockInfo(); + } + return res; + } catch (error) { + return false; + } + }; + return await tryLogin(); + }, + }, +}); diff --git a/src/store/modules/multipleTab.ts b/src/store/modules/multipleTab.ts new file mode 100644 index 0000000..e67c423 --- /dev/null +++ b/src/store/modules/multipleTab.ts @@ -0,0 +1,361 @@ +import type { RouteLocationNormalized, RouteLocationRaw, Router } from 'vue-router'; + +import { toRaw, unref } from 'vue'; +import { defineStore } from 'pinia'; +import { store } from '/@/store'; + +import { useGo, useRedo } from '/@/hooks/web/usePage'; +import { Persistent } from '/@/utils/cache/persistent'; + +import { PageEnum } from '/@/enums/pageEnum'; +import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '/@/router/routes/basic'; +import { getRawRoute } from '/@/utils'; +import { MULTIPLE_TABS_KEY } from '/@/enums/cacheEnum'; + +import projectSetting from '/@/settings/projectSetting'; +import { useUserStore } from '/@/store/modules/user'; + +export interface MultipleTabState { + cacheTabList: Set; + tabList: RouteLocationNormalized[]; + lastDragEndIndex: number; +} + +function handleGotoPage(router: Router) { + const go = useGo(router); + go(unref(router.currentRoute).fullPath, true); +} + +const getToTarget = (tabItem: RouteLocationNormalized) => { + const { params, path, query } = tabItem; + return { + params: params || {}, + path, + query: query || {}, + }; +}; + +const cacheTab = projectSetting.multiTabsSetting.cache; + +export const useMultipleTabStore = defineStore({ + id: 'app-multiple-tab', + state: (): MultipleTabState => ({ + // Tabs that need to be cached + cacheTabList: new Set(), + // multiple tab list + tabList: cacheTab ? Persistent.getLocal(MULTIPLE_TABS_KEY) || [] : [], + // Index of the last moved tab + lastDragEndIndex: 0, + }), + getters: { + getTabList(state): RouteLocationNormalized[] { + return state.tabList; + }, + getCachedTabList(state): string[] { + return Array.from(state.cacheTabList); + }, + getLastDragEndIndex(state): number { + return state.lastDragEndIndex; + }, + }, + actions: { + /** + * Update the cache according to the currently opened tabs + */ + async updateCacheTab() { + const cacheMap: Set = new Set(); + + for (const tab of this.tabList) { + const item = getRawRoute(tab); + // Ignore the cache + const needCache = !item.meta?.ignoreKeepAlive; + if (!needCache) { + continue; + } + const name = item.name as string; + cacheMap.add(name); + } + this.cacheTabList = cacheMap; + }, + + /** + * Refresh tabs + */ + async refreshPage(router: Router) { + const { currentRoute } = router; + const route = unref(currentRoute); + const name = route.name; + + const findTab = this.getCachedTabList.find((item) => item === name); + if (findTab) { + this.cacheTabList.delete(findTab); + } + const redo = useRedo(router); + await redo(); + }, + clearCacheTabs(): void { + this.cacheTabList = new Set(); + }, + resetState(): void { + this.tabList = []; + this.clearCacheTabs(); + }, + goToPage(router: Router) { + const go = useGo(router); + const len = this.tabList.length; + const { path } = unref(router.currentRoute); + + let toPath: PageEnum | string = PageEnum.BASE_HOME; + + if (len > 0) { + const page = this.tabList[len - 1]; + const p = page.fullPath || page.path; + if (p) { + toPath = p; + } + } + // Jump to the current page and report an error + path !== toPath && go(toPath as PageEnum, true); + }, + + async addTab(route: RouteLocationNormalized) { + const { path, name, fullPath, params, query, meta } = getRawRoute(route); + // 404 The page does not need to add a tab + if ( + path === PageEnum.ERROR_PAGE || + path === PageEnum.BASE_LOGIN || + !name || + [REDIRECT_ROUTE.name, PAGE_NOT_FOUND_ROUTE.name].includes(name as string) + ) { + return; + } + + let updateIndex = -1; + // Existing pages, do not add tabs repeatedly + const tabHasExits = this.tabList.some((tab, index) => { + updateIndex = index; + return (tab.fullPath || tab.path) === (fullPath || path); + }); + + // If the tab already exists, perform the update operation + if (tabHasExits) { + const curTab = toRaw(this.tabList)[updateIndex]; + if (!curTab) { + return; + } + curTab.params = params || curTab.params; + curTab.query = query || curTab.query; + curTab.fullPath = fullPath || curTab.fullPath; + this.tabList.splice(updateIndex, 1, curTab); + } else { + // Add tab + // 获取动态路由打开数,超过 0 即代表需要控制打开数 + const dynamicLevel = meta?.dynamicLevel ?? -1; + if (dynamicLevel > 0) { + // 如果动态路由层级大于 0 了,那么就要限制该路由的打开数限制了 + // 首先获取到真实的路由,使用配置方式减少计算开销. + // const realName: string = path.match(/(\S*)\//)![1]; + const realPath = meta?.realPath ?? ''; + // 获取到已经打开的动态路由数, 判断是否大于某一个值 + if ( + this.tabList.filter((e) => e.meta?.realPath ?? '' === realPath).length >= dynamicLevel + ) { + // 关闭第一个 + const index = this.tabList.findIndex((item) => item.meta.realPath === realPath); + index !== -1 && this.tabList.splice(index, 1); + } + } + this.tabList.push(route); + } + this.updateCacheTab(); + cacheTab && Persistent.setLocal(MULTIPLE_TABS_KEY, this.tabList); + }, + + async closeTab(tab: RouteLocationNormalized, router: Router) { + const close = (route: RouteLocationNormalized) => { + const { fullPath, meta: { affix } = {} } = route; + if (affix) { + return; + } + const index = this.tabList.findIndex((item) => item.fullPath === fullPath); + index !== -1 && this.tabList.splice(index, 1); + }; + + const { currentRoute, replace } = router; + + const { path } = unref(currentRoute); + if (path !== tab.path) { + // Closed is not the activation tab + close(tab); + this.updateCacheTab(); + return; + } + + // Closed is activated atb + let toTarget: RouteLocationRaw = {}; + + const index = this.tabList.findIndex((item) => item.path === path); + + // If the current is the leftmost tab + if (index === 0) { + // There is only one tab, then jump to the homepage, otherwise jump to the right tab + if (this.tabList.length === 1) { + const userStore = useUserStore(); + toTarget = userStore.getUserInfo.homePath || PageEnum.BASE_HOME; + } else { + // Jump to the right tab + const page = this.tabList[index + 1]; + toTarget = getToTarget(page); + } + } else { + // Close the current tab + const page = this.tabList[index - 1]; + toTarget = getToTarget(page); + } + close(currentRoute.value); + await replace(toTarget); + }, + + // Close according to key + async closeTabByKey(key: string, router: Router) { + const index = this.tabList.findIndex((item) => (item.fullPath || item.path) === key); + if (index !== -1) { + await this.closeTab(this.tabList[index], router); + const { currentRoute, replace } = router; + // 检查当前路由是否存在于tabList中 + const isActivated = this.tabList.findIndex((item) => { + return item.fullPath === currentRoute.value.fullPath; + }); + // 如果当前路由不存在于TabList中,尝试切换到其它路由 + if (isActivated === -1) { + let pageIndex; + if (index > 0) { + pageIndex = index - 1; + } else if (index < this.tabList.length - 1) { + pageIndex = index + 1; + } else { + pageIndex = -1; + } + if (pageIndex >= 0) { + const page = this.tabList[index - 1]; + const toTarget = getToTarget(page); + await replace(toTarget); + } + } + } + }, + + // Sort the tabs + async sortTabs(oldIndex: number, newIndex: number) { + const currentTab = this.tabList[oldIndex]; + this.tabList.splice(oldIndex, 1); + this.tabList.splice(newIndex, 0, currentTab); + this.lastDragEndIndex = this.lastDragEndIndex + 1; + }, + + // Close the tab on the right and jump + async closeLeftTabs(route: RouteLocationNormalized, router: Router) { + const index = this.tabList.findIndex((item) => item.path === route.path); + + if (index > 0) { + const leftTabs = this.tabList.slice(0, index); + const pathList: string[] = []; + for (const item of leftTabs) { + const affix = item?.meta?.affix ?? false; + if (!affix) { + pathList.push(item.fullPath); + } + } + this.bulkCloseTabs(pathList); + } + this.updateCacheTab(); + handleGotoPage(router); + }, + + // Close the tab on the left and jump + async closeRightTabs(route: RouteLocationNormalized, router: Router) { + const index = this.tabList.findIndex((item) => item.fullPath === route.fullPath); + + if (index >= 0 && index < this.tabList.length - 1) { + const rightTabs = this.tabList.slice(index + 1, this.tabList.length); + + const pathList: string[] = []; + for (const item of rightTabs) { + const affix = item?.meta?.affix ?? false; + if (!affix) { + pathList.push(item.fullPath); + } + } + this.bulkCloseTabs(pathList); + } + this.updateCacheTab(); + handleGotoPage(router); + }, + + async closeAllTab(router: Router) { + this.tabList = this.tabList.filter((item) => item?.meta?.affix ?? false); + this.clearCacheTabs(); + this.goToPage(router); + }, + + /** + * Close other tabs + */ + async closeOtherTabs(route: RouteLocationNormalized, router: Router) { + const closePathList = this.tabList.map((item) => item.fullPath); + + const pathList: string[] = []; + + for (const path of closePathList) { + if (path !== route.fullPath) { + const closeItem = this.tabList.find((item) => item.fullPath === path); + if (!closeItem) { + continue; + } + const affix = closeItem?.meta?.affix ?? false; + if (!affix) { + pathList.push(closeItem.fullPath); + } + } + } + this.bulkCloseTabs(pathList); + this.updateCacheTab(); + Persistent.setLocal(MULTIPLE_TABS_KEY, this.tabList, true); + handleGotoPage(router); + }, + + /** + * Close tabs in bulk + */ + async bulkCloseTabs(pathList: string[]) { + this.tabList = this.tabList.filter((item) => !pathList.includes(item.fullPath)); + }, + + /** + * Set tab's title + */ + async setTabTitle(title: string, route: RouteLocationNormalized) { + const findTab = this.getTabList.find((item) => item === route); + if (findTab) { + findTab.meta.title = title; + await this.updateCacheTab(); + } + }, + /** + * replace tab's path + * **/ + async updateTabPath(fullPath: string, route: RouteLocationNormalized) { + const findTab = this.getTabList.find((item) => item === route); + if (findTab) { + findTab.fullPath = fullPath; + findTab.path = fullPath; + await this.updateCacheTab(); + } + }, + }, +}); + +// Need to be used outside the setup +export function useMultipleTabWithOutStore() { + return useMultipleTabStore(store); +} diff --git a/src/store/modules/permission.ts b/src/store/modules/permission.ts new file mode 100644 index 0000000..f914a92 --- /dev/null +++ b/src/store/modules/permission.ts @@ -0,0 +1,264 @@ +import type { AppRouteRecordRaw, Menu } from '/@/router/types'; + +import { defineStore } from 'pinia'; +import { store } from '/@/store'; +import { useI18n } from '/@/hooks/web/useI18n'; +import { useUserStore } from './user'; +import { useAppStoreWithOut } from './app'; +import { toRaw } from 'vue'; +import { transformObjToRoute, flatMultiLevelRoutes } from '/@/router/helper/routeHelper'; +import { transformRouteToMenu } from '/@/router/helper/menuHelper'; + +import projectSetting from '/@/settings/projectSetting'; + +import { PermissionModeEnum } from '/@/enums/appEnum'; + +import { asyncRoutes } from '/@/router/routes'; +import { ERROR_LOG_ROUTE, PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic'; + +import { filter } from '/@/utils/helper/treeHelper'; + +import { getMenuList } from '/@/api/sys/menu'; +import { getPermCode } from '/@/api/sys/user'; + +import { useMessage } from '/@/hooks/web/useMessage'; +import { PageEnum } from '/@/enums/pageEnum'; +import {array2tree} from "@axolo/tree-array"; + +interface PermissionState { + // Permission code list + // 权限代码列表 + permCodeList: string[] | number[]; + // Whether the route has been dynamically added + // 路由是否动态添加 + isDynamicAddedRoute: boolean; + // To trigger a menu update + // 触发菜单更新 + lastBuildMenuTime: number; + // Backstage menu list + // 后台菜单列表 + backMenuList: Menu[]; + // 菜单列表 + frontMenuList: Menu[]; +} + +export const usePermissionStore = defineStore({ + id: 'app-permission', + state: (): PermissionState => ({ + // 权限代码列表 + permCodeList: [], + // Whether the route has been dynamically added + // 路由是否动态添加 + isDynamicAddedRoute: false, + // To trigger a menu update + // 触发菜单更新 + lastBuildMenuTime: 0, + // Backstage menu list + // 后台菜单列表 + backMenuList: [], + // menu List + // 菜单列表 + frontMenuList: [], + }), + getters: { + getPermCodeList(state): string[] | number[] { + return state.permCodeList; + }, + getBackMenuList(state): Menu[] { + return state.backMenuList; + }, + getFrontMenuList(state): Menu[] { + return state.frontMenuList; + }, + getLastBuildMenuTime(state): number { + return state.lastBuildMenuTime; + }, + getIsDynamicAddedRoute(state): boolean { + return state.isDynamicAddedRoute; + }, + }, + actions: { + setPermCodeList(codeList: string[]) { + this.permCodeList = codeList; + }, + + setBackMenuList(list: Menu[]) { + this.backMenuList = list; + list?.length > 0 && this.setLastBuildMenuTime(); + }, + + setFrontMenuList(list: Menu[]) { + this.frontMenuList = list; + }, + + setLastBuildMenuTime() { + this.lastBuildMenuTime = new Date().getTime(); + }, + + setDynamicAddedRoute(added: boolean) { + this.isDynamicAddedRoute = added; + }, + resetState(): void { + this.isDynamicAddedRoute = false; + this.permCodeList = []; + this.backMenuList = []; + this.lastBuildMenuTime = 0; + }, + async changePermissionCode() { + const codeList = await getPermCode(); + this.setPermCodeList(codeList); + }, + + // 构建路由 + async buildRoutesAction(): Promise { + const { t } = useI18n(); + const userStore = useUserStore(); + const appStore = useAppStoreWithOut(); + + let routes: AppRouteRecordRaw[] = []; + const roleList = toRaw(userStore.getRoleList) || []; + const { permissionMode = projectSetting.permissionMode } = appStore.getProjectConfig; + + // 路由过滤器 在 函数filter 作为回调传入遍历使用 + const routeFilter = (route: AppRouteRecordRaw) => { + const { meta } = route; + // 抽出角色 + const { roles } = meta || {}; + if (!roles) return true; + // 进行角色权限判断 + return roleList.some((role) => roles.includes(role)); + }; + + const routeRemoveIgnoreFilter = (route: AppRouteRecordRaw) => { + const { meta } = route; + // ignoreRoute 为true 则路由仅用于菜单生成,不会在实际的路由表中出现 + const { ignoreRoute } = meta || {}; + // arr.filter 返回 true 表示该元素通过测试 + return !ignoreRoute; + }; + + /** + * @description 根据设置的首页path,修正routes中的affix标记(固定首页) + * */ + const patchHomeAffix = (routes: AppRouteRecordRaw[]) => { + if (!routes || routes.length === 0) return; + let homePath: string = userStore.getUserInfo.homePath || PageEnum.BASE_HOME; + + function patcher(routes: AppRouteRecordRaw[], parentPath = '') { + if (parentPath) parentPath = parentPath + '/'; + routes.forEach((route: AppRouteRecordRaw) => { + const { path, children, redirect } = route; + const currentPath = path.startsWith('/') ? path : parentPath + path; + if (currentPath === homePath) { + if (redirect) { + homePath = route.redirect! as string; + } else { + route.meta = Object.assign({}, route.meta, { affix: true }); + throw new Error('end'); + } + } + children && children.length > 0 && patcher(children, currentPath); + }); + } + + try { + patcher(routes); + } catch (e) { + // 已处理完毕跳出循环 + } + return; + }; + + switch (permissionMode) { + // 角色权限 + case PermissionModeEnum.ROLE: + // 对非一级路由进行过滤 + routes = filter(asyncRoutes, routeFilter); + // 对一级路由根据角色权限过滤 + routes = routes.filter(routeFilter); + // Convert multi-level routing to level 2 routing + // 将多级路由转换为 2 级路由 + routes = flatMultiLevelRoutes(routes); + break; + + // 路由映射, 默认进入该case + case PermissionModeEnum.ROUTE_MAPPING: + // 对非一级路由进行过滤 + routes = filter(asyncRoutes, routeFilter); + // 对一级路由再次根据角色权限过滤 + routes = routes.filter(routeFilter); + // 将路由转换成菜单 + const menuList = transformRouteToMenu(routes, true); + // 移除掉 ignoreRoute: true 的路由 非一级路由 + routes = filter(routes, routeRemoveIgnoreFilter); + // 移除掉 ignoreRoute: true 的路由 一级路由; + routes = routes.filter(routeRemoveIgnoreFilter); + // 对菜单进行排序 + menuList.sort((a, b) => { + return (a.meta?.orderNo || 0) - (b.meta?.orderNo || 0); + }); + + // 设置菜单列表 + this.setFrontMenuList(menuList); + + // Convert multi-level routing to level 2 routing + // 将多级路由转换为 2 级路由 + routes = flatMultiLevelRoutes(routes); + break; + + // If you are sure that you do not need to do background dynamic permissions, please comment the entire judgment below + // 如果确定不需要做后台动态权限,请在下方注释整个判断 + case PermissionModeEnum.BACK: + const { createMessage } = useMessage(); + + createMessage.loading({ + content: t('sys.app.menuLoading'), + duration: 1, + }); + + // !Simulate to obtain permission codes from the background, + // 模拟从后台获取权限码, + // this function may only need to be executed once, and the actual project can be put at the right time by itself + // 这个功能可能只需要执行一次,实际项目可以自己放在合适的时间 + let routeList: AppRouteRecordRaw[] = []; + try { + await this.changePermissionCode(); + // routeList = (await getMenuList()) as AppRouteRecordRaw[]; + const menus = await getMenuList(); + const menuTree = array2tree(menus.data.data); + routeList = menuTree as AppRouteRecordRaw[]; + } catch (error) { + console.error(error); + } + + // Dynamically introduce components + // 动态引入组件 + routeList = transformObjToRoute(routeList); + + // Background routing to menu structure + // 后台路由到菜单结构 + const backMenuList = transformRouteToMenu(routeList); + this.setBackMenuList(backMenuList); + + // remove meta.ignoreRoute item + // 删除 meta.ignoreRoute 项 + routeList = filter(routeList, routeRemoveIgnoreFilter); + routeList = routeList.filter(routeRemoveIgnoreFilter); + + routeList = flatMultiLevelRoutes(routeList); + routes = [PAGE_NOT_FOUND_ROUTE, ...routeList]; + break; + } + + routes.push(ERROR_LOG_ROUTE); + patchHomeAffix(routes); + return routes; + }, + }, +}); + +// Need to be used outside the setup +// 需要在设置之外使用 +export function usePermissionStoreWithOut() { + return usePermissionStore(store); +} diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts new file mode 100644 index 0000000..fb5e3e0 --- /dev/null +++ b/src/store/modules/user.ts @@ -0,0 +1,222 @@ +import type { ErrorMessageMode } from '/#/axios'; +import { defineStore } from 'pinia'; +import { store } from '/@/store'; +import { RoleEnum } from '/@/enums/roleEnum'; +import { PageEnum } from '/@/enums/pageEnum'; +import { ROLES_KEY, ROLES_NAME_KEY, TOKEN_KEY, USER_INFO_KEY } from '/@/enums/cacheEnum'; +import { getAuthCache, setAuthCache } from '/@/utils/auth'; +import { + GetUserInfoModel, + LoginReq, mobileLoginReq, updatePasswordReq, +} from '/@/api/sys/model/userModel'; +import {doLogout, getUserInfo, login, mobileLogin} from '/@/api/sys/user'; +import { useI18n } from '/@/hooks/web/useI18n'; +import { useMessage } from '/@/hooks/web/useMessage'; +import { router } from '/@/router'; +import { usePermissionStore } from '/@/store/modules/permission'; +import { RouteRecordRaw } from 'vue-router'; +import { PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic'; +import { isArray } from '/@/utils/is'; +import { h } from 'vue'; + +interface UserState { + userInfo: Nullable; + token?: string; + roleList: RoleEnum[]; + roleName: string[]; + sessionTimeout?: boolean; + lastUpdateTime: number; +} + +export const useUserStore = defineStore({ + id: 'app-user', + state: (): UserState => ({ + // user info + userInfo: null, + // token + token: undefined, + // roleList + roleList: [], + // role name + roleName: [], + // Whether the login expired + sessionTimeout: false, + // Last fetch time + lastUpdateTime: 0, + }), + getters: { + getUserInfo(): GetUserInfoModel { + return this.userInfo || getAuthCache(USER_INFO_KEY) || {}; + }, + getToken(): string { + return this.token || getAuthCache(TOKEN_KEY); + }, + getRoleList(): RoleEnum[] { + return this.roleList.length > 0 ? this.roleList : getAuthCache(ROLES_KEY); + }, + getRoleName(): string[] { + return this.roleName.length > 0 ? this.roleName : getAuthCache(ROLES_NAME_KEY); + }, + getSessionTimeout(): boolean { + return !!this.sessionTimeout; + }, + getLastUpdateTime(): number { + return this.lastUpdateTime; + }, + }, + actions: { + setToken(info: string | undefined) { + this.token = info ? info : ''; // for null or undefined value + setAuthCache(TOKEN_KEY, info); + }, + setRoleList(roleList: RoleEnum[]) { + this.roleList = roleList; + setAuthCache(ROLES_KEY, roleList); + }, + setRoleName(roleName: string[]) { + this.roleName = roleName; + setAuthCache(ROLES_NAME_KEY, roleName); + }, + setUserInfo(info: GetUserInfoModel | null) { + this.userInfo = info; + this.lastUpdateTime = new Date().getTime(); + setAuthCache(USER_INFO_KEY, info); + }, + setSessionTimeout(flag: boolean) { + this.sessionTimeout = flag; + }, + resetState() { + this.userInfo = null; + this.token = ''; + this.roleList = []; + this.roleName = []; + this.sessionTimeout = false; + }, + /** + * @description: login + */ + async login( + params: LoginReq & { + goHome?: boolean; + mode?: ErrorMessageMode; + }, + ): Promise { + try { + const { goHome = true, mode, ...loginParams } = params; + const data = await login(loginParams, mode); + if (data.code !== '00000') { + return Promise.reject(null); + } + const { token } = data.data; + + // save token + this.setToken(token); + return this.afterLoginAction(goHome); + } catch (error) { + return Promise.reject(error); + } + }, + + /** + * @description: mobileLogin + */ + async mobileLogin( + params: mobileLoginReq & { + goHome?: boolean; + mode?: ErrorMessageMode; + }, + ): Promise { + try { + const { goHome = true, mode, ...mobileLoginReq } = params; + const data = await mobileLogin(mobileLoginReq, mode); + if (data.code !== '00000') { + return Promise.reject(null); + } + const { token } = data.data; + + // save token + this.setToken(token); + return this.afterLoginAction(goHome); + } catch (error) { + return Promise.reject(error); + } + }, + + async afterLoginAction(goHome?: boolean): Promise { + if (!this.getToken) return null; + // get user info + const userInfo = await this.getUserInfoAction(); + + const sessionTimeout = this.sessionTimeout; + if (sessionTimeout) { + this.setSessionTimeout(false); + } else { + const permissionStore = usePermissionStore(); + if (!permissionStore.isDynamicAddedRoute) { + const routes = await permissionStore.buildRoutesAction(); + routes.forEach((route) => { + router.addRoute(route as unknown as RouteRecordRaw); + }); + router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw); + permissionStore.setDynamicAddedRoute(true); + } + goHome && (await router.replace(userInfo?.homePath || PageEnum.BASE_HOME)); + } + return userInfo; + }, + async getUserInfoAction(): Promise { + if (!this.getToken) return null; + const userInfo = await getUserInfo(); + const { roles = [], roleName = [] } = userInfo.data; + if (isArray(roles)) { + const roleList = roles.map((item) => item.valueOf) as unknown as RoleEnum[]; + this.setRoleList(roleList); + } else { + userInfo.data.roles = []; + this.setRoleList([]); + } + this.setRoleName(roleName); + this.setUserInfo(userInfo.data); + return userInfo.data; + }, + /** + * @description: logout + */ + async logout(goLogin = false) { + if (this.getToken) { + try { + // in the future the server may need to log out, and we can uncomment this + await doLogout(); + console.log('logout successful'); + } catch { + console.log('注销Token失败'); + } + } + this.setToken(undefined); + this.setSessionTimeout(false); + this.setUserInfo(null); + goLogin && router.push(PageEnum.BASE_LOGIN); + }, + + /** + * @description: Confirm before logging out + */ + confirmLoginOut() { + const { createConfirm } = useMessage(); + const { t } = useI18n(); + createConfirm({ + iconType: 'warning', + title: () => h('span', t('sys.app.logoutTip')), + content: () => h('span', t('sys.app.logoutMessage')), + onOk: async () => { + await this.logout(true); + }, + }); + }, + }, +}); + +// Need to be used outside the setup +export function useUserStoreWithOut() { + return useUserStore(store); +} diff --git a/src/utils/.DS_Store b/src/utils/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..f2994643f9d188970199de0e7b36fdf1eb24afb6 GIT binary patch literal 6148 zcmeHKK~BRk5M0wxD!B9rHy^nm(FY)fD!iZ{fR;cjS`t+$61O}7UI5}RNC`q~6`kdYafZ5vlR!azr#Fq5&FXw2Q98*w3wHTW&-H72jidJ(|q2Ro;pW z13`hHz+Y5Aqo{~3XhQ|f<@?(^s{2-1l1!J`6l1&?eB3;}o=X4akN$jKUmJM6p>3Lh zc}8MIs zGFsEUtfBvg8X6IvI$BYkwKSqS>WNU#f|ku+WAKPdDxar@n!l61@=IQgTT`E(0PyDM z*HVRpho;}dFYe)a8bpk&OK#DmFwZI{F3*Xd3%`qf~JzS_x|ni zaJoDXqw`8W^V~5f8}@9r!Jfs?2L*xxL4isEULQ0XW9+cBXqFCi<_G|cFl-FhW{m-A z9stG;ON$tRDVqwksmdKOlugIDc5$)8(xOc#Wtedv$E@55MY$DDX%kK=wix=LKu|y` z(6e8My#Jr!9rm36Wm5PS6bK6ZD+N@POp-CCuXy<5b99LR2Dd^mGY%X{! d-bXVApXLi-?69(key: BasicKeys) { + const fn = isLocal ? Persistent.getLocal : Persistent.getSession; + return fn(key) as T; +} + +export function setAuthCache(key: BasicKeys, value) { + const fn = isLocal ? Persistent.setLocal : Persistent.setSession; + return fn(key, value, true); +} + +export function clearAuthCache(immediate = true) { + const fn = isLocal ? Persistent.clearLocal : Persistent.clearSession; + return fn(immediate); +} diff --git a/src/utils/bem.ts b/src/utils/bem.ts new file mode 100644 index 0000000..7dcadbc --- /dev/null +++ b/src/utils/bem.ts @@ -0,0 +1,52 @@ +import { prefixCls } from '/@/settings/designSetting'; + +type Mod = string | { [key: string]: any }; +type Mods = Mod | Mod[]; + +export type BEM = ReturnType; + +function genBem(name: string, mods?: Mods): string { + if (!mods) { + return ''; + } + + if (typeof mods === 'string') { + return ` ${name}--${mods}`; + } + + if (Array.isArray(mods)) { + return mods.reduce((ret, item) => ret + genBem(name, item), ''); + } + + return Object.keys(mods).reduce((ret, key) => ret + (mods[key] ? genBem(name, key) : ''), ''); +} + +/** + * bem helper + * b() // 'button' + * b('text') // 'button__text' + * b({ disabled }) // 'button button--disabled' + * b('text', { disabled }) // 'button__text button__text--disabled' + * b(['disabled', 'primary']) // 'button button--disabled button--primary' + */ +export function buildBEM(name: string) { + return (el?: Mods, mods?: Mods): Mods => { + if (el && typeof el !== 'string') { + mods = el; + el = ''; + } + + el = el ? `${name}__${el}` : name; + + return `${el}${genBem(el, mods)}`; + }; +} + +export function createBEM(name: string) { + return [buildBEM(`${prefixCls}-${name}`)]; +} + +export function createNamespace(name: string) { + const prefixedName = `${prefixCls}-${name}`; + return [prefixedName, buildBEM(prefixedName)] as const; +} diff --git a/src/utils/cache/index.ts b/src/utils/cache/index.ts new file mode 100644 index 0000000..01a11f5 --- /dev/null +++ b/src/utils/cache/index.ts @@ -0,0 +1,31 @@ +import { getStorageShortName } from '/@/utils/env'; +import { createStorage as create, CreateStorageParams } from './storageCache'; +import { enableStorageEncryption, DEFAULT_CACHE_TIME } from '/@/settings/encryptionSetting'; + +export type Options = Partial; + +const createOptions = (storage: Storage, options: Options = {}): Options => { + return { + // No encryption in debug mode + hasEncrypt: enableStorageEncryption, + storage, + prefixKey: getStorageShortName(), + ...options, + }; +}; + +export const WebStorage = create(createOptions(sessionStorage)); + +export const createStorage = (storage: Storage = sessionStorage, options: Options = {}) => { + return create(createOptions(storage, options)); +}; + +export const createSessionStorage = (options: Options = {}) => { + return createStorage(sessionStorage, { ...options, timeout: DEFAULT_CACHE_TIME }); +}; + +export const createLocalStorage = (options: Options = {}) => { + return createStorage(localStorage, { ...options, timeout: DEFAULT_CACHE_TIME }); +}; + +export default WebStorage; diff --git a/src/utils/cache/memory.ts b/src/utils/cache/memory.ts new file mode 100644 index 0000000..08a0a64 --- /dev/null +++ b/src/utils/cache/memory.ts @@ -0,0 +1,107 @@ +export interface Cache { + value?: V; + timeoutId?: ReturnType; + time?: number; + alive?: number; +} + +const NOT_ALIVE = 0; + +export class Memory { + private cache: { [key in keyof T]?: Cache } = {}; + private alive: number; + + constructor(alive = NOT_ALIVE) { + // Unit second + this.alive = alive * 1000; + } + + get getCache() { + return this.cache; + } + + setCache(cache) { + this.cache = cache; + } + + // get(key: K) { + // const item = this.getItem(key); + // const time = item?.time; + // if (!isNullOrUnDef(time) && time < new Date().getTime()) { + // this.remove(key); + // } + // return item?.value ?? undefined; + // } + + get(key: K) { + return this.cache[key]; + } + + set(key: K, value: V, expires?: number) { + let item = this.get(key); + + if (!expires || (expires as number) <= 0) { + expires = this.alive; + } + if (item) { + if (item.timeoutId) { + clearTimeout(item.timeoutId); + item.timeoutId = undefined; + } + item.value = value; + } else { + item = { value, alive: expires }; + this.cache[key] = item; + } + + if (!expires) { + return value; + } + const now = new Date().getTime(); + /** + * Prevent overflow of the setTimeout Maximum delay value + * Maximum delay value 2,147,483,647 ms + * https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value + */ + item.time = expires > now ? expires : now + expires; + item.timeoutId = setTimeout( + () => { + this.remove(key); + }, + expires > now ? expires - now : expires, + ); + + return value; + } + + remove(key: K) { + const item = this.get(key); + Reflect.deleteProperty(this.cache, key); + if (item) { + clearTimeout(item.timeoutId!); + return item.value; + } + } + + resetCache(cache: { [K in keyof T]: Cache }) { + Object.keys(cache).forEach((key) => { + const k = key as any as keyof T; + const item = cache[k]; + if (item && item.time) { + const now = new Date().getTime(); + const expire = item.time; + if (expire > now) { + this.set(k, item.value, expire); + } + } + }); + } + + clear() { + Object.keys(this.cache).forEach((key) => { + const item = this.cache[key]; + item.timeoutId && clearTimeout(item.timeoutId); + }); + this.cache = {}; + } +} diff --git a/src/utils/cache/persistent.ts b/src/utils/cache/persistent.ts new file mode 100644 index 0000000..cd68a36 --- /dev/null +++ b/src/utils/cache/persistent.ts @@ -0,0 +1,132 @@ +import type { LockInfo, UserInfo } from '/#/store'; +import type { ProjectConfig } from '/#/config'; +import type { RouteLocationNormalized } from 'vue-router'; + +import { createLocalStorage, createSessionStorage } from '/@/utils/cache'; +import { Memory } from './memory'; +import { + TOKEN_KEY, + USER_INFO_KEY, + ROLES_KEY, + LOCK_INFO_KEY, + PROJ_CFG_KEY, + APP_LOCAL_CACHE_KEY, + APP_SESSION_CACHE_KEY, + MULTIPLE_TABS_KEY, +} from '/@/enums/cacheEnum'; +import { DEFAULT_CACHE_TIME } from '/@/settings/encryptionSetting'; +import { toRaw } from 'vue'; +import { pick, omit } from 'lodash-es'; + +interface BasicStore { + [TOKEN_KEY]: string | number | null | undefined; + [USER_INFO_KEY]: UserInfo; + [ROLES_KEY]: string[]; + [LOCK_INFO_KEY]: LockInfo; + [PROJ_CFG_KEY]: ProjectConfig; + [MULTIPLE_TABS_KEY]: RouteLocationNormalized[]; +} + +type LocalStore = BasicStore; + +type SessionStore = BasicStore; + +export type BasicKeys = keyof BasicStore; +type LocalKeys = keyof LocalStore; +type SessionKeys = keyof SessionStore; + +const ls = createLocalStorage(); +const ss = createSessionStorage(); + +const localMemory = new Memory(DEFAULT_CACHE_TIME); +const sessionMemory = new Memory(DEFAULT_CACHE_TIME); + +function initPersistentMemory() { + const localCache = ls.get(APP_LOCAL_CACHE_KEY); + const sessionCache = ss.get(APP_SESSION_CACHE_KEY); + localCache && localMemory.resetCache(localCache); + sessionCache && sessionMemory.resetCache(sessionCache); +} + +export class Persistent { + static getLocal(key: LocalKeys) { + return localMemory.get(key)?.value as Nullable; + } + + static setLocal(key: LocalKeys, value: LocalStore[LocalKeys], immediate = false): void { + localMemory.set(key, toRaw(value)); + immediate && ls.set(APP_LOCAL_CACHE_KEY, localMemory.getCache); + } + + static removeLocal(key: LocalKeys, immediate = false): void { + localMemory.remove(key); + immediate && ls.set(APP_LOCAL_CACHE_KEY, localMemory.getCache); + } + + static clearLocal(immediate = false): void { + localMemory.clear(); + immediate && ls.clear(); + } + + static getSession(key: SessionKeys) { + return sessionMemory.get(key)?.value as Nullable; + } + + static setSession(key: SessionKeys, value: SessionStore[SessionKeys], immediate = false): void { + sessionMemory.set(key, toRaw(value)); + immediate && ss.set(APP_SESSION_CACHE_KEY, sessionMemory.getCache); + } + + static removeSession(key: SessionKeys, immediate = false): void { + sessionMemory.remove(key); + immediate && ss.set(APP_SESSION_CACHE_KEY, sessionMemory.getCache); + } + static clearSession(immediate = false): void { + sessionMemory.clear(); + immediate && ss.clear(); + } + + static clearAll(immediate = false) { + sessionMemory.clear(); + localMemory.clear(); + if (immediate) { + ls.clear(); + ss.clear(); + } + } +} + +window.addEventListener('beforeunload', function () { + // TOKEN_KEY 在登录或注销时已经写入到storage了,此处为了解决同时打开多个窗口时token不同步的问题 + // LOCK_INFO_KEY 在锁屏和解锁时写入,此处也不应修改 + ls.set(APP_LOCAL_CACHE_KEY, { + ...omit(localMemory.getCache, LOCK_INFO_KEY), + ...pick(ls.get(APP_LOCAL_CACHE_KEY), [TOKEN_KEY, USER_INFO_KEY, LOCK_INFO_KEY]), + }); + ss.set(APP_SESSION_CACHE_KEY, { + ...omit(sessionMemory.getCache, LOCK_INFO_KEY), + ...pick(ss.get(APP_SESSION_CACHE_KEY), [TOKEN_KEY, USER_INFO_KEY, LOCK_INFO_KEY]), + }); +}); + +function storageChange(e: any) { + const { key, newValue, oldValue } = e; + + if (!key) { + Persistent.clearAll(); + return; + } + + if (!!newValue && !!oldValue) { + if (APP_LOCAL_CACHE_KEY === key) { + Persistent.clearLocal(); + } + if (APP_SESSION_CACHE_KEY === key) { + Persistent.clearSession(); + } + } +} + +window.addEventListener('storage', storageChange); + +initPersistentMemory(); diff --git a/src/utils/cache/storageCache.ts b/src/utils/cache/storageCache.ts new file mode 100644 index 0000000..84ba2aa --- /dev/null +++ b/src/utils/cache/storageCache.ts @@ -0,0 +1,111 @@ +import { cacheCipher } from '/@/settings/encryptionSetting'; +import type { EncryptionParams } from '/@/utils/cipher'; +import { AesEncryption } from '/@/utils/cipher'; +import { isNullOrUnDef } from '/@/utils/is'; + +export interface CreateStorageParams extends EncryptionParams { + prefixKey: string; + storage: Storage; + hasEncrypt: boolean; + timeout?: Nullable; +} +export const createStorage = ({ + prefixKey = '', + storage = sessionStorage, + key = cacheCipher.key, + iv = cacheCipher.iv, + timeout = null, + hasEncrypt = true, +}: Partial = {}) => { + if (hasEncrypt && [key.length, iv.length].some((item) => item !== 16)) { + throw new Error('When hasEncrypt is true, the key or iv must be 16 bits!'); + } + + const encryption = new AesEncryption({ key, iv }); + + /** + * Cache class + * Construction parameters can be passed into sessionStorage, localStorage, + * @class Cache + * @example + */ + const WebStorage = class WebStorage { + private storage: Storage; + private prefixKey?: string; + private encryption: AesEncryption; + private hasEncrypt: boolean; + /** + * + * @param {*} storage + */ + constructor() { + this.storage = storage; + this.prefixKey = prefixKey; + this.encryption = encryption; + this.hasEncrypt = hasEncrypt; + } + + private getKey(key: string) { + return `${this.prefixKey}${key}`.toUpperCase(); + } + + /** + * Set cache + * @param {string} key + * @param {*} value + * @param {*} expire Expiration time in seconds + * @memberof Cache + */ + set(key: string, value: any, expire: number | null = timeout) { + const stringData = JSON.stringify({ + value, + time: Date.now(), + expire: !isNullOrUnDef(expire) ? new Date().getTime() + expire * 1000 : null, + }); + const stringifyValue = this.hasEncrypt + ? this.encryption.encryptByAES(stringData) + : stringData; + this.storage.setItem(this.getKey(key), stringifyValue); + } + + /** + * Read cache + * @param {string} key + * @param {*} def + * @memberof Cache + */ + get(key: string, def: any = null): any { + const val = this.storage.getItem(this.getKey(key)); + if (!val) return def; + + try { + const decVal = this.hasEncrypt ? this.encryption.decryptByAES(val) : val; + const data = JSON.parse(decVal); + const { value, expire } = data; + if (isNullOrUnDef(expire) || expire >= new Date().getTime()) { + return value; + } + this.remove(key); + } catch (e) { + return def; + } + } + + /** + * Delete cache based on key + * @param {string} key + * @memberof Cache + */ + remove(key: string) { + this.storage.removeItem(this.getKey(key)); + } + + /** + * Delete all caches of this instance + */ + clear(): void { + this.storage.clear(); + } + }; + return new WebStorage(); +}; diff --git a/src/utils/cipher.ts b/src/utils/cipher.ts new file mode 100644 index 0000000..7a02cfc --- /dev/null +++ b/src/utils/cipher.ts @@ -0,0 +1,54 @@ +import { encrypt, decrypt } from 'crypto-js/aes'; +import UTF8, { parse } from 'crypto-js/enc-utf8'; +import pkcs7 from 'crypto-js/pad-pkcs7'; +import ECB from 'crypto-js/mode-ecb'; +import md5 from 'crypto-js/md5'; +import Base64 from 'crypto-js/enc-base64'; + +export interface EncryptionParams { + key: string; + iv: string; +} + +export class AesEncryption { + private key; + private iv; + + constructor(opt: Partial = {}) { + const { key, iv } = opt; + if (key) { + this.key = parse(key); + } + if (iv) { + this.iv = parse(iv); + } + } + + get getOptions() { + return { + mode: ECB, + padding: pkcs7, + iv: this.iv, + }; + } + + encryptByAES(cipherText: string) { + return encrypt(cipherText, this.key, this.getOptions).toString(); + } + + decryptByAES(cipherText: string) { + return decrypt(cipherText, this.key, this.getOptions).toString(UTF8); + } +} + +export function encryptByBase64(cipherText: string) { + return UTF8.parse(cipherText).toString(Base64); +} + +export function decodeByBase64(cipherText: string) { + return Base64.parse(cipherText).toString(UTF8); +} + +export function encryptByMd5(password: string) { + return md5(password).toString(); +} diff --git a/src/utils/color.ts b/src/utils/color.ts new file mode 100644 index 0000000..3c0ca5e --- /dev/null +++ b/src/utils/color.ts @@ -0,0 +1,151 @@ +/** + * 判断是否 十六进制颜色值. + * 输入形式可为 #fff000 #f00 + * + * @param String color 十六进制颜色值 + * @return Boolean + */ +export function isHexColor(color: string) { + const reg = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/; + return reg.test(color); +} + +/** + * RGB 颜色值转换为 十六进制颜色值. + * r, g, 和 b 需要在 [0, 255] 范围内 + * + * @return String 类似#ff00ff + * @param r + * @param g + * @param b + */ +export function rgbToHex(r: number, g: number, b: number) { + // tslint:disable-next-line:no-bitwise + const hex = ((r << 16) | (g << 8) | b).toString(16); + return '#' + new Array(Math.abs(hex.length - 7)).join('0') + hex; +} + +/** + * Transform a HEX color to its RGB representation + * @param {string} hex The color to transform + * @returns The RGB representation of the passed color + */ +export function hexToRGB(hex: string) { + let sHex = hex.toLowerCase(); + if (isHexColor(hex)) { + if (sHex.length === 4) { + let sColorNew = '#'; + for (let i = 1; i < 4; i += 1) { + sColorNew += sHex.slice(i, i + 1).concat(sHex.slice(i, i + 1)); + } + sHex = sColorNew; + } + const sColorChange: number[] = []; + for (let i = 1; i < 7; i += 2) { + sColorChange.push(parseInt('0x' + sHex.slice(i, i + 2))); + } + return 'RGB(' + sColorChange.join(',') + ')'; + } + return sHex; +} + +export function colorIsDark(color: string) { + if (!isHexColor(color)) return; + const [r, g, b] = hexToRGB(color) + .replace(/(?:\(|\)|rgb|RGB)*/g, '') + .split(',') + .map((item) => Number(item)); + return r * 0.299 + g * 0.578 + b * 0.114 < 192; +} + +/** + * Darkens a HEX color given the passed percentage + * @param {string} color The color to process + * @param {number} amount The amount to change the color by + * @returns {string} The HEX representation of the processed color + */ +export function darken(color: string, amount: number) { + color = color.indexOf('#') >= 0 ? color.substring(1, color.length) : color; + amount = Math.trunc((255 * amount) / 100); + return `#${subtractLight(color.substring(0, 2), amount)}${subtractLight( + color.substring(2, 4), + amount, + )}${subtractLight(color.substring(4, 6), amount)}`; +} + +/** + * Lightens a 6 char HEX color according to the passed percentage + * @param {string} color The color to change + * @param {number} amount The amount to change the color by + * @returns {string} The processed color represented as HEX + */ +export function lighten(color: string, amount: number) { + color = color.indexOf('#') >= 0 ? color.substring(1, color.length) : color; + amount = Math.trunc((255 * amount) / 100); + return `#${addLight(color.substring(0, 2), amount)}${addLight( + color.substring(2, 4), + amount, + )}${addLight(color.substring(4, 6), amount)}`; +} + +/* Suma el porcentaje indicado a un color (RR, GG o BB) hexadecimal para aclararlo */ +/** + * Sums the passed percentage to the R, G or B of a HEX color + * @param {string} color The color to change + * @param {number} amount The amount to change the color by + * @returns {string} The processed part of the color + */ +function addLight(color: string, amount: number) { + const cc = parseInt(color, 16) + amount; + const c = cc > 255 ? 255 : cc; + return c.toString(16).length > 1 ? c.toString(16) : `0${c.toString(16)}`; +} + +/** + * Calculates luminance of an rgb color + * @param {number} r red + * @param {number} g green + * @param {number} b blue + */ +function luminanace(r: number, g: number, b: number) { + const a = [r, g, b].map((v) => { + v /= 255; + return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4); + }); + return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722; +} + +/** + * Calculates contrast between two rgb colors + * @param {string} rgb1 rgb color 1 + * @param {string} rgb2 rgb color 2 + */ +function contrast(rgb1: string[], rgb2: number[]) { + return ( + (luminanace(~~rgb1[0], ~~rgb1[1], ~~rgb1[2]) + 0.05) / + (luminanace(rgb2[0], rgb2[1], rgb2[2]) + 0.05) + ); +} + +/** + * Determines what the best text color is (black or white) based con the contrast with the background + * @param hexColor - Last selected color by the user + */ +export function calculateBestTextColor(hexColor: string) { + const rgbColor = hexToRGB(hexColor.substring(1)); + const contrastWithBlack = contrast(rgbColor.split(','), [0, 0, 0]); + + return contrastWithBlack >= 12 ? '#000000' : '#FFFFFF'; +} + +/** + * Subtracts the indicated percentage to the R, G or B of a HEX color + * @param {string} color The color to change + * @param {number} amount The amount to change the color by + * @returns {string} The processed part of the color + */ +function subtractLight(color: string, amount: number) { + const cc = parseInt(color, 16) - amount; + const c = cc < 0 ? 0 : cc; + return c.toString(16).length > 1 ? c.toString(16) : `0${c.toString(16)}`; +} diff --git a/src/utils/dateUtil.ts b/src/utils/dateUtil.ts new file mode 100644 index 0000000..a719d93 --- /dev/null +++ b/src/utils/dateUtil.ts @@ -0,0 +1,28 @@ +/** + * Independent time operation tool to facilitate subsequent switch to dayjs + */ +import dayjs from 'dayjs'; + +const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss'; +const DATE_FORMAT = 'YYYY-MM-DD'; + +export function formatToDateTime(date?: dayjs.ConfigType, format = DATE_TIME_FORMAT): string { + return dayjs(date).format(format); +} + +export function formatToDate(date?: dayjs.ConfigType, format = DATE_FORMAT): string { + return dayjs(date).format(format); +} + +export const getTimestamp = (date) => { + return ( + date.getFullYear() * 10000000000 + + (date.getMonth() + 1) * 100000000 + + date.getDate() * 1000000 + + date.getHours() * 10000 + + date.getMinutes() * 100 + + date.getSeconds() + ).toString(); +}; + +export const dateUtil = dayjs; diff --git a/src/utils/domUtils.ts b/src/utils/domUtils.ts new file mode 100644 index 0000000..7efe9cb --- /dev/null +++ b/src/utils/domUtils.ts @@ -0,0 +1,180 @@ +import type { FunctionArgs } from '@vueuse/core'; +import { upperFirst } from 'lodash-es'; + +export interface ViewportOffsetResult { + left: number; + top: number; + right: number; + bottom: number; + rightIncludeBody: number; + bottomIncludeBody: number; +} + +export function getBoundingClientRect(element: Element): DOMRect | number { + if (!element || !element.getBoundingClientRect) { + return 0; + } + return element.getBoundingClientRect(); +} + +function trim(string: string) { + return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, ''); +} + +/* istanbul ignore next */ +export function hasClass(el: Element, cls: string) { + if (!el || !cls) return false; + if (cls.indexOf(' ') !== -1) throw new Error('className should not contain space.'); + if (el.classList) { + return el.classList.contains(cls); + } else { + return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > -1; + } +} + +/* istanbul ignore next */ +export function addClass(el: Element, cls: string) { + if (!el) return; + let curClass = el.className; + const classes = (cls || '').split(' '); + + for (let i = 0, j = classes.length; i < j; i++) { + const clsName = classes[i]; + if (!clsName) continue; + + if (el.classList) { + el.classList.add(clsName); + } else if (!hasClass(el, clsName)) { + curClass += ' ' + clsName; + } + } + if (!el.classList) { + el.className = curClass; + } +} + +/* istanbul ignore next */ +export function removeClass(el: Element, cls: string) { + if (!el || !cls) return; + const classes = cls.split(' '); + let curClass = ' ' + el.className + ' '; + + for (let i = 0, j = classes.length; i < j; i++) { + const clsName = classes[i]; + if (!clsName) continue; + + if (el.classList) { + el.classList.remove(clsName); + } else if (hasClass(el, clsName)) { + curClass = curClass.replace(' ' + clsName + ' ', ' '); + } + } + if (!el.classList) { + el.className = trim(curClass); + } +} +/** + * Get the left and top offset of the current element + * left: the distance between the leftmost element and the left side of the document + * top: the distance from the top of the element to the top of the document + * right: the distance from the far right of the element to the right of the document + * bottom: the distance from the bottom of the element to the bottom of the document + * rightIncludeBody: the distance between the leftmost element and the right side of the document + * bottomIncludeBody: the distance from the bottom of the element to the bottom of the document + * + * @description: + */ +export function getViewportOffset(element: Element): ViewportOffsetResult { + const doc = document.documentElement; + + const docScrollLeft = doc.scrollLeft; + const docScrollTop = doc.scrollTop; + const docClientLeft = doc.clientLeft; + const docClientTop = doc.clientTop; + + const pageXOffset = window.pageXOffset; + const pageYOffset = window.pageYOffset; + + const box = getBoundingClientRect(element); + + const { left: retLeft, top: rectTop, width: rectWidth, height: rectHeight } = box as DOMRect; + + const scrollLeft = (pageXOffset || docScrollLeft) - (docClientLeft || 0); + const scrollTop = (pageYOffset || docScrollTop) - (docClientTop || 0); + const offsetLeft = retLeft + pageXOffset; + const offsetTop = rectTop + pageYOffset; + + const left = offsetLeft - scrollLeft; + const top = offsetTop - scrollTop; + + const clientWidth = window.document.documentElement.clientWidth; + const clientHeight = window.document.documentElement.clientHeight; + return { + left: left, + top: top, + right: clientWidth - rectWidth - left, + bottom: clientHeight - rectHeight - top, + rightIncludeBody: clientWidth - left, + bottomIncludeBody: clientHeight - top, + }; +} + +export function hackCss(attr: string, value: string) { + const prefix: string[] = ['webkit', 'Moz', 'ms', 'OT']; + + const styleObj: any = {}; + prefix.forEach((item) => { + styleObj[`${item}${upperFirst(attr)}`] = value; + }); + return { + ...styleObj, + [attr]: value, + }; +} + +/* istanbul ignore next */ +export function on( + element: Element | HTMLElement | Document | Window, + event: string, + handler: EventListenerOrEventListenerObject, +): void { + if (element && event && handler) { + element.addEventListener(event, handler, false); + } +} + +/* istanbul ignore next */ +export function off( + element: Element | HTMLElement | Document | Window, + event: string, + handler: Fn, +): void { + if (element && event && handler) { + element.removeEventListener(event, handler, false); + } +} + +/* istanbul ignore next */ +export function once(el: HTMLElement, event: string, fn: EventListener): void { + const listener = function (this: any, ...args: unknown[]) { + if (fn) { + fn.apply(this, args); + } + off(el, event, listener); + }; + on(el, event, listener); +} + +export function useRafThrottle(fn: T): T { + let locked = false; + // @ts-ignore + return function (...args: any[]) { + if (locked) return; + locked = true; + window.requestAnimationFrame(() => { + // @ts-ignore + fn.apply(this, args); + locked = false; + }); + }; +} diff --git a/src/utils/env.ts b/src/utils/env.ts new file mode 100644 index 0000000..77a7b3c --- /dev/null +++ b/src/utils/env.ts @@ -0,0 +1,74 @@ +import type { GlobEnvConfig } from '/#/config'; +import pkg from '../../package.json'; + +const getVariableName = (title: string) => { + return `__PRODUCTION__${title.replace(/\s/g, '_').replace(/-/g, '_') || '__APP'}__CONF__` + .toUpperCase() + .replace(/\s/g, ''); +}; + +export function getCommonStoragePrefix() { + const { VITE_GLOB_APP_TITLE } = getAppEnvConfig(); + return `${VITE_GLOB_APP_TITLE.replace(/\s/g, '_')}__${getEnv()}`.toUpperCase(); +} + +// Generate cache key according to version +export function getStorageShortName() { + return `${getCommonStoragePrefix()}${`__${pkg.version}`}__`.toUpperCase(); +} + +export function getAppEnvConfig() { + const ENV_NAME = getVariableName(import.meta.env.VITE_GLOB_APP_TITLE); + + const ENV = (import.meta.env.DEV + ? // Get the global configuration (the configuration will be extracted independently when packaging) + (import.meta.env as unknown as GlobEnvConfig) + : window[ENV_NAME as any]) as unknown as GlobEnvConfig; + + const { VITE_GLOB_APP_TITLE, VITE_GLOB_API_URL, VITE_GLOB_API_URL_PREFIX, VITE_GLOB_UPLOAD_URL } = + ENV; + + return { + VITE_GLOB_APP_TITLE, + VITE_GLOB_API_URL, + VITE_GLOB_API_URL_PREFIX, + VITE_GLOB_UPLOAD_URL, + }; +} + +/** + * @description: Development mode + */ +export const devMode = 'development'; + +/** + * @description: Production mode + */ +export const prodMode = 'production'; + +/** + * @description: Get environment variables + * @returns: + * @example: + */ +export function getEnv(): string { + return import.meta.env.MODE; +} + +/** + * @description: Is it a development mode + * @returns: + * @example: + */ +export function isDevMode(): boolean { + return import.meta.env.DEV; +} + +/** + * @description: Is it a production mode + * @returns: + * @example: + */ +export function isProdMode(): boolean { + return import.meta.env.PROD; +} \ No newline at end of file diff --git a/src/utils/event/index.ts b/src/utils/event/index.ts new file mode 100644 index 0000000..3a60d7c --- /dev/null +++ b/src/utils/event/index.ts @@ -0,0 +1,42 @@ +import ResizeObserver from 'resize-observer-polyfill'; + +const isServer = typeof window === 'undefined'; + +/* istanbul ignore next */ +function resizeHandler(entries: any[]) { + for (const entry of entries) { + const listeners = entry.target.__resizeListeners__ || []; + if (listeners.length) { + listeners.forEach((fn: () => any) => { + fn(); + }); + } + } +} + +/* istanbul ignore next */ +export function addResizeListener(element: any, fn: () => any) { + if (isServer) return; + if (!element.__resizeListeners__) { + element.__resizeListeners__ = []; + element.__ro__ = new ResizeObserver(resizeHandler); + element.__ro__.observe(element); + } + element.__resizeListeners__.push(fn); +} + +/* istanbul ignore next */ +export function removeResizeListener(element: any, fn: () => any) { + if (!element || !element.__resizeListeners__) return; + element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1); + if (!element.__resizeListeners__.length) { + element.__ro__.disconnect(); + } +} + +export function triggerWindowResize() { + const event = document.createEvent('HTMLEvents'); + event.initEvent('resize', true, true); + (event as any).eventType = 'message'; + window.dispatchEvent(event); +} diff --git a/src/utils/factory/createAsyncComponent.tsx b/src/utils/factory/createAsyncComponent.tsx new file mode 100644 index 0000000..f7d8622 --- /dev/null +++ b/src/utils/factory/createAsyncComponent.tsx @@ -0,0 +1,56 @@ +import { + AsyncComponentLoader, + Component, + ComponentPublicInstance, + defineAsyncComponent, + // FunctionalComponent, CSSProperties +} from 'vue'; +import { Spin } from 'ant-design-vue'; +import { noop } from '/@/utils'; + +interface Options { + size?: 'default' | 'small' | 'large'; + delay?: number; + timeout?: number; + loading?: boolean; + retry?: boolean; +} + +export function createAsyncComponent< + T extends Component = { + new (): ComponentPublicInstance; + }, +>(loader: AsyncComponentLoader, options: Options = {}) { + const { size = 'small', delay = 100, timeout = 30000, loading = false, retry = true } = options; + return defineAsyncComponent({ + loader, + loadingComponent: loading ? : undefined, + // The error component will be displayed if a timeout is + // provided and exceeded. Default: Infinity. + // TODO + timeout, + // errorComponent + // Defining if component is suspensible. Default: true. + // suspensible: false, + delay, + /** + * + * @param {*} error Error message object + * @param {*} retry A function that indicating whether the async component should retry when the loader promise rejects + * @param {*} fail End of failure + * @param {*} attempts Maximum allowed retries number + */ + onError: !retry + ? noop + : (error, retry, fail, attempts) => { + if (error.message.match(/fetch/) && attempts <= 3) { + // retry on fetch errors, 3 max attempts + retry(); + } else { + // Note that retry/fail are like resolve/reject of a promise: + // one of them must be called for the error handling to continue. + fail(); + } + }, + }); +} diff --git a/src/utils/file/base64Conver.ts b/src/utils/file/base64Conver.ts new file mode 100644 index 0000000..6751d97 --- /dev/null +++ b/src/utils/file/base64Conver.ts @@ -0,0 +1,41 @@ +/** + * @description: base64 to blob + */ +export function dataURLtoBlob(base64Buf: string): Blob { + const arr = base64Buf.split(','); + const typeItem = arr[0]; + const mime = typeItem.match(/:(.*?);/)![1]; + const bstr = window.atob(arr[1]); + let n = bstr.length; + const u8arr = new Uint8Array(n); + while (n--) { + u8arr[n] = bstr.charCodeAt(n); + } + return new Blob([u8arr], { type: mime }); +} + +/** + * img url to base64 + * @param url + */ +export function urlToBase64(url: string, mineType?: string): Promise { + return new Promise((resolve, reject) => { + let canvas = document.createElement('CANVAS') as Nullable; + const ctx = canvas!.getContext('2d'); + + const img = new Image(); + img.crossOrigin = ''; + img.onload = function () { + if (!canvas || !ctx) { + return reject(); + } + canvas.height = img.height; + canvas.width = img.width; + ctx.drawImage(img, 0, 0); + const dataURL = canvas.toDataURL(mineType || 'image/png'); + canvas = null; + resolve(dataURL); + }; + img.src = url; + }); +} diff --git a/src/utils/file/download.ts b/src/utils/file/download.ts new file mode 100644 index 0000000..c31fb7e --- /dev/null +++ b/src/utils/file/download.ts @@ -0,0 +1,45 @@ +import { openWindow } from '..'; + +/** + * Download file according to file address + * @param {*} sUrl + */ +export function downloadByUrl({ + url, + target = '_blank', + fileName, +}: { + url: string; + target?: TargetContext; + fileName?: string; +}): boolean { + const isChrome = window.navigator.userAgent.toLowerCase().indexOf('chrome') > -1; + const isSafari = window.navigator.userAgent.toLowerCase().indexOf('safari') > -1; + + if (/(iP)/g.test(window.navigator.userAgent)) { + console.error('Your browser does not support download!'); + return false; + } + if (isChrome || isSafari) { + const link = document.createElement('a'); + link.href = url; + link.target = target; + + if (link.download !== undefined) { + link.download = fileName || url.substring(url.lastIndexOf('/') + 1, url.length); + } + + if (document.createEvent) { + const e = document.createEvent('MouseEvents'); + e.initEvent('click', true, true); + link.dispatchEvent(e); + return true; + } + } + if (url.indexOf('?') === -1) { + url += '?download'; + } + + openWindow(url, { target }); + return true; +} diff --git a/src/utils/helper/treeHelper.ts b/src/utils/helper/treeHelper.ts new file mode 100644 index 0000000..f915dbd --- /dev/null +++ b/src/utils/helper/treeHelper.ts @@ -0,0 +1,216 @@ +interface TreeHelperConfig { + id: string; + children: string; + pid: string; +} + +// 默认配置 +const DEFAULT_CONFIG: TreeHelperConfig = { + id: 'id', + children: 'children', + pid: 'pid', +}; + +// 获取配置。 Object.assign 从一个或多个源对象复制到目标对象 +const getConfig = (config: Partial) => Object.assign({}, DEFAULT_CONFIG, config); + +// tree from list +// 列表中的树 +export function listToTree(list: any[], config: Partial = {}): T[] { + const conf = getConfig(config) as TreeHelperConfig; + const nodeMap = new Map(); + const result: T[] = []; + const { id, children, pid } = conf; + + for (const node of list) { + node[children] = node[children] || []; + nodeMap.set(node[id], node); + } + for (const node of list) { + const parent = nodeMap.get(node[pid]); + (parent ? parent[children] : result).push(node); + } + return result; +} + +export function treeToList(tree: any, config: Partial = {}): T { + config = getConfig(config); + const { children } = config; + const result: any = [...tree]; + for (let i = 0; i < result.length; i++) { + if (!result[i][children!]) continue; + result.splice(i + 1, 0, ...result[i][children!]); + } + return result; +} + +export function findNode( + tree: any, + func: Fn, + config: Partial = {}, +): T | null { + config = getConfig(config); + const { children } = config; + const list = [...tree]; + for (const node of list) { + if (func(node)) return node; + node[children!] && list.push(...node[children!]); + } + return null; +} + +export function findNodeAll( + tree: any, + func: Fn, + config: Partial = {}, +): T[] { + config = getConfig(config); + const { children } = config; + const list = [...tree]; + const result: T[] = []; + for (const node of list) { + func(node) && result.push(node); + node[children!] && list.push(...node[children!]); + } + return result; +} + +export function findPath( + tree: any, + func: Fn, + config: Partial = {}, +): T | T[] | null { + config = getConfig(config); + const path: T[] = []; + const list = [...tree]; + const visitedSet = new Set(); + const { children } = config; + while (list.length) { + const node = list[0]; + if (visitedSet.has(node)) { + path.pop(); + list.shift(); + } else { + visitedSet.add(node); + node[children!] && list.unshift(...node[children!]); + path.push(node); + if (func(node)) { + return path; + } + } + } + return null; +} + +export function findPathAll(tree: any, func: Fn, config: Partial = {}) { + config = getConfig(config); + const path: any[] = []; + const list = [...tree]; + const result: any[] = []; + const visitedSet = new Set(), + { children } = config; + while (list.length) { + const node = list[0]; + if (visitedSet.has(node)) { + path.pop(); + list.shift(); + } else { + visitedSet.add(node); + node[children!] && list.unshift(...node[children!]); + path.push(node); + func(node) && result.push([...path]); + } + } + return result; +} + +export function filter( + tree: T[], + func: (n: T) => boolean, + // Partial 将 T 中的所有属性设为可选 + config: Partial = {}, +): T[] { + // 获取配置 + config = getConfig(config); + const children = config.children as string; + + function listFilter(list: T[]) { + return list + .map((node: any) => ({ ...node })) + .filter((node) => { + // 递归调用 对含有children项 进行再次调用自身函数 listFilter + node[children] = node[children] && listFilter(node[children]); + // 执行传入的回调 func 进行过滤 + return func(node) || (node[children] && node[children].length); + }); + } + + return listFilter(tree); +} + +export function forEach( + tree: T[], + func: (n: T) => any, + config: Partial = {}, +): void { + config = getConfig(config); + const list: any[] = [...tree]; + const { children } = config; + for (let i = 0; i < list.length; i++) { + //func 返回true就终止遍历,避免大量节点场景下无意义循环,引起浏览器卡顿 + if (func(list[i])) { + return; + } + children && list[i][children] && list.splice(i + 1, 0, ...list[i][children]); + } +} + +/** + * @description: Extract tree specified structure + * @description: 提取树指定结构 + */ +export function treeMap(treeData: T[], opt: { children?: string; conversion: Fn }): T[] { + return treeData.map((item) => treeMapEach(item, opt)); +} + +/** + * @description: Extract tree specified structure + * @description: 提取树指定结构 + */ +export function treeMapEach( + data: any, + { children = 'children', conversion }: { children?: string; conversion: Fn }, +) { + const haveChildren = Array.isArray(data[children]) && data[children].length > 0; + const conversionData = conversion(data) || {}; + if (haveChildren) { + return { + ...conversionData, + [children]: data[children].map((i: number) => + treeMapEach(i, { + children, + conversion, + }), + ), + }; + } else { + return { + ...conversionData, + }; + } +} + +/** + * 递归遍历树结构 + * @param treeData 树 + * @param callBack 回调 + * @param parentNode 父节点 + */ +export function eachTree(treeData: any[], callBack: Fn, parentNode = {}) { + treeData.forEach((element) => { + const newNode = callBack(element, parentNode) || element; + if (element.children) { + eachTree(element.children, callBack, newNode); + } + }); +} diff --git a/src/utils/helper/tsxHelper.tsx b/src/utils/helper/tsxHelper.tsx new file mode 100644 index 0000000..3de2365 --- /dev/null +++ b/src/utils/helper/tsxHelper.tsx @@ -0,0 +1,37 @@ +import { Slots } from 'vue'; +import { isFunction } from '/@/utils/is'; +import { RenderOpts } from '/@/components/Form'; + +/** + * @description: Get slot to prevent empty error + */ +export function getSlot(slots: Slots, slot = 'default', data?: any, opts?: RenderOpts) { + if (!slots || !Reflect.has(slots, slot)) { + return null; + } + if (!isFunction(slots[slot])) { + console.error(`${slot} is not a function!`); + return null; + } + const slotFn = slots[slot]; + if (!slotFn) return null; + const params = { ...data, ...opts }; + return slotFn(params); +} + +/** + * extends slots + * @param slots + * @param excludeKeys + */ +export function extendSlots(slots: Slots, excludeKeys: string[] = []) { + const slotKeys = Object.keys(slots); + const ret: any = {}; + slotKeys.map((key) => { + if (excludeKeys.includes(key)) { + return null; + } + ret[key] = (data?: any) => getSlot(slots, key, data); + }); + return ret; +} diff --git a/src/utils/http/axios/Axios.ts b/src/utils/http/axios/Axios.ts new file mode 100644 index 0000000..e75dfdd --- /dev/null +++ b/src/utils/http/axios/Axios.ts @@ -0,0 +1,251 @@ +import type { + AxiosRequestConfig, + AxiosInstance, + AxiosResponse, + AxiosError, + InternalAxiosRequestConfig, +} from 'axios'; +import type { RequestOptions, Result, UploadFileParams } from '/#/axios'; +import type { CreateAxiosOptions } from './axiosTransform'; +import axios from 'axios'; +import qs from 'qs'; +import { AxiosCanceler } from './axiosCancel'; +import { isFunction } from '/@/utils/is'; +import { cloneDeep } from 'lodash-es'; +import { ContentTypeEnum, RequestEnum } from '/@/enums/httpEnum'; + +export * from './axiosTransform'; + +/** + * @description: axios module + */ +export class VAxios { + private axiosInstance: AxiosInstance; + private readonly options: CreateAxiosOptions; + + constructor(options: CreateAxiosOptions) { + this.options = options; + this.axiosInstance = axios.create(options); + this.setupInterceptors(); + } + + /** + * @description: Create axios instance + */ + private createAxios(config: CreateAxiosOptions): void { + this.axiosInstance = axios.create(config); + } + + private getTransform() { + const { transform } = this.options; + return transform; + } + + getAxios(): AxiosInstance { + return this.axiosInstance; + } + + /** + * @description: Reconfigure axios + */ + configAxios(config: CreateAxiosOptions) { + if (!this.axiosInstance) { + return; + } + this.createAxios(config); + } + + /** + * @description: Set general header + */ + setHeader(headers: any): void { + if (!this.axiosInstance) { + return; + } + Object.assign(this.axiosInstance.defaults.headers, headers); + } + + /** + * @description: Interceptor configuration 拦截器配置 + */ + private setupInterceptors() { + // const transform = this.getTransform(); + const { + axiosInstance, + options: { transform }, + } = this; + if (!transform) { + return; + } + const { + requestInterceptors, + requestInterceptorsCatch, + responseInterceptors, + responseInterceptorsCatch, + } = transform; + + const axiosCanceler = new AxiosCanceler(); + + // Request interceptor configuration processing + this.axiosInstance.interceptors.request.use((config: InternalAxiosRequestConfig) => { + // If cancel repeat request is turned on, then cancel repeat request is prohibited + const requestOptions = (config as unknown as any).requestOptions ?? this.options.requestOptions; + const ignoreCancelToken = requestOptions?.ignoreCancelToken ?? true; + + !ignoreCancelToken && axiosCanceler.addPending(config); + + if (requestInterceptors && isFunction(requestInterceptors)) { + config = requestInterceptors(config, this.options); + } + return config; + }, undefined); + + // Request interceptor error capture + requestInterceptorsCatch && + isFunction(requestInterceptorsCatch) && + this.axiosInstance.interceptors.request.use(undefined, requestInterceptorsCatch); + + // Response result interceptor processing + this.axiosInstance.interceptors.response.use((res: AxiosResponse) => { + res && axiosCanceler.removePending(res.config); + if (responseInterceptors && isFunction(responseInterceptors)) { + res = responseInterceptors(res); + } + return res; + }, undefined); + + // Response result interceptor error capture + responseInterceptorsCatch && + isFunction(responseInterceptorsCatch) && + this.axiosInstance.interceptors.response.use(undefined, (error) => { + return responseInterceptorsCatch(axiosInstance, error); + }); + } + + /** + * @description: File Upload + */ + uploadFile(config: AxiosRequestConfig, params: UploadFileParams) { + const formData = new window.FormData(); + const customFilename = params.name || 'file'; + + if (params.filename) { + formData.append(customFilename, params.file, params.filename); + } else { + formData.append(customFilename, params.file); + } + + if (params.data) { + Object.keys(params.data).forEach((key) => { + const value = params.data![key]; + if (Array.isArray(value)) { + value.forEach((item) => { + formData.append(`${key}[]`, item); + }); + return; + } + + formData.append(key, params.data![key]); + }); + } + + return this.axiosInstance.request({ + ...config, + method: 'POST', + data: formData, + headers: { + 'Content-type': ContentTypeEnum.FORM_DATA, + // @ts-ignore + ignoreCancelToken: true, + }, + }); + } + + // support form-data + supportFormData(config: AxiosRequestConfig) { + const headers = config.headers || this.options.headers; + const contentType = headers?.['Content-Type'] || headers?.['content-type']; + + if ( + contentType !== ContentTypeEnum.FORM_URLENCODED || + !Reflect.has(config, 'data') || + config.method?.toUpperCase() === RequestEnum.GET + ) { + return config; + } + + return { + ...config, + data: qs.stringify(config.data, { arrayFormat: 'brackets' }), + }; + } + + get(config: AxiosRequestConfig, options?: RequestOptions): Promise { + return this.request({ ...config, method: 'GET' }, options); + } + + post(config: AxiosRequestConfig, options?: RequestOptions): Promise { + return this.request({ ...config, method: 'POST' }, options); + } + + put(config: AxiosRequestConfig, options?: RequestOptions): Promise { + return this.request({ ...config, method: 'PUT' }, options); + } + + delete(config: AxiosRequestConfig, options?: RequestOptions): Promise { + return this.request({ ...config, method: 'DELETE' }, options); + } + + request(config: AxiosRequestConfig, options?: RequestOptions): Promise { + let conf: CreateAxiosOptions = cloneDeep(config); + // cancelToken 如果被深拷贝,会导致最外层无法使用cancel方法来取消请求 + if (config.cancelToken) { + conf.cancelToken = config.cancelToken; + } + + if (config.signal) { + conf.signal = config.signal; + } + + const transform = this.getTransform(); + + const { requestOptions } = this.options; + + const opt: RequestOptions = Object.assign({}, requestOptions, options); + + const { beforeRequestHook, requestCatchHook, transformResponseHook } = transform || {}; + if (beforeRequestHook && isFunction(beforeRequestHook)) { + conf = beforeRequestHook(conf, opt); + } + conf.requestOptions = opt; + + conf = this.supportFormData(conf); + + return new Promise((resolve, reject) => { + this.axiosInstance + .request>(conf) + .then((res: AxiosResponse) => { + if (transformResponseHook && isFunction(transformResponseHook)) { + try { + const ret = transformResponseHook(res, opt); + resolve(ret); + } catch (err) { + reject(err || new Error('request error!')); + } + return; + } + resolve(res as unknown as Promise); + }) + .catch((e: Error | AxiosError) => { + if (requestCatchHook && isFunction(requestCatchHook)) { + reject(requestCatchHook(e, opt)); + return; + } + if (axios.isAxiosError(e)) { + // rewrite error message from axios in here + } + reject(e); + }); + }); + } +} diff --git a/src/utils/http/axios/axiosCancel.ts b/src/utils/http/axios/axiosCancel.ts new file mode 100644 index 0000000..f115ccf --- /dev/null +++ b/src/utils/http/axios/axiosCancel.ts @@ -0,0 +1,60 @@ +import type { AxiosRequestConfig } from 'axios'; + +// 用于存储每个请求的标识和取消函数 +const pendingMap = new Map(); + +const getPendingUrl = (config: AxiosRequestConfig): string => { + return [config.method, config.url].join('&'); +}; + +export class AxiosCanceler { + /** + * 添加请求 + * @param config 请求配置 + */ + public addPending(config: AxiosRequestConfig): void { + this.removePending(config); + const url = getPendingUrl(config); + const controller = new AbortController(); + config.signal = config.signal || controller.signal; + if (!pendingMap.has(url)) { + // 如果当前请求不在等待中,将其添加到等待中 + pendingMap.set(url, controller); + } + } + + /** + * 清除所有等待中的请求 + */ + public removeAllPending(): void { + pendingMap.forEach((abortController) => { + if (abortController) { + abortController.abort(); + } + }); + this.reset(); + } + + /** + * 移除请求 + * @param config 请求配置 + */ + public removePending(config: AxiosRequestConfig): void { + const url = getPendingUrl(config); + if (pendingMap.has(url)) { + // 如果当前请求在等待中,取消它并将其从等待中移除 + const abortController = pendingMap.get(url); + if (abortController) { + abortController.abort(url); + } + pendingMap.delete(url); + } + } + + /** + * 重置 + */ + public reset(): void { + pendingMap.clear(); + } +} diff --git a/src/utils/http/axios/axiosRetry.ts b/src/utils/http/axios/axiosRetry.ts new file mode 100644 index 0000000..bf44cf7 --- /dev/null +++ b/src/utils/http/axios/axiosRetry.ts @@ -0,0 +1,30 @@ +import { AxiosError, AxiosInstance } from 'axios'; +/** + * 请求重试机制 + */ + +export class AxiosRetry { + /** + * 重试 + */ + retry(axiosInstance: AxiosInstance, error: AxiosError) { + // @ts-ignore + const { config } = error.response; + const { waitTime, count } = config?.requestOptions?.retryRequest ?? {}; + config.__retryCount = config.__retryCount || 0; + if (config.__retryCount >= count) { + return Promise.reject(error); + } + config.__retryCount += 1; + //请求返回后config的header不正确造成重试请求失败,删除返回headers采用默认headers + delete config.headers; + return this.delay(waitTime).then(() => axiosInstance(config)); + } + + /** + * 延迟 + */ + private delay(waitTime: number) { + return new Promise((resolve) => setTimeout(resolve, waitTime)); + } +} diff --git a/src/utils/http/axios/axiosTransform.ts b/src/utils/http/axios/axiosTransform.ts new file mode 100644 index 0000000..a997438 --- /dev/null +++ b/src/utils/http/axios/axiosTransform.ts @@ -0,0 +1,57 @@ +/** + * Data processing class, can be configured according to the project + */ +import type { + AxiosInstance, + AxiosRequestConfig, + AxiosResponse, + InternalAxiosRequestConfig, +} from 'axios'; +import type { RequestOptions, Result } from '/#/axios'; + +export interface CreateAxiosOptions extends AxiosRequestConfig { + authenticationScheme?: string; + transform?: AxiosTransform; + requestOptions?: RequestOptions; +} + +export abstract class AxiosTransform { + /** + * A function that is called before a request is sent. It can modify the request configuration as needed. + * 在发送请求之前调用的函数。它可以根据需要修改请求配置。 + */ + beforeRequestHook?: (config: AxiosRequestConfig, options: RequestOptions) => AxiosRequestConfig; + + /** + * @description: 处理响应数据 + */ + transformResponseHook?: (res: AxiosResponse, options: RequestOptions) => any; + + /** + * @description: 请求失败处理 + */ + requestCatchHook?: (e: Error, options: RequestOptions) => Promise; + + /** + * @description: 请求之前的拦截器 + */ + requestInterceptors?: ( + config: InternalAxiosRequestConfig, + options: CreateAxiosOptions, + ) => InternalAxiosRequestConfig; + + /** + * @description: 请求之后的拦截器 + */ + responseInterceptors?: (res: AxiosResponse) => AxiosResponse; + + /** + * @description: 请求之前的拦截器错误处理 + */ + requestInterceptorsCatch?: (error: Error) => void; + + /** + * @description: 请求之后的拦截器错误处理 + */ + responseInterceptorsCatch?: (axiosInstance: AxiosInstance, error: Error) => void; +} diff --git a/src/utils/http/axios/checkStatus.ts b/src/utils/http/axios/checkStatus.ts new file mode 100644 index 0000000..acadffa --- /dev/null +++ b/src/utils/http/axios/checkStatus.ts @@ -0,0 +1,80 @@ +import type { ErrorMessageMode } from '/#/axios'; +import { useMessage } from '/@/hooks/web/useMessage'; +import { useI18n } from '/@/hooks/web/useI18n'; +// import router from '/@/router'; +// import { PageEnum } from '/@/enums/pageEnum'; +import { useUserStoreWithOut } from '/@/store/modules/user'; +import projectSetting from '/@/settings/projectSetting'; +import { SessionTimeoutProcessingEnum } from '/@/enums/appEnum'; + +const { createMessage, createErrorModal } = useMessage(); +const error = createMessage.error!; +const stp = projectSetting.sessionTimeoutProcessing; + +export function checkStatus( + status: number, + msg: string, + errorMessageMode: ErrorMessageMode = 'message', +): void { + const { t } = useI18n(); + const userStore = useUserStoreWithOut(); + let errMessage = ''; + + switch (status) { + case 400: + errMessage = `${msg}`; + break; + // 401: Not logged in + // Jump to the login page if not logged in, and carry the path of the current page + // Return to the current page after successful login. This step needs to be operated on the login page. + case 401: + userStore.setToken(undefined); + errMessage = msg || t('sys.api.errMsg401'); + if (stp === SessionTimeoutProcessingEnum.PAGE_COVERAGE) { + userStore.setSessionTimeout(true); + } else { + userStore.logout(true); + } + break; + case 403: + errMessage = t('sys.api.errMsg403'); + break; + // 404请求不存在 + case 404: + errMessage = t('sys.api.errMsg404'); + break; + case 405: + errMessage = t('sys.api.errMsg405'); + break; + case 408: + errMessage = t('sys.api.errMsg408'); + break; + case 500: + errMessage = t('sys.api.errMsg500'); + break; + case 501: + errMessage = t('sys.api.errMsg501'); + break; + case 502: + errMessage = t('sys.api.errMsg502'); + break; + case 503: + errMessage = t('sys.api.errMsg503'); + break; + case 504: + errMessage = t('sys.api.errMsg504'); + break; + case 505: + errMessage = t('sys.api.errMsg505'); + break; + default: + } + + if (errMessage) { + if (errorMessageMode === 'modal') { + createErrorModal({ title: t('sys.api.errorTip'), content: errMessage }); + } else if (errorMessageMode === 'message') { + error({ content: errMessage, key: `global_error_message_status_${status}` }); + } + } +} diff --git a/src/utils/http/axios/helper.ts b/src/utils/http/axios/helper.ts new file mode 100644 index 0000000..30cc2b0 --- /dev/null +++ b/src/utils/http/axios/helper.ts @@ -0,0 +1,48 @@ +import { isObject, isString } from '/@/utils/is'; + +const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss'; + +export function joinTimestamp( + join: boolean, + restful: T, +): T extends true ? string : object; + +export function joinTimestamp(join: boolean, restful = false): string | object { + if (!join) { + return restful ? '' : {}; + } + const now = new Date().getTime(); + if (restful) { + return `?_t=${now}`; + } + return { _t: now }; +} + +/** + * @description: Format request parameter time + */ +export function formatRequestDate(params: Recordable) { + if (Object.prototype.toString.call(params) !== '[object Object]') { + return; + } + + for (const key in params) { + const format = params[key]?.format ?? null; + if (format && typeof format === 'function') { + params[key] = params[key].format(DATE_TIME_FORMAT); + } + if (isString(key)) { + const value = params[key]; + if (value) { + try { + params[key] = isString(value) ? value.trim() : value; + } catch (error: any) { + throw new Error(error); + } + } + } + if (isObject(params[key])) { + formatRequestDate(params[key]); + } + } +} diff --git a/src/utils/http/axios/index.ts b/src/utils/http/axios/index.ts new file mode 100644 index 0000000..fd14d31 --- /dev/null +++ b/src/utils/http/axios/index.ts @@ -0,0 +1,295 @@ +// axios配置 可自行根据项目进行更改,只需更改该文件即可,其他文件可以不动 +// The axios configuration can be changed according to the project, just change the file, other files can be left unchanged + +import type { AxiosInstance, AxiosResponse } from 'axios'; +import { clone } from 'lodash-es'; +import type { RequestOptions, Result } from '/#/axios'; +import type { AxiosTransform, CreateAxiosOptions } from './axiosTransform'; +import { VAxios } from './Axios'; +import { checkStatus } from './checkStatus'; +import { useGlobSetting } from '/@/hooks/setting'; +import { useMessage } from '/@/hooks/web/useMessage'; +import { RequestEnum, ContentTypeEnum } from '/@/enums/httpEnum'; +import { isString} from '/@/utils/is'; +import { getToken } from '/@/utils/auth'; +import { setObjToUrlParams, deepMerge } from '/@/utils'; +import { useErrorLogStoreWithOut } from '/@/store/modules/errorLog'; +import { useI18n } from '/@/hooks/web/useI18n'; +import { joinTimestamp, formatRequestDate } from './helper'; +import { AxiosRetry } from '/@/utils/http/axios/axiosRetry'; +import axios from 'axios'; +import {notification} from "ant-design-vue"; + +const globSetting = useGlobSetting(); +const urlPrefix = globSetting.urlPrefix; +const { createMessage, createErrorModal, createSuccessModal } = useMessage(); + +/** + * @description: 数据处理,方便区分多种处理方式 + */ +const transform: AxiosTransform = { + /** + * @description: 处理响应数据。如果数据不是预期格式,可直接抛出错误 + */ + transformResponseHook: (res: AxiosResponse, options: RequestOptions) => { + const { t } = useI18n(); + const { isTransformResponse, isReturnNativeResponse } = options; + // 是否返回原生响应头 比如:需要获取响应头时使用该属性 + if (isReturnNativeResponse) { + return res; + } + // 不进行任何处理,直接返回 + // 用于页面代码可能需要直接获取code,data,message这些信息时开启 + if (!isTransformResponse) { + return res.data; + } + // 错误的时候返回 + + const { data } = res; + if (!data) { + // return '[HTTP] Request has no return value'; + throw new Error(t('sys.api.apiRequestFailed')); + } + + // 这里逻辑可以根据项目进行修改 + if (!res.data) { + // return '[HTTP] Request has no return value'; + throw new Error(t('sys.api.apiRequestFailed')); + } + // 这里定义了我返回后端正确业务的状态 + const validCodes = ['00000', 'A0001', 'A0002', 'A0013', 'A0014', 'R0001', 'R0002', 'R0003', 'R0004', 'R0005', 'R0006', + 'A0007', 'A0008', 'A0004', 'A0005', 'A0006', 'A0003', 'A0015', 'A0009', 'A0010', 'A0011', 'P0015', 'P0016', 'P0017', 'P0018', + 'P0019', 'P0020', 'P0021', 'P0022', 'P0023', 'S0001', 'S0002', 'S0003', 'S0004', 'S0005', 'S0006', 'S0007', 'S0008', 'S0009', + 'S0016', 'S0017', 'S0018', 'S0013', 'S0014', 'S0015', 'S0010', 'S0011', 'S0012', 'A0020', 'A0021', 'A0022', 'D0001', 'D0002', + 'D0003', 'F0000', 'F0002', 'F0003', 'F0004', 'F0005', 'F0006', 'F0007', 'I0001', 'I0002', 'I0003', 'I0004', 'I0005', 'I0006', + 'E0004', 'E0005', 'E0006', 'T0001', 'T0002', 'T0003', 'C0001', 'C0003', 'C0004', 'P0024', 'P0025', 'P0026', 'P0001', 'P0000', + 'P0002', 'P0003', 'P0004', 'P0005', 'P0006', 'P0007', 'P0008', 'P0009', 'P0010', 'P0011', 'P0012', 'P0013', 'P0014', 'U0001', + 'U0002', 'U0003', 'U0004', 'M0001', 'M0002', 'M0003', 'M0004', 'W0001', 'W0002', 'W0003', 'W0004', 'O0001', 'O0002', 'O0003', + 'O0004', 'A0012', 'A0016', 'A0100', 'A0101', 'A0017']; // 定义包含可能值的数组 + + const warningCodes = ['A0404', 'A0113', 'A0502', 'B0010', 'B0020']; + + if (validCodes.includes(res.data.code) || res.data.code === undefined) { + if (options.successMessageMode === 'message') { + createMessage.success(res.data.msg); + } else if (options.successMessageMode === 'modal') { + createSuccessModal({ title: res.data.msg, content: res.data.msg }); + } else if (options.successMessageMode === 'notice') { + notification.success({ + message: t('common.successful'), + description: t(res.data.msg), + duration: 3, + }); + } + return res.data; + // add info here to handle warning codes + } else if (warningCodes.includes(res.data.code)) { + if (options.errorMessageMode === 'message') { + createMessage.info(res.data.msg); + } else if (options.errorMessageMode === 'modal') { + createSuccessModal({ title: res.data.msg, content: res.data.msg }); + } else if (options.errorMessageMode === 'notice') { + notification.info({ + message: t('common.warning'), + description: t(res.data.msg), + duration: 3, + }); + } + return res.data; + } else { + if (options.errorMessageMode === 'message') { + createMessage.error(res.data.msg); + } else if (options.errorMessageMode === 'modal') { + createErrorModal({ title: res.data.msg, content: res.data.msg }); + } else if (options.errorMessageMode === 'notice') { + notification.warning({ + message: t('common.failed'), + description: t(res.data.msg), + duration: 3, + }); + } + + return res.data; + } + }, + + // 请求之前处理config + beforeRequestHook: (config, options) => { + const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true, urlPrefix } = options; + + if (joinPrefix) { + config.url = `${urlPrefix}${config.url}`; + } + + if (apiUrl && isString(apiUrl)) { + config.url = `${apiUrl}${config.url}`; + } + const params = config.params || {}; + const data = config.data || false; + formatDate && data && !isString(data) && formatRequestDate(data); + if (config.method?.toUpperCase() === RequestEnum.GET) { + if (!isString(params)) { + // 给 get 请求加上时间戳参数,避免从缓存中拿数据。 + config.params = Object.assign(params || {}, joinTimestamp(joinTime, false)); + } else { + // 兼容restful风格 + config.url = config.url + params + `${joinTimestamp(joinTime, true)}`; + config.params = undefined; + } + } else { + if (!isString(params)) { + formatDate && formatRequestDate(params); + if ( + Reflect.has(config, 'data') && + config.data && + (Object.keys(config.data).length > 0 || config.data instanceof FormData) + ) { + config.data = data; + config.params = params; + } else { + // 非GET请求如果没有提供data,则将params视为data + config.data = params; + config.params = undefined; + } + if (joinParamsToUrl) { + config.url = setObjToUrlParams( + config.url as string, + Object.assign({}, config.params, config.data), + ); + } + } else { + // 兼容restful风格 + config.url = config.url + params; + config.params = undefined; + } + } + return config; + }, + + /** + * @description: 请求拦截器处理 + */ + requestInterceptors: (config, options) => { + // 请求之前处理config + const token = getToken(); + if (token && (config as Recordable)?.requestOptions?.withToken !== false) { + // jwt token + (config as Recordable).headers.Authorization = options.authenticationScheme + ? `${options.authenticationScheme} ${token}` + : token; + } + return config; + }, + + /** + * @description: 响应拦截器处理 + */ + responseInterceptors: (res: AxiosResponse) => { + return res; + }, + + /** + * @description: 响应错误处理 + */ + responseInterceptorsCatch: (axiosInstance: AxiosInstance, error: any) => { + const { t } = useI18n(); + const errorLogStore = useErrorLogStoreWithOut(); + errorLogStore.addAjaxErrorInfo(error); + const { response, code, message, config } = error || {}; + const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none'; + const msg: string = response?.data?.error?.message ?? ''; + const err: string = error?.toString?.() ?? ''; + let errMessage = ''; + + if (axios.isCancel(error)) { + return Promise.reject(error); + } + + try { + if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) { + errMessage = t('sys.api.apiTimeoutMessage'); + } + if (err?.includes('Network Error')) { + errMessage = t('sys.api.networkExceptionMsg'); + } + + if (errMessage) { + if (errorMessageMode === 'modal') { + createErrorModal({ title: t('sys.api.errorTip'), content: errMessage }); + } else if (errorMessageMode === 'message') { + createMessage.error(errMessage); + } + return Promise.reject(error); + } + } catch (error) { + throw new Error(error as unknown as string); + } + + checkStatus(error?.response?.status, msg, errorMessageMode); + + // 添加自动重试机制 保险起见 只针对GET请求 + const retryRequest = new AxiosRetry(); + const { isOpenRetry } = config.requestOptions.retryRequest; + config.method?.toUpperCase() === RequestEnum.GET && + isOpenRetry && + // @ts-ignore + retryRequest.retry(axiosInstance, error); + return Promise.reject(error); + }, +}; + +function createAxios(opt?: Partial) { + return new VAxios( + // 深度合并 + deepMerge( + { + // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#authentication_schemes + // authentication schemes,e.g: Bearer + // authenticationScheme: 'Bearer', + authenticationScheme: '', + timeout: 30 * 1000, + // 基础接口地址 + // baseURL: globSetting.apiUrl, + + headers: { 'Content-Type': ContentTypeEnum.JSON }, + // 如果是form-data格式 + // headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED }, + // 数据处理方式 + transform: clone(transform), + // 配置项,下面的选项都可以在独立的接口请求中覆盖 + requestOptions: { + // 默认将prefix 添加到url + joinPrefix: true, + // 是否返回原生响应头 比如:需要获取响应头时使用该属性 + isReturnNativeResponse: false, + // 需要对返回数据进行处理 + isTransformResponse: true, + // post请求的时候添加参数到url + joinParamsToUrl: false, + // 格式化提交参数时间 + formatDate: true, + // 消息提示类型 + errorMessageMode: 'message', + // 接口地址 + apiUrl: globSetting.apiUrl, + // 接口拼接地址 + urlPrefix: urlPrefix, + // 是否加入时间戳 + joinTime: false, + // 忽略重复请求 + ignoreCancelToken: true, + // 是否携带token + withToken: true, + retryRequest: { + isOpenRetry: true, + count: 5, + waitTime: 100, + }, + decompress: false, + }, + }, + opt || {}, + ), + ); +} +export const defHttp = createAxios(); diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..84c407a --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,122 @@ +import type { App, Component } from 'vue'; +import type { RouteLocationNormalized, RouteRecordNormalized } from 'vue-router'; + +import { cloneDeep, mergeWith, uniq } from 'lodash-es'; +import { unref } from 'vue'; +import { isArray, isObject } from '/@/utils/is'; + +export const noop = () => {}; + +/** + * @description: Set ui mount node + */ +export function getPopupContainer(node?: HTMLElement): HTMLElement { + return (node?.parentNode as HTMLElement) ?? document.body; +} + +/** + * Add the object as a parameter to the URL + * @param baseUrl url + * @param obj + * @returns {string} + * eg: + * let obj = {a: '3', b: '4'} + * setObjToUrlParams('www.baidu.com', obj) + * ==>www.baidu.com?a=3&b=4 + */ +export function setObjToUrlParams(baseUrl: string, obj: any): string { + let parameters = ''; + for (const key in obj) { + parameters += key + '=' + encodeURIComponent(obj[key]) + '&'; + } + parameters = parameters.replace(/&$/, ''); + return /\?$/.test(baseUrl) ? baseUrl + parameters : baseUrl.replace(/\/?$/, '?') + parameters; +} + +/** + + 递归合并两个对象。 + Recursively merge two objects. + @param target 目标对象,合并后结果存放于此。The target object to merge into. + @param source 要合并的源对象。The source object to merge from. + @returns 合并后的对象。The merged object. + */ +export function deepMerge( + target: T, + source: U, +): T & U { + return mergeWith(cloneDeep(target), source, (objValue, srcValue) => { + if (isObject(objValue) && isObject(srcValue)) { + return mergeWith(cloneDeep(objValue), srcValue, (prevValue, nextValue) => { + // 如果是数组,合并数组(去重) If it is an array, merge the array (remove duplicates) + return isArray(prevValue) ? uniq(prevValue, nextValue) : undefined; + }); + } + }); +} + +export function openWindow( + url: string, + opt?: { target?: TargetContext | string; noopener?: boolean; noreferrer?: boolean }, +) { + const { target = '__blank', noopener = true, noreferrer = true } = opt || {}; + const feature: string[] = []; + + noopener && feature.push('noopener=yes'); + noreferrer && feature.push('noreferrer=yes'); + + window.open(url, target, feature.join(',')); +} + +// dynamic use hook props +export function getDynamicProps, U>(props: T): Partial { + const ret: Recordable = {}; + + Object.keys(props).map((key) => { + ret[key] = unref((props as Recordable)[key]); + }); + + return ret as Partial; +} + +export function getRawRoute(route: RouteLocationNormalized): RouteLocationNormalized { + if (!route) return route; + const { matched, ...opt } = route; + return { + ...opt, + matched: (matched + ? matched.map((item) => ({ + meta: item.meta, + name: item.name, + path: item.path, + })) + : undefined) as RouteRecordNormalized[], + }; +} + +// https://github.com/vant-ui/vant/issues/8302 +type EventShim = { + new (...args: any[]): { + $props: { + onClick?: (...args: any[]) => void; + }; + }; +}; + +export type WithInstall = T & { + install(app: App): void; +} & EventShim; + +export type CustomComponent = Component & { displayName?: string }; + +export const withInstall = (component: T, alias?: string) => { + (component as Record).install = (app: App) => { + const compName = component.name || component.displayName; + if (!compName) return; + app.component(compName, component); + if (alias) { + app.config.globalProperties[alias] = component; + } + }; + return component as WithInstall; +}; \ No newline at end of file diff --git a/src/utils/is.ts b/src/utils/is.ts new file mode 100644 index 0000000..3a5c4a6 --- /dev/null +++ b/src/utils/is.ts @@ -0,0 +1,98 @@ +const toString = Object.prototype.toString; + +export function is(val: unknown, type: string) { + return toString.call(val) === `[object ${type}]`; +} + +export function isDef(val?: T): val is T { + return typeof val !== 'undefined'; +} + +export function isUnDef(val?: T): val is T { + return !isDef(val); +} + +export function isObject(val: any): val is Record { + return val !== null && is(val, 'Object'); +} + +export function isEmpty(val: T): val is T { + if (isArray(val) || isString(val)) { + return val.length === 0; + } + + if (val instanceof Map || val instanceof Set) { + return val.size === 0; + } + + if (isObject(val)) { + return Object.keys(val).length === 0; + } + + return false; +} + +export function isDate(val: unknown): val is Date { + return is(val, 'Date'); +} + +export function isNull(val: unknown): val is null { + return val === null; +} + +export function isNullAndUnDef(val: unknown): val is null | undefined { + return isUnDef(val) && isNull(val); +} + +export function isNullOrUnDef(val: unknown): val is null | undefined { + return isUnDef(val) || isNull(val); +} + +export function isNumber(val: unknown): val is number { + return is(val, 'Number'); +} + +export function isPromise(val: unknown): val is Promise { + return is(val, 'Promise') && isObject(val) && isFunction(val.then) && isFunction(val.catch); +} + +export function isString(val: unknown): val is string { + return is(val, 'String'); +} + +export function isFunction(val: unknown): val is Function { + return typeof val === 'function'; +} + +export function isBoolean(val: unknown): val is boolean { + return is(val, 'Boolean'); +} + +export function isRegExp(val: unknown): val is RegExp { + return is(val, 'RegExp'); +} + +export function isArray(val: any): val is Array { + return val && Array.isArray(val); +} + +export function isWindow(val: any): val is Window { + return typeof window !== 'undefined' && is(val, 'Window'); +} + +export function isElement(val: unknown): val is Element { + return isObject(val) && !!val.tagName; +} + +export function isMap(val: unknown): val is Map { + return is(val, 'Map'); +} + +export const isServer = typeof window === 'undefined'; + +export const isClient = !isServer; + +export function isUrl(path: string): boolean { + const reg = /^http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- ./?%&=]*)?/; + return reg.test(path); +} diff --git a/src/utils/lib/echarts.ts b/src/utils/lib/echarts.ts new file mode 100644 index 0000000..e1f95cd --- /dev/null +++ b/src/utils/lib/echarts.ts @@ -0,0 +1,57 @@ +import * as echarts from 'echarts/core'; + +import { + BarChart, + LineChart, + PieChart, + MapChart, + PictorialBarChart, + RadarChart, + ScatterChart, +} from 'echarts/charts'; + +import { + TitleComponent, + TooltipComponent, + GridComponent, + PolarComponent, + AriaComponent, + ParallelComponent, + LegendComponent, + RadarComponent, + ToolboxComponent, + DataZoomComponent, + VisualMapComponent, + TimelineComponent, + CalendarComponent, + GraphicComponent, +} from 'echarts/components'; + +import { SVGRenderer } from 'echarts/renderers'; + +echarts.use([ + LegendComponent, + TitleComponent, + TooltipComponent, + GridComponent, + PolarComponent, + AriaComponent, + ParallelComponent, + BarChart, + LineChart, + PieChart, + MapChart, + RadarChart, + SVGRenderer, + PictorialBarChart, + RadarComponent, + ToolboxComponent, + DataZoomComponent, + VisualMapComponent, + TimelineComponent, + CalendarComponent, + GraphicComponent, + ScatterChart, +]); + +export default echarts; diff --git a/src/utils/log.ts b/src/utils/log.ts new file mode 100644 index 0000000..8f79800 --- /dev/null +++ b/src/utils/log.ts @@ -0,0 +1,9 @@ +const projectName = import.meta.env.VITE_GLOB_APP_TITLE; + +export function warn(message: string) { + console.warn(`[${projectName} warn]:${message}`); +} + +export function error(message: string) { + throw new Error(`[${projectName} error]:${message}`); +} diff --git a/src/utils/mitt.ts b/src/utils/mitt.ts new file mode 100644 index 0000000..cf09fd8 --- /dev/null +++ b/src/utils/mitt.ts @@ -0,0 +1,122 @@ +/** + * copy to https://github.com/developit/mitt + * Expand clear method + */ +export type EventType = string | symbol; + +// An event handler can take an optional event argument +// and should not return a value +export type Handler = (event: T) => void; +export type WildcardHandler> = ( + type: keyof T, + event: T[keyof T], +) => void; + +// An array of all currently registered event handlers for a type +export type EventHandlerList = Array>; +export type WildCardEventHandlerList> = Array>; + +// A map of event types and their corresponding event handlers. +export type EventHandlerMap> = Map< + keyof Events | '*', + EventHandlerList | WildCardEventHandlerList +>; + +export interface Emitter> { + all: EventHandlerMap; + + on(type: Key, handler: Handler): void; + on(type: '*', handler: WildcardHandler): void; + + off(type: Key, handler?: Handler): void; + off(type: '*', handler: WildcardHandler): void; + + emit(type: Key, event: Events[Key]): void; + emit(type: undefined extends Events[Key] ? Key : never): void; + clear(): void; +} + +/** + * Mitt: Tiny (~200b) functional event emitter / pubsub. + * @name mitt + * @returns {Mitt} + */ +export function mitt>( + all?: EventHandlerMap, +): Emitter { + type GenericEventHandler = Handler | WildcardHandler; + all = all || new Map(); + + return { + /** + * A Map of event names to registered handler functions. + */ + all, + + /** + * Register an event handler for the given type. + * @param {string|symbol} type Type of event to listen for, or `'*'` for all events + * @param {Function} handler Function to call in response to given event + * @memberOf mitt + */ + on(type: Key, handler: GenericEventHandler) { + const handlers: Array | undefined = all!.get(type); + if (handlers) { + handlers.push(handler); + } else { + all!.set(type, [handler] as EventHandlerList); + } + }, + + /** + * Remove an event handler for the given type. + * If `handler` is omitted, all handlers of the given type are removed. + * @param {string|symbol} type Type of event to unregister `handler` from (`'*'` to remove a wildcard handler) + * @param {Function} [handler] Handler function to remove + * @memberOf mitt + */ + off(type: Key, handler?: GenericEventHandler) { + const handlers: Array | undefined = all!.get(type); + if (handlers) { + if (handler) { + handlers.splice(handlers.indexOf(handler) >>> 0, 1); + } else { + all!.set(type, []); + } + } + }, + + /** + * Invoke all handlers for the given type. + * If present, `'*'` handlers are invoked after type-matched handlers. + * + * Note: Manually firing '*' handlers is not supported. + * + * @param {string|symbol} type The event type to invoke + * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler + * @memberOf mitt + */ + emit(type: Key, evt?: Events[Key]) { + let handlers = all!.get(type); + if (handlers) { + (handlers as EventHandlerList).slice().forEach((handler) => { + handler(evt as Events[Key]); + }); + } + + handlers = all!.get('*'); + if (handlers) { + (handlers as WildCardEventHandlerList).slice().forEach((handler) => { + handler(type, evt as Events[Key]); + }); + } + }, + + /** + * Clear all + */ + clear() { + this.all.clear(); + }, + }; +} diff --git a/src/utils/propTypes.ts b/src/utils/propTypes.ts new file mode 100644 index 0000000..16cf9cd --- /dev/null +++ b/src/utils/propTypes.ts @@ -0,0 +1,35 @@ +import { CSSProperties, VNodeChild } from 'vue'; +import { createTypes, VueTypeValidableDef, VueTypesInterface, toValidableType } from 'vue-types'; + +export type VueNode = VNodeChild | JSX.Element; + +type PropTypes = VueTypesInterface & { + readonly style: VueTypeValidableDef; + readonly VNodeChild: VueTypeValidableDef; + // readonly trueBool: VueTypeValidableDef; +}; +const newPropTypes = createTypes({ + func: undefined, + bool: undefined, + string: undefined, + number: undefined, + object: undefined, + integer: undefined, +}) as PropTypes; + +// 从 vue-types v5.0 开始,extend()方法已经废弃,当前已改为官方推荐的ES6+方法 https://dwightjack.github.io/vue-types/advanced/extending-vue-types.html#the-extend-method +class propTypes extends newPropTypes { + // a native-like validator that supports the `.validable` method + static get style() { + return toValidableType('style', { + type: [String, Object], + }); + } + + static get VNodeChild() { + return toValidableType('VNodeChild', { + type: undefined, + }); + } +} +export { propTypes }; diff --git a/src/utils/props.ts b/src/utils/props.ts new file mode 100644 index 0000000..00b364d --- /dev/null +++ b/src/utils/props.ts @@ -0,0 +1,184 @@ +// copy from element-plus + +import { warn } from 'vue'; +import { fromPairs, isObject } from 'lodash-es'; +import type { ExtractPropTypes, PropType } from 'vue'; +import type { Mutable } from './types'; + +const wrapperKey = Symbol(); +export type PropWrapper = { [wrapperKey]: T }; + +export const propKey = Symbol(); + +type ResolveProp = ExtractPropTypes<{ + key: { type: T; required: true }; +}>['key']; +type ResolvePropType = ResolveProp extends { type: infer V } ? V : ResolveProp; +type ResolvePropTypeWithReadonly = Readonly extends Readonly> + ? ResolvePropType + : ResolvePropType; + +type IfUnknown = [unknown] extends [T] ? V : T; + +export type BuildPropOption, R, V, C> = { + type?: T; + values?: readonly V[]; + required?: R; + default?: R extends true + ? never + : D extends Record | Array + ? () => D + : (() => D) | D; + validator?: ((val: any) => val is C) | ((val: any) => boolean); +}; + +type _BuildPropType = + | (T extends PropWrapper + ? T[typeof wrapperKey] + : [V] extends [never] + ? ResolvePropTypeWithReadonly + : never) + | V + | C; +export type BuildPropType = _BuildPropType< + IfUnknown, + IfUnknown, + IfUnknown +>; + +type _BuildPropDefault = [T] extends [ + // eslint-disable-next-line @typescript-eslint/ban-types + Record | Array | Function, +] + ? D + : D extends () => T + ? ReturnType + : D; + +export type BuildPropDefault = R extends true + ? { readonly default?: undefined } + : { + readonly default: Exclude extends never + ? undefined + : Exclude<_BuildPropDefault, undefined>; + }; +export type BuildPropReturn = { + readonly type: PropType>; + readonly required: IfUnknown; + readonly validator: ((val: unknown) => boolean) | undefined; + [propKey]: true; +} & BuildPropDefault, IfUnknown, IfUnknown>; + +/** + * @description Build prop. It can better optimize prop types + * @description 生成 prop,能更好地优化类型 + * @example + // limited options + // the type will be PropType<'light' | 'dark'> + buildProp({ + type: String, + values: ['light', 'dark'], + } as const) + * @example + // limited options and other types + // the type will be PropType<'small' | 'medium' | number> + buildProp({ + type: [String, Number], + values: ['small', 'medium'], + validator: (val: unknown): val is number => typeof val === 'number', + } as const) + @link see more: https://github.com/element-plus/element-plus/pull/3341 + */ +export function buildProp< + T = never, + D extends BuildPropType = never, + R extends boolean = false, + V = never, + C = never, +>(option: BuildPropOption, key?: string): BuildPropReturn { + // filter native prop type and nested prop, e.g `null`, `undefined` (from `buildProps`) + if (!isObject(option) || !!option[propKey]) return option as any; + + const { values, required, default: defaultValue, type, validator } = option; + + const _validator = + values || validator + ? (val: unknown) => { + let valid = false; + let allowedValues: unknown[] = []; + + if (values) { + allowedValues = [...values, defaultValue]; + valid ||= allowedValues.includes(val); + } + if (validator) valid ||= validator(val); + + if (!valid && allowedValues.length > 0) { + const allowValuesText = [...new Set(allowedValues)] + .map((value) => JSON.stringify(value)) + .join(', '); + warn( + `Invalid prop: validation failed${ + key ? ` for prop "${key}"` : '' + }. Expected one of [${allowValuesText}], got value ${JSON.stringify(val)}.`, + ); + } + return valid; + } + : undefined; + + return { + type: + typeof type === 'object' && Object.getOwnPropertySymbols(type).includes(wrapperKey) + ? type[wrapperKey] + : type, + required: !!required, + default: defaultValue, + validator: _validator, + [propKey]: true, + } as unknown as BuildPropReturn; +} + +type NativePropType = [((...args: any) => any) | { new (...args: any): any } | undefined | null]; + +export const buildProps = < + O extends { + [K in keyof O]: O[K] extends BuildPropReturn + ? O[K] + : [O[K]] extends NativePropType + ? O[K] + : O[K] extends BuildPropOption + ? D extends BuildPropType + ? BuildPropOption + : never + : never; + }, +>( + props: O, +) => + fromPairs( + Object.entries(props).map(([key, option]) => [key, buildProp(option as any, key)]), + ) as unknown as { + [K in keyof O]: O[K] extends { [propKey]: boolean } + ? O[K] + : [O[K]] extends NativePropType + ? O[K] + : O[K] extends BuildPropOption< + infer T, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + infer _D, + infer R, + infer V, + infer C + > + ? BuildPropReturn + : never; + }; + +export const definePropType = (val: any) => ({ [wrapperKey]: val } as PropWrapper); + +export const keyOf = (arr: T) => Object.keys(arr) as Array; +export const mutable = >(val: T) => + val as Mutable; + +export const componentSize = ['large', 'medium', 'small', 'mini'] as const; diff --git a/src/utils/tree.ts b/src/utils/tree.ts new file mode 100644 index 0000000..17dcb3c --- /dev/null +++ b/src/utils/tree.ts @@ -0,0 +1,83 @@ +import { DataNode } from 'ant-design-vue/es/vc-tree/interface'; +import { map, pick } from 'lodash-es'; +import { array2tree } from '@axolo/tree-array'; + +export interface buildNodeOption { + labelField: string; + idKeyField: string; + valueField: string; + parentKeyField: string; + defaultValue?: string | object; + childrenKeyField: string; +} + +export function buildDataNode(data: any, options: buildNodeOption): DataNode[] { + const treeNodeData = map(data, (obj) => { + const tmpData = pick(obj, [ + options.labelField, + options.idKeyField, + options.valueField, + options.parentKeyField, + ]); + Object.keys(tmpData).forEach((e) => { + if (e === options.labelField) { + tmpData['title'] = tmpData[e]; + delete tmpData[e]; + } else if (e === options.valueField) { + tmpData['key'] = tmpData[e]; + if (e !== options.idKeyField && e !== options.parentKeyField) { + delete tmpData[e]; + } + } + }); + return tmpData; + }); + + const treeConv = array2tree(treeNodeData, { + idKey: options.idKeyField, + parentKey: options.parentKeyField, + childrenKey: options.childrenKeyField, + }); + + // add default label + if (options.defaultValue) { + treeConv.push(options.defaultValue); + } + return treeConv as DataNode[]; +} + +// buildTreeNode returns treeData for tree select from data +export function buildTreeNode(data: any, options: buildNodeOption): Recordable[] { + const treeNodeData = map(data, (obj) => { + const tmpData = pick(obj, [ + options.labelField, + options.idKeyField, + options.valueField, + options.parentKeyField, + ]); + Object.keys(tmpData).forEach((e) => { + if (e === options.labelField) { + tmpData['label'] = tmpData[e]; + delete tmpData[e]; + } else if (e === options.valueField) { + tmpData['value'] = tmpData[e]; + if (e !== options.idKeyField && e !== options.parentKeyField) { + delete tmpData[e]; + } + } + }); + return tmpData; + }); + + const treeConv = array2tree(treeNodeData, { + idKey: options.idKeyField, + parentKey: options.parentKeyField, + childrenKey: options.childrenKeyField, + }); + + // add default label + if (options.defaultValue) { + treeConv.push(options.defaultValue); + } + return treeConv as Recordable[]; +} diff --git a/src/utils/types.ts b/src/utils/types.ts new file mode 100644 index 0000000..4453ec4 --- /dev/null +++ b/src/utils/types.ts @@ -0,0 +1,42 @@ +// copy from element-plus + +import type { CSSProperties, Plugin } from 'vue'; + +type OptionalKeys> = { + [K in keyof T]: T extends Record ? never : K; +}[keyof T]; + +type RequiredKeys> = Exclude>; + +type MonoArgEmitter = (evt: K, arg?: T[K]) => void; + +type BiArgEmitter = (evt: K, arg: T[K]) => void; + +export type EventEmitter> = MonoArgEmitter> & + BiArgEmitter>; + +export type AnyFunction = (...args: any[]) => T; + +export type PartialReturnType unknown> = Partial>; + +export type SFCWithInstall = T & Plugin; + +export type Nullable = T | null; + +export type RefElement = Nullable; + +export type CustomizedHTMLElement = HTMLElement & T; + +export type Indexable = { + [key: string]: T; +}; + +export type Hash = Indexable; + +export type TimeoutHandle = ReturnType; + +export type ComponentSize = 'large' | 'medium' | 'small' | 'mini'; + +export type StyleValue = string | CSSProperties | Array; + +export type Mutable = { -readonly [P in keyof T]: T[P] }; diff --git a/src/utils/uuid.ts b/src/utils/uuid.ts new file mode 100644 index 0000000..548bcf3 --- /dev/null +++ b/src/utils/uuid.ts @@ -0,0 +1,28 @@ +const hexList: string[] = []; +for (let i = 0; i <= 15; i++) { + hexList[i] = i.toString(16); +} + +export function buildUUID(): string { + let uuid = ''; + for (let i = 1; i <= 36; i++) { + if (i === 9 || i === 14 || i === 19 || i === 24) { + uuid += '-'; + } else if (i === 15) { + uuid += 4; + } else if (i === 20) { + uuid += hexList[(Math.random() * 4) | 8]; + } else { + uuid += hexList[(Math.random() * 16) | 0]; + } + } + return uuid.replace(/-/g, ''); +} + +let unique = 0; +export function buildShortUUID(prefix = ''): string { + const time = Date.now(); + const random = Math.floor(Math.random() * 1000000000); + unique++; + return prefix + '_' + random + unique + String(time); +} diff --git a/src/views/.DS_Store b/src/views/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..4ba9e090350069e453c65be65374096ae1b92fba GIT binary patch literal 8196 zcmeI1KW-E;6vm%tHe^>&P^KXoE`X97EYTtg3W{7{vwz4&+0BfStX6a*PJp-o6s}VbwC~XFCF0b zLxqcD-^bQP`|3buj{t}r6x)P*oC9o|%E!Kst&6rP`gErUMNEb_I+$! zbj``Q=4AZH#-C7(9Ubi|D<{);QFC=b9f%#+L(vwE=!h=pBsjmDt1q&4Q4a>Ac|AfY zKW?8+-+p`?DkgtWG_#E_1jTzaryfo0_%m?SxI3qb{Eo1Cl~!eV68$aeBv(Qy_}ts0 zM=#*b8OY9PjJqS63%>HlbITX0vU~|;hA&bIzRqj*Z<`u;R>Q?5_$~#TdG{<xqCh2hh#xz;V|g0P+<8D_K0gZUGc2Ny42jSPj$-(W;}Uaq60B@Xo8xXJ zW`&-909~ZXuqAX!vPdVmXow*--H-#N>t~10|4;JY|8HnC?M59?2X3PSrZYGk9DvN9 zts_Q0Ygf32xHz${b + + + + + + +
    +
    头像(更新头像后,请刷新浏览器)
    + +
    +
    +
    + +
    + + + + diff --git a/src/views/basic/account/BindEmailModal.vue b/src/views/basic/account/BindEmailModal.vue new file mode 100644 index 0000000..25b6d07 --- /dev/null +++ b/src/views/basic/account/BindEmailModal.vue @@ -0,0 +1,145 @@ + + + + + \ No newline at end of file diff --git a/src/views/basic/account/BindPhoneModal.vue b/src/views/basic/account/BindPhoneModal.vue new file mode 100644 index 0000000..1dc6462 --- /dev/null +++ b/src/views/basic/account/BindPhoneModal.vue @@ -0,0 +1,146 @@ + + + + + \ No newline at end of file diff --git a/src/views/basic/account/MsgNotify.vue b/src/views/basic/account/MsgNotify.vue new file mode 100644 index 0000000..7d76d6f --- /dev/null +++ b/src/views/basic/account/MsgNotify.vue @@ -0,0 +1,75 @@ + + + diff --git a/src/views/basic/account/ResetPasswordModal.vue b/src/views/basic/account/ResetPasswordModal.vue new file mode 100644 index 0000000..4669f1f --- /dev/null +++ b/src/views/basic/account/ResetPasswordModal.vue @@ -0,0 +1,50 @@ + + + \ No newline at end of file diff --git a/src/views/basic/account/SecureSetting.vue b/src/views/basic/account/SecureSetting.vue new file mode 100644 index 0000000..66df47f --- /dev/null +++ b/src/views/basic/account/SecureSetting.vue @@ -0,0 +1,93 @@ + + + diff --git a/src/views/basic/account/data.ts b/src/views/basic/account/data.ts new file mode 100644 index 0000000..027e41c --- /dev/null +++ b/src/views/basic/account/data.ts @@ -0,0 +1,133 @@ +import { FormSchema } from '/@/components/Form/index'; + +export interface ListItem { + key: string; + title: string; + description: string; + extra?: string; + avatar?: string; + color?: string; +} + +// tab的list +export const settingList = [ + { + key: '1', + name: '基本设置', + component: 'BaseSetting', + }, + { + key: '2', + name: '安全设置', + component: 'SecureSetting', + }, + { + key: '4', + name: '新消息通知', + component: 'MsgNotify', + }, +]; + +// 基础设置 form +export const baseSetSchemas: FormSchema[] = [ + { + field: 'id', + component: 'Input', + ifShow: false, + }, + { + field: 'name', + component: 'Input', + label: '昵称', + colProps: { span: 18 }, + required: true, + }, + { + field: 'position', + component: 'Input', + label: '职位', + colProps: { span: 18 }, + }, + { + field: 'description', + component: 'InputTextArea', + label: '个人简介', + colProps: { span: 18 }, + }, +]; + +// 安全设置 list +export const secureSettingList: ListItem[] = [ + { + key: '1', + title: '账户密码', + description: '当前密码强度:中', + extra: '修改', + }, + { + key: '2', + title: '密保手机', + description: '已绑定手机:', + extra: '修改', + }, + { + key: '3', + title: '密保邮箱', + description: '已绑定邮箱:', + extra: '修改', + }, +]; + + +export const resetPasswordFormSchema: FormSchema[] = [ + { + field: 'id', + component: 'Input', + ifShow: false, + }, + { + field: 'userName', + component: 'Input', + ifShow: false, + }, + { + label: '原密码', + field: 'password', + component: 'InputPassword', + required: true, + rules: [ + { + required: true, + message: '请输入旧密码', + trigger: 'change', + }, + ], + }, + { + label: '新密码', + field: 'newPassword', + valueField: 'newPassword', + component: 'InputPassword', + required: true, + rules: [ + { + required: true, + message: '请输入新密码', + trigger: 'change', + }, + ], + }, + { + label: '确认密码', + field: 'confirmPassword', + component: 'InputPassword', + required: true, + rules: [ + { + required: true, + message: '请输入确认密码', + trigger: 'change', + } + ], + }, +] \ No newline at end of file diff --git a/src/views/basic/account/index.vue b/src/views/basic/account/index.vue new file mode 100644 index 0000000..6f15e89 --- /dev/null +++ b/src/views/basic/account/index.vue @@ -0,0 +1,59 @@ + + + + diff --git a/src/views/basic/customer/components/CustomerModal.vue b/src/views/basic/customer/components/CustomerModal.vue new file mode 100644 index 0000000..88316d2 --- /dev/null +++ b/src/views/basic/customer/components/CustomerModal.vue @@ -0,0 +1,101 @@ + + + \ No newline at end of file diff --git a/src/views/basic/customer/customer.data.ts b/src/views/basic/customer/customer.data.ts new file mode 100644 index 0000000..1a135e3 --- /dev/null +++ b/src/views/basic/customer/customer.data.ts @@ -0,0 +1,251 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import { h } from 'vue'; +import {Switch} from "ant-design-vue"; +import {useMessage} from "@/hooks/web/useMessage"; +import {useI18n} from "@/hooks/web/useI18n"; +import {updateCustomerStatus} from "@/api/basic/customer"; + +const { t } = useI18n(); + +export const columns: BasicColumn[] = [ + { + title: '客户名称', + dataIndex: 'customerName', + width: 180, + }, + { + title: '联系人', + dataIndex: 'contact', + width: 80, + }, + { + title: '手机号', + dataIndex: 'phoneNumber', + width: 120, + }, + { + title: '电子邮箱', + dataIndex: 'email', + width: 120, + }, + { + title: '状态', + dataIndex: 'status', + width: 100, + customRender: ({ record }) => { + if (!Reflect.has(record, 'pendingStatus')) { + record.pendingStatus = false; + } + return h(Switch, { + checked: record.status === 0, + checkedChildren: t('common.on'), + unCheckedChildren: t('common.off'), + loading: record.pendingStatus, + onChange(checked, _) { + const {createMessage} = useMessage(); + if (record.id == 1) { + createMessage.warn(t('common.notice')); + return; + } + record.pendingStatus = true; + const newStatus = checked ? 0 : 1; + updateCustomerStatus([record.id], newStatus ) + .then(() => { + record.status = newStatus; + }) + .finally(() => { + record.pendingStatus = false; + }); + }, + }); + } + }, + { + title: '累计应收账款', + dataIndex: 'totalAccountReceivable', + width: 90, + }, + { + title: '税率(%)', + dataIndex: 'taxRate', + width: 80, + }, + { + title: '排序', + dataIndex: 'sort', + width: 80, + }, + { + title: '创建时间', + dataIndex: 'createTime', + width: 150, + } +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '客户名称', + field: 'customerName', + component: 'Input', + colProps: { span: 5 }, + }, + { + label: '手机号码', + field: 'phoneNumber', + component: 'Input', + colProps: { span: 5 }, + }, + { + field: '[startDate, endDate]', + label: '时间', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { span: 7 }, + }, +] + +export const formSchema: FormSchema[] = [ + { + label: '客户名称', + field: 'customerName', + helpMessage: '可以是个人,如果是个人可以不用填写联系人', + component: 'Input', + colProps: { + span: 11, + }, + required: true, + }, + { + label: '联系人', + field: 'contact', + component: 'Input', + colProps: { + span: 11, + }, + }, + { + label: '手机号码', + field: 'phoneNumber', + component: 'Input', + colProps: { + span: 11, + }, + required: true, + }, + { + label: '电子邮箱', + field: 'email', + component: 'Input', + colProps: { + span: 11, + }, + }, + { + label: '传真', + field: 'fax', + component: 'Input', + colProps: { + span: 11, + }, + }, + { + label: '地址', + field: 'address', + component: 'InputTextArea', + colProps: { + span: 11, + }, + }, + { + label: '备注', + field: 'remark', + component: 'InputTextArea', + colProps: { + span: 11, + }, + }, + { + field: '', + component: 'Divider', + label: '应收账款信息', + colProps: { + span: 22, + }, + }, + { + label: '一季度收款', + field: 'firstQuarterAccountReceivable', + component: 'InputNumber', + colProps: { + span: 11, + }, + }, + { + label: '二季度收款', + field: 'secondQuarterAccountReceivable', + component: 'InputNumber', + colProps: { + span: 11, + }, + }, + { + label: '三季度收款', + field: 'thirdQuarterAccountReceivable', + component: 'InputNumber', + colProps: { + span: 11, + }, + }, + { + label: '四季度收款', + field: 'fourthQuarterAccountReceivable', + component: 'InputNumber', + colProps: { + span: 11, + }, + }, + { + field: '', + component: 'Divider', + label: '账户信息', + colProps: { + span: 22, + }, + }, + { + label: '纳税人识别号', + field: 'taxNumber', + component: 'Input', + colProps: { + span: 11, + }, + }, + { + label: '税率(%)', + field: 'taxRate', + component: 'InputNumber', + colProps: { + span: 11, + }, + }, + { + label: '开户行', + field: 'bankName', + component: 'Input', + colProps: { + span: 11, + }, + }, + { + label: '银行账号', + field: 'accountNumber', + component: 'InputNumber', + colProps: { + span: 11, + }, + } +] \ No newline at end of file diff --git a/src/views/basic/customer/index.vue b/src/views/basic/customer/index.vue new file mode 100644 index 0000000..bbfc35b --- /dev/null +++ b/src/views/basic/customer/index.vue @@ -0,0 +1,194 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/basic/income-expense/components/AddEditModal.vue b/src/views/basic/income-expense/components/AddEditModal.vue new file mode 100644 index 0000000..b6d75b0 --- /dev/null +++ b/src/views/basic/income-expense/components/AddEditModal.vue @@ -0,0 +1,76 @@ + + + \ No newline at end of file diff --git a/src/views/basic/income-expense/incomeExpense.data.ts b/src/views/basic/income-expense/incomeExpense.data.ts new file mode 100644 index 0000000..ec62d99 --- /dev/null +++ b/src/views/basic/income-expense/incomeExpense.data.ts @@ -0,0 +1,93 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; + +export const columns: BasicColumn[] = [ + { + title: '名称', + dataIndex: 'name', + width: 90, + }, + { + title: '类型', + dataIndex: 'type', + width: 120, + }, + { + title: '备注', + dataIndex: 'remark', + width: 200, + }, + { + title: '排序', + dataIndex: 'sort', + width: 80, + }, + { + title: '状态', + dataIndex: 'status', + width: 80, + }, + { + title: '创建时间', + dataIndex: 'createTime', + width: 150, + } +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '名称', + field: 'name', + component: 'Input', + colProps: { span: 7 }, + }, + { + label: '类型', + field: 'type', + component: 'Select', + colProps: { span: 7 }, + componentProps: { + options: [ + { label: '收入', value: '收入', key: 0 }, + { label: '支出', value: '支出', key: 1 }, + ], + }, + }, + { + label: '备注', + field: 'remark', + component: 'Input', + colProps: { span: 7 }, + }, +] + +export const formSchema: FormSchema[] = [ + { + label: '名称', + field: 'name', + component: 'Input', + required: true, + }, + { + label: '类型', + field: 'type', + component: 'Select', + componentProps: { + options: [ + { label: '收入', value: '收入', key: 0 }, + { label: '支出', value: '支出', key: 1 }, + ], + }, + required: true, + }, + { + label: '排序', + field: 'sort', + component: 'InputNumber', + }, + { + label: '备注', + field: 'remark', + component: 'InputTextArea', + } +] \ No newline at end of file diff --git a/src/views/basic/income-expense/index.vue b/src/views/basic/income-expense/index.vue new file mode 100644 index 0000000..7ee62a8 --- /dev/null +++ b/src/views/basic/income-expense/index.vue @@ -0,0 +1,153 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/basic/member/components/MemberModal.vue b/src/views/basic/member/components/MemberModal.vue new file mode 100644 index 0000000..18a4cad --- /dev/null +++ b/src/views/basic/member/components/MemberModal.vue @@ -0,0 +1,78 @@ + + + \ No newline at end of file diff --git a/src/views/basic/member/index.vue b/src/views/basic/member/index.vue new file mode 100644 index 0000000..70b4d07 --- /dev/null +++ b/src/views/basic/member/index.vue @@ -0,0 +1,193 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/basic/member/member.data.ts b/src/views/basic/member/member.data.ts new file mode 100644 index 0000000..dfde6b6 --- /dev/null +++ b/src/views/basic/member/member.data.ts @@ -0,0 +1,170 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import { h } from 'vue'; +import {Switch} from "ant-design-vue"; +import {useMessage} from "@/hooks/web/useMessage"; +import {useI18n} from "@/hooks/web/useI18n"; +import {updateMemberStatus} from "@/api/basic/member"; + +const { t } = useI18n(); + +export const columns: BasicColumn[] = [ + { + title: '会员卡号', + dataIndex: 'memberNumber', + width: 180, + }, + { + title: '会员名称', + dataIndex: 'memberName', + width: 80, + }, + { + title: '手机号', + dataIndex: 'phoneNumber', + width: 120, + }, + { + title: '电子邮箱', + dataIndex: 'email', + width: 120, + }, + { + title: '预付款', + dataIndex: 'advancePayment', + width: 90, + }, + { + title: '状态', + dataIndex: 'status', + width: 100, + customRender: ({ record }) => { + if (!Reflect.has(record, 'pendingStatus')) { + record.pendingStatus = false; + } + return h(Switch, { + checked: record.status === 0, + checkedChildren: t('common.on'), + unCheckedChildren: t('common.off'), + loading: record.pendingStatus, + onChange(checked, _) { + const {createMessage} = useMessage(); + if (record.id == 1) { + createMessage.warn(t('common.notice')); + return; + } + record.pendingStatus = true; + const newStatus = checked ? 0 : 1; + updateMemberStatus([record.id], newStatus ) + .then(() => { + record.status = newStatus; + }) + .finally(() => { + record.pendingStatus = false; + }); + }, + }); + } + }, + { + title: '备注', + dataIndex: 'remark', + width: 80, + }, + { + title: '排序', + dataIndex: 'sort', + width: 80, + }, + { + title: '创建时间', + dataIndex: 'createTime', + width: 150, + } +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '会员卡号', + field: 'memberNumber', + component: 'Input', + colProps: { span: 5 }, + }, + { + label: '手机号码', + field: 'phoneNumber', + component: 'Input', + colProps: { span: 5 }, + }, + { + field: '[startDate, endDate]', + label: '时间', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { span: 7 }, + }, +] + +export const formSchema: FormSchema[] = [ + { + label: '会员卡号', + field: 'memberNumber', + component: 'Input', + colProps: { + span: 11, + }, + required: true, + }, + { + label: '会员名称', + field: 'memberName', + component: 'Input', + colProps: { + span: 11, + }, + required: true, + }, + { + label: '手机号码', + field: 'phoneNumber', + component: 'Input', + colProps: { + span: 11, + }, + }, + { + label: '电子邮箱', + field: 'email', + component: 'Input', + colProps: { + span: 11, + }, + }, + { + label: '预付款', + field: 'advancePayment', + component: 'InputNumber', + colProps: { + span: 11, + } + }, + { + label: '备注', + field: 'remark', + component: 'InputTextArea', + colProps: { + span: 11, + }, + }, + { + label: '排序', + field: 'sort', + component: 'InputNumber', + colProps: { + span: 11, + } + } +] \ No newline at end of file diff --git a/src/views/basic/operator/components/OperatorModal.vue b/src/views/basic/operator/components/OperatorModal.vue new file mode 100644 index 0000000..2293a07 --- /dev/null +++ b/src/views/basic/operator/components/OperatorModal.vue @@ -0,0 +1,76 @@ + + + \ No newline at end of file diff --git a/src/views/basic/operator/index.vue b/src/views/basic/operator/index.vue new file mode 100644 index 0000000..df4a6be --- /dev/null +++ b/src/views/basic/operator/index.vue @@ -0,0 +1,147 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/basic/operator/operator.data.ts b/src/views/basic/operator/operator.data.ts new file mode 100644 index 0000000..e246433 --- /dev/null +++ b/src/views/basic/operator/operator.data.ts @@ -0,0 +1,118 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import { h } from 'vue'; +import {Switch} from "ant-design-vue"; +import {useMessage} from "@/hooks/web/useMessage"; +import {useI18n} from "@/hooks/web/useI18n"; +import {updateOperatorStatus} from "@/api/basic/operator"; + +const { t } = useI18n(); + +export const columns: BasicColumn[] = [ + { + title: '姓名', + dataIndex: 'name', + width: 90, + }, + { + title: '类型', + dataIndex: 'type', + width: 120, + }, + { + title: '状态', + dataIndex: 'status', + width: 100, + customRender: ({ record }) => { + if (!Reflect.has(record, 'pendingStatus')) { + record.pendingStatus = false; + } + return h(Switch, { + checked: record.status === 0, + checkedChildren: t('common.on'), + unCheckedChildren: t('common.off'), + loading: record.pendingStatus, + onChange(checked, _) { + const {createMessage} = useMessage(); + if (record.id == 1) { + createMessage.warn(t('common.notice')); + return; + } + record.pendingStatus = true; + const newStatus = checked ? 0 : 1; + updateOperatorStatus([record.id], newStatus ) + .then(() => { + record.status = newStatus; + }) + .finally(() => { + record.pendingStatus = false; + }); + }, + }); + } + }, + { + title: '排序', + dataIndex: 'sort', + width: 80, + }, + { + title: '创建时间', + dataIndex: 'createTime', + width: 150, + } +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '姓名', + field: 'name', + component: 'Input', + colProps: { span: 5 }, + }, + { + label: '类型', + field: 'type', + component: 'Select', + colProps: { span: 5 }, + componentProps: { + options: [ + { label: '业务员', value: '业务员', key: 0 }, + { label: '财务员', value: '财务员', key: 1 }, + { label: '销售员', value: '销售员', key: 2 }, + ], + }, + } +] + +export const formSchema: FormSchema[] = [ + { + label: '姓名', + field: 'name', + component: 'Input', + required: true, + }, + { + label: '类型', + field: 'type', + component: 'Select', + componentProps: { + options: [ + { label: '业务员', value: '业务员', key: 0 }, + { label: '财务员', value: '财务员', key: 1 }, + { label: '销售员', value: '销售员', key: 2 }, + ], + }, + required: true, + }, + { + label: '排序', + field: 'sort', + component: 'InputNumber', + }, + { + label: '备注', + field: 'remark', + component: 'InputTextArea', + } +] \ No newline at end of file diff --git a/src/views/basic/settlement-account/components/FinancialAccountModal.vue b/src/views/basic/settlement-account/components/FinancialAccountModal.vue new file mode 100644 index 0000000..d2d1126 --- /dev/null +++ b/src/views/basic/settlement-account/components/FinancialAccountModal.vue @@ -0,0 +1,78 @@ + + + \ No newline at end of file diff --git a/src/views/basic/settlement-account/components/MultipleAccountsModal.vue b/src/views/basic/settlement-account/components/MultipleAccountsModal.vue new file mode 100644 index 0000000..1eff1f3 --- /dev/null +++ b/src/views/basic/settlement-account/components/MultipleAccountsModal.vue @@ -0,0 +1,152 @@ + + \ No newline at end of file diff --git a/src/views/basic/settlement-account/financialAccount.data.ts b/src/views/basic/settlement-account/financialAccount.data.ts new file mode 100644 index 0000000..78c3988 --- /dev/null +++ b/src/views/basic/settlement-account/financialAccount.data.ts @@ -0,0 +1,147 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {h} from 'vue'; +import {Switch} from "ant-design-vue"; +import {useMessage} from "@/hooks/web/useMessage"; +import {useI18n} from "@/hooks/web/useI18n"; +import {updateAccountStatus} from "@/api/financial/account"; + +const { t } = useI18n(); + +export const columns: BasicColumn[] = [ + { + title: '账户编号', + dataIndex: 'accountNumber', + width: 90, + }, + { + title: '账户名称', + dataIndex: 'accountName', + width: 120, + }, + { + title: '期初金额', + dataIndex: 'initialAmount', + width: 120, + }, + { + title: '当前余额', + dataIndex: 'currentAmount', + width: 120, + }, + { + title: '状态', + dataIndex: 'status', + width: 100, + customRender: ({ record }) => { + if (!Reflect.has(record, 'pendingStatus')) { + record.pendingStatus = false; + } + return h(Switch, { + checked: record.status === 0, + checkedChildren: t('common.on'), + unCheckedChildren: t('common.off'), + loading: record.pendingStatus, + onChange(checked, _) { + const {createMessage} = useMessage(); + if (record.id == 1) { + createMessage.warn(t('common.notice')); + return; + } + record.pendingStatus = true; + const newStatus = checked ? 0 : 1; + updateAccountStatus([record.id], newStatus ) + .then(() => { + record.status = newStatus; + }) + .finally(() => { + record.pendingStatus = false; + }); + }, + }); + } + }, + { + title: '排序', + dataIndex: 'sort', + width: 80, + }, + { + title: '是否默认账户', + dataIndex: 'isDefault', + width: 80, + }, + { + title: '创建时间', + dataIndex: 'createTime', + width: 150, + } +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '账户编号', + field: 'accountNumber', + component: 'Input', + colProps: { span: 5 }, + }, + { + label: '账户名称', + field: 'accountName', + component: 'Input', + colProps: { span: 5 }, + } +] + +export const formSchema: FormSchema[] = [ + { + label: '账户名称', + field: 'accountName', + component: 'Input', + required: true, + }, + { + label: '账户编号', + field: 'accountNumber', + component: 'Input', + }, + { + label: '期初金额', + field: 'initialAmount', + component: 'InputNumber', + }, + { + label: '当前余额', + field: 'currentAmount', + component: 'InputNumber', + }, + { + label: '默认账户', + field: 'isDefault', + helpMessage: '只允许有一个默认账户,如果选择是,之前的默认账户将会变成非默认账户', + component: 'RadioGroup', + defaultValue: 0, + componentProps: { + options: [ + { + label: '不是', + value: 0, + }, + { + label: '是', + value: 1, + }, + ], + }, + }, + { + label: '备注', + field: 'remark', + component: 'InputTextArea', + }, + { + label: '排序', + field: 'sort', + component: 'InputNumber', + } +] \ No newline at end of file diff --git a/src/views/basic/settlement-account/index.vue b/src/views/basic/settlement-account/index.vue new file mode 100644 index 0000000..94c5484 --- /dev/null +++ b/src/views/basic/settlement-account/index.vue @@ -0,0 +1,153 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/basic/supplier/components/SupplierModal.vue b/src/views/basic/supplier/components/SupplierModal.vue new file mode 100644 index 0000000..07bcf03 --- /dev/null +++ b/src/views/basic/supplier/components/SupplierModal.vue @@ -0,0 +1,102 @@ + + + \ No newline at end of file diff --git a/src/views/basic/supplier/index.vue b/src/views/basic/supplier/index.vue new file mode 100644 index 0000000..d86e370 --- /dev/null +++ b/src/views/basic/supplier/index.vue @@ -0,0 +1,196 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/basic/supplier/supplier.data.ts b/src/views/basic/supplier/supplier.data.ts new file mode 100644 index 0000000..888325e --- /dev/null +++ b/src/views/basic/supplier/supplier.data.ts @@ -0,0 +1,261 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import { h } from 'vue'; +import {Switch} from "ant-design-vue"; +import {useMessage} from "@/hooks/web/useMessage"; +import {useI18n} from "@/hooks/web/useI18n"; +import {updateSupplierStatus} from "@/api/basic/supplier"; + +const { t } = useI18n(); + +export const columns: BasicColumn[] = [ + { + title: '名称', + dataIndex: 'supplierName', + width: 180, + }, + { + title: '联系人', + dataIndex: 'contact', + width: 80, + }, + { + title: '手机号', + dataIndex: 'phoneNumber', + width: 120, + }, + { + title: '电子邮箱', + dataIndex: 'email', + width: 120, + }, + { + title: '状态', + dataIndex: 'status', + width: 100, + customRender: ({ record }) => { + if (!Reflect.has(record, 'pendingStatus')) { + record.pendingStatus = false; + } + return h(Switch, { + checked: record.status === 0, + checkedChildren: t('common.on'), + unCheckedChildren: t('common.off'), + loading: record.pendingStatus, + onChange(checked, _) { + const {createMessage} = useMessage(); + if (record.id == 1) { + createMessage.warn(t('common.notice')); + return; + } + record.pendingStatus = true; + const newStatus = checked ? 0 : 1; + updateSupplierStatus({ids: [record.id], status: newStatus} ) + .then(() => { + record.status = newStatus; + }) + .finally(() => { + record.pendingStatus = false; + }); + }, + }); + } + }, + { + title: '累计应付账款', + dataIndex: 'totalAccountPayment', + width: 90, + }, + { + title: '税率(%)', + dataIndex: 'taxRate', + width: 80, + }, + { + title: '排序', + dataIndex: 'sort', + width: 80, + }, + { + title: '创建时间', + dataIndex: 'createTime', + width: 150, + } +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '名称', + field: 'supplierName', + component: 'Input', + colProps: { span: 5 }, + }, + { + label: '联系电话', + field: 'contactNumber', + component: 'Input', + colProps: { span: 5 }, + }, + { + field: '[startDate, endDate]', + label: '时间', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { span: 7 }, + }, +] + +export const formSchema: FormSchema[] = [ + { + label: '名称', + field: 'supplierName', + helpMessage: '供应商的名字, 也可以是个人', + component: 'Input', + colProps: { + span: 11, + }, + required: true, + }, + { + label: '联系人', + field: 'contact', + component: 'Input', + colProps: { + span: 11, + }, + required: true, + }, + { + label: '手机号码', + field: 'phoneNumber', + component: 'Input', + colProps: { + span: 11, + }, + required: true, + }, + { + label: '联系电话', + helpMessage: '座机号码 (010/021之类)', + field: 'contactNumber', + component: 'Input', + colProps: { + span: 11, + }, + }, + { + label: '电子邮箱', + field: 'email', + component: 'Input', + colProps: { + span: 11, + }, + }, + { + label: '传真', + field: 'fax', + component: 'Input', + colProps: { + span: 11, + }, + }, + { + label: '地址', + field: 'address', + component: 'InputTextArea', + colProps: { + span: 11, + }, + }, + { + label: '备注', + field: 'remark', + component: 'InputTextArea', + colProps: { + span: 11, + }, + }, + { + field: '', + component: 'Divider', + label: '应付账款信息', + colProps: { + span: 22, + }, + }, + { + label: '一季度付款', + field: 'firstQuarterAccountPayment', + component: 'InputNumber', + colProps: { + span: 11, + }, + }, + { + label: '二季度付款', + field: 'secondQuarterAccountPayment', + component: 'InputNumber', + colProps: { + span: 11, + }, + }, + { + label: '三季度付款', + field: 'thirdQuarterAccountPayment', + component: 'InputNumber', + colProps: { + span: 11, + }, + }, + { + label: '四季度付款', + field: 'fourthQuarterAccountPayment', + component: 'InputNumber', + colProps: { + span: 11, + }, + }, + { + field: '', + component: 'Divider', + label: '账户信息', + colProps: { + span: 22, + }, + }, + { + label: '纳税人识别号', + field: 'taxNumber', + component: 'Input', + colProps: { + span: 11, + }, + }, + { + label: '税率(%)', + field: 'taxRate', + component: 'InputNumber', + colProps: { + span: 11, + }, + }, + { + label: '开户行', + field: 'bankName', + component: 'Input', + colProps: { + span: 11, + }, + }, + { + label: '银行账号', + field: 'accountNumber', + component: 'InputNumber', + colProps: { + span: 11, + }, + } +] \ No newline at end of file diff --git a/src/views/basic/warehouse/components/WarehouseModal.vue b/src/views/basic/warehouse/components/WarehouseModal.vue new file mode 100644 index 0000000..371e1bc --- /dev/null +++ b/src/views/basic/warehouse/components/WarehouseModal.vue @@ -0,0 +1,80 @@ + + + \ No newline at end of file diff --git a/src/views/basic/warehouse/index.vue b/src/views/basic/warehouse/index.vue new file mode 100644 index 0000000..66ff69e --- /dev/null +++ b/src/views/basic/warehouse/index.vue @@ -0,0 +1,153 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/basic/warehouse/warehouse.data.ts b/src/views/basic/warehouse/warehouse.data.ts new file mode 100644 index 0000000..ab299ac --- /dev/null +++ b/src/views/basic/warehouse/warehouse.data.ts @@ -0,0 +1,165 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import { h } from 'vue'; +import {Switch} from "ant-design-vue"; +import {useMessage} from "@/hooks/web/useMessage"; +import {useI18n} from "@/hooks/web/useI18n"; +import {updateWarehouseStatus} from "@/api/basic/warehouse"; +import {getTenantUserList} from "@/api/sys/user"; + +const { t } = useI18n(); + +export const columns: BasicColumn[] = [ + { + title: '仓库名称', + dataIndex: 'warehouseName', + width: 180, + }, + { + title: '仓库地址', + dataIndex: 'address', + width: 80, + }, + { + title: '仓储费', + dataIndex: 'price', + width: 120, + }, + { + title: '搬运费', + dataIndex: 'truckage', + width: 120, + }, + { + title: '负责人', + dataIndex: 'warehouseManagerName', + width: 90, + }, + { + title: '状态', + dataIndex: 'status', + width: 100, + customRender: ({ record }) => { + if (!Reflect.has(record, 'pendingStatus')) { + record.pendingStatus = false; + } + return h(Switch, { + checked: record.status === 0, + checkedChildren: t('common.on'), + unCheckedChildren: t('common.off'), + loading: record.pendingStatus, + onChange(checked, _) { + const {createMessage} = useMessage(); + if (record.id == 1) { + createMessage.warn(t('common.notice')); + return; + } + record.pendingStatus = true; + const newStatus = checked ? 0 : 1; + updateWarehouseStatus([record.id], newStatus ) + .then(() => { + record.status = newStatus; + }) + .finally(() => { + record.pendingStatus = false; + }); + }, + }); + } + }, + { + title: '默认仓库', + dataIndex: 'isDefault', + width: 80, + }, + { + title: '排序', + dataIndex: 'sort', + width: 80, + }, + { + title: '创建时间', + dataIndex: 'createTime', + width: 150, + } +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '仓库名称', + field: 'warehouseName', + component: 'Input', + colProps: { span: 5 }, + }, + { + label: '备注', + field: 'remark', + component: 'Input', + colProps: { span: 5 }, + } +] + +export const formSchema: FormSchema[] = [ + { + label: '仓库名称', + field: 'warehouseName', + component: 'Input', + required: true, + }, + { + label: '仓库地址', + field: 'address', + component: 'Input', + }, + { + label: '仓储费', + field: 'price', + component: 'InputNumber', + }, + { + label: '搬运费', + field: 'truckage', + component: 'InputNumber', + }, + { + label: '默认仓库', + field: 'isDefault', + helpMessage: '只允许有一个默认仓库,如果选择是,之前的默认仓库将会变成非默认仓库', + component: 'RadioGroup', + defaultValue: 0, + componentProps: { + options: [ + { + label: '不是', + value: 0, + }, + { + label: '是', + value: 1, + }, + ], + }, + }, + { + field: 'warehouseManager', + label: '负责人', + component: 'ApiSelect', + helpMessage: ['用户列表中的用户'], + componentProps: { + api: getTenantUserList, + resultField: 'data', + labelField: 'name', + valueField: 'id', + }, + }, + { + label: '备注', + field: 'remark', + component: 'InputTextArea', + }, + { + label: '排序', + field: 'sort', + component: 'InputNumber', + } +] \ No newline at end of file diff --git a/src/views/dashboard/analysis/components/GrowCard.vue b/src/views/dashboard/analysis/components/GrowCard.vue new file mode 100644 index 0000000..7e0df45 --- /dev/null +++ b/src/views/dashboard/analysis/components/GrowCard.vue @@ -0,0 +1,50 @@ + + diff --git a/src/views/dashboard/analysis/components/GrowCardFour.vue b/src/views/dashboard/analysis/components/GrowCardFour.vue new file mode 100644 index 0000000..0b51621 --- /dev/null +++ b/src/views/dashboard/analysis/components/GrowCardFour.vue @@ -0,0 +1,39 @@ + + diff --git a/src/views/dashboard/analysis/components/GrowCardThree.vue b/src/views/dashboard/analysis/components/GrowCardThree.vue new file mode 100644 index 0000000..e5fe166 --- /dev/null +++ b/src/views/dashboard/analysis/components/GrowCardThree.vue @@ -0,0 +1,39 @@ + + diff --git a/src/views/dashboard/analysis/components/GrowCardTwo.vue b/src/views/dashboard/analysis/components/GrowCardTwo.vue new file mode 100644 index 0000000..b896b65 --- /dev/null +++ b/src/views/dashboard/analysis/components/GrowCardTwo.vue @@ -0,0 +1,39 @@ + + diff --git a/src/views/dashboard/analysis/components/SalesProductPie.vue b/src/views/dashboard/analysis/components/SalesProductPie.vue new file mode 100644 index 0000000..f08fd7f --- /dev/null +++ b/src/views/dashboard/analysis/components/SalesProductPie.vue @@ -0,0 +1,63 @@ + + diff --git a/src/views/dashboard/analysis/components/SiteAnalysis.vue b/src/views/dashboard/analysis/components/SiteAnalysis.vue new file mode 100644 index 0000000..d105be6 --- /dev/null +++ b/src/views/dashboard/analysis/components/SiteAnalysis.vue @@ -0,0 +1,38 @@ + + diff --git a/src/views/dashboard/analysis/components/VisitAnalysis.vue b/src/views/dashboard/analysis/components/VisitAnalysis.vue new file mode 100644 index 0000000..2f4f7a5 --- /dev/null +++ b/src/views/dashboard/analysis/components/VisitAnalysis.vue @@ -0,0 +1,89 @@ + + + diff --git a/src/views/dashboard/analysis/components/VisitAnalysisBar.vue b/src/views/dashboard/analysis/components/VisitAnalysisBar.vue new file mode 100644 index 0000000..956b691 --- /dev/null +++ b/src/views/dashboard/analysis/components/VisitAnalysisBar.vue @@ -0,0 +1,46 @@ + + + diff --git a/src/views/dashboard/analysis/components/VisitRadar.vue b/src/views/dashboard/analysis/components/VisitRadar.vue new file mode 100644 index 0000000..beb66bf --- /dev/null +++ b/src/views/dashboard/analysis/components/VisitRadar.vue @@ -0,0 +1,62 @@ + + diff --git a/src/views/dashboard/analysis/components/VisitSource.vue b/src/views/dashboard/analysis/components/VisitSource.vue new file mode 100644 index 0000000..13fe4fc --- /dev/null +++ b/src/views/dashboard/analysis/components/VisitSource.vue @@ -0,0 +1,63 @@ + + diff --git a/src/views/dashboard/analysis/components/props.ts b/src/views/dashboard/analysis/components/props.ts new file mode 100644 index 0000000..8643650 --- /dev/null +++ b/src/views/dashboard/analysis/components/props.ts @@ -0,0 +1,16 @@ +import { PropType } from 'vue'; + +export interface BasicProps { + width: string; + height: string; +} +export const basicProps = { + width: { + type: String as PropType, + default: '100%', + }, + height: { + type: String as PropType, + default: '280px', + }, +}; diff --git a/src/views/dashboard/analysis/data.ts b/src/views/dashboard/analysis/data.ts new file mode 100644 index 0000000..bdcf37e --- /dev/null +++ b/src/views/dashboard/analysis/data.ts @@ -0,0 +1,141 @@ +import {ref} from "vue"; + +export interface GrowCardItem { + icon: string; + dataIndex: string; + title: string; + value: number; + total: number; + color: string; + action: string; +} + +export const growCardList: GrowCardItem[] = [ + { + title: '今日零售', + dataIndex: 'todayRetailSales', + icon: 'visit-count|svg', + value: 0, + total: 0, + color: 'green', + action: '今日', + }, + { + title: '今日销售', + dataIndex: 'todaySales', + icon: 'visit-count|svg', + value: 0, + total: 0, + color: 'green', + action: '今日', + }, + { + title: '今日采购', + dataIndex: 'todayPurchase', + icon: 'visit-count|svg', + value: 0, + total: 0, + color: 'green', + action: '今日', + }, +]; + +export const growCardTwoList: GrowCardItem[] = [ + { + title: '昨日零售', + dataIndex: 'yesterdayRetailSales', + icon: 'visit-count|svg', + value: 0, + total: 0, + color: 'blue', + action: '昨日', + }, + { + title: '昨日销售', + dataIndex: 'yesterdaySales', + icon: 'total-sales|svg', + value: 0, + total: 0, + color: 'blue', + action: '昨日', + }, + { + title: '昨日采购', + dataIndex: 'yesterdayPurchase', + icon: 'download-count|svg', + value: 0, + total: 0, + color: 'blue', + action: '昨日', + }, +]; + +export const growCardThreeList: GrowCardItem[] = [ + { + title: '本月累计零售', + dataIndex: 'monthRetailSales', + icon: 'total-sales|svg', + value: 0, + total: 0, + color: 'orange', + action: '本月', + }, + { + title: '本月累计销售', + dataIndex: 'monthSales', + icon: 'total-sales|svg', + value: 0, + total: 0, + color: 'orange', + action: '本月', + }, + { + title: '本月累计采购', + dataIndex: 'monthPurchase', + icon: 'total-sales|svg', + value: 0, + total: 0, + color: 'orange', + action: '本月', + }, +]; + +export const growCardFourList: GrowCardItem[] = [ + { + title: '今年累计零售', + dataIndex: 'yearRetailSales', + icon: 'transaction|svg', + value: 0, + total: 0, + color: 'purple', + action: '今年', + }, + { + title: '今年累计销售', + dataIndex: 'yearSales', + icon: 'transaction|svg', + value: 0, + total: 0, + color: 'purple', + action: '今年', + }, + { + title: '今年累计采购', + dataIndex: 'yearPurchase', + icon: 'transaction|svg', + value: 0, + total: 0, + color: 'purple', + action: '今年', + }, +]; + +export interface XyAxisData { + xaxisData: string; + yaxisData: number; +} +// 定义图表数据类型 用于图表数据的展示 +export const retailAxisStatisticalData: XyAxisData[] = ref(); +export const saleAxisStatisticalData: XyAxisData[] = ref(); +export const purchaseAxisStatisticalData: XyAxisData[] = ref(); + diff --git a/src/views/dashboard/analysis/index.vue b/src/views/dashboard/analysis/index.vue new file mode 100644 index 0000000..8445596 --- /dev/null +++ b/src/views/dashboard/analysis/index.vue @@ -0,0 +1,81 @@ + + diff --git a/src/views/dashboard/workbench/components/DynamicInfo.vue b/src/views/dashboard/workbench/components/DynamicInfo.vue new file mode 100644 index 0000000..9947817 --- /dev/null +++ b/src/views/dashboard/workbench/components/DynamicInfo.vue @@ -0,0 +1,31 @@ + + diff --git a/src/views/dashboard/workbench/components/ProjectCard.vue b/src/views/dashboard/workbench/components/ProjectCard.vue new file mode 100644 index 0000000..c7260df --- /dev/null +++ b/src/views/dashboard/workbench/components/ProjectCard.vue @@ -0,0 +1,32 @@ + + diff --git a/src/views/dashboard/workbench/components/QuickNav.vue b/src/views/dashboard/workbench/components/QuickNav.vue new file mode 100644 index 0000000..a589601 --- /dev/null +++ b/src/views/dashboard/workbench/components/QuickNav.vue @@ -0,0 +1,15 @@ + + diff --git a/src/views/dashboard/workbench/components/SaleRadar.vue b/src/views/dashboard/workbench/components/SaleRadar.vue new file mode 100644 index 0000000..3d176f2 --- /dev/null +++ b/src/views/dashboard/workbench/components/SaleRadar.vue @@ -0,0 +1,94 @@ + + diff --git a/src/views/dashboard/workbench/components/WorkbenchHeader.vue b/src/views/dashboard/workbench/components/WorkbenchHeader.vue new file mode 100644 index 0000000..2e50647 --- /dev/null +++ b/src/views/dashboard/workbench/components/WorkbenchHeader.vue @@ -0,0 +1,33 @@ + + diff --git a/src/views/dashboard/workbench/components/data.ts b/src/views/dashboard/workbench/components/data.ts new file mode 100644 index 0000000..47da637 --- /dev/null +++ b/src/views/dashboard/workbench/components/data.ts @@ -0,0 +1,144 @@ +interface GroupItem { + title: string; + icon: string; + color: string; + desc: string; + date: string; + group: string; +} + +interface NavItem { + title: string; + icon: string; + color: string; +} + +interface DynamicInfoItem { + avatar: string; + name: string; + date: string; + desc: string; +} + +export const navItems: NavItem[] = [ + { + title: '首页', + icon: 'ion:home-outline', + color: '#1fdaca', + }, + { + title: '仪表盘', + icon: 'ion:grid-outline', + color: '#bf0c2c', + }, + { + title: 'OA内部办公系统', + icon: 'ion:layers-outline', + color: '#e18525', + }, + { + title: '系统管理', + icon: 'ion:settings-outline', + color: '#3fb27f', + }, + { + title: '权限管理', + icon: 'ion:key-outline', + color: '#4daf1bc9', + }, + { + title: '报表查询', + icon: 'ion:bar-chart-outline', + color: '#00d8ff', + }, +]; + +export const dynamicInfoItems: DynamicInfoItem[] = [ + { + avatar: 'dynamic-avatar-1|svg', + name: '小李', + date: '刚刚', + desc: `在
    A仓库 采购了100个零件 H3C`, + }, + { + avatar: 'dynamic-avatar-2|svg', + name: '艾文', + date: '1个小时前', + desc: `关注了 小李 `, + }, + { + avatar: 'dynamic-avatar-3|svg', + name: '克里斯', + date: '1天前', + desc: `发布了 本月采购物料表 `, + }, + { + avatar: 'dynamic-avatar-4|svg', + name: '赵伟', + date: '2天前', + desc: `发表文章 企业如何集成GPT微调模型配合ERP使用 `, + }, + { + avatar: 'dynamic-avatar-5|svg', + name: '皮特', + date: '3天前', + desc: `回复了 赵伟 的问题 如何让用户能直接微调模型?`, + }, + { + avatar: 'dynamic-avatar-6|svg', + name: '杰克', + date: '1周前', + desc: `添加了会员 检测公司的会员 `, + }, +]; + +export const groupItems: GroupItem[] = [ + { + title: 'WanSen ERP Core', + icon: 'carbon:logo-github', + color: '', + desc: 'ERP系统的API', + group: '万森智能开源组', + date: '2023-09-28', + }, + { + title: 'WanSen ERP', + icon: 'ion:logo-vue', + color: '#3fb27f', + desc: '该项目使用了Vue3+Vite+Ant-Design', + group: '前端开发小组', + date: '2023-09-28', + }, + { + title: 'Html 5', + icon: 'ion:logo-html5', + color: '#e18525', + desc: '该项目也使用了HTML5', + group: '前端开发小组', + date: '2023-10-01', + }, + { + title: 'Angular', + icon: 'ion:logo-angular', + color: '#bf0c2c', + desc: '设计新的页面交互', + group: 'UI组', + date: '2023-10-01', + }, + { + title: 'React', + icon: 'bx:bxl-react', + color: '#00d8ff', + desc: '下一步计划支持React重构', + group: '前端开发小组', + date: '2023-10-02', + }, + { + title: 'JavaScript', + icon: 'ion:logo-javascript', + color: '#EBD94E', + desc: '我们也可使用javascript进行重写', + group: '前端开发小组', + date: '2023-10-03', + }, +]; diff --git a/src/views/dashboard/workbench/index.vue b/src/views/dashboard/workbench/index.vue new file mode 100644 index 0000000..5ee292e --- /dev/null +++ b/src/views/dashboard/workbench/index.vue @@ -0,0 +1,36 @@ + + diff --git a/src/views/financial/advance-charge/advance.data.ts b/src/views/financial/advance-charge/advance.data.ts new file mode 100644 index 0000000..3f63d82 --- /dev/null +++ b/src/views/financial/advance-charge/advance.data.ts @@ -0,0 +1,183 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {h, reactive, UnwrapRef} from 'vue'; +import {Switch} from "ant-design-vue"; +import {useMessage} from "@/hooks/web/useMessage"; +import {useI18n} from "@/hooks/web/useI18n"; +import dayjs, {Dayjs} from "dayjs"; + +const {t} = useI18n(); + +export const columns: BasicColumn[] = [ + { + title: '付款会员', + dataIndex: 'memberName', + width: 120, + }, + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 150, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 150, + }, + { + title: '收款金额', + dataIndex: 'collectedAmount', + width: 90, + }, + { + title: '合计金额', + dataIndex: 'totalAmount', + width: 90, + }, + { + title: '备注', + dataIndex: 'remark', + width: 150, + }, + { + title: '财务人员', + dataIndex: 'financialPersonnel', + width: 80, + }, + { + title: '操作员', + dataIndex: 'operator', + width: 80, + }, + { + title: '状态', + dataIndex: 'status', + width: 100, + } +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'memberNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '付款会员', + field: 'phoneNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '单据状态', + field: 'type', + component: 'Select', + colProps: { + xl: 8, + xxl: 8, + }, + componentProps: { + options: [ + {label: '未审核', value: 0, key: 0}, + {label: '已审核', value: 1, key: 1}, + ], + }, + }, + { + label: '单据备注', + field: 'type', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + } +] + +export const formSchema: FormSchema[] = [] + +export const tableColumns = [ + { + title: '账户名称', + key: 'accountId', + width: '25%', + placeholder: '请选择${title}', + options: [], + allowSearch: true, + validateRules: [{required: true, message: '${title}不能为空'}], + }, + { + title: '金额', + key: 'amount', + width: '20%', + statistics: true, + placeholder: '请选择${title}', + validateRules: [{required: true, message: '${title}不能为空'}] + }, + { + title: '备注', + key: 'remark', + width: '50%', + placeholder: '请选择${title}' + } +] + +interface FormState { + id: string | undefined; + memberId: string; + receiptNumber: string; + financialPersonnelId: string; + receiptDate: string | undefined | Dayjs; + remark: string; + totalAmount: number; + collectedAmount: number; +} + +export const formState: UnwrapRef = reactive({ + id: '', + memberId: '', + receiptNumber: '', + financialPersonnelId: '', + receiptDate: undefined, + remark: '', + totalAmount: 0, + collectedAmount: 0, +}); + +export const advanceChargeTableColumns: BasicColumn[] = [ + { + title: '账户名称', + dataIndex: 'accountName', + width: 200, + }, + { + title: '金额', + dataIndex: 'amount', + width: 180, + }, + { + title: '备注', + dataIndex: 'remark', + width: 200, + }, +] \ No newline at end of file diff --git a/src/views/financial/advance-charge/components/AdvanceChargeModal.vue b/src/views/financial/advance-charge/components/AdvanceChargeModal.vue new file mode 100644 index 0000000..4459439 --- /dev/null +++ b/src/views/financial/advance-charge/components/AdvanceChargeModal.vue @@ -0,0 +1,584 @@ + + + + + \ No newline at end of file diff --git a/src/views/financial/advance-charge/components/ViewAdvanceChargeModal.vue b/src/views/financial/advance-charge/components/ViewAdvanceChargeModal.vue new file mode 100644 index 0000000..0a87be8 --- /dev/null +++ b/src/views/financial/advance-charge/components/ViewAdvanceChargeModal.vue @@ -0,0 +1,181 @@ + + + diff --git a/src/views/financial/advance-charge/index.vue b/src/views/financial/advance-charge/index.vue new file mode 100644 index 0000000..b14307b --- /dev/null +++ b/src/views/financial/advance-charge/index.vue @@ -0,0 +1,223 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/financial/collection/addEditCollection.data.ts b/src/views/financial/collection/addEditCollection.data.ts new file mode 100644 index 0000000..f994938 --- /dev/null +++ b/src/views/financial/collection/addEditCollection.data.ts @@ -0,0 +1,148 @@ +import {reactive, ref} from "vue"; +import XEUtils from "xe-utils"; +import {VxeGridInstance, VxeGridProps} from "vxe-table"; +import {Dayjs} from "dayjs"; + +export interface RowVO { + [key: string]: any, + collectionId: number | string; + saleReceiptNumber: string | undefined, + receivableArrears: number, + receivedArrears: number |string, + thisCollectionAmount: number, + remark: string, +} + +interface CollectionFormState { + id: number | string | undefined; + customerId: number | string | undefined; + receiptDate: string | undefined | Dayjs; + receiptNumber: string |undefined; + financialPersonId: number | string |undefined; + collectionAccountId: number | string |undefined; + totalCollectionAmount: number | string; + discountAmount: number | string; + actualCollectionAmount: number | string; + remark: string; +} + +const xGrid = ref>() +const tableData = ref([]) +const gridOptions = reactive>({ + border: true, + showHeaderOverflow: true, + showOverflow: true, + showFooter: true, + keepSource: true, + id: 'full_edit', + height: 400, + rowConfig: { + keyField: 'id', + isHover: true + }, + columnConfig: { + resizable: true + }, + sortConfig: { + trigger: 'cell', + remote: true + }, + filterConfig: { + remote: true + }, + formConfig: { + titleWidth: 100, + titleAlign: 'right', + items: [ + ] + }, + toolbarConfig: { + slots: { + buttons: 'toolbar_buttons' + }, + zoom: true, + custom: true + }, + columns: [ + { type: 'checkbox', field:'id', title: 'ID', width: 180}, + { field: 'saleReceiptNumber', + width:200, + title: '销售单据编号', + }, + { field: 'receivableArrears', + width:180, + title: '应收欠款', + }, + { field: 'receivedArrears', + width:180, + title: '已收欠款', + }, + { field: 'thisCollectionAmount', + width:200, + title: '本次收款', + slots: { edit: 'amount_edit' }, + sortable: true, + editRender: { name: 'input', attrs: { placeholder: '请输入本次收款金额' } } + }, + { field: 'remark', title: '备注', editRender: { name: 'input', attrs: { placeholder: '请输入备注' } } }, + + ], + footerMethod ({ columns, data }) { + return [ + columns.map((column, columnIndex) => { + if (columnIndex === 0) { + return '总计' + } + if (['thisCollectionAmount', 'rate'].includes(column.field)) { + collectionFormState.actualCollectionAmount = `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + collectionFormState.totalCollectionAmount = `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + getThisCollectionAmount.value = `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + return '' + }) + ] + }, + checkboxConfig: { + labelField: 'id', + reserve: true, + highlight: true, + range: true + }, + editConfig: { + trigger: 'click', + mode: 'row', + showStatus: true + } +}) + +const getThisCollectionAmount = ref('0') + +const sumNum = (list: RowVO[], field: string) => { + let count = 0 + list.forEach(item => { + count += Number(item[field]) + }) + return count +} +const collectionFormState = reactive({ + id: undefined, + customerId: '', + receiptDate: '', + receiptNumber: '', + financialPersonId: '', + collectionAccountId: '', + totalCollectionAmount: 0, + discountAmount: 0, + actualCollectionAmount: 0, + remark: '', +}); + +export { + xGrid, + sumNum, + tableData, + gridOptions, + collectionFormState, + getThisCollectionAmount +} \ No newline at end of file diff --git a/src/views/financial/collection/collection.data.ts b/src/views/financial/collection/collection.data.ts new file mode 100644 index 0000000..6db668a --- /dev/null +++ b/src/views/financial/collection/collection.data.ts @@ -0,0 +1,266 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {getAccountList} from "@/api/financial/account"; +import {getCustomerList} from "@/api/basic/customer"; +import {getOperatorList} from "@/api/basic/operator"; + +export const columns: BasicColumn[] = [ + { + title: '客户', + dataIndex: 'customerName', + width: 120, + }, + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 130, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '财务人员', + dataIndex: 'financialPerson', + width: 70, + }, + { + title: '收款账户', + dataIndex: 'collectionAccountName', + width: 100, + }, + { + title: '合计收款', + dataIndex: 'totalCollectionAmount', + width: 70, + }, + { + title: '优惠金额', + dataIndex: 'discountAmount', + width: 70, + }, + { + title: '实际收款', + dataIndex: 'actualCollectionAmount', + width: 70, + }, + { + title: '备注', + dataIndex: 'remark', + width: 150, + }, + { + title: '状态', + dataIndex: 'status', + width: 70, + }, +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { span: 7 }, + }, + { + label: '收款账户', + field: 'accountId', + component: 'ApiSelect', + componentProps: { + api: getAccountList, + resultField: 'data', + labelField: 'accountName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '客户', + field: 'customerId', + component: 'ApiSelect', + componentProps: { + api: getCustomerList, + resultField: 'data', + labelField: 'customerName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '财务人员', + field: 'financialPersonId', + component: 'ApiSelect', + componentProps: { + api: getOperatorList, + params: '财务员', + resultField: 'data', + labelField: 'name', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '单据状态', + field: 'status', + component: 'Select', + colProps: { + xl: 8, + xxl: 8, + }, + componentProps: { + options: [ + { label: '未审核', value: 0, key: 0 }, + { label: '已审核', value: 1, key: 1 }, + ], + }, + }, + { + label: '单据备注', + field: 'remark', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + } +] + +export const collectionReceiptTableColumns: BasicColumn[] = [ + { + title: '销售单据编号', + dataIndex: 'saleReceiptNumber', + width: 180, + }, + { + title: '应收欠款', + dataIndex: 'receivableArrears', + width: 80, + }, + { + title: '已收欠款', + dataIndex: 'receivedArrears', + width: 80, + }, + { + title: '本次收款', + dataIndex: 'thisCollectionAmount', + width: 80, + }, + { + title: '备注', + dataIndex: 'remark', + width: 200, + }, +] + +export const searchSaleArrearsFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '商品信息', + field: 'productInfo', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, +] + +export const saleArrearsReceiptTableColumns: BasicColumn[] = [ + { + title: '销售单据id', + dataIndex: 'id', + ifShow: false, + width: 0, + }, + { + title: '客户', + dataIndex: 'customerName', + width: 90, + }, + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 200, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 150, + }, + { + title: '商品信息', + dataIndex: 'productInfo', + width: 150, + }, + { + title: '本单欠款', + dataIndex: 'thisReceiptArrears', + width: 80, + }, + { + title: '已收欠款', + dataIndex: 'receivedArrears', + width: 80, + }, + { + title: '待收欠款', + dataIndex: 'receivableArrears', + width: 80, + }, + { + title: '操作员', + dataIndex: 'operatorName', + width: 80, + }, + { + title: '备注', + dataIndex: 'remark', + width: 140, + }, +] \ No newline at end of file diff --git a/src/views/financial/collection/components/AddEditCollectionModal.vue b/src/views/financial/collection/components/AddEditCollectionModal.vue new file mode 100644 index 0000000..b379958 --- /dev/null +++ b/src/views/financial/collection/components/AddEditCollectionModal.vue @@ -0,0 +1,617 @@ + + + + + \ No newline at end of file diff --git a/src/views/financial/collection/components/SaleArrearsModal.vue b/src/views/financial/collection/components/SaleArrearsModal.vue new file mode 100644 index 0000000..6a5fec0 --- /dev/null +++ b/src/views/financial/collection/components/SaleArrearsModal.vue @@ -0,0 +1,95 @@ + + + \ No newline at end of file diff --git a/src/views/financial/collection/components/ViewCollectionModal.vue b/src/views/financial/collection/components/ViewCollectionModal.vue new file mode 100644 index 0000000..26d3093 --- /dev/null +++ b/src/views/financial/collection/components/ViewCollectionModal.vue @@ -0,0 +1,193 @@ + + + diff --git a/src/views/financial/collection/index.vue b/src/views/financial/collection/index.vue new file mode 100644 index 0000000..3a6b0e8 --- /dev/null +++ b/src/views/financial/collection/index.vue @@ -0,0 +1,242 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/financial/expense/addEditExpense.data.ts b/src/views/financial/expense/addEditExpense.data.ts new file mode 100644 index 0000000..03e4bce --- /dev/null +++ b/src/views/financial/expense/addEditExpense.data.ts @@ -0,0 +1,141 @@ +import {reactive, ref} from "vue"; +import XEUtils from "xe-utils"; +import {VxeGridInstance, VxeGridProps} from "vxe-table"; +import {Dayjs} from "dayjs"; + +export interface RowVO { + [key: string]: any, + incomeExpenseId: number | string, + incomeExpenseAmount: number, + remark: string, +} + +interface ExpenseFormState { + id: number | string | undefined; + relatedPersonId: number | string | undefined; + receiptDate: string | undefined | Dayjs; + receiptNumber: string |undefined; + financialPersonId: number | string |undefined; + expenseAccountId: number | string |undefined; + incomeExpenseAmount: number | string; + expenseAmount: number | string; + remark: string; +} + +const xGrid = ref>() +const tableData = ref([]) +const gridOptions = reactive>({ + border: true, + showHeaderOverflow: true, + showOverflow: true, + showFooter: true, + keepSource: true, + id: 'full_edit', + height: 400, + rowConfig: { + keyField: 'id', + isHover: true + }, + columnConfig: { + resizable: true + }, + sortConfig: { + trigger: 'cell', + remote: true + }, + filterConfig: { + remote: true + }, + formConfig: { + titleWidth: 100, + titleAlign: 'right', + items: [ + ] + }, + toolbarConfig: { + slots: { + buttons: 'toolbar_buttons' + }, + zoom: true, // 显示全屏按钮 + custom: true // 显示自定义列按钮 + }, + columns: [ + { type: 'checkbox', field:'id', title: 'ID', width: 180}, + { field: 'incomeExpenseId', + width:200, + title: '支出项目', + slots: { edit: 'id_edit',default: 'id_default' }, + sortable: true, + editRender: {} + }, + { field: 'incomeExpenseAmount', + width:200, + title: '支出金额', + slots: { edit: 'amount_edit' }, + sortable: true, + editRender: { name: 'input', attrs: { placeholder: '请输入金额' } } + }, + { field: 'remark', title: '备注', editRender: { name: 'input', attrs: { placeholder: '请输入备注' } } }, + + ], + footerMethod ({ columns, data }) { + return [ + columns.map((column, columnIndex) => { + if (columnIndex === 0) { + return '总计' + } + if (['incomeExpenseAmount', 'rate'].includes(column.field)) { + expenseFormState.expenseAmount = `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + return '' + }) + ] + }, + checkboxConfig: { + labelField: 'id', + reserve: true, + highlight: true, + range: true + }, + editRules: { + incomeExpenseId: [ + { required: true, message: '支出项目不能为空' } + ], + incomeExpenseAmount: [ + { required: true, message: '支出金额不能为空' } + ] + }, + editConfig: { + trigger: 'click', + mode: 'row', + showStatus: true + } +}) + +const sumNum = (list: RowVO[], field: string) => { + let count = 0 + list.forEach(item => { + count += Number(item[field]) + }) + return count +} +const expenseFormState = reactive({ + id: undefined, + relatedPersonId: '', + receiptDate: '', + receiptNumber: '', + financialPersonId: '', + expenseAccountId: 0, + incomeExpenseAmount: 0, + expenseAmount: 0, + remark: '', +}); + +export { + xGrid, + sumNum, + tableData, + gridOptions, + expenseFormState, +} \ No newline at end of file diff --git a/src/views/financial/expense/components/AddEditExpenseModal.vue b/src/views/financial/expense/components/AddEditExpenseModal.vue new file mode 100644 index 0000000..e4c300a --- /dev/null +++ b/src/views/financial/expense/components/AddEditExpenseModal.vue @@ -0,0 +1,569 @@ + + + + + \ No newline at end of file diff --git a/src/views/financial/expense/components/ViewExpenseModal.vue b/src/views/financial/expense/components/ViewExpenseModal.vue new file mode 100644 index 0000000..cb0418e --- /dev/null +++ b/src/views/financial/expense/components/ViewExpenseModal.vue @@ -0,0 +1,181 @@ + + + diff --git a/src/views/financial/expense/expense.data.ts b/src/views/financial/expense/expense.data.ts new file mode 100644 index 0000000..d5ee024 --- /dev/null +++ b/src/views/financial/expense/expense.data.ts @@ -0,0 +1,159 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {getAccountList} from "@/api/financial/account"; +import {getRelatedPerson} from "@/api/report/report"; +import {getOperatorList} from "@/api/basic/operator"; + +export const columns: BasicColumn[] = [ + { + title: '名称', + dataIndex: 'name', + width: 120, + }, + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 130, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '财务人员', + dataIndex: 'financialPerson', + width: 70, + }, + { + title: '支出账户', + dataIndex: 'expenseAccountName', + width: 70, + }, + { + title: '支出金额', + dataIndex: 'expenseAmount', + width: 70, + }, + { + title: '备注', + dataIndex: 'remark', + width: 150, + }, + { + title: '状态', + dataIndex: 'status', + width: 70, + }, +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { span: 7 }, + }, + { + label: '支出账户', + field: 'accountId', + component: 'ApiSelect', + componentProps: { + api: getAccountList, + resultField: 'data', + labelField: 'accountName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '往来单位', + field: 'relatedPersonId', + component: 'ApiSelect', + componentProps: { + api: getRelatedPerson, + resultField: 'data', + labelField: 'name', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '财务人员', + field: 'financialPersonId', + component: 'ApiSelect', + componentProps: { + api: getOperatorList, + params: '财务员', + resultField: 'data', + labelField: 'name', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '单据状态', + field: 'status', + component: 'Select', + colProps: { + xl: 8, + xxl: 8, + }, + componentProps: { + options: [ + { label: '未审核', value: 0, key: 0 }, + { label: '已审核', value: 1, key: 1 }, + ], + }, + }, + { + label: '单据备注', + field: 'remark', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + + } +] + +export const expenseReceiptTableColumns: BasicColumn[] = [ + { + title: '支出项目', + dataIndex: 'incomeExpenseName', + width: 200, + }, + { + title: '金额', + dataIndex: 'incomeExpenseAmount', + width: 180, + }, + { + title: '备注', + dataIndex: 'remark', + width: 200, + }, +] \ No newline at end of file diff --git a/src/views/financial/expense/index.vue b/src/views/financial/expense/index.vue new file mode 100644 index 0000000..694924a --- /dev/null +++ b/src/views/financial/expense/index.vue @@ -0,0 +1,241 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/financial/income/addEditIncome.data.ts b/src/views/financial/income/addEditIncome.data.ts new file mode 100644 index 0000000..afaca6f --- /dev/null +++ b/src/views/financial/income/addEditIncome.data.ts @@ -0,0 +1,141 @@ +import {reactive, ref} from "vue"; +import XEUtils from "xe-utils"; +import {VxeGridInstance, VxeGridProps} from "vxe-table"; +import {Dayjs} from "dayjs"; + +export interface RowVO { + [key: string]: any, + incomeExpenseId: number | string, + incomeExpenseAmount: number, + remark: string, +} + +interface IncomeFormState { + id: number | string | undefined; + relatedPersonId: number | string | undefined; + receiptDate: string | undefined | Dayjs; + receiptNumber: string |undefined; + financialPersonId: number | string |undefined; + incomeAccountId: number | string |undefined; + incomeExpenseAmount: number | string; + incomeAmount: number | string; + remark: string; +} + +const xGrid = ref>() +const tableData = ref([]) +const gridOptions = reactive>({ + border: true, + showHeaderOverflow: true, + showOverflow: true, + showFooter: true, + keepSource: true, + id: 'full_edit', + height: 400, + rowConfig: { + keyField: 'id', + isHover: true + }, + columnConfig: { + resizable: true + }, + sortConfig: { + trigger: 'cell', + remote: true + }, + filterConfig: { + remote: true + }, + formConfig: { + titleWidth: 100, + titleAlign: 'right', + items: [ + ] + }, + toolbarConfig: { + slots: { + buttons: 'toolbar_buttons' + }, + zoom: true, // 显示全屏按钮 + custom: true // 显示自定义列按钮 + }, + columns: [ + { type: 'checkbox', field:'id', title: 'ID', width: 180}, + { field: 'incomeExpenseId', + width:200, + title: '收入项目', + slots: { edit: 'id_edit',default: 'id_default' }, + sortable: true, + editRender: {} + }, + { field: 'incomeExpenseAmount', + width:200, + title: '收入金额', + slots: { edit: 'amount_edit' }, + sortable: true, + editRender: { name: 'input', attrs: { placeholder: '请输入金额' } } + }, + { field: 'remark', title: '备注', editRender: { name: 'input', attrs: { placeholder: '请输入备注' } } }, + + ], + footerMethod ({ columns, data }) { + return [ + columns.map((column, columnIndex) => { + if (columnIndex === 0) { + return '总计' + } + if (['incomeExpenseAmount', 'rate'].includes(column.field)) { + incomeFormState.incomeAmount = `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + return '' + }) + ] + }, + editRules: { + incomeExpenseId: [ + { required: true, message: '收入项目不能为空' } + ], + incomeExpenseAmount: [ + { required: true, message: '收入金额不能为空' } + ] + }, + checkboxConfig: { + labelField: 'id', + reserve: true, + highlight: true, + range: true + }, + editConfig: { + trigger: 'click', + mode: 'row', + showStatus: true + } +}) + +const sumNum = (list: RowVO[], field: string) => { + let count = 0 + list.forEach(item => { + count += Number(item[field]) + }) + return count +} +const incomeFormState = reactive({ + id: undefined, + relatedPersonId: '', + receiptDate: '', + receiptNumber: '', + financialPersonId: '', + incomeAccountId: 0, + incomeExpenseAmount: 0, + incomeAmount: 0, + remark: '', +}); + +export { + xGrid, + sumNum, + tableData, + gridOptions, + incomeFormState, +} \ No newline at end of file diff --git a/src/views/financial/income/components/AddEditIncomeModal.vue b/src/views/financial/income/components/AddEditIncomeModal.vue new file mode 100644 index 0000000..e9b55e5 --- /dev/null +++ b/src/views/financial/income/components/AddEditIncomeModal.vue @@ -0,0 +1,575 @@ + + + + + \ No newline at end of file diff --git a/src/views/financial/income/components/ViewIncomeModal.vue b/src/views/financial/income/components/ViewIncomeModal.vue new file mode 100644 index 0000000..5a34810 --- /dev/null +++ b/src/views/financial/income/components/ViewIncomeModal.vue @@ -0,0 +1,181 @@ + + + diff --git a/src/views/financial/income/income.data.ts b/src/views/financial/income/income.data.ts new file mode 100644 index 0000000..31f270e --- /dev/null +++ b/src/views/financial/income/income.data.ts @@ -0,0 +1,159 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {getAccountList} from "@/api/financial/account"; +import {getRelatedPerson} from "@/api/report/report"; +import {getOperatorList} from "@/api/basic/operator"; + +export const columns: BasicColumn[] = [ + { + title: '名称', + dataIndex: 'name', + width: 120, + }, + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 130, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '财务人员', + dataIndex: 'financialPerson', + width: 70, + }, + { + title: '收入账户', + dataIndex: 'incomeAccountName', + width: 70, + }, + { + title: '收入金额', + dataIndex: 'incomeAmount', + width: 70, + }, + { + title: '备注', + dataIndex: 'remark', + width: 150, + }, + { + title: '状态', + dataIndex: 'status', + width: 70, + }, +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { span: 7 }, + }, + { + label: '收入账户', + field: 'accountId', + component: 'ApiSelect', + componentProps: { + api: getAccountList, + resultField: 'data', + labelField: 'accountName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '往来单位', + field: 'relatedPersonId', + component: 'ApiSelect', + componentProps: { + api: getRelatedPerson, + resultField: 'data', + labelField: 'name', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '财务人员', + field: 'financialPersonId', + component: 'ApiSelect', + componentProps: { + api: getOperatorList, + params: '财务员', + resultField: 'data', + labelField: 'name', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '单据状态', + field: 'status', + component: 'Select', + colProps: { + xl: 8, + xxl: 8, + }, + componentProps: { + options: [ + { label: '未审核', value: 0, key: 0 }, + { label: '已审核', value: 1, key: 1 }, + ], + }, + }, + { + label: '单据备注', + field: 'remark', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + + } +] + +export const incomeReceiptTableColumns: BasicColumn[] = [ + { + title: '收入项目', + dataIndex: 'incomeExpenseName', + width: 200, + }, + { + title: '金额', + dataIndex: 'incomeExpenseAmount', + width: 180, + }, + { + title: '备注', + dataIndex: 'remark', + width: 200, + }, +] \ No newline at end of file diff --git a/src/views/financial/income/index.vue b/src/views/financial/income/index.vue new file mode 100644 index 0000000..57db71d --- /dev/null +++ b/src/views/financial/income/index.vue @@ -0,0 +1,240 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/financial/payment/addEditPayment.data.ts b/src/views/financial/payment/addEditPayment.data.ts new file mode 100644 index 0000000..8a45776 --- /dev/null +++ b/src/views/financial/payment/addEditPayment.data.ts @@ -0,0 +1,148 @@ +import {reactive, ref} from "vue"; +import XEUtils from "xe-utils"; +import {VxeGridInstance, VxeGridProps} from "vxe-table"; +import {Dayjs} from "dayjs"; + +export interface RowVO { + [key: string]: any, + paymentId: number | string; + purchaseReceiptNumber: string | undefined, + paymentArrears: number, + prepaidArrears: number |string, + thisPaymentAmount: number, + remark: string, +} + +interface PaymentFormState { + id: number | string | undefined; + supplierId: number | string | undefined; + receiptDate: string | undefined | Dayjs; + receiptNumber: string |undefined; + financialPersonId: number | string |undefined; + paymentAccountId: number | string |undefined; + totalPaymentAmount: number | string; + discountAmount: number | string; + actualPaymentAmount: number | string; + remark: string; +} + +const xGrid = ref>() +const tableData = ref([]) +const gridOptions = reactive>({ + border: true, + showHeaderOverflow: true, + showOverflow: true, + showFooter: true, + keepSource: true, + id: 'full_edit', + height: 400, + rowConfig: { + keyField: 'id', + isHover: true + }, + columnConfig: { + resizable: true + }, + sortConfig: { + trigger: 'cell', + remote: true + }, + filterConfig: { + remote: true + }, + formConfig: { + titleWidth: 100, + titleAlign: 'right', + items: [ + ] + }, + toolbarConfig: { + slots: { + buttons: 'toolbar_buttons' + }, + zoom: true, + custom: true + }, + columns: [ + { type: 'checkbox', field:'id', title: 'ID', width: 180}, + { field: 'purchaseReceiptNumber', + width:200, + title: '采购单据编号', + }, + { field: 'paymentArrears', + width:180, + title: '应付欠款', + }, + { field: 'prepaidArrears', + width:180, + title: '已付欠款', + }, + { field: 'thisPaymentAmount', + width:200, + title: '本次付款', + slots: { edit: 'amount_edit' }, + sortable: true, + editRender: { name: 'input', attrs: { placeholder: '请输入本次收款金额' } } + }, + { field: 'remark', title: '备注', editRender: { name: 'input', attrs: { placeholder: '请输入备注' } } }, + + ], + footerMethod ({ columns, data }) { + return [ + columns.map((column, columnIndex) => { + if (columnIndex === 0) { + return '总计' + } + if (['thisPaymentAmount', 'rate'].includes(column.field)) { + paymentFormState.actualPaymentAmount = `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + paymentFormState.totalPaymentAmount = `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + getThisPaymentAmount.value = `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + return '' + }) + ] + }, + checkboxConfig: { + labelField: 'id', + reserve: true, + highlight: true, + range: true + }, + editConfig: { + trigger: 'click', + mode: 'row', + showStatus: true + } +}) + +const getThisPaymentAmount = ref('0') + +const sumNum = (list: RowVO[], field: string) => { + let count = 0 + list.forEach(item => { + count += Number(item[field]) + }) + return count +} +const paymentFormState = reactive({ + id: undefined, + supplierId: '', + receiptDate: '', + receiptNumber: '', + financialPersonId: '', + paymentAccountId: '', + totalPaymentAmount: 0, + discountAmount: 0, + actualPaymentAmount: 0, + remark: '', +}); + +export { + xGrid, + sumNum, + tableData, + gridOptions, + paymentFormState, + getThisPaymentAmount +} \ No newline at end of file diff --git a/src/views/financial/payment/components/AddEditPaymentModal.vue b/src/views/financial/payment/components/AddEditPaymentModal.vue new file mode 100644 index 0000000..259adc9 --- /dev/null +++ b/src/views/financial/payment/components/AddEditPaymentModal.vue @@ -0,0 +1,614 @@ + + + + + \ No newline at end of file diff --git a/src/views/financial/payment/components/PurchaseArrearsModal.vue b/src/views/financial/payment/components/PurchaseArrearsModal.vue new file mode 100644 index 0000000..7acfa7a --- /dev/null +++ b/src/views/financial/payment/components/PurchaseArrearsModal.vue @@ -0,0 +1,95 @@ + + + \ No newline at end of file diff --git a/src/views/financial/payment/components/ViewPaymentModal.vue b/src/views/financial/payment/components/ViewPaymentModal.vue new file mode 100644 index 0000000..b3c7f25 --- /dev/null +++ b/src/views/financial/payment/components/ViewPaymentModal.vue @@ -0,0 +1,193 @@ + + + diff --git a/src/views/financial/payment/index.vue b/src/views/financial/payment/index.vue new file mode 100644 index 0000000..cdc87bd --- /dev/null +++ b/src/views/financial/payment/index.vue @@ -0,0 +1,240 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/financial/payment/payment.data.ts b/src/views/financial/payment/payment.data.ts new file mode 100644 index 0000000..d932d73 --- /dev/null +++ b/src/views/financial/payment/payment.data.ts @@ -0,0 +1,266 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {getAccountList} from "@/api/financial/account"; +import {getSupplierList} from "@/api/basic/supplier"; +import {getOperatorList} from "@/api/basic/operator"; + +export const columns: BasicColumn[] = [ + { + title: '供应商', + dataIndex: 'supplierName', + width: 120, + }, + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 130, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '财务人员', + dataIndex: 'financialPerson', + width: 70, + }, + { + title: '付款账户', + dataIndex: 'paymentAccountName', + width: 100, + }, + { + title: '合计付款', + dataIndex: 'totalPaymentAmount', + width: 70, + }, + { + title: '优惠金额', + dataIndex: 'discountAmount', + width: 70, + }, + { + title: '实际付款', + dataIndex: 'actualPaymentAmount', + width: 70, + }, + { + title: '备注', + dataIndex: 'remark', + width: 150, + }, + { + title: '状态', + dataIndex: 'status', + width: 70, + }, +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { span: 7 }, + }, + { + label: '付款账户', + field: 'accountId', + component: 'ApiSelect', + componentProps: { + api: getAccountList, + resultField: 'data', + labelField: 'accountName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '供应商', + field: 'supplierId', + component: 'ApiSelect', + componentProps: { + api: getSupplierList, + resultField: 'data', + labelField: 'supplierName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '财务人员', + field: 'financialPersonId', + component: 'ApiSelect', + componentProps: { + api: getOperatorList, + params: '财务员', + resultField: 'data', + labelField: 'name', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '单据状态', + field: 'status', + component: 'Select', + colProps: { + xl: 8, + xxl: 8, + }, + componentProps: { + options: [ + { label: '未审核', value: 0, key: 0 }, + { label: '已审核', value: 1, key: 1 }, + ], + }, + }, + { + label: '单据备注', + field: 'remark', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + } +] + +export const paymentReceiptTableColumns: BasicColumn[] = [ + { + title: '采购单据编号', + dataIndex: 'purchaseReceiptNumber', + width: 180, + }, + { + title: '应付欠款', + dataIndex: 'paymentArrears', + width: 80, + }, + { + title: '已付欠款', + dataIndex: 'prepaidArrears', + width: 80, + }, + { + title: '本次付款', + dataIndex: 'thisPaymentAmount', + width: 80, + }, + { + title: '备注', + dataIndex: 'remark', + width: 200, + }, +] + +export const searchPurchaseArrearsFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '商品信息', + field: 'productInfo', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, +] + +export const purchaseArrearsReceiptTableColumns: BasicColumn[] = [ + { + title: '销售单据id', + dataIndex: 'id', + ifShow: false, + width: 0, + }, + { + title: '供应商', + dataIndex: 'supplierName', + width: 130, + }, + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 200, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 140, + }, + { + title: '商品信息', + dataIndex: 'productInfo', + width: 150, + }, + { + title: '本单欠款', + dataIndex: 'thisReceiptArrears', + width: 75, + }, + { + title: '已付欠款', + dataIndex: 'prepaidArrears', + width: 75, + }, + { + title: '待付欠款', + dataIndex: 'paymentArrears', + width: 75, + }, + { + title: '操作员', + dataIndex: 'operatorName', + width: 75, + }, + { + title: '备注', + dataIndex: 'remark', + width: 140, + }, +] \ No newline at end of file diff --git a/src/views/financial/transfer/addEditTransfer.data.ts b/src/views/financial/transfer/addEditTransfer.data.ts new file mode 100644 index 0000000..7971efd --- /dev/null +++ b/src/views/financial/transfer/addEditTransfer.data.ts @@ -0,0 +1,139 @@ +import {reactive, ref} from "vue"; +import XEUtils from "xe-utils"; +import {VxeGridInstance, VxeGridProps} from "vxe-table"; +import {Dayjs} from "dayjs"; + +export interface RowVO { + [key: string]: any, + accountId: number | string, + transferAmount: number, + remark: string, +} + +interface TransferFormState { + id: number | string | undefined; + receiptDate: string | undefined | Dayjs; + receiptNumber: string |undefined; + financialPersonId: number | string |undefined; + paymentAccountId: number | string |undefined; + accountId: number | string |undefined; + paymentAmount: number | string; + remark: string; +} + +const xGrid = ref>() +const tableData = ref([]) +const gridOptions = reactive>({ + border: true, + showHeaderOverflow: true, + showOverflow: true, + showFooter: true, + keepSource: true, + id: 'full_edit', + height: 400, + rowConfig: { + keyField: 'id', + isHover: true + }, + columnConfig: { + resizable: true + }, + sortConfig: { + trigger: 'cell', + remote: true + }, + filterConfig: { + remote: true + }, + formConfig: { + titleWidth: 100, + titleAlign: 'right', + items: [ + ] + }, + toolbarConfig: { + slots: { + buttons: 'toolbar_buttons' + }, + zoom: true, // 显示全屏按钮 + custom: true // 显示自定义列按钮 + }, + columns: [ + { type: 'checkbox', field:'id', title: 'ID', width: 180}, + { field: 'accountId', + width:200, + title: '账户名称', + slots: { edit: 'id_edit',default: 'id_default' }, + sortable: true, + editRender: {} + }, + { field: 'transferAmount', + width:200, + title: '金额', + slots: { edit: 'amount_edit' }, + sortable: true, + editRender: { name: 'input', attrs: { placeholder: '请输入金额' } } + }, + { field: 'remark', title: '备注', editRender: { name: 'input', attrs: { placeholder: '请输入备注' } } }, + + ], + footerMethod ({ columns, data }) { + return [ + columns.map((column, columnIndex) => { + if (columnIndex === 0) { + return '总计' + } + if (['transferAmount'].includes(column.field)) { + transferFormState.paymentAmount = `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + return '' + }) + ] + }, + checkboxConfig: { + labelField: 'id', + reserve: true, + highlight: true, + range: true + }, + editRules: { + accountId: [ + { required: true, message: '转账账户不能为空' } + ], + transferAmount: [ + { required: true, message: '转账金额不能为空' } + ] + }, + editConfig: { + trigger: 'click', + mode: 'row', + showStatus: true + } +}) + +const sumNum = (list: RowVO[], field: string) => { + let count = 0 + list.forEach(item => { + count += Number(item[field]) + }) + return count +} +const transferFormState = reactive({ + id: undefined, + receiptDate: '', + receiptNumber: '', + financialPersonId: '', + paymentAccountId: '', + accountId: 0, + paymentAmount: 0, + remark: '', +}); + +export { + xGrid, + sumNum, + tableData, + gridOptions, + transferFormState, +} \ No newline at end of file diff --git a/src/views/financial/transfer/components/AddEditTransferModal.vue b/src/views/financial/transfer/components/AddEditTransferModal.vue new file mode 100644 index 0000000..e3e315a --- /dev/null +++ b/src/views/financial/transfer/components/AddEditTransferModal.vue @@ -0,0 +1,530 @@ + + + + + \ No newline at end of file diff --git a/src/views/financial/transfer/components/ViewTransferModal.vue b/src/views/financial/transfer/components/ViewTransferModal.vue new file mode 100644 index 0000000..ef57fcb --- /dev/null +++ b/src/views/financial/transfer/components/ViewTransferModal.vue @@ -0,0 +1,177 @@ + + + diff --git a/src/views/financial/transfer/index.vue b/src/views/financial/transfer/index.vue new file mode 100644 index 0000000..9b014a6 --- /dev/null +++ b/src/views/financial/transfer/index.vue @@ -0,0 +1,240 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/financial/transfer/transfer.data.ts b/src/views/financial/transfer/transfer.data.ts new file mode 100644 index 0000000..ac9ed86 --- /dev/null +++ b/src/views/financial/transfer/transfer.data.ts @@ -0,0 +1,141 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {getAccountList} from "@/api/financial/account"; +import {getOperatorList} from "@/api/basic/operator"; + +export const columns: BasicColumn[] = [ + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 130, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '财务人员', + dataIndex: 'financialPerson', + width: 60, + }, + { + title: '付款账户', + dataIndex: 'paymentAccountName', + width: 130, + }, + { + title: '实付金额', + dataIndex: 'paymentAmount', + width: 60, + }, + { + title: '备注', + dataIndex: 'remark', + width: 200, + }, + { + title: '状态', + dataIndex: 'status', + width: 60, + }, +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '付款账户', + field: 'accountId', + component: 'ApiSelect', + componentProps: { + api: getAccountList, + resultField: 'data', + labelField: 'accountName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '财务人员', + field: 'financialPersonId', + component: 'ApiSelect', + componentProps: { + api: getOperatorList, + params: '财务员', + resultField: 'data', + labelField: 'name', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '单据状态', + field: 'status', + component: 'Select', + colProps: { + xl: 8, + xxl: 8, + }, + componentProps: { + options: [ + { label: '未审核', value: 0, key: 0 }, + { label: '已审核', value: 1, key: 1 }, + ], + }, + }, + { + label: '单据备注', + field: 'remark', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + + } +] + +export const transferReceiptTableColumns: BasicColumn[] = [ + { + title: '账户名称', + dataIndex: 'accountName', + width: 150, + }, + { + title: '金额', + dataIndex: 'transferAmount', + width: 100, + }, + { + title: '备注', + dataIndex: 'remark', + width: 200, + }, +] \ No newline at end of file diff --git a/src/views/product/attributes/attributes.data.ts b/src/views/product/attributes/attributes.data.ts new file mode 100644 index 0000000..3279f5a --- /dev/null +++ b/src/views/product/attributes/attributes.data.ts @@ -0,0 +1,71 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; + +export const columns: BasicColumn[] = [ + { + title: '属性名称', + dataIndex: 'attributeName', + width: 100, + }, + { + title: '属性值 (用|隔开)', + dataIndex: 'attributeValue', + width: 150, + }, + { + title: '排序', + dataIndex: 'sort', + width: 80, + }, + { + title: '备注', + dataIndex: 'remark', + width: 150, + }, + { + title: '创建时间', + dataIndex: 'createTime', + width: 150, + } +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '属性名称', + field: 'attributeName', + component: 'Input', + colProps: { span: 8 }, + }, +] + +export const formSchema: FormSchema[] = [ + { + label: '属性id', + field: 'id', + show: false, + component: 'Input', + }, + { + label: '属性名称', + field: 'attributeName', + component: 'Input', + required: true, + }, + { + label: '属性值', + helpMessage: '多个属性值用|隔开', + field: 'attributeValue', + component: 'InputTextArea', + required: true, + }, + { + label: '排序', + field: 'sort', + component: 'InputNumber', + }, + { + label: '备注', + field: 'remark', + component: 'InputTextArea', + } +] \ No newline at end of file diff --git a/src/views/product/attributes/components/AttributeModal.vue b/src/views/product/attributes/components/AttributeModal.vue new file mode 100644 index 0000000..03c65cb --- /dev/null +++ b/src/views/product/attributes/components/AttributeModal.vue @@ -0,0 +1,73 @@ + + \ No newline at end of file diff --git a/src/views/product/attributes/index.vue b/src/views/product/attributes/index.vue new file mode 100644 index 0000000..539f569 --- /dev/null +++ b/src/views/product/attributes/index.vue @@ -0,0 +1,110 @@ + + \ No newline at end of file diff --git a/src/views/product/category/category.data.ts b/src/views/product/category/category.data.ts new file mode 100644 index 0000000..1f9fba3 --- /dev/null +++ b/src/views/product/category/category.data.ts @@ -0,0 +1,72 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {getCategoryList} from "@/api/product/productCategory"; +export const columns: BasicColumn[] = [ + { + title: '分类名称', + dataIndex: 'categoryName', + width: 150, + align: 'left', + }, + { + title: '分类编号', + dataIndex: 'categoryNumber', + }, + { + title: '上级分类', + dataIndex: 'parentName', + }, + { + title: '排序', + dataIndex: 'sort', + }, + { + title: '备注', + dataIndex: 'remark', + }, + { + title: '创建时间', + dataIndex: 'createTime', + } +] +export const CategorySchema: FormSchema[] = [ + { + field: 'id', + label: '分类id', + component: 'Input', + show: false, + }, + { + field: 'categoryName', + label: '分类名称', + component: 'Input', + required: true, + }, + { + label: '分类编号', + field: 'categoryNumber', + component: 'Input', + required: true, + }, + { + field: 'parentId', + label: '上级分类', + component: 'ApiTreeSelect', + componentProps: { + api: getCategoryList, + resultField: 'data', + labelField: 'categoryName', + valueField: 'id', + }, + }, + { + label: '排序', + field: 'sort', + component: 'InputNumber', + }, + { + label: '备注', + field: 'remark', + component: 'InputTextArea', + }, +] \ No newline at end of file diff --git a/src/views/product/category/components/CategoryModal.vue b/src/views/product/category/components/CategoryModal.vue new file mode 100644 index 0000000..0b5a63b --- /dev/null +++ b/src/views/product/category/components/CategoryModal.vue @@ -0,0 +1,74 @@ + + + + + \ No newline at end of file diff --git a/src/views/product/category/index.vue b/src/views/product/category/index.vue new file mode 100644 index 0000000..9e21545 --- /dev/null +++ b/src/views/product/category/index.vue @@ -0,0 +1,134 @@ + + + \ No newline at end of file diff --git a/src/views/product/info/components/BatchEditModal.vue b/src/views/product/info/components/BatchEditModal.vue new file mode 100644 index 0000000..c8aad63 --- /dev/null +++ b/src/views/product/info/components/BatchEditModal.vue @@ -0,0 +1,206 @@ + + + \ No newline at end of file diff --git a/src/views/product/info/components/BatchSetPriceModal.vue b/src/views/product/info/components/BatchSetPriceModal.vue new file mode 100644 index 0000000..171d692 --- /dev/null +++ b/src/views/product/info/components/BatchSetPriceModal.vue @@ -0,0 +1,119 @@ + + + + + \ No newline at end of file diff --git a/src/views/product/info/components/BatchSetStockModal.vue b/src/views/product/info/components/BatchSetStockModal.vue new file mode 100644 index 0000000..2ee2ef0 --- /dev/null +++ b/src/views/product/info/components/BatchSetStockModal.vue @@ -0,0 +1,108 @@ + + + + + \ No newline at end of file diff --git a/src/views/product/info/components/ProductInfoModal.vue b/src/views/product/info/components/ProductInfoModal.vue new file mode 100644 index 0000000..48c34ad --- /dev/null +++ b/src/views/product/info/components/ProductInfoModal.vue @@ -0,0 +1,1304 @@ + + + + + \ No newline at end of file diff --git a/src/views/product/info/components/SelectProductModal.vue b/src/views/product/info/components/SelectProductModal.vue new file mode 100644 index 0000000..5c22d4e --- /dev/null +++ b/src/views/product/info/components/SelectProductModal.vue @@ -0,0 +1,63 @@ + + + \ No newline at end of file diff --git a/src/views/product/info/index.vue b/src/views/product/info/index.vue new file mode 100644 index 0000000..b5f1888 --- /dev/null +++ b/src/views/product/info/index.vue @@ -0,0 +1,201 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/product/info/info.data.ts b/src/views/product/info/info.data.ts new file mode 100644 index 0000000..7e6351d --- /dev/null +++ b/src/views/product/info/info.data.ts @@ -0,0 +1,382 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {h, reactive, ref} from 'vue'; +import {Switch} from "ant-design-vue"; +import {useMessage} from "@/hooks/web/useMessage"; +import {useI18n} from "@/hooks/web/useI18n"; +import {updateProductStatus} from "@/api/product/product"; +import {getCategoryList} from "@/api/product/productCategory"; +import {MeTable, ProductInfo} from "@/views/product/info/model/productInfoModel"; +import {getWarehouseList} from "@/api/basic/warehouse"; + +const { t } = useI18n(); + +const columns: BasicColumn[] = [ + { + title: '条码', + dataIndex: 'productBarcode', + width: 80, + }, + { + title: '名称', + dataIndex: 'productName', + width: 100, + }, + { + title: '规格', + dataIndex: 'productStandard', + width: 80, + }, + { + title: '型号', + dataIndex: 'productModel', + width: 100, + }, + { + title: '颜色', + dataIndex: 'productColor', + width: 60, + }, + { + title: '类别', + dataIndex: 'productCategoryName', + width: 80, + }, + { + title: '单位', + dataIndex: 'productUnit', + width: 80, + }, + { + title: '库存', + dataIndex: 'productStock', + width: 60, + }, + { + title: '采购价', + dataIndex: 'purchasePrice', + width: 60, + }, + { + title: '零售价', + dataIndex: 'retailPrice', + width: 60, + }, + { + title: '销售价', + dataIndex: 'salePrice', + width: 60, + }, + { + title: '最低售价', + dataIndex: 'lowPrice', + width: 60, + }, + { + title: '状态', + dataIndex: 'status', + width: 80, + customRender: ({ record }) => { + if (!Reflect.has(record, 'pendingStatus')) { + record.pendingStatus = false; + } + return h(Switch, { + checked: record.status === 0, + checkedChildren: t('common.on'), + unCheckedChildren: t('common.off'), + loading: record.pendingStatus, + onChange(checked, _) { + const {createMessage} = useMessage(); + if (record.id == 1) { + createMessage.warn(t('common.notice')); + return; + } + record.pendingStatus = true; + const newStatus = checked ? 0 : 1; + updateProductStatus([record.id], newStatus ) + .then(() => { + record.status = newStatus; + }) + .finally(() => { + record.pendingStatus = false; + }); + }, + }); + } + }, + { + title: '创建时间', + dataIndex: 'createTime', + width: 80, + } +] + + +const extendPriceColumn: BasicColumn[] = [ + { + title: '条码', + dataIndex: 'barCode', + width: 80, + }, + { + title: '名称', + dataIndex: 'productName', + width: 100, + }, + { + title: '分类', + dataIndex: 'productCategoryName', + width: 100, + }, + { + title: '所属仓库', + dataIndex: 'warehouseName', + width: 100, + }, + { + title: '规格', + dataIndex: 'productStandard', + width: 80, + }, + { + title: '型号', + dataIndex: 'productModel', + width: 100, + }, + { + title: '颜色', + dataIndex: 'productColor', + width: 60, + }, + { + title: '类别', + dataIndex: 'productCategoryName', + width: 80, + }, + { + title: '单位', + dataIndex: 'productUnit', + width: 80, + }, + { + title: '库存', + dataIndex: 'stock', + width: 60, + }, + { + title: '零售价', + dataIndex: 'retailPrice', + width: 60, + }, + { + title: '销售价', + dataIndex: 'salePrice', + width: 60, + }, + { + title: '采购价', + dataIndex: 'purchasePrice', + width: 60, + }, + { + title: '扩展信息', + dataIndex: 'extendInfo', + width: 60, + }, +] + +const searchFormSchema: FormSchema[] = [ + { + label: '商品类别', + field: 'productCategoryId', + component: 'ApiTreeSelect', + colProps: { + xl: 8, + xxl: 8, + }, + componentProps: { + api: getCategoryList, + resultField: 'data', + labelField: 'categoryName', + valueField: 'id', + }, + }, + { + label: '关键词', + field: 'keywords', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '序列号', + field: 'enableSerialNumber', + component: 'Select', + colProps: { + xl: 12, + xxl: 8, + }, + componentProps: { + options: [ + { label: '无', value: 0, key: 0 }, + { label: '有', value: 1, key: 1 }, + ], + }, + }, + { + label: '批次号', + field: 'enableBatchNumber', + component: 'Select', + colProps: { + xl: 12, + xxl: 8, + }, + componentProps: { + options: [ + { label: '无', value: 0, key: 0 }, + { label: '有', value: 1, key: 1 }, + ], + }, + }, + { + label: '仓库', + field: 'warehouseId', + component: 'ApiTreeSelect', + colProps: { + xl: 12, + xxl: 8, + }, + componentProps: { + api: getWarehouseList, + resultField: 'data', + labelField: 'warehouseName', + valueField: 'id', + }, + }, +] + +const meTable: MeTable = reactive({ + loading: false, + dataSource: ref([]), + columns: [ + { + title: '条码', + key: 'barCode', + type: 'inputNumber', + placeholder: '请输入${title}', + }, + { + title: '单位', + key: 'productUnit', + type: 'input', + placeholder: '请输入${title}', + validateRules: [{ required: true, message: '单位不能为空' }], + }, + { + title: '多属性', + key: 'multiAttribute', + type: 'input', + readonly: true, + placeholder: '请输入${title}', + }, + { + title: '采购价', + key: 'purchasePrice', + type: 'inputNumber', + defaultValue: '', + placeholder: '请输入${title}', + }, + { + title: '零售价', + key: 'retailPrice', + type: 'inputNumber', + defaultValue: '', + placeholder: '请输入${title}', + }, + { + title: '销售价', + key: 'salesPrice', + type: 'inputNumber', + defaultValue: '', + placeholder: '请输入${title}', + }, + { + title: '最低售价', + key: 'lowSalesPrice', + type: 'inputNumber', + defaultValue: '', + placeholder: '请输入${title}', + }, + ], +}); + +const stock: any = reactive({ + loading: false, + dataSource: ref([]), + columns: [ + { + title: '仓库 (商品条码/商品单位)', + key: 'warehouseName', + type: 'input', + }, + { + title: '期初库存数量', + key: 'initStockQuantity', + type: 'inputNumber', + placeholder: '请输入${title}', + }, + { + title: '最低安全库存数量', + key: 'lowStockQuantity', + type: 'inputNumber', + placeholder: '请输入${title}', + }, + { + title: '最高安全库存数量', + key: 'highStockQuantity', + type: 'inputNumber', + placeholder: '请输入${title}', + }, + ], +}); + +const formState: any = reactive({ + productId: '', + productName: '', + productStandard: '', + productModel: '', + productUnit: '', + productUnitId: null, + productColor: '', + productWeight: null, + productExpiryNum: null, + productCategoryId: null, + enableSerialNumber: null, + enableBatchNumber: null, + remark: '', + warehouseShelves: '', + productManufacturer: '', + otherFieldOne: '', + otherFieldTwo: '', + otherFieldThree: '', +}); + +const productInfo: ProductInfo = reactive({ + mfrs: '制造商', + otherField1: '自定义1', + otherField2: '自定义2', + otherField3: '自定义3', +}); + + +export { + columns, + extendPriceColumn, + searchFormSchema, + meTable, + stock, + formState, + productInfo, +}; \ No newline at end of file diff --git a/src/views/product/info/model/productInfoModel.ts b/src/views/product/info/model/productInfoModel.ts new file mode 100644 index 0000000..0ebe426 --- /dev/null +++ b/src/views/product/info/model/productInfoModel.ts @@ -0,0 +1,99 @@ + +export interface Column { + title: string; + key: string; + type: string; + placeholder: string; + validateRules?: { required: boolean; message: string }[]; + readonly?: boolean; + defaultValue?: string | number; +} + +export interface ProductAttributeModel { + id: number | string; + attributeName: string; + attributeValue: string; + remark: string; + sort: number; + disabled: boolean; +} + +export interface ProductImageModel { + productImageId: string; + imageName: string; + imageUrl: string; +} + +export interface ProductPriceModel { + key: number|string; + productPriceId: string; + barCode: number; + productUnit: string; + multiAttribute: string; + purchasePrice: number; + retailPrice: number; + salesPrice: number; + lowSalesPrice: number; +} + +export interface ProductStockModel { + key: number|string; + productStockId: number | string; + id: number | string; + warehouseName: string; + initStockQuantity: number; + lowStockQuantity: number; + highStockQuantity: number; +} + +export interface MeTable { + loading: boolean; + dataSource: ProductPriceModel[]; + columns: Column[]; +} + +export interface Stock { + loading: boolean; + dataSource: ProductStockModel[]; + columns: Column[]; +} + +export interface ProductInfo { + mfrs: string; + otherField1: string; + otherField2: string; + otherField3: string; +} + +export interface FormState { + productId: number | string | undefined; + productName: string | undefined; + productStandard: string | undefined; + productModel: string | undefined; + productUnit: string | undefined; + productUnitId: string | undefined; + productColor: string | undefined; + productWeight: number | undefined; + productExpiryNum: number | undefined; + productCategoryId: string | undefined; + enableSerialNumber: number | undefined; + enableBatchNumber: number | undefined; + warehouseShelves: string | undefined; + productManufacturer: string | undefined; + otherFieldOne: string | undefined; + otherFieldTwo: string | undefined; + otherFieldThree: string | undefined; + remark: string | undefined; +} + +export interface Unit { + id: number; + computeUnit: string + basicUnit: string; + otherUnit: string; + ratio: number; + otherUnitTwo: string; + ratioTwo: number; + otherUnitThree: string; + ratioThree: number; +} \ No newline at end of file diff --git a/src/views/product/units/components/UnitModal.vue b/src/views/product/units/components/UnitModal.vue new file mode 100644 index 0000000..9ba8074 --- /dev/null +++ b/src/views/product/units/components/UnitModal.vue @@ -0,0 +1,90 @@ + + \ No newline at end of file diff --git a/src/views/product/units/index.vue b/src/views/product/units/index.vue new file mode 100644 index 0000000..61cbc6b --- /dev/null +++ b/src/views/product/units/index.vue @@ -0,0 +1,110 @@ + + \ No newline at end of file diff --git a/src/views/product/units/units.data.ts b/src/views/product/units/units.data.ts new file mode 100644 index 0000000..e8f6ef0 --- /dev/null +++ b/src/views/product/units/units.data.ts @@ -0,0 +1,173 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import { h } from 'vue'; +import {Switch} from "ant-design-vue"; +import {useMessage} from "@/hooks/web/useMessage"; +import {useI18n} from "@/hooks/web/useI18n"; +import {updateUnitStatus} from "@/api/product/productUnit"; + +const { t } = useI18n(); +export const columns: BasicColumn[] = [ + { + title: '计量单位', + dataIndex: 'computeUnit', + width: 230, + }, + { + title: '基本单位', + dataIndex: 'basicUnit', + width: 70, + }, + { + title: '副单位', + dataIndex: 'otherComputeUnit', + width: 70, + }, + { + title: '副单位二', + dataIndex: 'otherComputeUnitTwo', + width: 150, + }, + { + title: '副单位三', + dataIndex: 'otherComputeUnitThree', + width: 150, + }, + { + title: '状态', + dataIndex: 'status', + width: 150, + customRender: ({ record }) => { + if (!Reflect.has(record, 'pendingStatus')) { + record.pendingStatus = false; + } + return h(Switch, { + checked: record.status === 0, + checkedChildren: t('common.on'), + unCheckedChildren: t('common.off'), + loading: record.pendingStatus, + onChange(checked, _) { + const {createMessage} = useMessage(); + if (record.id == 1) { + createMessage.warn(t('common.notice')); + return; + } + record.pendingStatus = true; + const newStatus = checked ? 0 : 1; + updateUnitStatus({id: record.id, status: newStatus} ) + .then(() => { + record.status = newStatus; + }) + .finally(() => { + record.pendingStatus = false; + }); + }, + }); + } + }, + { + title: '创建时间', + dataIndex: 'createTime', + width: 150, + } +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '计量单位', + field: 'computeUnit', + component: 'Input', + colProps: { span: 8 }, + }, +] + +export const formSchema: FormSchema[] = [ + { + label: '单位id', + field: 'id', + show: false, + component: 'Input', + }, + { + label: '基本单位', + field: 'basicUnit', + component: 'Input', + required: true, + componentProps: { + placeholder: '请输入基本单位(小单位)', + }, + }, + { + label: '副单位', + field: 'otherUnit', + component: 'Input', + required: true, + componentProps: { + placeholder: '请输入副单位(大单位)', + }, + colProps: { + span: 13, + }, + }, + { + label: '=', + field: 'ratio', + component: 'InputNumber', + labelWidth: 10, + componentProps: { + addonAfter: '基本单位', + placeholder: '请输入比例', + }, + colProps: { + span: 11, + }, + }, + { + label: '副单位二', + field: 'otherUnitTwo', + component: 'Input', + componentProps: { + placeholder: '请输入副单位2(大单位)', + }, + colProps: { + span: 13, + }, + }, + { + label: '=', + field: 'ratioTwo', + labelWidth: 10, + componentProps: { + addonAfter: '基本单位', + placeholder: '请输入比例2', + }, + component: 'Input', + colProps: { + span: 11, + } + }, + { + label: '副单位三', + field: 'otherUnitThree', + component: 'Input', + componentProps: { + placeholder: '请输入副单位2(大单位)', + }, + colProps: { + span: 13, + }, + }, + { + label: '=', + labelWidth: 10, + field: 'ratioThree', + componentProps: { + addonAfter: '基本单位', + placeholder: '请输入比例3', + }, + component: 'Input', + colProps: { + span: 11, + } + } +] \ No newline at end of file diff --git a/src/views/purchase/model/addEditModel.ts b/src/views/purchase/model/addEditModel.ts new file mode 100644 index 0000000..0bf30bd --- /dev/null +++ b/src/views/purchase/model/addEditModel.ts @@ -0,0 +1,467 @@ +import {reactive, ref} from "vue"; +import XEUtils from "xe-utils"; +import {VxeGridInstance, VxeGridProps} from "vxe-table"; +import {Dayjs} from "dayjs"; + +export interface RowVO { + [key: string]: any, + barCode: number | string, + productName:string, + productStandard: string, + stock: number, + productUnit: string, + productNumber: number, + unitPrice: number, + amount: number, + taxRate: number, + taxAmount: number, + taxTotalPrice: number, + remark: string, +} +interface PurchaseOrderFormState { + id: number | string | undefined; + supplierId: string; + receiptNumber: string; + discountRate: number; + discountAmount: number; + discountLastAmount: number | string; + deposit: number; + remark: string; + receiptDate: string | undefined | Dayjs; + warehouseId: number | string; + accountId: string | undefined; + multipleAccountIds: number[] | undefined; + multipleAccountAmounts: number[] | undefined; +} + +interface PurchaseStorageFormState { + id: number | string | undefined; + supplierId: string; + accountId: number | string | undefined; + receiptNumber: string; + receiptDate: string | undefined | Dayjs; + otherReceipt: string; + paymentRate: number; + paymentAmount: number; + paymentLastAmount: number | string; + otherAmount: number; + thisPaymentAmount: number | string; + thisArrearsAmount: number | string; + remark: string; + status: number | undefined; + warehouseId: number | string; + multipleAccountIds: number[] | undefined; + multipleAccountAmounts: number[] | undefined; +} + +interface PurchaseRefundFormState { + id: number | string | undefined; + supplierId: string; + accountId: number | string | undefined; + receiptNumber: string; + receiptDate: string | undefined | Dayjs; + otherReceipt: string; + refundOfferRate: number; + refundOfferAmount: number; + refundLastAmount: number | string; + otherAmount: number; + thisRefundAmount: number; + thisArrearsAmount: number; + remark: string; + status: number | undefined; + warehouseId: number | string; + multipleAccountIds: number[] | undefined; + multipleAccountAmounts: number[] | undefined; +} + +const xGrid = ref>() +const tableData = ref([]) +const orderGridOptions = reactive>({ + border: true, + showHeaderOverflow: true, + showOverflow: true, + showFooter: true, + keepSource: true, + id: 'full_edit', + height: 400, + rowConfig: { + keyField: 'id', + isHover: true + }, + columnConfig: { + resizable: true + }, + printConfig: { + columns: [ + { field: 'barCode' }, + { field: 'productName' }, + { field: 'productStandard' }, + { field: 'stockNumber' }, + { field: 'productUnit' }, + { field: 'productNumber' }, + { field: 'retailPrice' }, + { field: 'amount' }, + { field: 'remark' } + ] + }, + sortConfig: { + trigger: 'cell', + remote: true + }, + filterConfig: { + remote: true + }, + pagerConfig: { + enabled: true, + pageSize: 10, + pageSizes: [5, 10, 15, 20, 50, 100, 200, 500, 1000] + }, + formConfig: { + titleWidth: 100, + titleAlign: 'right', + items: [ + ] + }, + toolbarConfig: { + slots: { + buttons: 'toolbar_buttons' + }, + refresh: true, // 显示刷新按钮 + print: true, // 显示打印按钮 + zoom: true, // 显示全屏按钮 + custom: true // 显示自定义列按钮 + }, + columns: [ + { type: 'checkbox', field:'productId', title: 'ID', width: 80}, + { field: 'barCode', + width:160, + title: '条码', + slots: { edit: 'barCode_edit' }, + titlePrefix: { content: '输入条码商品信息自动带出!' }, + editRender: { name: 'input', attrs: { placeholder: '请输入条码并回车' } } + }, + { + field: 'productName', + title: '名称', + width:160, + }, + { field: 'productStandard', title: '规格', width: 120, }, + { field: 'stock', title: '库存', width: 70}, + { field: 'productUnit', title: '单位', width: 70}, + { field: 'productNumber', title: '数量', sortable: true, width:100, + slots: { edit: 'product_number_edit' }, + editRender: { name: '$input', props: { type: 'number', min: 1, max: 9999 } }, + }, + { + field: 'unitPrice', + title: '单价', width:105, + formatter ({ cellValue }) { + return cellValue ? `¥${XEUtils.commafy(XEUtils.toNumber(cellValue), { digits: 2 })}` : '' + }, + slots: { edit: 'price_edit' }, + editRender: { name: '$input', props: { type: 'float', digits: 2, placeholder: '输入单价' } } + }, + { + field: 'amount', + title: '金额', width:105, + formatter ({ cellValue }) { + return cellValue ? `¥${XEUtils.commafy(XEUtils.toNumber(cellValue), { digits: 2 })}` : '' + }, + slots: { edit: 'amount_edit' }, + editRender: { name: '$input', props: { type: 'float', digits: 2, placeholder: '输入金额' } } + }, + { field: 'taxRate', title: '税率', width: 105, + slots: { edit: 'tax_rate_edit' }, + editRender: { name: '$input', attrs: { type: 'float', digits: 2, placeholder: '请输入税率' } } + }, + { field: 'taxAmount', title: '税额', width: 105, + editRender:{attrs: {type: 'float', digits: 2}}, + slots: { edit: 'tax_amount_edit' }, + }, + { field: 'taxTotalPrice', title: '价税合计', width: 105, + slots: { edit: 'tax_total_price_edit' }, + editRender: { name: '$input', attrs: {type: 'float', digits: 2, placeholder: '请输入价税合计' } } + }, + { field: 'remark', title: '备注', editRender: { name: 'input', attrs: { placeholder: '请输入备注' } } }, + + ], + footerMethod ({ columns, data }) { + return [ + columns.map((column, columnIndex) => { + if (columnIndex === 0) { + return '总计' + } + if (['amount', 'rate'].includes(column.field)) { + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + if (['productNumber', 'rate'].includes(column.field)) { + return sumNum(data, column.field) + } + if (['taxAmount', 'rate'].includes(column.field)) { + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + + if (['taxTotalPrice', 'rate'].includes(column.field)) { + getTaxTotalPrice.value = `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + return '' + }) + ] + }, + checkboxConfig: { + labelField: 'id', + reserve: true, + highlight: true, + range: true + }, + editRules: { + barCode: [ + { required: true, message: '商品条码不能为空' } + ] + }, + editConfig: { + trigger: 'click', + mode: 'row', + showStatus: true + } +}) + +const gridOptions = reactive>({ + border: true, + showHeaderOverflow: true, + showOverflow: true, + showFooter: true, + keepSource: true, + id: 'full_edit', + height: 400, + rowConfig: { + keyField: 'id', + isHover: true + }, + columnConfig: { + resizable: true + }, + printConfig: { + columns: [ + { field: 'barCode' }, + { field: 'productName' }, + { field: 'productStandard' }, + { field: 'stockNumber' }, + { field: 'productUnit' }, + { field: 'productNumber' }, + { field: 'retailPrice' }, + { field: 'amount' }, + { field: 'remark' } + ] + }, + sortConfig: { + trigger: 'cell', + remote: true + }, + filterConfig: { + remote: true + }, + pagerConfig: { + enabled: true, + pageSize: 10, + pageSizes: [5, 10, 15, 20, 50, 100, 200, 500, 1000] + }, + formConfig: { + titleWidth: 100, + titleAlign: 'right', + items: [ + ] + }, + toolbarConfig: { + slots: { + buttons: 'toolbar_buttons' + }, + refresh: true, // 显示刷新按钮 + print: true, // 显示打印按钮 + zoom: true, // 显示全屏按钮 + custom: true // 显示自定义列按钮 + }, + columns: [ + { type: 'checkbox', field:'productId', title: 'ID', width: 80}, + { + field: 'warehouseId', + title: '仓库', + width: 130, + slots: { edit: 'warehouse_edit', default: 'warehouse_default'}, + editRender: { name: 'input', attrs: { placeholder: '请选择仓库' } } + }, + { field: 'barCode', + width:160, + title: '条码', + slots: { edit: 'barCode_edit' }, + titlePrefix: { content: '输入条码商品信息自动带出!' }, + editRender: { name: 'input', attrs: { placeholder: '请输入条码并回车' } } + }, + { + field: 'productName', + title: '名称', + width:160, + }, + { field: 'productStandard', title: '规格', width: 120, }, + { field: 'stock', title: '库存', width: 70}, + { field: 'productUnit', title: '单位', width: 70}, + { field: 'productNumber', title: '数量', sortable: true, width:100, + slots: { edit: 'product_number_edit' }, + editRender: { name: '$input', props: { type: 'number', min: 1, max: 9999 } }, + }, + { + field: 'unitPrice', + title: '单价', width:105, + formatter ({ cellValue }) { + return cellValue ? `¥${XEUtils.commafy(XEUtils.toNumber(cellValue), { digits: 2 })}` : '' + }, + slots: { edit: 'price_edit' }, + editRender: { name: '$input', props: { type: 'float', digits: 2, placeholder: '输入单价' } } + }, + { + field: 'amount', + title: '金额', width:105, + formatter ({ cellValue }) { + return cellValue ? `¥${XEUtils.commafy(XEUtils.toNumber(cellValue), { digits: 2 })}` : '' + }, + slots: { edit: 'amount_edit' }, + editRender: { name: '$input', props: { type: 'float', digits: 2, placeholder: '输入金额' } } + }, + { field: 'taxRate', title: '税率', width: 105, + slots: { edit: 'tax_rate_edit' }, + editRender: { name: '$input', attrs: { type: 'float', digits: 2, placeholder: '请输入税率' } } + }, + { field: 'taxAmount', title: '税额', width: 105, + editRender:{attrs: {type: 'float', digits: 2}}, + slots: { edit: 'tax_amount_edit' }, + }, + { field: 'taxTotalPrice', title: '价税合计', width: 105, + slots: { edit: 'tax_total_price_edit' }, + editRender: { name: '$input', attrs: {type: 'float', digits: 2, placeholder: '请输入价税合计' } } + }, + { field: 'remark', title: '备注', editRender: { name: 'input', attrs: { placeholder: '请输入备注' } } }, + + ], + footerMethod ({ columns, data }) { + return [ + columns.map((column, columnIndex) => { + if (columnIndex === 0) { + return '总计' + } + if (['amount', 'rate'].includes(column.field)) { + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + if (['productNumber', 'rate'].includes(column.field)) { + return sumNum(data, column.field) + } + if (['taxAmount', 'rate'].includes(column.field)) { + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + + if (['taxTotalPrice', 'rate'].includes(column.field)) { + getTaxTotalPrice.value = `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + return '' + }) + ] + }, + checkboxConfig: { + labelField: 'id', + reserve: true, + highlight: true, + range: true + }, + editRules: { + warehouseId: [ + { required: true, message: '仓库不能为空' } + ], + barCode: [ + { required: true, message: '商品条码不能为空' } + ] + }, + editConfig: { + trigger: 'click', + mode: 'row', + showStatus: true + } +}) + +const sumNum = (list: RowVO[], field: string) => { + let count = 0 + list.forEach(item => { + count += Number(item[field]) + }) + return count +} + +const getTaxTotalPrice = ref(''); + +const purchaseOrderFormState = reactive({ + id: undefined, + supplierId: '', + receiptNumber: '', + remark: '', + discountRate: 0, + discountAmount: 0, + discountLastAmount: 0, + deposit: 0, + accountId: undefined, + receiptDate: '', + warehouseId: '', + multipleAccountIds: undefined, + multipleAccountAmounts: undefined, +}); + +const purchaseStorageFormState = reactive({ + id: undefined, + supplierId: '', + receiptNumber: '', + otherReceipt: '', + remark: '', + paymentRate: 0, + paymentAmount: 0, + paymentLastAmount: 0, + otherAmount: 0, + thisPaymentAmount: 0, + thisArrearsAmount: 0, + status: undefined, + accountId: undefined, + receiptDate: '', + warehouseId: '', + multipleAccountIds: undefined, + multipleAccountAmounts: undefined, +}); + +const purchaseRefundFormState = reactive({ + id: undefined, + supplierId: '', + receiptNumber: '', + otherReceipt: '', + remark: '', + refundOfferRate: 0, + refundOfferAmount: 0, + refundLastAmount: 0, + otherAmount: 0, + thisRefundAmount: 0, + thisArrearsAmount: 0, + status: undefined, + accountId: undefined, + receiptDate: '', + warehouseId: '', + multipleAccountIds: undefined, + multipleAccountAmounts: undefined, +}); + +export { + xGrid, + sumNum, + tableData, + orderGridOptions, + gridOptions, + purchaseOrderFormState, + purchaseStorageFormState, + purchaseRefundFormState, + getTaxTotalPrice, +} \ No newline at end of file diff --git a/src/views/purchase/order/components/AddEditModal.vue b/src/views/purchase/order/components/AddEditModal.vue new file mode 100644 index 0000000..54490da --- /dev/null +++ b/src/views/purchase/order/components/AddEditModal.vue @@ -0,0 +1,998 @@ + + + + + \ No newline at end of file diff --git a/src/views/purchase/order/components/ViewOrderModal.vue b/src/views/purchase/order/components/ViewOrderModal.vue new file mode 100644 index 0000000..5a55351 --- /dev/null +++ b/src/views/purchase/order/components/ViewOrderModal.vue @@ -0,0 +1,197 @@ + + + diff --git a/src/views/purchase/order/index.vue b/src/views/purchase/order/index.vue new file mode 100644 index 0000000..dce1402 --- /dev/null +++ b/src/views/purchase/order/index.vue @@ -0,0 +1,239 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/purchase/order/purchaseOrder.data.ts b/src/views/purchase/order/purchaseOrder.data.ts new file mode 100644 index 0000000..6702043 --- /dev/null +++ b/src/views/purchase/order/purchaseOrder.data.ts @@ -0,0 +1,213 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {useI18n} from "@/hooks/web/useI18n"; +import {getSupplierList} from "@/api/basic/supplier"; + +export const { t } = useI18n(); + +export const columns: BasicColumn[] = [ + { + title: '供应商', + dataIndex: 'supplierName', + width: 130, + }, + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 130, + }, + { + title: '商品信息', + dataIndex: 'productInfo', + width: 80, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 50, + }, + { + title: '金额合计', + dataIndex: 'totalAmount', + width: 60, + }, + { + title: '含税合计', + dataIndex: 'taxRateTotalAmount', + width: 80, + }, + { + title: '收取定金', + dataIndex: 'deposit', + width: 80, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '操作员', + dataIndex: 'operator', + width: 60, + }, + { + title: '状态', + dataIndex: 'status', + width: 80, + }, +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '供应商', + field: 'supplierId', + component: 'ApiSelect', + componentProps: { + api: getSupplierList, + resultField: 'data', + labelField: 'supplierName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '商品信息', + field: 'productInfo', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '单据状态', + field: 'status', + component: 'Select', + colProps: { + xl: 8, + xxl: 8, + }, + componentProps: { + options: [ + { label: '未审核', value: 0, key: 0 }, + { label: '已审核', value: 1, key: 1 }, + { label: '部分采购', value: 2, key: 2 }, + { label: '完成采购', value: 3, key: 3 }, + ], + }, + }, + { + label: '单据备注', + field: 'remark', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + + } +] + +export const purchaseOrderTableColumns: BasicColumn[] = [ + { + title: '仓库名称', + dataIndex: 'warehouseName', + width: 100, + }, + { + title: '条码', + dataIndex: 'barCode', + width: 100, + }, + { + title: '商品名称', + dataIndex: 'productName', + width: 120, + }, + { + title: '规格', + dataIndex: 'productStandard', + width: 120, + }, + { + title: '型号', + dataIndex: 'productModel', + width: 120, + }, + { + title: '颜色', + dataIndex: 'productColor', + width: 70, + }, + { + title: '库存', + dataIndex: 'stock', + width: 80, + }, + { + title: '单位', + dataIndex: 'productUnit', + width: 60, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 60, + }, + { + title: '单价', + dataIndex: 'unitPrice', + width: 60, + }, + { + title: '金额', + dataIndex: 'amount', + width: 60, + }, + { + title: '税率(%)', + dataIndex: 'taxRate', + width: 60, + }, + { + title: '税额', + dataIndex: 'taxAmount', + width: 60, + }, + { + title: '价税合计', + dataIndex: 'taxTotalPrice', + width: 80, + }, + { + title: '备注', + dataIndex: 'remark', + width: 100, + }, +] \ No newline at end of file diff --git a/src/views/purchase/refund/components/AddEditModal.vue b/src/views/purchase/refund/components/AddEditModal.vue new file mode 100644 index 0000000..932a821 --- /dev/null +++ b/src/views/purchase/refund/components/AddEditModal.vue @@ -0,0 +1,1189 @@ + + + + + \ No newline at end of file diff --git a/src/views/purchase/refund/components/ViewRefundModal.vue b/src/views/purchase/refund/components/ViewRefundModal.vue new file mode 100644 index 0000000..0c04aef --- /dev/null +++ b/src/views/purchase/refund/components/ViewRefundModal.vue @@ -0,0 +1,231 @@ + + + diff --git a/src/views/purchase/refund/index.vue b/src/views/purchase/refund/index.vue new file mode 100644 index 0000000..4178cc4 --- /dev/null +++ b/src/views/purchase/refund/index.vue @@ -0,0 +1,242 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/purchase/refund/purchaseRefund.data.ts b/src/views/purchase/refund/purchaseRefund.data.ts new file mode 100644 index 0000000..281ae21 --- /dev/null +++ b/src/views/purchase/refund/purchaseRefund.data.ts @@ -0,0 +1,143 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {useI18n} from "@/hooks/web/useI18n"; +import {getSupplierList} from "@/api/basic/supplier"; + +export const { t } = useI18n(); + +export const columns: BasicColumn[] = [ + { + title: '供应商', + dataIndex: 'supplierName', + width: 130, + }, + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 130, + }, + { + title: '商品信息', + dataIndex: 'productInfo', + width: 80, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 50, + }, + { + title: '金额合计', + dataIndex: 'totalAmount', + width: 60, + }, + { + title: '含税合计', + dataIndex: 'taxIncludedAmount', + width: 80, + }, + { + title: '待退金额', + dataIndex: 'refundTotalAmount', + width: 80, + }, + { + title: '本次退款', + dataIndex: 'thisRefundAmount', + width: 80, + }, + { + title: '本次欠款', + dataIndex: 'thisArrearsAmount', + width: 80, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '操作员', + dataIndex: 'operator', + width: 60, + }, + { + title: '状态', + dataIndex: 'status', + width: 80, + }, +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '供应商', + field: 'supplierId', + component: 'ApiSelect', + componentProps: { + api: getSupplierList, + resultField: 'data', + labelField: 'supplierName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '商品信息', + field: 'productInfo', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '单据状态', + field: 'status', + component: 'Select', + colProps: { + xl: 8, + xxl: 8, + }, + componentProps: { + options: [ + { label: '未审核', value: 0, key: 0 }, + { label: '已审核', value: 1, key: 1 }, + ], + }, + }, + { + label: '单据备注', + field: 'remark', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + + } +] \ No newline at end of file diff --git a/src/views/purchase/storage/components/AddEditModal.vue b/src/views/purchase/storage/components/AddEditModal.vue new file mode 100644 index 0000000..5ccefc5 --- /dev/null +++ b/src/views/purchase/storage/components/AddEditModal.vue @@ -0,0 +1,1195 @@ + + + + + \ No newline at end of file diff --git a/src/views/purchase/storage/components/ViewStorageModal.vue b/src/views/purchase/storage/components/ViewStorageModal.vue new file mode 100644 index 0000000..7c9cb0a --- /dev/null +++ b/src/views/purchase/storage/components/ViewStorageModal.vue @@ -0,0 +1,223 @@ + + + diff --git a/src/views/purchase/storage/index.vue b/src/views/purchase/storage/index.vue new file mode 100644 index 0000000..bb85266 --- /dev/null +++ b/src/views/purchase/storage/index.vue @@ -0,0 +1,244 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/purchase/storage/purchaseStorage.data.ts b/src/views/purchase/storage/purchaseStorage.data.ts new file mode 100644 index 0000000..e06a410 --- /dev/null +++ b/src/views/purchase/storage/purchaseStorage.data.ts @@ -0,0 +1,145 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {useI18n} from "@/hooks/web/useI18n"; +import {getSupplierList} from "@/api/basic/supplier"; + +export const { t } = useI18n(); + +export const columns: BasicColumn[] = [ + { + title: '供应商', + dataIndex: 'supplierName', + width: 130, + }, + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 130, + }, + { + title: '商品信息', + dataIndex: 'productInfo', + width: 80, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 50, + }, + { + title: '金额合计', + dataIndex: 'totalAmount', + width: 60, + }, + { + title: '含税合计', + dataIndex: 'taxIncludedAmount', + width: 80, + }, + { + title: '待付金额', + dataIndex: 'totalPaymentAmount', + width: 80, + }, + { + title: '本次付款', + dataIndex: 'thisPaymentAmount', + width: 80, + }, + { + title: '本次欠款', + dataIndex: 'thisArrearsAmount', + width: 80, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '操作员', + dataIndex: 'operator', + width: 60, + }, + { + title: '状态', + dataIndex: 'status', + width: 80, + }, +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '供应商', + field: 'supplierId', + component: 'ApiSelect', + componentProps: { + api: getSupplierList, + resultField: 'data', + labelField: 'supplierName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '商品信息', + field: 'productInfo', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '单据状态', + field: 'status', + component: 'Select', + colProps: { + xl: 8, + xxl: 8, + }, + componentProps: { + options: [ + { label: '未审核', value: 0, key: 0 }, + { label: '已审核', value: 1, key: 1 }, + { label: '部分采购', value: 2, key: 2 }, + { label: '完成采购', value: 3, key: 3 }, + ], + }, + }, + { + label: '单据备注', + field: 'remark', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + + } +] \ No newline at end of file diff --git a/src/views/receipt/LinkReceiptModal.vue b/src/views/receipt/LinkReceiptModal.vue new file mode 100644 index 0000000..08b9317 --- /dev/null +++ b/src/views/receipt/LinkReceiptModal.vue @@ -0,0 +1,104 @@ + + + \ No newline at end of file diff --git a/src/views/receipt/ReceiptDetailModal.vue b/src/views/receipt/ReceiptDetailModal.vue new file mode 100644 index 0000000..cc62b86 --- /dev/null +++ b/src/views/receipt/ReceiptDetailModal.vue @@ -0,0 +1,73 @@ + + + \ No newline at end of file diff --git a/src/views/receipt/receipt.data.ts b/src/views/receipt/receipt.data.ts new file mode 100644 index 0000000..01d2426 --- /dev/null +++ b/src/views/receipt/receipt.data.ts @@ -0,0 +1,162 @@ +import {BasicColumn, FormSchema} from "@/components/Table"; + +export const ReceiptDetailColumn: BasicColumn[] = [ + { + title: 'id', + dataIndex: 'id', + width: 60, + ifShow: false, + }, + { + title: '条码', + dataIndex: 'productBarcode', + width: 130, + }, + { + title: '商品名称', + dataIndex: 'productName', + width: 130, + }, + { + title: '商品规格', + dataIndex: 'productStandard', + width: 100, + }, + { + title: '商品型号', + dataIndex: 'productModel', + width: 100, + }, + { + title: '单位', + dataIndex: 'unit', + width: 80, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 60, + }, + { + title: '单价', + dataIndex: 'unitPrice', + width: 60, + }, + { + title: '金额', + dataIndex: 'amount', + width: 60, + }, + { + title: '税率(%)', + dataIndex: 'taxRate', + width: 80, + }, + { + title: '税额', + dataIndex: 'taxAmount', + width: 80, + }, + { + title: '优惠合计', + dataIndex: 'taxIncludedAmount', + width: 80, + }, + { + title: '备注', + dataIndex: 'remark', + width: 100, + }, +] + +export const ReceiptColumn: BasicColumn[] = [ + { + title: 'id', + dataIndex: 'id', + width: 60, + ifShow: false, + }, + { + title: '名称', + dataIndex: 'name', + width: 70, + }, + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 190, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 150, + }, + { + title: '商品信息', + dataIndex: 'productInfo', + width: 200, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 70, + }, + { + title: '金额合计', + dataIndex: 'totalAmount', + width: 70, + }, + { + title: '含税合计', + dataIndex: 'taxRateTotalAmount', + width: 70, + }, + { + title: '操作员', + dataIndex: 'operator', + width: 80, + }, + { + title: '状态', + dataIndex: 'status', + width: 90, + }, +] + +export const searchSchema: FormSchema[] = [ + { + label: '类型', + field: 'type', + component: 'Input', + show: false, + }, + { + label: '子类型', + field: 'subType', + component: 'Input', + show: false, + }, + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { span: 8 }, + }, + { + label: '商品信息', + field: 'productInfo', + component: 'Input', + helpMessage: '支持商品名称、商品编号、商品规格、商品型号', + colProps: { span: 7 }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { span: 7 }, + }, +] \ No newline at end of file diff --git a/src/views/report/accountStatistics.vue b/src/views/report/accountStatistics.vue new file mode 100644 index 0000000..489132f --- /dev/null +++ b/src/views/report/accountStatistics.vue @@ -0,0 +1,147 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/report/customerBill.vue b/src/views/report/customerBill.vue new file mode 100644 index 0000000..79650a1 --- /dev/null +++ b/src/views/report/customerBill.vue @@ -0,0 +1,174 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/report/modal/AccountFlowModal.vue b/src/views/report/modal/AccountFlowModal.vue new file mode 100644 index 0000000..4d97fda --- /dev/null +++ b/src/views/report/modal/AccountFlowModal.vue @@ -0,0 +1,149 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/report/modal/CustomerBillDetailModal.vue b/src/views/report/modal/CustomerBillDetailModal.vue new file mode 100644 index 0000000..8ffade7 --- /dev/null +++ b/src/views/report/modal/CustomerBillDetailModal.vue @@ -0,0 +1,170 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/report/modal/StockFlowModal.vue b/src/views/report/modal/StockFlowModal.vue new file mode 100644 index 0000000..57f2193 --- /dev/null +++ b/src/views/report/modal/StockFlowModal.vue @@ -0,0 +1,180 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/report/modal/SupplierBillDetailModal.vue b/src/views/report/modal/SupplierBillDetailModal.vue new file mode 100644 index 0000000..9de57e8 --- /dev/null +++ b/src/views/report/modal/SupplierBillDetailModal.vue @@ -0,0 +1,171 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/report/productStock.vue b/src/views/report/productStock.vue new file mode 100644 index 0000000..01b0535 --- /dev/null +++ b/src/views/report/productStock.vue @@ -0,0 +1,160 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/report/purchaseStatistics.vue b/src/views/report/purchaseStatistics.vue new file mode 100644 index 0000000..9e2e729 --- /dev/null +++ b/src/views/report/purchaseStatistics.vue @@ -0,0 +1,143 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/report/report.data.ts b/src/views/report/report.data.ts new file mode 100644 index 0000000..932133d --- /dev/null +++ b/src/views/report/report.data.ts @@ -0,0 +1,1452 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {getWarehouseList} from "@/api/basic/warehouse"; +import {getCategoryList} from "@/api/product/productCategory"; +import {getMemberList} from "@/api/basic/member"; +import {getSupplierList} from "@/api/basic/supplier"; +import {getCustomerList} from "@/api/basic/customer"; +import {getRelatedPerson} from "@/api/report/report"; +import {getOperatorList} from "@/api/basic/operator"; +export const productStockColumns: BasicColumn[] = [ + { + title: '产品id', + dataIndex: 'productId', + width: 120, + ifShow: false + }, + { + title: '仓库id', + dataIndex: 'warehouseId', + width: 60, + ifShow: false + }, + { + title: '库存流水', + dataIndex: 'id', + width: 80, + }, + { + title: '商品条码', + dataIndex: 'productBarcode', + width: 120, + }, + { + title: '仓库', + dataIndex: 'warehouseName', + width: 120, + }, + { + title: '商品名称', + dataIndex: 'productName', + width: 120, + }, + { + title: '商品类别', + dataIndex: 'productCategoryName', + width: 80, + }, + { + title: '规格', + dataIndex: 'productStandard', + width: 120, + }, + { + title: '型号', + dataIndex: 'productModel', + width: 120, + }, + { + title: '重量', + dataIndex: 'productWeight', + width: 80, + }, + { + title: '颜色', + dataIndex: 'productColor', + width: 80, + }, + { + title: '单位', + dataIndex: 'productUnit', + width: 80, + }, + { + title: '仓位货架', + dataIndex: 'warehouseShelves', + width: 100, + }, + { + title: '单价', + dataIndex: 'unitPrice', + width: 70, + }, + { + title: '初始库存', + dataIndex: 'initialStock', + width: 70, + }, + { + title: '当前库存', + dataIndex: 'currentStock', + width: 70, + }, + { + title: '库存金额', + dataIndex: 'stockAmount', + width: 90, + }, +] + +export const searchProductStockSchema: FormSchema[] = [ + { + label: '仓库', + field: 'warehouseId', + component: 'ApiSelect', + componentProps: { + api: getWarehouseList, + resultField: 'data', + labelField: 'warehouseName', + valueField: 'id', + }, + colProps: { span: 5 }, + }, + { + label: '商品信息', + field: 'productInfo', + component: 'Input', + colProps: { span: 5 }, + }, + { + label: '商品类别', + field: 'productCategoryId', + component: 'ApiTreeSelect', + componentProps: { + api: getCategoryList, + resultField: 'data', + labelField: 'categoryName', + valueField: 'id', + }, + colProps: { span: 5 } + }, + { + label: '仓位货架', + field: 'warehouseShelves', + component: 'Input', + colProps: { span: 5 }, + }, +] + +export const stockFlowColumns: BasicColumn[] = [ + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 180, + }, + { + title: '类型', + dataIndex: 'type', + width: 80, + }, + { + title: '商品条码', + dataIndex: 'productBarcode', + width: 120, + }, + { + title: '商品名称', + dataIndex: 'productName', + width: 120, + }, + { + title: '仓库', + dataIndex: 'warehouseName', + width: 120, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 60, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 150, + } +] + +export const searchStockFlowSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { span: 10 }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { span: 10 }, + }, +] + +export const accountStatisticsColumns: BasicColumn[] = [ + { + title: '账户流水', + dataIndex: 'accountId', + width: 80, + }, + { + title: '账户名称', + dataIndex: 'accountName', + width: 180, + }, + { + title: '账户编号', + dataIndex: 'accountNumber', + width: 120, + }, + { + title: '期初金额', + dataIndex: 'initialAmount', + width: 120, + }, + { + title: '本月发生金额', + dataIndex: 'thisMonthChangeAmount', + width: 120, + }, + { + title: '当前余额', + dataIndex: 'currentAmount', + width: 120, + }, +] + +export const searchAccountSchema: FormSchema[] = [ + { + label: '账户名称', + field: 'accountName', + component: 'Input', + colProps: { span: 10 }, + }, + { + label: '账户编号', + field: 'accountNumber', + component: 'Input', + colProps: { span: 10 }, + }, +] + +export const accountFlowColumns: BasicColumn[] = [ + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 180, + }, + { + title: '单据类型', + dataIndex: 'subType', + width: 80, + }, + { + title: '收付款放', + dataIndex: 'useType', + width: 90, + }, + { + title: '名称', + dataIndex: 'name', + width: 120, + }, + { + title: '金额', + dataIndex: 'amount', + width: 110, + }, + { + title: '余额', + dataIndex: 'balance', + width: 110, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 150, + } +] + +export const searchRetailSchema: FormSchema[] = [ + { + label: '商品信息', + field: 'productExtendInfo', + component: 'Input', + colProps: { span: 7 }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { span: 7 }, + }, + { + label: '会员卡号', + field: 'memberId', + component: 'ApiSelect', + componentProps: { + api: getMemberList, + resultField: 'data', + labelField: 'memberName', + valueField: 'id', + }, + colProps: { span: 7 }, + }, +] + +export const retailStatisticsColumns: BasicColumn[] = [ + { + title: '商品条码', + dataIndex: 'productBarcode', + width: 100, + }, + { + title: '仓库', + dataIndex: 'warehouseName', + width: 100, + }, + { + title: '商品名称', + dataIndex: 'productName', + width: 120, + }, + { + title: '规格', + dataIndex: 'productStandard', + width: 120, + }, + { + title: '型号', + dataIndex: 'productModel', + width: 90, + }, + { + title: '扩展信息', + dataIndex: 'productExtendInfo', + width: 120, + }, + { + title: '单位', + dataIndex: 'productUnit', + width: 80, + }, + { + title: '零售数量', + dataIndex: 'retailNumber', + width: 70, + }, + { + title: '零售金额', + dataIndex: 'retailAmount', + width: 70, + }, + { + title: '零售退货数量', + dataIndex: 'retailRefundNumber', + width: 70, + }, + { + title: '零售退货金额', + dataIndex: 'retailRefundAmount', + width: 70, + }, + { + title: '实际零售金额', + dataIndex: 'retailLastAmount', + width: 70, + } +] + + +export const searchPurchaseSchema: FormSchema[] = [ + { + label: '商品信息', + field: 'productExtendInfo', + component: 'Input', + colProps: { span: 7 }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { span: 7 }, + }, + { + label: '供应商', + field: 'supplierId', + component: 'ApiSelect', + componentProps: { + api: getSupplierList, + resultField: 'data', + labelField: 'supplierName', + valueField: 'id', + }, + colProps: { span: 7 }, + }, +] + +export const purchaseStatisticsColumns: BasicColumn[] = [ + { + title: '商品条码', + dataIndex: 'productBarcode', + width: 100, + }, + { + title: '仓库', + dataIndex: 'warehouseName', + width: 100, + }, + { + title: '商品名称', + dataIndex: 'productName', + width: 120, + }, + { + title: '规格', + dataIndex: 'productStandard', + width: 120, + }, + { + title: '型号', + dataIndex: 'productModel', + width: 90, + }, + { + title: '扩展信息', + dataIndex: 'productExtendInfo', + width: 120, + }, + { + title: '单位', + dataIndex: 'productUnit', + width: 80, + }, + { + title: '采购数量', + dataIndex: 'purchaseNumber', + width: 70, + }, + { + title: '采购金额', + dataIndex: 'purchaseAmount', + width: 70, + }, + { + title: '采购退货数量', + dataIndex: 'purchaseRefundNumber', + width: 70, + }, + { + title: '采购退货金额', + dataIndex: 'purchaseRefundAmount', + width: 70, + }, + { + title: '实际采购金额', + dataIndex: 'purchaseLastAmount', + width: 70, + } +] + +export const searchSalesSchema: FormSchema[] = [ + { + label: '商品信息', + field: 'productExtendInfo', + component: 'Input', + colProps: { span: 7 }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { span: 7 }, + }, + { + label: '客户', + field: 'customerId', + component: 'ApiSelect', + componentProps: { + api: getCustomerList, + resultField: 'data', + labelField: 'customerName', + valueField: 'id', + }, + colProps: { span: 7 }, + }, +] + +export const salesStatisticsColumns: BasicColumn[] = [ + { + title: '商品条码', + dataIndex: 'productBarcode', + width: 100, + }, + { + title: '仓库', + dataIndex: 'warehouseName', + width: 100, + }, + { + title: '商品名称', + dataIndex: 'productName', + width: 120, + }, + { + title: '规格', + dataIndex: 'productStandard', + width: 120, + }, + { + title: '型号', + dataIndex: 'productModel', + width: 90, + }, + { + title: '扩展信息', + dataIndex: 'productExtendInfo', + width: 120, + }, + { + title: '单位', + dataIndex: 'productUnit', + width: 80, + }, + { + title: '销售数量', + dataIndex: 'salesNumber', + width: 70, + }, + { + title: '销售金额', + dataIndex: 'salesAmount', + width: 70, + }, + { + title: '销售退货数量', + dataIndex: 'salesRefundNumber', + width: 70, + }, + { + title: '销售退货金额', + dataIndex: 'salesRefundAmount', + width: 70, + }, + { + title: '实际销售金额', + dataIndex: 'salesLastAmount', + width: 70, + } +] + +export const searchShipmentsDetailSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '商品信息', + field: 'productInfo', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '往来单位', + field: 'relatedPersonId', + component: 'ApiSelect', + componentProps: { + api: getRelatedPerson, + resultField: 'data', + labelField: 'name', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '仓库', + field: 'warehouseId', + component: 'ApiSelect', + componentProps: { + api: getWarehouseList, + resultField: 'data', + labelField: 'warehouseName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '操作人员', + field: 'operatorId', + component: 'ApiSelect', + componentProps: { + api: getOperatorList, + params: "所有", + resultField: 'data', + labelField: 'name', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '单据备注', + field: 'remark', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + } +] + +export const shipmentsDetailStatisticsColumns: BasicColumn[] = [ + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 170, + }, + { + title: '类型', + dataIndex: 'type', + width: 70, + }, + { + title: '往来人员', + dataIndex: 'name', + width: 70, + }, + { + title: '商品条码', + dataIndex: 'productBarcode', + width: 100, + }, + { + title: '仓库', + dataIndex: 'warehouseName', + width: 100, + }, + { + title: '商品名称', + dataIndex: 'productName', + width: 120, + }, + { + title: '规格', + dataIndex: 'productStandard', + width: 120, + }, + { + title: '型号', + dataIndex: 'productModel', + width: 90, + }, + { + title: '单位', + dataIndex: 'productUnit', + width: 60, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 65, + }, + { + title: '单价', + dataIndex: 'unitPrice', + width: 65, + }, + { + title: '金额', + dataIndex: 'amount', + width: 75, + }, + { + title: '税率(%)', + dataIndex: 'taxRate', + width: 65, + }, + { + title: '税额', + dataIndex: 'taxAmount', + width: 70, + }, + { + title: '出库时间', + dataIndex: 'createTime', + width: 140, + }, +] + +export const searchStorageDetailSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '商品信息', + field: 'productInfo', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '往来单位', + field: 'relatedPersonId', + component: 'ApiSelect', + componentProps: { + api: getRelatedPerson, + resultField: 'data', + labelField: 'name', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '仓库', + field: 'warehouseId', + component: 'ApiSelect', + componentProps: { + api: getWarehouseList, + resultField: 'data', + labelField: 'warehouseName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '操作人员', + field: 'operatorId', + component: 'ApiSelect', + componentProps: { + api: getOperatorList, + params: "所有", + resultField: 'data', + labelField: 'name', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '单据备注', + field: 'remark', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + } +] + +export const storageDetailStatisticsColumns: BasicColumn[] = [ + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 170, + }, + { + title: '类型', + dataIndex: 'type', + width: 70, + }, + { + title: '往来人员', + dataIndex: 'name', + width: 70, + }, + { + title: '商品条码', + dataIndex: 'productBarcode', + width: 100, + }, + { + title: '仓库', + dataIndex: 'warehouseName', + width: 100, + }, + { + title: '商品名称', + dataIndex: 'productName', + width: 120, + }, + { + title: '规格', + dataIndex: 'productStandard', + width: 120, + }, + { + title: '型号', + dataIndex: 'productModel', + width: 90, + }, + { + title: '单位', + dataIndex: 'productUnit', + width: 80, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 65, + }, + { + title: '单价', + dataIndex: 'unitPrice', + width: 65, + }, + { + title: '金额', + dataIndex: 'amount', + width: 65, + }, + { + title: '税率(%)', + dataIndex: 'taxRate', + width: 65, + }, + { + title: '税额', + dataIndex: 'taxAmount', + width: 65, + }, + { + title: '入库时间', + dataIndex: 'createTime', + width: 140, + }, +] + +export const searchShipmentsSummarySchema: FormSchema[] = [ + { + label: '商品信息', + field: 'productInfo', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '往来单位', + field: 'relatedPersonId', + component: 'ApiSelect', + componentProps: { + api: getRelatedPerson, + resultField: 'data', + labelField: 'name', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '仓库', + field: 'warehouseId', + component: 'ApiSelect', + componentProps: { + api: getWarehouseList, + resultField: 'data', + labelField: 'warehouseName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + } +] + +export const shipmentsSummaryStatisticsColumns: BasicColumn[] = [ + { + title: '商品条码', + dataIndex: 'productBarcode', + width: 100, + }, + { + title: '仓库', + dataIndex: 'warehouseName', + width: 100, + }, + { + title: '商品名称', + dataIndex: 'productName', + width: 120, + }, + { + title: '商品分类', + dataIndex: 'productCategoryName', + width: 100, + }, + { + title: '规格', + dataIndex: 'productStandard', + width: 120, + }, + { + title: '型号', + dataIndex: 'productModel', + width: 90, + }, + { + title: '单位', + dataIndex: 'productUnit', + width: 60, + }, + { + title: '出库数量', + dataIndex: 'shipmentsNumber', + width: 65, + }, + { + title: '出库金额', + dataIndex: 'shipmentsAmount', + width: 65, + }, + { + title: '出库时间', + dataIndex: 'createTime', + width: 140, + }, +] + +export const searchStorageSummarySchema: FormSchema[] = [ + { + label: '商品信息', + field: 'productInfo', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '往来单位', + field: 'relatedPersonId', + component: 'ApiSelect', + componentProps: { + api: getRelatedPerson, + resultField: 'data', + labelField: 'name', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '仓库', + field: 'warehouseId', + component: 'ApiSelect', + componentProps: { + api: getWarehouseList, + resultField: 'data', + labelField: 'warehouseName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + } +] + +export const storageSummaryStatisticsColumns: BasicColumn[] = [ + { + title: '商品条码', + dataIndex: 'productBarcode', + width: 100, + }, + { + title: '仓库', + dataIndex: 'warehouseName', + width: 100, + }, + { + title: '商品名称', + dataIndex: 'productName', + width: 120, + }, + { + title: '商品分类', + dataIndex: 'productCategoryName', + width: 100, + }, + { + title: '规格', + dataIndex: 'productStandard', + width: 120, + }, + { + title: '型号', + dataIndex: 'productModel', + width: 90, + }, + { + title: '单位', + dataIndex: 'productUnit', + width: 60, + }, + { + title: '入库数量', + dataIndex: 'storageNumber', + width: 65, + }, + { + title: '入库金额', + dataIndex: 'storageAmount', + width: 65, + }, + { + title: '入库时间', + dataIndex: 'createTime', + width: 140, + }, +] + +export const searchCustomerBillSchema: FormSchema[] = [ + { + label: '客户', + field: 'customerId', + component: 'ApiSelect', + componentProps: { + api: getCustomerList, + resultField: 'data', + labelField: 'customerName', + valueField: 'id', + }, + colProps: { span: 7 }, + }, + { + field: '[startDate, endDate]', + label: '账单日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 9, + xxl: 9, + }, + }, +] + +export const customerBillColumns: BasicColumn[] = [ + { + title: '欠款详情', + dataIndex: 'customerId', + width: 60, + }, + { + title: '客户', + dataIndex: 'customerName', + width: 100, + }, + { + title: '联系人', + dataIndex: 'contactName', + width: 80, + }, + { + title: '联系电话', + dataIndex: 'contactPhone', + width: 100, + }, + { + title: '电子邮箱', + dataIndex: 'email', + width: 120, + }, + { + title: '一季度应收账款', + dataIndex: 'firstQuarterReceivable', + width: 80, + }, + { + title: '二季度应收账款', + dataIndex: 'secondQuarterReceivable', + width: 80, + }, + { + title: '三季度应收账款', + dataIndex: 'thirdQuarterReceivable', + width: 80, + }, + { + title: '四季度应收账款', + dataIndex: 'fourthQuarterReceivable', + width: 80, + }, + { + title: '累计欠款', + dataIndex: 'totalQuarterArrears', + width: 100, + }, + { + title: '累计收款', + dataIndex: 'totalQuarterReceivable', + width: 100, + }, + { + title: '应收欠款', + dataIndex: 'remainingReceivableArrears', + width: 100, + helpMessage: '应收欠款=4个季度的应收账款+累计欠款' + }, +] + + +export const searchCustomerBillDetailSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '商品信息', + field: 'productInfo', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '账单日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, +] + +export const customerBillDetailColumns: BasicColumn[] = [ + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 180, + }, + { + title: '客户', + dataIndex: 'customerName', + width: 120, + }, + { + title: '商品信息', + dataIndex: 'productInfo', + width: 150, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '操作员', + dataIndex: 'operator', + width: 80, + }, + { + title: '本单欠款', + dataIndex: 'thisReceiptArrears', + width: 65, + }, + { + title: '已收欠款', + dataIndex: 'receivedArrears', + width: 65, + }, + { + title: '待收欠款', + dataIndex: 'receivableArrears', + width: 65, + }, +] + +export const searchSupplierBillSchema: FormSchema[] = [ + { + label: '供应商', + field: 'supplierId', + component: 'ApiSelect', + componentProps: { + api: getSupplierList, + resultField: 'data', + labelField: 'supplierName', + valueField: 'id', + }, + colProps: { span: 7 }, + }, + { + field: '[startDate, endDate]', + label: '账单周期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 9, + xxl: 9, + }, + }, +] + +export const supplierBillColumns: BasicColumn[] = [ + { + title: '欠款详情', + dataIndex: 'supplierId', + width: 60, + }, + { + title: '供应商', + dataIndex: 'supplierName', + width: 100, + }, + { + title: '联系人', + dataIndex: 'contactName', + width: 80, + }, + { + title: '联系电话', + dataIndex: 'contactPhone', + width: 100, + }, + { + title: '电子邮箱', + dataIndex: 'email', + width: 120, + }, + { + title: '一季度应付账款', + dataIndex: 'firstQuarterPayment', + width: 80, + }, + { + title: '二季度应付账款', + dataIndex: 'secondQuarterPayment', + width: 80, + }, + { + title: '三季度应付账款', + dataIndex: 'thirdQuarterPayment', + width: 80, + }, + { + title: '四季度应付账款', + dataIndex: 'fourthQuarterPayment', + width: 80, + }, + { + title: '累计欠款', + dataIndex: 'totalArrears', + width: 100, + }, + { + title: '累计付款', + dataIndex: 'totalPayment', + width: 100, + }, + { + title: '应付欠款', + dataIndex: 'remainingPaymentArrears', + width: 100, + helpMessage: '应付欠款=4个季度的应付账款+累计欠款' + }, +] + +export const searchSupplierBillDetailSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '商品信息', + field: 'productInfo', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '账单日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, +] + +export const supplierBillDetailColumns: BasicColumn[] = [ + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 180, + }, + { + title: '供应商', + dataIndex: 'supplierName', + width: 140, + }, + { + title: '商品信息', + dataIndex: 'productInfo', + width: 150, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '操作员', + dataIndex: 'operator', + width: 70, + }, + { + title: '本单欠款', + dataIndex: 'thisReceiptArrears', + width: 65, + }, + { + title: '已付欠款', + dataIndex: 'prepaidArrears', + width: 65, + }, + { + title: '待付欠款', + dataIndex: 'paymentArrears', + width: 65, + }, +] \ No newline at end of file diff --git a/src/views/report/retailStatistics.vue b/src/views/report/retailStatistics.vue new file mode 100644 index 0000000..3af8687 --- /dev/null +++ b/src/views/report/retailStatistics.vue @@ -0,0 +1,144 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/report/saleStatistics.vue b/src/views/report/saleStatistics.vue new file mode 100644 index 0000000..8e2e29b --- /dev/null +++ b/src/views/report/saleStatistics.vue @@ -0,0 +1,143 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/report/shipmentsDetail.vue b/src/views/report/shipmentsDetail.vue new file mode 100644 index 0000000..4fa6a79 --- /dev/null +++ b/src/views/report/shipmentsDetail.vue @@ -0,0 +1,176 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/report/shipmentsSummary.vue b/src/views/report/shipmentsSummary.vue new file mode 100644 index 0000000..e7fe38c --- /dev/null +++ b/src/views/report/shipmentsSummary.vue @@ -0,0 +1,132 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/report/storageDetail.vue b/src/views/report/storageDetail.vue new file mode 100644 index 0000000..655fdce --- /dev/null +++ b/src/views/report/storageDetail.vue @@ -0,0 +1,180 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/report/storageSummary.vue b/src/views/report/storageSummary.vue new file mode 100644 index 0000000..ad4be1d --- /dev/null +++ b/src/views/report/storageSummary.vue @@ -0,0 +1,133 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/report/supplierBill.vue b/src/views/report/supplierBill.vue new file mode 100644 index 0000000..3e5e550 --- /dev/null +++ b/src/views/report/supplierBill.vue @@ -0,0 +1,169 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/retail/refund/components/AddEditModal.vue b/src/views/retail/refund/components/AddEditModal.vue new file mode 100644 index 0000000..019d77a --- /dev/null +++ b/src/views/retail/refund/components/AddEditModal.vue @@ -0,0 +1,859 @@ + + + + + \ No newline at end of file diff --git a/src/views/retail/refund/components/ViewRefundModal.vue b/src/views/retail/refund/components/ViewRefundModal.vue new file mode 100644 index 0000000..e761606 --- /dev/null +++ b/src/views/retail/refund/components/ViewRefundModal.vue @@ -0,0 +1,215 @@ + + + diff --git a/src/views/retail/refund/index.vue b/src/views/retail/refund/index.vue new file mode 100644 index 0000000..f4fd175 --- /dev/null +++ b/src/views/retail/refund/index.vue @@ -0,0 +1,240 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/retail/refund/refund.data.ts b/src/views/retail/refund/refund.data.ts new file mode 100644 index 0000000..9a8cdc6 --- /dev/null +++ b/src/views/retail/refund/refund.data.ts @@ -0,0 +1,213 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {useI18n} from "@/hooks/web/useI18n"; +import {getMemberList} from "@/api/basic/member"; +import {getAccountList} from "@/api/financial/account"; +import {h, Text} from "vue"; +import {Input} from "ant-design-vue"; + +export const { t } = useI18n(); + +export const columns: BasicColumn[] = [ + { + title: '会员', + dataIndex: 'memberName', + width: 60, + }, + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 130, + }, + { + title: '商品信息', + dataIndex: 'productInfo', + width: 80, + }, + { + title: '金额合计', + dataIndex: 'totalPrice', + width: 60, + }, + { + title: '付款金额', + dataIndex: 'paymentAmount', + width: 80, + }, + { + title: '找零金额', + dataIndex: 'backAmount', + width: 80, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '操作员', + dataIndex: 'operator', + width: 60, + }, + { + title: '状态', + dataIndex: 'status', + width: 80, + }, +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { span: 7 }, + }, + { + label: '结算账户', + field: 'accountId', + component: 'ApiSelect', + componentProps: { + api: getAccountList, + resultField: 'data', + labelField: 'accountName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '商品信息', + field: 'productInfo', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '会员卡号', + field: 'memberId', + component: 'ApiSelect', + componentProps: { + api: getMemberList, + resultField: 'data', + labelField: 'memberName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '单据状态', + field: 'status', + component: 'Select', + colProps: { + xl: 8, + xxl: 8, + }, + componentProps: { + options: [ + { label: '未审核', value: 0, key: 0 }, + { label: '已审核', value: 1, key: 1 }, + ], + }, + }, + { + label: '单据备注', + field: 'remark', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + + } +] + +export const RetailShipmentsColumn: BasicColumn[] = [ + { + title: '单据主ID', + dataIndex: 'id', + width: 60, + ifShow: false, + }, + { + title: '会员', + dataIndex: 'memberName', + width: 60, + }, + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 130, + }, + { + title: '商品信息', + dataIndex: 'productInfo', + width: 80, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 80, + }, + { + title: '金额合计', + dataIndex: 'totalPrice', + width: 80, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '状态', + dataIndex: 'status', + width: 80, + }, +] + +export const searchRetailShipmentsSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { span: 8 }, + }, + { + label: '商品信息', + field: 'productInfo', + component: 'Input', + helpMessage: '支持商品名称、商品编号、商品规格、商品型号', + colProps: { span: 7 }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { span: 7 }, + }, +] \ No newline at end of file diff --git a/src/views/retail/shipments/components/AddEditModal.vue b/src/views/retail/shipments/components/AddEditModal.vue new file mode 100644 index 0000000..55c4c17 --- /dev/null +++ b/src/views/retail/shipments/components/AddEditModal.vue @@ -0,0 +1,838 @@ + + + + + \ No newline at end of file diff --git a/src/views/retail/shipments/components/ViewShipmentModal.vue b/src/views/retail/shipments/components/ViewShipmentModal.vue new file mode 100644 index 0000000..e1f0de7 --- /dev/null +++ b/src/views/retail/shipments/components/ViewShipmentModal.vue @@ -0,0 +1,211 @@ + + + diff --git a/src/views/retail/shipments/index.vue b/src/views/retail/shipments/index.vue new file mode 100644 index 0000000..d899348 --- /dev/null +++ b/src/views/retail/shipments/index.vue @@ -0,0 +1,243 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/retail/shipments/model/addEditModel.ts b/src/views/retail/shipments/model/addEditModel.ts new file mode 100644 index 0000000..42801e8 --- /dev/null +++ b/src/views/retail/shipments/model/addEditModel.ts @@ -0,0 +1,230 @@ +import {reactive, ref} from "vue"; +import XEUtils from "xe-utils"; +import {VxeGridInstance, VxeGridProps} from "vxe-table"; +import {Dayjs} from "dayjs"; + +interface FormState { + id: number | string | undefined; + memberId: string; + receiptNumber: string; + paymentType: string; + remark: string; + receiptAmount: number; + paymentAmount: number; + scanBarCode: string; + otherReceipt: string; + collectAmount: number; + backAmount: number; + accountId: string; + receiptDate: string | undefined | Dayjs; +} + + +export interface RowVO { + [key: string]: any, + warehouseId: number | string, + barCode: number | string, + productName:string, + productStandard: string, + stock: number, + productUnit: string, + productNumber: number, + retailPrice: number, + amount: number, +} + +const xGrid = ref>() +const tableData = ref([]) +const gridOptions = reactive>({ + border: true, + showHeaderOverflow: true, + showOverflow: true, + showFooter: true, + keepSource: true, + id: 'full_edit', + height: 400, + rowConfig: { + keyField: 'id', + isHover: true + }, + columnConfig: { + resizable: true + }, + printConfig: { + columns: [ + { field: 'warehouseId' }, + { field: 'barCode' }, + { field: 'productName' }, + { field: 'productStandard' }, + { field: 'stockNumber' }, + { field: 'productUnit' }, + { field: 'productNumber' }, + { field: 'retailPrice' }, + { field: 'amount' }, + { field: 'remark' } + ] + }, + sortConfig: { + trigger: 'cell', + remote: true + }, + filterConfig: { + remote: true + }, + pagerConfig: { + enabled: true, + pageSize: 10, + pageSizes: [5, 10, 15, 20, 50, 100, 200, 500, 1000] + }, + formConfig: { + titleWidth: 100, + titleAlign: 'right', + items: [ + ] + }, + toolbarConfig: { + slots: { + buttons: 'toolbar_buttons' + }, + refresh: true, // 显示刷新按钮 + export: true, // 显示导出按钮 + print: true, // 显示打印按钮 + zoom: true, // 显示全屏按钮 + custom: true // 显示自定义列按钮 + }, + columns: [ + { type: 'checkbox', field:'productId', title: 'ID', width: 80}, + { + field: 'warehouseId', + title: '仓库名称', + width: 130, + editRender: { name: '$select', options: [], props: { placeholder: '请选择仓库' } } + }, + { field: 'barCode', + width:160, + title: '条码', + slots: { edit: 'barCode_edit' }, + titlePrefix: { content: '需要在商品管理添加商品' }, + editRender: { name: '$select', options: []} + }, + { + field: 'productName', + title: '名称', + width:160, + }, + { field: 'productStandard', title: '规格', width: 120, }, + { field: 'stock', title: '库存', width: 70}, + { field: 'productUnit', title: '单位', width: 70}, + { field: 'productNumber', title: '数量', sortable: true, width:100, + slots: { edit: 'product_number_edit' }, + editRender: { name: '$input', props: { type: 'number', min: 1, max: 9999 } }, }, + { + field: 'retailPrice', + title: '单价', width:105, + formatter ({ cellValue }) { + return cellValue ? `¥${XEUtils.commafy(XEUtils.toNumber(cellValue), { digits: 2 })}` : '' + }, + editRender: { name: '$input', props: { type: 'float', digits: 2, placeholder: '输入单价' } } + }, + { + field: 'amount', + title: '金额', width:105, + formatter ({ cellValue }) { + return cellValue ? `¥${XEUtils.commafy(XEUtils.toNumber(cellValue), { digits: 2 })}` : '' + }, + slots: { edit: 'amount_edit' }, + editRender: { name: '$input', props: { type: 'float', digits: 2, placeholder: '输入金额' } } + }, + // { field: 'remark', title: '备注', editRender: { name: 'input', attrs: { placeholder: '请输入备注' } } }, + + ], + footerMethod ({ columns, data }) { + return [ + columns.map((column, columnIndex) => { + if (columnIndex === 0) { + return '总计' + } + if (['amount', 'rate'].includes(column.field)) { + // 设置单价 = 金额 / 数量 设置保留两位小数 + data.forEach(item => { + const price = item.amount / item.productNumber + item.retailPrice = XEUtils.toFixed(price, 2) + }) + receiptAmount.value = `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + collectAmount.value = `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + paymentAmount.value = `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + if (['productNumber', 'rate'].includes(column.field)) { + // 设置单价 = 金额 / 数量 + data.forEach(item => { + const price = item.amount / item.productNumber + item.retailPrice = XEUtils.toFixed(price, 2) + }) + return sumNum(data, column.field) + } + if (['productUnit', 'rate'].includes(column.field)) { + // 获取单价和数量进相乘计算赋值给金额 保留两位小数 + data.forEach(item => { + const amount = item.productNumber * item.retailPrice + item.amount = XEUtils.toFixed(amount, 2) + }) + } + return '' + }) + ] + }, + checkboxConfig: { + labelField: 'id', + reserve: true, + highlight: true, + range: true + }, + editRules: { + warehouseId: [ + { required: true, message: '仓库名称不能为空' } + ] + }, + editConfig: { + trigger: 'click', + mode: 'row', + showStatus: true + } +}) +const receiptAmount = ref(''); +const collectAmount = ref(''); + +const paymentAmount = ref(''); +const sumNum = (list: RowVO[], field: string) => { + let count = 0 + list.forEach(item => { + count += Number(item[field]) + }) + return count +} + +const formState = reactive({ + id: undefined, + memberId: '', + receiptNumber: '', + paymentType: '', + remark: '', + receiptAmount: 0, + scanBarCode: '', + collectAmount: 0, + paymentAmount: 0, + backAmount: 0, + accountId: '', + receiptDate: '', + otherReceipt: '', +}); + +export { + formState, + gridOptions, + xGrid, + receiptAmount, + collectAmount, + paymentAmount, + tableData +} \ No newline at end of file diff --git a/src/views/retail/shipments/shipments.data.ts b/src/views/retail/shipments/shipments.data.ts new file mode 100644 index 0000000..2c65271 --- /dev/null +++ b/src/views/retail/shipments/shipments.data.ts @@ -0,0 +1,224 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {useI18n} from "@/hooks/web/useI18n"; +import {getMemberList} from "@/api/basic/member"; +import {getAccountList} from "@/api/financial/account"; + +export const { t } = useI18n(); + +export const columns: BasicColumn[] = [ + { + title: '会员', + dataIndex: 'memberName', + width: 60, + }, + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 130, + }, + { + title: '商品信息', + dataIndex: 'productInfo', + width: 80, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 60, + }, + { + title: '金额合计', + dataIndex: 'totalPrice', + width: 60, + }, + { + title: '收款金额', + dataIndex: 'collectionAmount', + width: 80, + }, + { + title: '找零金额', + dataIndex: 'backAmount', + width: 80, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '操作员', + dataIndex: 'operator', + width: 60, + }, + { + title: '状态', + dataIndex: 'status', + width: 80, + }, +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { span: 7 }, + }, + { + label: '结算账户', + field: 'accountId', + component: 'ApiSelect', + componentProps: { + api: getAccountList, + resultField: 'data', + labelField: 'accountName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '商品信息', + field: 'productInfo', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '会员卡号', + field: 'memberId', + component: 'ApiSelect', + componentProps: { + api: getMemberList, + resultField: 'data', + labelField: 'memberName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + // { + // label: '仓库', + // field: 'warehouseId', + // component: 'ApiSelect', + // componentProps: { + // api: getWarehouseList, + // resultField: 'data', + // labelField: 'warehouseName', + // valueField: 'id', + // }, + // colProps: { + // xl: 8, + // xxl: 8, + // }, + // }, + { + label: '单据状态', + field: 'status', + component: 'Select', + colProps: { + xl: 8, + xxl: 8, + }, + componentProps: { + options: [ + { label: '未审核', value: 0, key: 0 }, + { label: '已审核', value: 1, key: 1 }, + ], + }, + }, + { + label: '单据备注', + field: 'remark', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + + } +] + +export const retailShipmentsTableColumns: BasicColumn[] = [ + { + title: '仓库名称', + dataIndex: 'warehouseName', + width: 100, + }, + { + title: '条码', + dataIndex: 'barCode', + width: 100, + }, + { + title: '商品名称', + dataIndex: 'productName', + width: 120, + }, + { + title: '规格', + dataIndex: 'productStandard', + width: 120, + }, + { + title: '型号', + dataIndex: 'productModel', + width: 120, + }, + { + title: '颜色', + dataIndex: 'productColor', + width: 70, + }, + { + title: '库存', + dataIndex: 'stock', + width: 80, + }, + { + title: '单位', + dataIndex: 'productUnit', + width: 60, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 60, + }, + { + title: '单价', + dataIndex: 'unitPrice', + width: 60, + }, + { + title: '金额', + dataIndex: 'amount', + width: 60, + }, + { + title: '备注', + dataIndex: 'remark', + width: 100, + }, +] \ No newline at end of file diff --git a/src/views/sales/model/addEditModel.ts b/src/views/sales/model/addEditModel.ts new file mode 100644 index 0000000..150b9ab --- /dev/null +++ b/src/views/sales/model/addEditModel.ts @@ -0,0 +1,473 @@ +import {reactive, ref} from "vue"; +import XEUtils from "xe-utils"; +import {VxeGridInstance, VxeGridProps} from "vxe-table"; +import {Dayjs} from "dayjs"; + +export interface RowVO { + [key: string]: any, + barCode: number | string, + productName:string, + productStandard: string, + stock: number, + productUnit: string, + productNumber: number, + unitPrice: number, + amount: number, + taxRate: number, + taxAmount: number, + taxTotalPrice: number, + remark: string, +} +interface SaleOrderFormState { + id: number | string | undefined; + customerId: string; + receiptNumber: string; + discountRate: number; + discountAmount: number; + discountLastAmount: number | string; + deposit: number; + remark: string; + operatorIds: number[] | undefined; + receiptDate: string | undefined | Dayjs; + warehouseId: number | string; + accountId: string | undefined; + multipleAccountIds: number[] | undefined; + multipleAccountAmounts: number[] | undefined; +} + +interface SaleShipmentsFormState { + id: number | string | undefined; + customerId: string; + accountId: number | string | undefined; + receiptNumber: string; + receiptDate: string | undefined | Dayjs; + otherReceipt: string; + collectOfferRate: number; + collectOfferAmount: number; + collectOfferLastAmount: number | string; + otherAmount: number; + thisCollectAmount: number; + thisArrearsAmount: number; + remark: string; + status: number | undefined; + operatorIds: number[] | undefined; + warehouseId: number | string; + multipleAccountIds: number[] | undefined; + multipleAccountAmounts: number[] | undefined; +} + +interface SaleRefundFormState { + id: number | string | undefined; + customerId: string; + accountId: number | string | undefined; + receiptNumber: string; + receiptDate: string | undefined | Dayjs; + otherReceipt: string; + refundOfferRate: number; + refundOfferAmount: number; + refundLastAmount: number | string; + otherAmount: number; + thisRefundAmount: number; + thisArrearsAmount: number; + remark: string; + status: number | undefined; + operatorIds: number[] | undefined; + warehouseId: number | string; + multipleAccountIds: number[] | undefined; + multipleAccountAmounts: number[] | undefined; +} + +const xGrid = ref>() +const tableData = ref([]) +const orderGridOptions = reactive>({ + border: true, + showHeaderOverflow: true, + showOverflow: true, + showFooter: true, + keepSource: true, + id: 'full_edit', + height: 400, + rowConfig: { + keyField: 'id', + isHover: true + }, + columnConfig: { + resizable: true + }, + printConfig: { + columns: [ + { field: 'barCode' }, + { field: 'productName' }, + { field: 'productStandard' }, + { field: 'stockNumber' }, + { field: 'productUnit' }, + { field: 'productNumber' }, + { field: 'retailPrice' }, + { field: 'amount' }, + { field: 'remark' } + ] + }, + sortConfig: { + trigger: 'cell', + remote: true + }, + filterConfig: { + remote: true + }, + pagerConfig: { + enabled: true, + pageSize: 10, + pageSizes: [5, 10, 15, 20, 50, 100, 200, 500, 1000] + }, + formConfig: { + titleWidth: 100, + titleAlign: 'right', + items: [ + ] + }, + toolbarConfig: { + slots: { + buttons: 'toolbar_buttons' + }, + refresh: true, // 显示刷新按钮 + print: true, // 显示打印按钮 + zoom: true, // 显示全屏按钮 + custom: true // 显示自定义列按钮 + }, + columns: [ + { type: 'checkbox', field:'productId', title: 'ID', width: 80}, + { field: 'barCode', + width:160, + title: '条码', + slots: { edit: 'barCode_edit' }, + titlePrefix: { content: '输入条码商品信息自动带出!' }, + editRender: { name: 'input', attrs: { placeholder: '请输入条码并回车' } } + }, + { + field: 'productName', + title: '名称', + width:160, + }, + { field: 'productStandard', title: '规格', width: 120, }, + { field: 'stock', title: '库存', width: 70}, + { field: 'productUnit', title: '单位', width: 70}, + { field: 'productNumber', title: '数量', sortable: true, width:100, + slots: { edit: 'product_number_edit' }, + editRender: { name: '$input', props: { type: 'number', min: 1, max: 9999 } }, + }, + { + field: 'unitPrice', + title: '单价', width:105, + formatter ({ cellValue }) { + return cellValue ? `¥${XEUtils.commafy(XEUtils.toNumber(cellValue), { digits: 2 })}` : '' + }, + slots: { edit: 'price_edit' }, + editRender: { name: '$input', props: { type: 'float', digits: 2, placeholder: '输入单价' } } + }, + { + field: 'amount', + title: '金额', width:105, + formatter ({ cellValue }) { + return cellValue ? `¥${XEUtils.commafy(XEUtils.toNumber(cellValue), { digits: 2 })}` : '' + }, + slots: { edit: 'amount_edit' }, + editRender: { name: '$input', props: { type: 'float', digits: 2, placeholder: '输入金额' } } + }, + { field: 'taxRate', title: '税率', width: 105, + slots: { edit: 'tax_rate_edit' }, + editRender: { name: '$input', attrs: { type: 'float', digits: 2, placeholder: '请输入税率' } } + }, + { field: 'taxAmount', title: '税额', width: 105, + editRender:{attrs: {type: 'float', digits: 2}}, + slots: { edit: 'tax_amount_edit' }, + }, + { field: 'taxTotalPrice', title: '价税合计', width: 105, + slots: { edit: 'tax_total_price_edit' }, + editRender: { name: '$input', attrs: {type: 'float', digits: 2, placeholder: '请输入价税合计' } } + }, + { field: 'remark', title: '备注', editRender: { name: 'input', attrs: { placeholder: '请输入备注' } } }, + + ], + footerMethod ({ columns, data }) { + return [ + columns.map((column, columnIndex) => { + if (columnIndex === 0) { + return '总计' + } + if (['amount', 'rate'].includes(column.field)) { + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + if (['productNumber', 'rate'].includes(column.field)) { + return sumNum(data, column.field) + } + if (['taxAmount', 'rate'].includes(column.field)) { + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + + if (['taxTotalPrice', 'rate'].includes(column.field)) { + getTaxTotalPrice.value = `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + return '' + }) + ] + }, + checkboxConfig: { + labelField: 'id', + reserve: true, + highlight: true, + range: true + }, + editRules: { + barCode: [ + { required: true, message: '商品条码不能为空' } + ] + }, + editConfig: { + trigger: 'click', + mode: 'row', + showStatus: true + } +}) + +const gridOptions = reactive>({ + border: true, + showHeaderOverflow: true, + showOverflow: true, + showFooter: true, + keepSource: true, + id: 'full_edit', + height: 400, + rowConfig: { + keyField: 'id', + isHover: true + }, + columnConfig: { + resizable: true + }, + printConfig: { + columns: [ + { field: 'barCode' }, + { field: 'productName' }, + { field: 'productStandard' }, + { field: 'stockNumber' }, + { field: 'productUnit' }, + { field: 'productNumber' }, + { field: 'retailPrice' }, + { field: 'amount' }, + { field: 'remark' } + ] + }, + sortConfig: { + trigger: 'cell', + remote: true + }, + filterConfig: { + remote: true + }, + pagerConfig: { + enabled: true, + pageSize: 10, + pageSizes: [5, 10, 15, 20, 50, 100, 200, 500, 1000] + }, + formConfig: { + titleWidth: 100, + titleAlign: 'right', + items: [ + ] + }, + toolbarConfig: { + slots: { + buttons: 'toolbar_buttons' + }, + refresh: true, // 显示刷新按钮 + print: true, // 显示打印按钮 + zoom: true, // 显示全屏按钮 + custom: true // 显示自定义列按钮 + }, + columns: [ + { type: 'checkbox', field:'productId', title: 'ID', width: 80}, + { + field: 'warehouseId', + title: '仓库', + width: 130, + slots: { edit: 'warehouse_edit', default: 'warehouse_default' }, + editRender: { name: 'input', attrs: { placeholder: '请选择仓库' } } + }, + { field: 'barCode', + width:160, + title: '条码', + slots: { edit: 'barCode_edit' }, + titlePrefix: { content: '输入条码商品信息自动带出!' }, + editRender: { name: 'input', attrs: { placeholder: '请输入条码并回车' } } + }, + { + field: 'productName', + title: '名称', + width:160, + }, + { field: 'productStandard', title: '规格', width: 120, }, + { field: 'stock', title: '库存', width: 70}, + { field: 'productUnit', title: '单位', width: 70}, + { field: 'productNumber', title: '数量', sortable: true, width:100, + slots: { edit: 'product_number_edit' }, + editRender: { name: '$input', props: { type: 'number', min: 1, max: 9999 } }, + }, + { + field: 'unitPrice', + title: '单价', width:105, + formatter ({ cellValue }) { + return cellValue ? `¥${XEUtils.commafy(XEUtils.toNumber(cellValue), { digits: 2 })}` : '' + }, + slots: { edit: 'price_edit' }, + editRender: { name: '$input', props: { type: 'float', digits: 2, placeholder: '输入单价' } } + }, + { + field: 'amount', + title: '金额', width:105, + formatter ({ cellValue }) { + return cellValue ? `¥${XEUtils.commafy(XEUtils.toNumber(cellValue), { digits: 2 })}` : '' + }, + slots: { edit: 'amount_edit' }, + editRender: { name: '$input', props: { type: 'float', digits: 2, placeholder: '输入金额' } } + }, + { field: 'taxRate', title: '税率', width: 105, + slots: { edit: 'tax_rate_edit' }, + editRender: { name: '$input', attrs: { type: 'float', digits: 2, placeholder: '请输入税率' } } + }, + { field: 'taxAmount', title: '税额', width: 105, + editRender:{attrs: {type: 'float', digits: 2}}, + slots: { edit: 'tax_amount_edit' }, + }, + { field: 'taxTotalPrice', title: '价税合计', width: 105, + slots: { edit: 'tax_total_price_edit' }, + editRender: { name: '$input', attrs: {type: 'float', digits: 2, placeholder: '请输入价税合计' } } + }, + { field: 'remark', title: '备注', editRender: { name: 'input', attrs: { placeholder: '请输入备注' } } }, + + ], + footerMethod ({ columns, data }) { + return [ + columns.map((column, columnIndex) => { + if (columnIndex === 0) { + return '总计' + } + if (['amount', 'rate'].includes(column.field)) { + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + if (['productNumber', 'rate'].includes(column.field)) { + return sumNum(data, column.field) + } + if (['taxAmount', 'rate'].includes(column.field)) { + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + + if (['taxTotalPrice', 'rate'].includes(column.field)) { + getTaxTotalPrice.value = `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + return '' + }) + ] + }, + checkboxConfig: { + labelField: 'id', + reserve: true, + highlight: true, + range: true + }, + editRules: { + warehouseId: [ + { required: true, message: '仓库不能为空' } + ], + barCode: [ + { required: true, message: '商品条码不能为空' } + ] + }, + editConfig: { + trigger: 'click', + mode: 'row', + showStatus: true + } +}) + +const sumNum = (list: RowVO[], field: string) => { + let count = 0 + list.forEach(item => { + count += Number(item[field]) + }) + return count +} + +const getTaxTotalPrice = ref(''); + +const formState = reactive({ + id: undefined, + customerId: '', + receiptNumber: '', + remark: '', + discountRate: 0, + discountAmount: 0, + discountLastAmount: 0, + deposit: 0, + accountId: undefined, + operatorIds: undefined, + receiptDate: '', + warehouseId: '', + multipleAccountIds: undefined, + multipleAccountAmounts: undefined, +}); + +const saleShipmentsFormState = reactive({ + id: undefined, + customerId: '', + receiptNumber: '', + otherReceipt: '', + remark: '', + collectOfferRate: 0, + collectOfferAmount: 0, + collectOfferLastAmount: 0, + otherAmount: 0, + thisCollectAmount: 0, + thisArrearsAmount: 0, + status: undefined, + accountId: undefined, + operatorIds: undefined, + receiptDate: '', + warehouseId: '', + multipleAccountIds: undefined, + multipleAccountAmounts: undefined, +}); + +const saleRefundFormState = reactive({ + id: undefined, + customerId: '', + receiptNumber: '', + otherReceipt: '', + remark: '', + refundOfferRate: 0, + refundOfferAmount: 0, + refundLastAmount: 0, + otherAmount: 0, + thisRefundAmount: 0, + thisArrearsAmount: 0, + status: undefined, + accountId: undefined, + operatorIds: undefined, + receiptDate: '', + warehouseId: '', + multipleAccountIds: undefined, + multipleAccountAmounts: undefined, +}); + +export { + xGrid, + sumNum, + tableData, + orderGridOptions, + gridOptions, + formState, + saleShipmentsFormState, + saleRefundFormState, + getTaxTotalPrice, +} \ No newline at end of file diff --git a/src/views/sales/order/components/AddEditModal.vue b/src/views/sales/order/components/AddEditModal.vue new file mode 100644 index 0000000..2245e76 --- /dev/null +++ b/src/views/sales/order/components/AddEditModal.vue @@ -0,0 +1,1022 @@ + + + + + \ No newline at end of file diff --git a/src/views/sales/order/components/ViewSaleOrderModal.vue b/src/views/sales/order/components/ViewSaleOrderModal.vue new file mode 100644 index 0000000..eff253b --- /dev/null +++ b/src/views/sales/order/components/ViewSaleOrderModal.vue @@ -0,0 +1,196 @@ + + + diff --git a/src/views/sales/order/index.vue b/src/views/sales/order/index.vue new file mode 100644 index 0000000..239c285 --- /dev/null +++ b/src/views/sales/order/index.vue @@ -0,0 +1,238 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/sales/order/sales.data.ts b/src/views/sales/order/sales.data.ts new file mode 100644 index 0000000..433384f --- /dev/null +++ b/src/views/sales/order/sales.data.ts @@ -0,0 +1,213 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {useI18n} from "@/hooks/web/useI18n"; +import {getCustomerList} from "@/api/basic/customer"; + +export const { t } = useI18n(); + +export const columns: BasicColumn[] = [ + { + title: '客户', + dataIndex: 'customerName', + width: 60, + }, + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 130, + }, + { + title: '商品信息', + dataIndex: 'productInfo', + width: 80, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 80, + }, + { + title: '金额合计', + dataIndex: 'totalPrice', + width: 60, + }, + { + title: '含税合计', + dataIndex: 'taxRateTotalPrice', + width: 80, + }, + { + title: '收取定金', + dataIndex: 'deposit', + width: 80, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '操作员', + dataIndex: 'operator', + width: 60, + }, + { + title: '状态', + dataIndex: 'status', + width: 80, + }, +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '客户', + field: 'customerId', + component: 'ApiSelect', + componentProps: { + api: getCustomerList, + resultField: 'data', + labelField: 'customerName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '商品信息', + field: 'productInfo', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '单据状态', + field: 'status', + component: 'Select', + colProps: { + xl: 8, + xxl: 8, + }, + componentProps: { + options: [ + { label: '未审核', value: 0, key: 0 }, + { label: '已审核', value: 1, key: 1 }, + { label: '部分销售', value: 2, key: 2 }, + { label: '完成销售', value: 3, key: 3 }, + ], + }, + }, + { + label: '单据备注', + field: 'remark', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + + } +] + +export const TableColumns: BasicColumn[] = [ + { + title: '仓库名称', + dataIndex: 'warehouseName', + width: 100, + }, + { + title: '条码', + dataIndex: 'barCode', + width: 100, + }, + { + title: '商品名称', + dataIndex: 'productName', + width: 120, + }, + { + title: '规格', + dataIndex: 'productStandard', + width: 120, + }, + { + title: '型号', + dataIndex: 'productModel', + width: 120, + }, + { + title: '颜色', + dataIndex: 'productColor', + width: 70, + }, + { + title: '库存', + dataIndex: 'stock', + width: 80, + }, + { + title: '单位', + dataIndex: 'productUnit', + width: 60, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 60, + }, + { + title: '单价', + dataIndex: 'unitPrice', + width: 60, + }, + { + title: '金额', + dataIndex: 'amount', + width: 60, + }, + { + title: '税率(%)', + dataIndex: 'taxRate', + width: 60, + }, + { + title: '税额', + dataIndex: 'taxAmount', + width: 60, + }, + { + title: '价税合计', + dataIndex: 'taxTotalPrice', + width: 60, + }, + { + title: '备注', + dataIndex: 'remark', + width: 100, + }, +] \ No newline at end of file diff --git a/src/views/sales/refund/components/AddEditModal.vue b/src/views/sales/refund/components/AddEditModal.vue new file mode 100644 index 0000000..dd85bba --- /dev/null +++ b/src/views/sales/refund/components/AddEditModal.vue @@ -0,0 +1,1191 @@ + + + + + \ No newline at end of file diff --git a/src/views/sales/refund/components/ViewSaleRefundModal.vue b/src/views/sales/refund/components/ViewSaleRefundModal.vue new file mode 100644 index 0000000..f8c1915 --- /dev/null +++ b/src/views/sales/refund/components/ViewSaleRefundModal.vue @@ -0,0 +1,223 @@ + + + diff --git a/src/views/sales/refund/index.vue b/src/views/sales/refund/index.vue new file mode 100644 index 0000000..1199651 --- /dev/null +++ b/src/views/sales/refund/index.vue @@ -0,0 +1,238 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/sales/refund/saleRefund.data.ts b/src/views/sales/refund/saleRefund.data.ts new file mode 100644 index 0000000..0c4b955 --- /dev/null +++ b/src/views/sales/refund/saleRefund.data.ts @@ -0,0 +1,143 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {useI18n} from "@/hooks/web/useI18n"; +import {getCustomerList} from "@/api/basic/customer"; + +export const { t } = useI18n(); + +export const columns: BasicColumn[] = [ + { + title: '客户', + dataIndex: 'customerName', + width: 60, + }, + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 140, + }, + { + title: '商品信息', + dataIndex: 'productInfo', + width: 80, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 80, + }, + { + title: '金额合计', + dataIndex: 'totalAmount', + width: 60, + }, + { + title: '含税合计', + dataIndex: 'taxIncludedAmount', + width: 80, + }, + { + title: '待退金额', + dataIndex: 'refundTotalAmount', + width: 80, + }, + { + title: '本次退款', + dataIndex: 'thisRefundAmount', + width: 80, + }, + { + title: '本次欠款', + dataIndex: 'thisArrearsAmount', + width: 80, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '操作员', + dataIndex: 'operator', + width: 60, + }, + { + title: '状态', + dataIndex: 'status', + width: 80, + }, +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '客户', + field: 'customerId', + component: 'ApiSelect', + componentProps: { + api: getCustomerList, + resultField: 'data', + labelField: 'customerName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '商品信息', + field: 'productInfo', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '单据状态', + field: 'status', + component: 'Select', + colProps: { + xl: 8, + xxl: 8, + }, + componentProps: { + options: [ + { label: '未审核', value: 0, key: 0 }, + { label: '已审核', value: 1, key: 1 }, + ], + }, + }, + { + label: '单据备注', + field: 'remark', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + + } +] \ No newline at end of file diff --git a/src/views/sales/shipments/components/AddEditModal.vue b/src/views/sales/shipments/components/AddEditModal.vue new file mode 100644 index 0000000..65096b7 --- /dev/null +++ b/src/views/sales/shipments/components/AddEditModal.vue @@ -0,0 +1,1205 @@ + + + + + \ No newline at end of file diff --git a/src/views/sales/shipments/components/ViewSaleShipmentsModal.vue b/src/views/sales/shipments/components/ViewSaleShipmentsModal.vue new file mode 100644 index 0000000..3b8aa85 --- /dev/null +++ b/src/views/sales/shipments/components/ViewSaleShipmentsModal.vue @@ -0,0 +1,224 @@ + + + diff --git a/src/views/sales/shipments/index.vue b/src/views/sales/shipments/index.vue new file mode 100644 index 0000000..9bf5b7c --- /dev/null +++ b/src/views/sales/shipments/index.vue @@ -0,0 +1,238 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/sales/shipments/saleShipments.data.ts b/src/views/sales/shipments/saleShipments.data.ts new file mode 100644 index 0000000..92a58e5 --- /dev/null +++ b/src/views/sales/shipments/saleShipments.data.ts @@ -0,0 +1,143 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {useI18n} from "@/hooks/web/useI18n"; +import {getCustomerList} from "@/api/basic/customer"; + +export const { t } = useI18n(); + +export const columns: BasicColumn[] = [ + { + title: '客户', + dataIndex: 'customerName', + width: 60, + }, + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 140, + }, + { + title: '商品信息', + dataIndex: 'productInfo', + width: 80, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 80, + }, + { + title: '金额合计', + dataIndex: 'totalAmount', + width: 60, + }, + { + title: '含税合计', + dataIndex: 'taxIncludedAmount', + width: 80, + }, + { + title: '待收金额', + dataIndex: 'totalCollectAmount', + width: 80, + }, + { + title: '本次收款', + dataIndex: 'thisCollectAmount', + width: 80, + }, + { + title: '本次欠款', + dataIndex: 'thisArrearsAmount', + width: 80, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '操作员', + dataIndex: 'operator', + width: 60, + }, + { + title: '状态', + dataIndex: 'status', + width: 80, + }, +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '客户', + field: 'customerId', + component: 'ApiSelect', + componentProps: { + api: getCustomerList, + resultField: 'data', + labelField: 'customerName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '商品信息', + field: 'productInfo', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '单据状态', + field: 'status', + component: 'Select', + colProps: { + xl: 8, + xxl: 8, + }, + componentProps: { + options: [ + { label: '未审核', value: 0, key: 0 }, + { label: '已审核', value: 1, key: 1 }, + ], + }, + }, + { + label: '单据备注', + field: 'remark', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + + } +] \ No newline at end of file diff --git a/src/views/sys/about/index.vue b/src/views/sys/about/index.vue new file mode 100644 index 0000000..1b2cf37 --- /dev/null +++ b/src/views/sys/about/index.vue @@ -0,0 +1,98 @@ + + diff --git a/src/views/sys/config/config.data.ts b/src/views/sys/config/config.data.ts new file mode 100644 index 0000000..7705704 --- /dev/null +++ b/src/views/sys/config/config.data.ts @@ -0,0 +1,82 @@ +import { FormSchema } from '/@/components/Form'; + +const colProps = { + span: 12, +}; + +export const schemas: FormSchema[] = [ + { + field: 'id', + component: 'Input', + label: '系统配置id', + ifShow: false + }, + { + field: 'companyName', + component: 'Input', + label: '公司名称', + helpMessage: '更换公司名称后,请刷新浏览器生效', + colProps, + componentProps: { + placeholder: '请输入公司名称', + }, + defaultValue: 'EAIRP', + required: true, + }, + { + field: 'companyContact', + component: 'Input', + label: '联系人', + colProps, + componentProps: { + placeholder: '请输入联系人', + }, + }, + { + field: 'companyAddress', + component: 'Input', + label: '公司地址', + colProps, + componentProps: { + placeholder: '请输入公司地址', + }, + }, + { + field: 'companyPhone', + component: 'Input', + label: '公司电话', + colProps, + componentProps: { + placeholder: '请输入公司电话', + }, + }, + { + field: 'companyFax', + component: 'Input', + label: '公司传真', + colProps, + componentProps: { + placeholder: '请输入公司传真', + }, + }, + { + field: 'companyPostCode', + component: 'Input', + label: '公司邮编', + colProps, + componentProps: { + placeholder: '请输入公司邮编', + }, + }, + { + field: 'saleAgreement', + component: 'InputTextArea', + label: '销售协议', + subLabel: '( 选填 )', + colProps, + componentProps: { + placeholder: '请输入销售协议', + rows: 4, + }, + }, +]; diff --git a/src/views/sys/config/index.vue b/src/views/sys/config/index.vue new file mode 100644 index 0000000..f1faa3a --- /dev/null +++ b/src/views/sys/config/index.vue @@ -0,0 +1,86 @@ + + + diff --git a/src/views/sys/department/components/DeptModal.vue b/src/views/sys/department/components/DeptModal.vue new file mode 100644 index 0000000..47d6854 --- /dev/null +++ b/src/views/sys/department/components/DeptModal.vue @@ -0,0 +1,77 @@ + + + + + \ No newline at end of file diff --git a/src/views/sys/department/dept.data.ts b/src/views/sys/department/dept.data.ts new file mode 100644 index 0000000..f54bafe --- /dev/null +++ b/src/views/sys/department/dept.data.ts @@ -0,0 +1,116 @@ +import {BasicColumn, FormSchema} from "@/components/Table"; +import { h } from 'vue'; +import { Tag } from 'ant-design-vue'; +import {getDeptList} from "@/api/sys/dept"; + +export const columns: BasicColumn[] = [ + { + title: '部门名称', + dataIndex: 'deptName', + width: 160, + align: "left", + }, + { + title: '部门编号', + dataIndex: 'deptNumber', + width: 160, + }, + { + title: '部门负责人', + dataIndex: 'leader', + width: 160, + }, + { + title: '状态', + dataIndex: 'status', + width: 80, + customRender: ({ record }) => { + const status = record.status; + const enable = ~~status === 0; + const color = enable ? 'green' : 'red'; + const text = enable ? '启用' : '停用'; + return h(Tag, { color: color }, () => text); + }, + }, + { + title: '创建时间', + dataIndex: 'createTime', + width: 180, + }, + { + title: '备注', + dataIndex: 'remark', + width: 180 + }, +] + +export const searchFormSchema: FormSchema[] = [ + { + field: 'deptName', + label: '部门名称', + component: 'Input', + colProps: { span: 8 }, + } +] + +export const formSchema: FormSchema[] = [ + { + field: 'id', + label: '部门ID', + component: 'Input', + show: false, + }, + { + field: 'deptName', + label: '部门名称', + component: 'Input', + required: true, + }, + { + field: 'deptNumber', + label: '部门编号', + component: 'Input', + }, + { + field: 'parentId', + label: '上级部门', + component: 'ApiTreeSelect', + helpMessage: ['如果不填写,则默认为父级部门'], + componentProps: { + api: getDeptList, + resultField: 'data', + labelField: 'deptName', + valueField: 'id', + childrenKeyField: 'children', + }, + }, + { + field: 'leader', + label: '部门负责人', + component: 'Input', + }, + { + field: 'status', + label: '状态', + component: 'RadioButtonGroup', + defaultValue: 0, + componentProps: { + options: [ + { label: '启用', value: 0 }, + { label: '停用', value: 1 }, + ], + }, + required: true, + }, + + { + field: 'sort', + label: '排序', + component: 'InputNumber', + }, + { + label: '备注', + field: 'remark', + component: 'InputTextArea', + }, +]; \ No newline at end of file diff --git a/src/views/sys/department/index.vue b/src/views/sys/department/index.vue new file mode 100644 index 0000000..c710ef9 --- /dev/null +++ b/src/views/sys/department/index.vue @@ -0,0 +1,108 @@ + + + + diff --git a/src/views/sys/error-log/DetailModal.vue b/src/views/sys/error-log/DetailModal.vue new file mode 100644 index 0000000..2047707 --- /dev/null +++ b/src/views/sys/error-log/DetailModal.vue @@ -0,0 +1,27 @@ + + diff --git a/src/views/sys/error-log/data.tsx b/src/views/sys/error-log/data.tsx new file mode 100644 index 0000000..3ffc2f4 --- /dev/null +++ b/src/views/sys/error-log/data.tsx @@ -0,0 +1,67 @@ +import { Tag } from 'ant-design-vue'; +import { BasicColumn } from '/@/components/Table/index'; +import { ErrorTypeEnum } from '/@/enums/exceptionEnum'; +import { useI18n } from '/@/hooks/web/useI18n'; + +const { t } = useI18n(); + +export function getColumns(): BasicColumn[] { + return [ + { + dataIndex: 'type', + title: t('sys.errorLog.tableColumnType'), + width: 80, + customRender: ({ text }) => { + const color = + text === ErrorTypeEnum.VUE + ? 'green' + : text === ErrorTypeEnum.RESOURCE + ? 'cyan' + : text === ErrorTypeEnum.PROMISE + ? 'blue' + : ErrorTypeEnum.AJAX + ? 'red' + : 'purple'; + return {() => text}; + }, + }, + { + dataIndex: 'url', + title: 'URL', + width: 200, + }, + { + dataIndex: 'time', + title: t('sys.errorLog.tableColumnDate'), + width: 160, + }, + { + dataIndex: 'file', + title: t('sys.errorLog.tableColumnFile'), + width: 200, + }, + { + dataIndex: 'name', + title: 'Name', + width: 200, + }, + { + dataIndex: 'message', + title: t('sys.errorLog.tableColumnMsg'), + width: 300, + }, + { + dataIndex: 'stack', + title: t('sys.errorLog.tableColumnStackMsg'), + }, + ]; +} + +export function getDescSchema(): any { + return getColumns().map((column) => { + return { + field: column.dataIndex!, + label: column.title, + }; + }); +} diff --git a/src/views/sys/error-log/index.vue b/src/views/sys/error-log/index.vue new file mode 100644 index 0000000..049dd30 --- /dev/null +++ b/src/views/sys/error-log/index.vue @@ -0,0 +1,96 @@ + + + diff --git a/src/views/sys/exception/Exception.vue b/src/views/sys/exception/Exception.vue new file mode 100644 index 0000000..a8a6add --- /dev/null +++ b/src/views/sys/exception/Exception.vue @@ -0,0 +1,148 @@ + + diff --git a/src/views/sys/exception/index.ts b/src/views/sys/exception/index.ts new file mode 100644 index 0000000..5002c4a --- /dev/null +++ b/src/views/sys/exception/index.ts @@ -0,0 +1 @@ +export { default as Exception } from './Exception.vue'; diff --git a/src/views/sys/iframe/FrameBlank.vue b/src/views/sys/iframe/FrameBlank.vue new file mode 100644 index 0000000..99428bb --- /dev/null +++ b/src/views/sys/iframe/FrameBlank.vue @@ -0,0 +1,6 @@ + + diff --git a/src/views/sys/iframe/index.vue b/src/views/sys/iframe/index.vue new file mode 100644 index 0000000..ebf9fc4 --- /dev/null +++ b/src/views/sys/iframe/index.vue @@ -0,0 +1,90 @@ + + + diff --git a/src/views/sys/lock/LockPage.vue b/src/views/sys/lock/LockPage.vue new file mode 100644 index 0000000..1c53f40 --- /dev/null +++ b/src/views/sys/lock/LockPage.vue @@ -0,0 +1,236 @@ + + + diff --git a/src/views/sys/lock/index.vue b/src/views/sys/lock/index.vue new file mode 100644 index 0000000..e8c4d55 --- /dev/null +++ b/src/views/sys/lock/index.vue @@ -0,0 +1,13 @@ + + diff --git a/src/views/sys/lock/useNow.ts b/src/views/sys/lock/useNow.ts new file mode 100644 index 0000000..ee461fc --- /dev/null +++ b/src/views/sys/lock/useNow.ts @@ -0,0 +1,60 @@ +import { dateUtil } from '/@/utils/dateUtil'; +import { reactive, toRefs } from 'vue'; +import { tryOnMounted, tryOnUnmounted } from '@vueuse/core'; + +export function useNow(immediate = true) { + let timer: IntervalHandle; + + const state = reactive({ + year: 0, + month: 0, + week: '', + day: 0, + hour: '', + minute: '', + second: 0, + meridiem: '', + }); + + const update = () => { + const now = dateUtil(); + + const h = now.format('HH'); + const m = now.format('mm'); + const s = now.get('s'); + + state.year = now.get('y'); + state.month = now.get('M') + 1; + state.week = '星期' + ['日', '一', '二', '三', '四', '五', '六'][now.day()]; + state.day = now.get('date'); + state.hour = h; + state.minute = m; + state.second = s; + + state.meridiem = now.format('A'); + }; + + function start() { + update(); + clearInterval(timer); + timer = setInterval(() => update(), 1000); + } + + function stop() { + clearInterval(timer); + } + + tryOnMounted(() => { + immediate && start(); + }); + + tryOnUnmounted(() => { + stop(); + }); + + return { + ...toRefs(state), + start, + stop, + }; +} diff --git a/src/views/sys/login/ForgetPasswordForm.vue b/src/views/sys/login/ForgetPasswordForm.vue new file mode 100644 index 0000000..692dd0a --- /dev/null +++ b/src/views/sys/login/ForgetPasswordForm.vue @@ -0,0 +1,106 @@ + + diff --git a/src/views/sys/login/Login.vue b/src/views/sys/login/Login.vue new file mode 100644 index 0000000..9a1f1c5 --- /dev/null +++ b/src/views/sys/login/Login.vue @@ -0,0 +1,221 @@ + + + \ No newline at end of file diff --git a/src/views/sys/login/LoginForm.vue b/src/views/sys/login/LoginForm.vue new file mode 100644 index 0000000..cf55de4 --- /dev/null +++ b/src/views/sys/login/LoginForm.vue @@ -0,0 +1,200 @@ + + + + + diff --git a/src/views/sys/login/LoginFormTitle.vue b/src/views/sys/login/LoginFormTitle.vue new file mode 100644 index 0000000..a673636 --- /dev/null +++ b/src/views/sys/login/LoginFormTitle.vue @@ -0,0 +1,25 @@ + + diff --git a/src/views/sys/login/MobileForm.vue b/src/views/sys/login/MobileForm.vue new file mode 100644 index 0000000..87d1356 --- /dev/null +++ b/src/views/sys/login/MobileForm.vue @@ -0,0 +1,98 @@ + + diff --git a/src/views/sys/login/QrCodeForm.vue b/src/views/sys/login/QrCodeForm.vue new file mode 100644 index 0000000..d0860bd --- /dev/null +++ b/src/views/sys/login/QrCodeForm.vue @@ -0,0 +1,31 @@ + + diff --git a/src/views/sys/login/RegisterForm.vue b/src/views/sys/login/RegisterForm.vue new file mode 100644 index 0000000..b3ab96a --- /dev/null +++ b/src/views/sys/login/RegisterForm.vue @@ -0,0 +1,148 @@ + + diff --git a/src/views/sys/login/SessionTimeoutLogin.vue b/src/views/sys/login/SessionTimeoutLogin.vue new file mode 100644 index 0000000..16abf97 --- /dev/null +++ b/src/views/sys/login/SessionTimeoutLogin.vue @@ -0,0 +1,54 @@ + + + diff --git a/src/views/sys/login/useLogin.ts b/src/views/sys/login/useLogin.ts new file mode 100644 index 0000000..fc2895b --- /dev/null +++ b/src/views/sys/login/useLogin.ts @@ -0,0 +1,185 @@ +import type {ValidationRule, FormInstance} from 'ant-design-vue/lib/form/Form'; +import type {RuleObject, NamePath} from 'ant-design-vue/lib/form/interface'; +import {ref, computed, unref, Ref} from 'vue'; +import {useI18n} from '/@/hooks/web/useI18n'; +import CryptoJS from 'crypto-js'; + +export enum LoginStateEnum { + LOGIN, + REGISTER, + RESET_PASSWORD, + MOBILE, + QR_CODE, +} + +/** + * AES加密 + * @param plainText 明文 + * @param keyInBase64Str base64编码后的key + * @returns {string} base64编码后的密文 + */ +export function encryptByAES(plainText, keyInBase64Str) { + let key = CryptoJS.enc.Base64.parse(keyInBase64Str); + let encrypted = CryptoJS.AES.encrypt(plainText, key, { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7, + }); + return encrypted.ciphertext.toString(CryptoJS.enc.Base64); +} + +/** + * AES解密 + * @param cipherText 密文 + * @param keyInBase64Str base64编码后的key + * @return 明文 + */ +export function decryptByAES(cipherText, keyInBase64Str) { + let key = CryptoJS.enc.Base64.parse(keyInBase64Str); + let decrypted = CryptoJS.AES.decrypt(cipherText, key, { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7, + }); + + return decrypted.toString(CryptoJS.enc.Utf8); +} + +const currentState = ref(LoginStateEnum.LOGIN); + +// 这里也可以优化 +// import { createGlobalState } from '@vueuse/core' + +export function useLoginState() { + function setLoginState(state: LoginStateEnum) { + currentState.value = state; + } + + const getLoginState = computed(() => currentState.value); + + function handleBackLogin() { + setLoginState(LoginStateEnum.LOGIN); + } + + function handleBackMobileLogin() { + setLoginState(LoginStateEnum.MOBILE); + } + + return {setLoginState, getLoginState, handleBackLogin, handleBackMobileLogin}; +} + + +export function useFormValid(formRef: Ref) { + const validate = computed(() => { + const form = unref(formRef); + return form?.validate ?? ((_nameList?: NamePath) => Promise.resolve()); + }); + + async function validForm() { + const form = unref(formRef); + if (!form) return; + const data = await form.validate(); + return data as T; + } + + return {validate, validForm}; +} + + +export function useFormRules(formData?: Recordable) { + const {t} = useI18n(); + + const getAccountFormRule = computed(() => createRule(t('sys.login.accountPlaceholder'))); + const getPasswordFormRule = computed(() => createRule(t('sys.login.passwordPlaceholder'))); + const getCaptchaFormRule = computed(() => createRule(t('sys.login.captchaPlaceholder'))); + const getSmsFormRule = computed(() => createRule(t('sys.login.smsPlaceholder'))); + const getMobileFormRule = computed(() => phoneNumberRule()); + + const validatePolicy = async (_: RuleObject, value: boolean) => { + return !value ? Promise.reject(t('sys.login.policyPlaceholder')) : Promise.resolve(); + }; + + const validateConfirmPassword = (password: string) => { + return async (_: RuleObject, value: string) => { + if (!value) { + return Promise.reject(t('sys.login.passwordPlaceholder')); + } + if (value !== password) { + return Promise.reject(t('sys.login.diffPwd')); + } + return Promise.resolve(); + }; + }; + + const getFormRules = computed((): { [k: string]: ValidationRule | ValidationRule[] } => { + const accountFormRule = unref(getAccountFormRule); + const passwordFormRule = unref(getPasswordFormRule); + const captchaFormRule = unref(getCaptchaFormRule); + const smsFormRule = unref(getSmsFormRule); + const mobileFormRule = unref(getMobileFormRule); + + const mobileRule = { + sms: smsFormRule, + mobile: mobileFormRule, + }; + switch (unref(currentState)) { + // register form rules + case LoginStateEnum.REGISTER: + return { + username: accountFormRule, + password: passwordFormRule, + phoneNumber: mobileFormRule, + captcha: captchaFormRule, + confirmPassword: [ + {validator: validateConfirmPassword(formData?.password), trigger: 'change'}, + ], + policy: [{validator: validatePolicy, trigger: 'change'}], + ...mobileRule, + }; + + // reset password form rules + case LoginStateEnum.RESET_PASSWORD: + return { + username: accountFormRule, + password: passwordFormRule, + phoneNumber: mobileFormRule, + sms: smsFormRule, + }; + + // mobile form rules + case LoginStateEnum.MOBILE: + return { + phoneNumber: mobileFormRule, + sms: smsFormRule, + }; + + // login form rules + default: + return { + account: accountFormRule, + password: passwordFormRule, + captcha: captchaFormRule, + }; + } + }); + return {getFormRules}; +} + +function createRule(message: string) { + return [ + { + required: true, + message, + trigger: 'change', + }, + ]; +} + +function phoneNumberRule() { + return [ + { + required: true, + pattern: /^(0|86|17951)?(13[0-9]|15[012356789]|16[6]|19[89]]|17[01345678]|18[0-9]|14[579])[0-9]{8}$/, + message: "请输入正确的手机号", + trigger: 'change', + } + ]; +} diff --git a/src/views/sys/menu/MenuDrawer.vue b/src/views/sys/menu/MenuDrawer.vue new file mode 100644 index 0000000..c774331 --- /dev/null +++ b/src/views/sys/menu/MenuDrawer.vue @@ -0,0 +1,95 @@ + + + \ No newline at end of file diff --git a/src/views/sys/menu/index.vue b/src/views/sys/menu/index.vue new file mode 100644 index 0000000..f7a504d --- /dev/null +++ b/src/views/sys/menu/index.vue @@ -0,0 +1,115 @@ + + + + + \ No newline at end of file diff --git a/src/views/sys/menu/menu.data.ts b/src/views/sys/menu/menu.data.ts new file mode 100644 index 0000000..2596c55 --- /dev/null +++ b/src/views/sys/menu/menu.data.ts @@ -0,0 +1,208 @@ +import { BasicColumn, FormSchema } from '/@/components/Table'; +import { h } from 'vue'; +import { Tag } from 'ant-design-vue'; +import Icon from '@/components/Icon/Icon.vue'; +import {getMenuList} from "@/api/sys/menu"; +import {ParentIdEnum} from "@/enums/appEnum"; + +export const columns: BasicColumn[] = [ + { + title: '菜单名称', + dataIndex: 'title', + width: 150, + align: 'left', + }, + { + title: '图标', + dataIndex: 'icon', + width: 80, + customRender: ({ record }) => { + return h(Icon, { icon: record.icon }); + }, + }, + { + title: '路径', + dataIndex: 'path', + width: 180, + }, + { + title: '组件', + dataIndex: 'component', + width: 200, + }, + { + title: '排序', + dataIndex: 'sort', + width: 50, + }, + { + title: '状态', + dataIndex: 'status', + width: 80, + customRender: ({ record }) => { + const status = record.status; + const enable = ~~status === 0; + const color = enable ? 'green' : 'red'; + const text = enable ? '启用' : '停用'; + return h(Tag, { color: color }, () => text); + }, + }, + { + title: '创建时间', + dataIndex: 'createTime', + width: 180, + }, +]; +const isMenu = (type: number) => type === 1; + +export const searchFormSchema: FormSchema[] = [ + { + field: 'title', + label: '菜单名称', + component: 'Input', + colProps: { span: 8 }, + }, + { + field: 'status', + label: '状态', + component: 'Select', + componentProps: { + options: [ + { label: '启用', value: 0 }, + { label: '停用', value: 1 }, + ], + }, + colProps: { span: 8 }, + }, +]; + +export const formSchema: FormSchema[] = [ + { + field: 'id', + label: '菜单ID', + component: 'Input', + show: false, + }, + { + field: 'menuType', + label: '菜单类型', + component: 'RadioButtonGroup', + defaultValue: 1, + componentProps: { + options: [ + { label: '目录', value: 0 }, + { label: '菜单', value: 1 }, + ], + }, + colProps: { lg: 24, md: 24 }, + }, + { + field: 'name', + label: '菜单名称', + component: 'Input', + required: true, + }, + { + field: 'title', + label: '菜单标题', + component: 'Input', + required: true, + }, + { + field: 'parentId', + label: '上级菜单', + component: 'ApiTreeSelect', + helpMessage: ['如果不填写,则默认为目录'], + componentProps: { + api: getMenuList, + resultField: 'data.data', + labelField: 'title', + valueField: 'id', + defaultValue: { + id: ParentIdEnum.DEFAULT, + parentId: -1, + label: '根菜单', + value: ParentIdEnum.DEFAULT, + }, + }, + }, + { + field: 'sort', + label: '排序', + component: 'InputNumber', + required: true, + }, + { + field: 'icon', + label: '图标', + component: 'IconPicker', + required: true, + }, + + { + field: 'path', + label: '路由地址', + component: 'Input', + required: true, + ifShow: ({ values }) => isMenu(values.menuType), + }, + { + field: 'component', + label: '组件路径', + component: 'Input', + ifShow: ({ values }) => isMenu(values.menuType), + }, + { + field: 'status', + label: '状态', + component: 'RadioButtonGroup', + defaultValue: 0, + componentProps: { + options: [ + { label: '启用', value: 0 }, + { label: '禁用', value: 1 }, + ], + }, + }, + { + field: 'blank', + label: '是否外链', + component: 'RadioButtonGroup', + defaultValue: 0, + componentProps: { + options: [ + { label: '否', value: 0 }, + { label: '是', value: 1 }, + ], + }, + ifShow: ({ values }) => isMenu(values.menuType), + }, + + { + field: 'ignoreKeepAlive', + label: '是否缓存', + component: 'RadioButtonGroup', + defaultValue: 0, + componentProps: { + options: [ + { label: '否', value: 0 }, + { label: '是', value: 1 }, + ], + }, + ifShow: ({ values }) => isMenu(values.menuType), + }, + + { + field: 'hideMenu', + label: '是否显示', + component: 'RadioButtonGroup', + defaultValue: 0, + componentProps: { + options: [ + { label: '是', value: 0 }, + { label: '否', value: 1 }, + ], + }, + ifShow: ({ values }) => isMenu(values.menuType), + }, +]; diff --git a/src/views/sys/redirect/index.vue b/src/views/sys/redirect/index.vue new file mode 100644 index 0000000..9e6647b --- /dev/null +++ b/src/views/sys/redirect/index.vue @@ -0,0 +1,30 @@ + + diff --git a/src/views/sys/role/components/RoleDrawer.vue b/src/views/sys/role/components/RoleDrawer.vue new file mode 100644 index 0000000..2318fed --- /dev/null +++ b/src/views/sys/role/components/RoleDrawer.vue @@ -0,0 +1,70 @@ + + \ No newline at end of file diff --git a/src/views/sys/role/components/RolePermissionModal.vue b/src/views/sys/role/components/RolePermissionModal.vue new file mode 100644 index 0000000..a956717 --- /dev/null +++ b/src/views/sys/role/components/RolePermissionModal.vue @@ -0,0 +1,66 @@ + + diff --git a/src/views/sys/role/index.vue b/src/views/sys/role/index.vue new file mode 100644 index 0000000..3fed725 --- /dev/null +++ b/src/views/sys/role/index.vue @@ -0,0 +1,131 @@ + + \ No newline at end of file diff --git a/src/views/sys/role/role.data.ts b/src/views/sys/role/role.data.ts new file mode 100644 index 0000000..f5e9f80 --- /dev/null +++ b/src/views/sys/role/role.data.ts @@ -0,0 +1,163 @@ +import { BasicColumn, FormSchema } from '/@/components/Table'; +import { useI18n } from '/@/hooks/web/useI18n'; +import { h } from 'vue'; +import { Switch } from 'ant-design-vue'; +import { setRoleStatus } from '/@/api/sys/role'; + +const { t } = useI18n(); + +export const columns: BasicColumn[] = [ + { + title: '角色名称', + dataIndex: 'roleName', + width: 150, + }, + { + title: '类型', + dataIndex: 'type', + width: 120, + }, + { + title: '价格屏蔽', + dataIndex: 'priceLimit', + width: 120, + customRender: ({record}) => { + if(record.priceLimit === 1) { + return '屏蔽采购价' + } else if(record.priceLimit === 2) { + return '屏蔽零售价' + } else if(record.priceLimit === 3) { + return '屏蔽销售价' + } + } + }, + { + title: '状态', + dataIndex: 'status', + width: 120, + customRender: ({ record }) => { + if (!Reflect.has(record, 'pendingStatus')) { + record.pendingStatus = false; + } + return h(Switch, { + checked: record.status === 0, + checkedChildren: t('common.on'), + unCheckedChildren: t('common.off'), + loading: record.pendingStatus, + onChange(checked: boolean) { + record.pendingStatus = true; + const newStatus = checked ? 0 : 1; + setRoleStatus(record.id, newStatus) + .then(() => { + record.status = newStatus; + }) + .finally(() => { + record.pendingStatus = false; + }); + }, + }); + }, + }, + { + title: '创建时间', + dataIndex: 'createTime', + width: 180, + }, + { + title: '备注', + dataIndex: 'description', + width: 180, + }, +]; + +export const searchFormSchema: FormSchema[] = [ + { + field: 'roleName', + label: '角色名称', + component: 'Input', + colProps: { span: 8 }, + }, + { + field: 'status', + label: '状态', + component: 'Select', + componentProps: { + options: [ + { label: '启用', value: 0 }, + { label: '停用', value: 1 }, + ], + }, + colProps: { span: 8 }, + }, +]; + +export const formSchema: FormSchema[] = [ + { + field: 'id', + label: '角色id', + show: false, + component: 'Input', + }, + { + field: 'roleName', + label: '角色名称', + required: true, + component: 'Input', + }, + { + field: 'type', + label: '类型', + required: true, + component: 'Select', + componentProps: { + options: [ + { label: '查看全部数据', value: '全部数据' }, + { label: '查看个人数据', value: '个人数据' }, + ], + }, + }, + { + field: 'priceLimit', + label: '价格屏蔽', + component: 'Select', + componentProps: { + options: [ + { label: '屏蔽采购价', value: 1, key: 1}, + { label: '屏蔽零售价', value: 2, key: 2 }, + { label: '屏蔽销售价', value: 3, key: 3 }, + ], + }, + }, + { + field: 'status', + label: '状态', + component: 'RadioButtonGroup', + defaultValue: 0, + componentProps: { + options: [ + { label: '启用', value: 0 }, + { label: '停用', value: 1 }, + ], + }, + }, + { + label: '备注', + field: 'description', + component: 'InputTextArea', + }, +]; + +export const roleSchema: FormSchema[] = [ + { + field: 'id', + label: '角色id', + show: false, + component: 'Input', + }, + { + label: ' ', + field: 'menuIds', + slot: 'menu', + component: 'Input', + }, +] \ No newline at end of file diff --git a/src/views/sys/user/account.data.ts b/src/views/sys/user/account.data.ts new file mode 100644 index 0000000..1b5fa34 --- /dev/null +++ b/src/views/sys/user/account.data.ts @@ -0,0 +1,171 @@ +import { BasicColumn, FormSchema } from '/@/components/Table'; +import { useI18n } from '/@/hooks/web/useI18n'; +import { h } from 'vue'; +import { Switch } from 'ant-design-vue'; +import { useMessage } from '/@/hooks/web/useMessage'; +import { updateStatus } from "@/api/sys/user"; +import {getDeptList} from "@/api/sys/dept"; +import { getRoleList } from "@/api/sys/role"; + +const { t } = useI18n(); + +export const columns: BasicColumn[] = [ + { + title: t('sys.login.userName'), + dataIndex: 'username', + width: 120, + }, + { + title: t('sys.user.name'), + dataIndex: 'name', + width: 120, + }, + { + title: t('sys.user.roleName'), + dataIndex: 'roleName', + width: 120, + }, + { + title: t('sys.user.status'), + dataIndex: 'status', + width: 100, + customRender: ({ record }) => { + if (!Reflect.has(record, 'pendingStatus')) { + record.pendingStatus = false; + } + return h(Switch, { + checked: record.status === 0, + checkedChildren: t('common.on'), + unCheckedChildren: t('common.off'), + loading: record.pendingStatus, + onChange(checked, _) { + const {createMessage} = useMessage(); + if (record.id == 1) { + createMessage.warn(t('common.notice')); + return; + } + record.pendingStatus = true; + const newStatus = checked ? 0 : 1; + updateStatus({id: record.id, status: newStatus} ) + .then(() => { + record.status = newStatus; + }) + .finally(() => { + record.pendingStatus = false; + }); + }, + }); + } + }, + { + title: t('sys.login.email'), + dataIndex: 'email', + width: 120, + }, + { + title: t('sys.login.mobile'), + dataIndex: 'phoneNumber', + width: 120, + }, + { + title: t('common.createTime'), + dataIndex: 'createTime', + width: 180, + }, +]; + +export const searchFormSchema: FormSchema[] = [ + { + field: 'username', + label: t('sys.login.userName'), + component: 'Input', + colProps: { span: 8 }, + }, + { + field: 'name', + label: t('sys.user.name'), + component: 'Input', + colProps: { span: 8 }, + }, +]; + +function isNotExist({ values }) { + return !Boolean(values.id) +} + +export const accountFormSchema: FormSchema[] = [ + { + field: 'id', + label: '用户id', + show: false, + component: 'Input', + }, + { + field: 'username', + label: t('sys.login.userName'), + component: 'Input', + // 注意最好使用异步验证 + helpMessage: ['不能输入带有admin的用户名'], + rules: [ + { + required: true, + message: '请输入用户名', + }, + ], + ifShow: isNotExist + }, + { + field: 'password', + label: t('sys.login.password'), + component: 'InputPassword', + required: false, + helpMessage: ['如果不填写,则默认密码为123456'], + ifShow: isNotExist + }, + { + field: 'deptId', + label: t('sys.user.department'), + component: 'ApiMultipleTreeSelect', + required: true, + componentProps: { + api: getDeptList, + resultField: 'data', + labelField: 'deptName', + valueField: 'id', + }, + }, + { + field: 'roleId', + label: t('sys.user.roleName'), + required: true, + component: 'ApiMultipleSelect', + componentProps: { + api: getRoleList, + resultField: 'data', + labelField: 'roleName', + valueField: 'id', + }, + }, + { + field: 'name', + label: t('sys.user.name'), + component: 'Input', + required: true, + }, + { + field: 'phoneNumber', + label: t('sys.login.mobile'), + component: 'Input', + required: true, + }, + { + field: 'email', + label: t('sys.login.email'), + component: 'Input', + }, + { + field: 'remark', + label: t('sys.user.remake'), + component: 'InputTextArea', + }, +]; diff --git a/src/views/sys/user/components/AccountDetail.vue b/src/views/sys/user/components/AccountDetail.vue new file mode 100644 index 0000000..1d2a367 --- /dev/null +++ b/src/views/sys/user/components/AccountDetail.vue @@ -0,0 +1,61 @@ + + + + + diff --git a/src/views/sys/user/components/AccountModal.vue b/src/views/sys/user/components/AccountModal.vue new file mode 100644 index 0000000..64724e9 --- /dev/null +++ b/src/views/sys/user/components/AccountModal.vue @@ -0,0 +1,89 @@ + + diff --git a/src/views/sys/user/components/DeptTree.vue b/src/views/sys/user/components/DeptTree.vue new file mode 100644 index 0000000..40458fe --- /dev/null +++ b/src/views/sys/user/components/DeptTree.vue @@ -0,0 +1,43 @@ + + diff --git a/src/views/sys/user/index.vue b/src/views/sys/user/index.vue new file mode 100644 index 0000000..8a7a15d --- /dev/null +++ b/src/views/sys/user/index.vue @@ -0,0 +1,158 @@ + + diff --git a/src/views/warehouse/addEditAssembleOrDisassemble.data.ts b/src/views/warehouse/addEditAssembleOrDisassemble.data.ts new file mode 100644 index 0000000..8deed03 --- /dev/null +++ b/src/views/warehouse/addEditAssembleOrDisassemble.data.ts @@ -0,0 +1,194 @@ +import {reactive, ref} from "vue"; +import XEUtils from "xe-utils"; +import {VxeGridInstance, VxeGridProps} from "vxe-table"; +import {Dayjs} from "dayjs"; + +export interface RowVO { + [key: string]: any, + type: string, + warehouseId: number | string, + warehouseName: string | undefined, + barCode: string | number, + productId: number |string, + productName: string, + productModel: string, + productUnit: string, + productStandard: string, + stock: number, + productNumber: number, + unitPrice: number, + amount: number, + remark: string, +} + +interface AssembleFormState { + id: number | string | undefined; + warehouseId: number | string; + receiptDate: string | undefined | Dayjs; + receiptNumber: string |undefined; + remark: string; +} + +interface DisAssembleFormState { + id: number | string | undefined; + warehouseId: number | string; + receiptDate: string | undefined | Dayjs; + receiptNumber: string |undefined; + remark: string; +} + +const xGrid = ref>() +const tableData = ref([]) +const gridOptions = reactive>({ + border: true, + showHeaderOverflow: true, + showOverflow: true, + showFooter: true, + keepSource: true, + id: 'full_edit', + height: 400, + rowConfig: { + keyField: 'id', + isHover: true + }, + columnConfig: { + resizable: true + }, + sortConfig: { + trigger: 'cell', + remote: true + }, + filterConfig: { + remote: true + }, + formConfig: { + titleWidth: 100, + titleAlign: 'right', + items: [ + ] + }, + toolbarConfig: { + slots: { + buttons: 'toolbar_buttons' + }, + zoom: true, + custom: true + }, + columns: [ + { type: 'checkbox', field:'productId', title: 'ID', width: 80}, + { field: 'type', + width:100, + title: '商品类型', + }, + { field: 'warehouseId', + width:120, + title: '仓库', + slots: { edit: 'warehouseId_edit',default: 'warehouseId_default' }, + editRender: {} + }, + { field: 'barCode', + width:160, + title: '条码', + slots: { edit: 'barCode_edit' }, + titlePrefix: { content: '输入条码商品信息自动带出!' }, + editRender: { name: 'input', attrs: { placeholder: '请输入条码并回车' } } + }, + { + field: 'productName', + title: '名称', + width:140, + }, + { field: 'productStandard', title: '规格', width: 110, }, + { field: 'stock', title: '库存', width: 70}, + { field: 'productUnit', title: '单位', width: 70}, + { field: 'productNumber', title: '数量', width:80, + slots: { edit: 'product_number_edit' }, + editRender: { name: '$input', props: { type: 'number', min: 1, max: 9999 } }, }, + { + field: 'unitPrice', + title: '采购价', width:90, + formatter ({ cellValue }) { + return cellValue ? `¥${XEUtils.commafy(XEUtils.toNumber(cellValue), { digits: 2 })}` : '' + }, + slots: { edit: 'price_edit' }, + editRender: { name: '$input', props: { type: 'float', digits: 2, placeholder: '输入单价' } } + }, + { + field: 'amount', + title: '金额', width:90, + formatter ({ cellValue }) { + return cellValue ? `¥${XEUtils.commafy(XEUtils.toNumber(cellValue), { digits: 2 })}` : '' + }, + slots: { edit: 'amount_edit' }, + editRender: { name: '$input', props: { type: 'float', digits: 2, placeholder: '输入金额' } } + }, + { field: 'remark', title: '备注', editRender: { name: 'input', attrs: { placeholder: '请输入备注' } }, width: 150}, + ], + footerMethod ({ columns, data }) { + return [ + columns.map((column, columnIndex) => { + if (columnIndex === 0) { + return '总计' + } + if (['productNumber'].includes(column.field)) { + return sumNum(data, column.field) + } + if (['amount'].includes(column.field)) { + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + return '' + }) + ] + }, + checkboxConfig: { + labelField: 'id', + reserve: true, + highlight: true, + range: true + }, + editConfig: { + trigger: 'click', + mode: 'row', + showStatus: true + }, + editRules: { + warehouseId: [ + { required: true, message: '仓库不能为空' } + ], + barCode: [ + { required: true, message: '商品条码不能为空' } + ], + }, +}) + +const sumNum = (list: RowVO[], field: string) => { + let count = 0 + list.forEach(item => { + count += Number(item[field]) + }) + return count +} +const assembleFormState = reactive({ + id: undefined, + warehouseId: '', + receiptDate: '', + receiptNumber: '', + remark: '', +}); + +const disAssembleFormState = reactive({ + id: undefined, + warehouseId: '', + receiptDate: '', + receiptNumber: '', + remark: '', +}); + +export { + xGrid, + sumNum, + tableData, + gridOptions, + assembleFormState, + disAssembleFormState +} \ No newline at end of file diff --git a/src/views/warehouse/addEditStorageShipments.data.ts b/src/views/warehouse/addEditStorageShipments.data.ts new file mode 100644 index 0000000..7ee9eef --- /dev/null +++ b/src/views/warehouse/addEditStorageShipments.data.ts @@ -0,0 +1,196 @@ +import {reactive, ref} from "vue"; +import XEUtils from "xe-utils"; +import {VxeGridInstance, VxeGridProps} from "vxe-table"; +import {Dayjs} from "dayjs"; + +export interface RowVO { + [key: string]: any, + warehouseId: number | string; + warehouseName: string | undefined, + barCode: string | number, + productId: number |string, + productName: string, + productModel: string, + productUnit: string, + productStandard: string, + stock: number, + productNumber: number, + unitPrice: number, + amount: number, + remark: string, +} + +interface OtherStorageFormState { + id: number | string | undefined; + warehouseId: number | string; + supplierId: number | string | undefined; + receiptDate: string | undefined | Dayjs; + receiptNumber: string |undefined; + remark: string; +} + +interface OtherShipmentFormState { + id: number | string | undefined; + warehouseId: number | string; + customerId: number | string | undefined; + receiptDate: string | undefined | Dayjs; + receiptNumber: string |undefined; + remark: string; +} + +const xGrid = ref>() +const tableData = ref([]) +const gridOptions = reactive>({ + border: true, + showHeaderOverflow: true, + showOverflow: true, + showFooter: true, + keepSource: true, + id: 'full_edit', + height: 400, + rowConfig: { + keyField: 'id', + isHover: true + }, + columnConfig: { + resizable: true + }, + sortConfig: { + trigger: 'cell', + remote: true + }, + filterConfig: { + remote: true + }, + formConfig: { + titleWidth: 100, + titleAlign: 'right', + items: [ + ] + }, + toolbarConfig: { + slots: { + buttons: 'toolbar_buttons' + }, + export: true, + zoom: true, + custom: true + }, + columns: [ + { type: 'checkbox', field:'productId', title: 'ID', width: 80}, + { field: 'warehouseId', + width:120, + title: '仓库', + slots: { edit: 'warehouse_edit',default: 'warehouse_default' }, + editRender: {name: 'input', attrs: { placeholder: '请选择仓库' }} + }, + { field: 'barCode', + width:160, + title: '条码', + slots: { edit: 'barCode_edit' }, + titlePrefix: { content: '输入条码商品信息自动带出!' }, + editRender: { name: 'input', attrs: { placeholder: '请输入条码并回车' } } + }, + { + field: 'productName', + title: '名称', + width:140, + }, + { field: 'productStandard', title: '规格', width: 110, }, + { field: 'stock', title: '库存', width: 70}, + { field: 'productUnit', title: '单位', width: 70}, + { field: 'productNumber', title: '数量', width:80, + slots: { edit: 'product_number_edit' }, + editRender: { name: '$input', props: { type: 'number', min: 1, max: 9999 } }, }, + { + field: 'unitPrice', + title: '单价', width:90, + titlePrefix: { content: '其他入/出库没有单价信息,若需要可自行修改' }, + formatter ({ cellValue }) { + return cellValue ? `¥${XEUtils.commafy(XEUtils.toNumber(cellValue), { digits: 2 })}` : '' + }, + slots: { edit: 'price_edit' }, + editRender: { name: '$input', props: { type: 'float', digits: 2, placeholder: '输入单价' } } + }, + { + field: 'amount', + title: '金额', width:90, + titlePrefix: { content: '其他入/出库没有金额信息,若需要可自行修改' }, + formatter ({ cellValue }) { + return cellValue ? `¥${XEUtils.commafy(XEUtils.toNumber(cellValue), { digits: 2 })}` : '' + }, + slots: { edit: 'amount_edit' }, + editRender: { name: '$input', props: { type: 'float', digits: 2, placeholder: '输入金额' } } + }, + { field: 'remark', title: '备注', editRender: { name: 'input', attrs: { placeholder: '请输入备注' } }, width: 150}, + ], + footerMethod ({ columns, data }) { + return [ + columns.map((column, columnIndex) => { + if (columnIndex === 0) { + return '总计' + } + if (['productNumber'].includes(column.field)) { + return sumNum(data, column.field) + } + if (['amount'].includes(column.field)) { + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + return '' + }) + ] + }, + checkboxConfig: { + labelField: 'id', + reserve: true, + highlight: true, + range: true + }, + editConfig: { + trigger: 'click', + mode: 'row', + showStatus: true + }, + editRules: { + warehouseId: [ + { required: true, message: '仓库不能为空' } + ], + barCode: [ + { required: true, message: '商品条码不能为空' } + ], + }, +}) + +const sumNum = (list: RowVO[], field: string) => { + let count = 0 + list.forEach(item => { + count += Number(item[field]) + }) + return count +} +const otherStorageFormState = reactive({ + id: undefined, + warehouseId: '', + supplierId: '', + receiptDate: '', + receiptNumber: '', + remark: '', +}); + +const otherShipmentFormState = reactive({ + id: undefined, + warehouseId: '', + customerId: '', + receiptDate: '', + receiptNumber: '', + remark: '', +}); + +export { + xGrid, + sumNum, + tableData, + gridOptions, + otherStorageFormState, + otherShipmentFormState +} \ No newline at end of file diff --git a/src/views/warehouse/allot/allotShipments.data.ts b/src/views/warehouse/allot/allotShipments.data.ts new file mode 100644 index 0000000..d396761 --- /dev/null +++ b/src/views/warehouse/allot/allotShipments.data.ts @@ -0,0 +1,158 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {getUserOperatorList} from "@/api/sys/user"; + +export const columns: BasicColumn[] = [ + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 130, + }, + { + title: '商品信息', + dataIndex: 'productInfo', + width: 150, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 100, + }, + { + title: '操作员', + dataIndex: 'operator', + width: 70, + }, + { + title: '状态', + dataIndex: 'status', + width: 70, + }, +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '操作员', + field: 'operatorId', + component: 'ApiSelect', + componentProps: { + api: getUserOperatorList, + resultField: 'data', + labelField: 'name', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '单据状态', + field: 'status', + component: 'Select', + colProps: { + xl: 8, + xxl: 8, + }, + componentProps: { + options: [ + { label: '未审核', value: 0, key: 0 }, + { label: '已审核', value: 1, key: 1 }, + ], + }, + }, + { + label: '单据备注', + field: 'remark', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + } +] + +export const allotShipmentTableColumns: BasicColumn[] = [ + { + title: '调出方仓库', + dataIndex: 'warehouseName', + width: 100, + }, + { + title: '调入方仓库', + dataIndex: 'otherWarehouseName', + width: 100, + }, + { + title: '条码', + dataIndex: 'barCode', + width: 120, + }, + { + title: '商品名称', + dataIndex: 'productName', + width: 150, + }, + { + title: '规格', + dataIndex: 'productStandard', + width: 100, + }, + { + title: '型号', + dataIndex: 'productModel', + width: 100, + }, + { + title: '扩展信息', + dataIndex: 'productExtendInfo', + width: 150, + }, + { + title: '库存', + dataIndex: 'stock', + width: 70, + }, + { + title: '单位', + dataIndex: 'productUnit', + width: 70, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 70, + }, + { + title: '备注', + dataIndex: 'remark', + width: 130, + }, +] \ No newline at end of file diff --git a/src/views/warehouse/allot/components/AddEditAllotShipmentsModal.vue b/src/views/warehouse/allot/components/AddEditAllotShipmentsModal.vue new file mode 100644 index 0000000..0ed4dbe --- /dev/null +++ b/src/views/warehouse/allot/components/AddEditAllotShipmentsModal.vue @@ -0,0 +1,640 @@ + + + + + \ No newline at end of file diff --git a/src/views/warehouse/allot/components/ViewAllotShipmentsModal.vue b/src/views/warehouse/allot/components/ViewAllotShipmentsModal.vue new file mode 100644 index 0000000..c3e38cf --- /dev/null +++ b/src/views/warehouse/allot/components/ViewAllotShipmentsModal.vue @@ -0,0 +1,159 @@ + + + diff --git a/src/views/warehouse/allot/components/addEditAllotShipments.data.ts b/src/views/warehouse/allot/components/addEditAllotShipments.data.ts new file mode 100644 index 0000000..c04e964 --- /dev/null +++ b/src/views/warehouse/allot/components/addEditAllotShipments.data.ts @@ -0,0 +1,164 @@ +import {reactive, ref} from "vue"; +import XEUtils from "xe-utils"; +import {VxeGridInstance, VxeGridProps} from "vxe-table"; +import {Dayjs} from "dayjs"; + +export interface RowVO { + [key: string]: any, + warehouseId: number | string; + otherWarehouseId: number | string; + warehouseName: string | undefined, + barCode: string | number, + productId: number |string, + productName: string, + productModel: string, + productUnit: string, + productStandard: string, + stock: number, + productNumber: number, + unitPrice: number, + amount: number, + remark: string, +} + +interface AllotShipmentsFormState { + id: number | string | undefined; + warehouseId: number | string | undefined; + receiptDate: string | undefined | Dayjs; + receiptNumber: string |undefined; + remark: string; +} + +const xGrid = ref>() +const tableData = ref([]) +const gridOptions = reactive>({ + border: true, + showHeaderOverflow: true, + showOverflow: true, + showFooter: true, + keepSource: true, + id: 'full_edit', + height: 400, + rowConfig: { + keyField: 'id', + isHover: true + }, + columnConfig: { + resizable: true + }, + sortConfig: { + trigger: 'cell', + remote: true + }, + filterConfig: { + remote: true + }, + formConfig: { + titleWidth: 100, + titleAlign: 'right', + items: [ + ] + }, + toolbarConfig: { + slots: { + buttons: 'toolbar_buttons' + }, + zoom: true, + custom: true + }, + columns: [ + { type: 'checkbox', field:'productId', title: 'ID', width: 80}, + { field: 'warehouseId', + width:150, + title: '仓库', + slots: { edit: 'warehouse_edit',default: 'warehouse_default' }, + editRender: { name: 'input', attrs: { placeholder: '请选择仓库' } } + }, + { field: 'barCode', + width:160, + title: '条码', + slots: { edit: 'barCode_edit' }, + titlePrefix: { content: '输入条码商品信息自动带出!' }, + editRender: { name: 'input', attrs: { placeholder: '请输入条码并回车' } } + }, + { + field: 'productName', + title: '名称', + width:140, + }, + { field: 'productStandard', title: '规格', width: 110, }, + { field: 'stock', title: '库存', width: 70}, + { field: 'otherWarehouseId', + width:150, + title: '调入仓库', + slots: { edit: 'otherWarehouse_edit',default: 'otherWarehouse_default' }, + editRender: {} + }, + { field: 'productUnit', title: '单位', width: 70}, + { field: 'productNumber', title: '数量', width:80, + slots: { edit: 'product_number_edit' }, + editRender: { name: '$input', props: { type: 'number', min: 1, max: 9999 } }, }, + { field: 'remark', title: '备注', editRender: { name: 'input', attrs: { placeholder: '请输入备注' } }, width: 150}, + ], + footerMethod ({ columns, data }) { + return [ + columns.map((column, columnIndex) => { + if (columnIndex === 0) { + return '总计' + } + if (['productNumber'].includes(column.field)) { + return sumNum(data, column.field) + } + if (['amount'].includes(column.field)) { + return `¥${XEUtils.commafy(XEUtils.toNumber(sumNum(data, column.field)), { digits: 2 })}` + } + return '' + }) + ] + }, + checkboxConfig: { + labelField: 'id', + reserve: true, + highlight: true, + range: true + }, + editConfig: { + trigger: 'click', + mode: 'row', + showStatus: true + }, + editRules: { + warehouseId: [ + { required: true, message: '仓库不能为空' } + ], + barCode: [ + { required: true, message: '商品条码不能为空' } + ], + otherWarehouseId: [ + { required: true, message: '调入方仓库不能为空' } + ] + }, +}) + +const sumNum = (list: RowVO[], field: string) => { + let count = 0 + list.forEach(item => { + count += Number(item[field]) + }) + return count +} +const allotShipmentsFormState = reactive({ + id: undefined, + receiptDate: '', + receiptNumber: '', + warehouseId: '', + remark: '', +}); + +export { + xGrid, + sumNum, + tableData, + gridOptions, + allotShipmentsFormState +} \ No newline at end of file diff --git a/src/views/warehouse/allot/index.vue b/src/views/warehouse/allot/index.vue new file mode 100644 index 0000000..ffd7278 --- /dev/null +++ b/src/views/warehouse/allot/index.vue @@ -0,0 +1,241 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/warehouse/assemble/assemble.data.ts b/src/views/warehouse/assemble/assemble.data.ts new file mode 100644 index 0000000..100930c --- /dev/null +++ b/src/views/warehouse/assemble/assemble.data.ts @@ -0,0 +1,173 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {getUserOperatorList} from "@/api/sys/user"; + +export const columns: BasicColumn[] = [ + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 130, + }, + { + title: '商品信息', + dataIndex: 'productInfo', + width: 150, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 100, + }, + { + title: '金额合计', + dataIndex: 'totalAmount', + width: 70, + }, + { + title: '操作员', + dataIndex: 'operator', + width: 70, + }, + { + title: '状态', + dataIndex: 'status', + width: 70, + }, +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '操作员', + field: 'operatorId', + component: 'ApiSelect', + componentProps: { + api: getUserOperatorList, + resultField: 'data', + labelField: 'name', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '单据状态', + field: 'status', + component: 'Select', + colProps: { + xl: 8, + xxl: 8, + }, + componentProps: { + options: [ + { label: '未审核', value: 0, key: 0 }, + { label: '已审核', value: 1, key: 1 }, + ], + }, + }, + { + label: '单据备注', + field: 'remark', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + } +] + +export const assembleTableColumns: BasicColumn[] = [ + { + title: '商品类型', + dataIndex: 'type', + width: 80, + }, + { + title: '仓库名称', + dataIndex: 'warehouseName', + width: 100, + }, + { + title: '条码', + dataIndex: 'barCode', + width: 120, + }, + { + title: '商品名称', + dataIndex: 'productName', + width: 150, + }, + { + title: '规格', + dataIndex: 'productStandard', + width: 100, + }, + { + title: '型号', + dataIndex: 'productModel', + width: 100, + }, + { + title: '扩展信息', + dataIndex: 'productExtendInfo', + width: 150, + }, + { + title: '库存', + dataIndex: 'stock', + width: 70, + }, + { + title: '单位', + dataIndex: 'productUnit', + width: 70, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 70, + }, + { + title: '单价', + dataIndex: 'unitPrice', + width: 70, + }, + { + title: '金额', + dataIndex: 'amount', + width: 70, + }, + { + title: '备注', + dataIndex: 'remark', + width: 130, + }, +] \ No newline at end of file diff --git a/src/views/warehouse/assemble/components/AddEditAssembleModal.vue b/src/views/warehouse/assemble/components/AddEditAssembleModal.vue new file mode 100644 index 0000000..f4064f4 --- /dev/null +++ b/src/views/warehouse/assemble/components/AddEditAssembleModal.vue @@ -0,0 +1,728 @@ + + + + + \ No newline at end of file diff --git a/src/views/warehouse/assemble/components/ViewAssembleModal.vue b/src/views/warehouse/assemble/components/ViewAssembleModal.vue new file mode 100644 index 0000000..e3548bb --- /dev/null +++ b/src/views/warehouse/assemble/components/ViewAssembleModal.vue @@ -0,0 +1,157 @@ + + + diff --git a/src/views/warehouse/assemble/index.vue b/src/views/warehouse/assemble/index.vue new file mode 100644 index 0000000..fdc4865 --- /dev/null +++ b/src/views/warehouse/assemble/index.vue @@ -0,0 +1,241 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/warehouse/disassemble/components/AddEditDisassembleModal.vue b/src/views/warehouse/disassemble/components/AddEditDisassembleModal.vue new file mode 100644 index 0000000..7c52054 --- /dev/null +++ b/src/views/warehouse/disassemble/components/AddEditDisassembleModal.vue @@ -0,0 +1,731 @@ + + + + + \ No newline at end of file diff --git a/src/views/warehouse/disassemble/components/ViewDisassembleModal.vue b/src/views/warehouse/disassemble/components/ViewDisassembleModal.vue new file mode 100644 index 0000000..85ad674 --- /dev/null +++ b/src/views/warehouse/disassemble/components/ViewDisassembleModal.vue @@ -0,0 +1,157 @@ + + + diff --git a/src/views/warehouse/disassemble/disassemble.data.ts b/src/views/warehouse/disassemble/disassemble.data.ts new file mode 100644 index 0000000..bae2b81 --- /dev/null +++ b/src/views/warehouse/disassemble/disassemble.data.ts @@ -0,0 +1,173 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {getUserOperatorList} from "@/api/sys/user"; + +export const columns: BasicColumn[] = [ + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 130, + }, + { + title: '商品信息', + dataIndex: 'productInfo', + width: 150, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 100, + }, + { + title: '金额合计', + dataIndex: 'totalAmount', + width: 70, + }, + { + title: '操作员', + dataIndex: 'operator', + width: 70, + }, + { + title: '状态', + dataIndex: 'status', + width: 70, + }, +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '操作员', + field: 'operatorId', + component: 'ApiSelect', + componentProps: { + api: getUserOperatorList, + resultField: 'data', + labelField: 'name', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '单据状态', + field: 'status', + component: 'Select', + colProps: { + xl: 8, + xxl: 8, + }, + componentProps: { + options: [ + { label: '未审核', value: 0, key: 0 }, + { label: '已审核', value: 1, key: 1 }, + ], + }, + }, + { + label: '单据备注', + field: 'remark', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + } +] + +export const disAssembleTableColumns: BasicColumn[] = [ + { + title: '商品类型', + dataIndex: 'type', + width: 80, + }, + { + title: '仓库名称', + dataIndex: 'warehouseName', + width: 100, + }, + { + title: '条码', + dataIndex: 'barCode', + width: 120, + }, + { + title: '商品名称', + dataIndex: 'productName', + width: 150, + }, + { + title: '规格', + dataIndex: 'productStandard', + width: 100, + }, + { + title: '型号', + dataIndex: 'productModel', + width: 100, + }, + { + title: '扩展信息', + dataIndex: 'productExtendInfo', + width: 150, + }, + { + title: '库存', + dataIndex: 'stock', + width: 70, + }, + { + title: '单位', + dataIndex: 'productUnit', + width: 70, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 70, + }, + { + title: '单价', + dataIndex: 'unitPrice', + width: 70, + }, + { + title: '金额', + dataIndex: 'amount', + width: 70, + }, + { + title: '备注', + dataIndex: 'remark', + width: 130, + }, +] \ No newline at end of file diff --git a/src/views/warehouse/disassemble/index.vue b/src/views/warehouse/disassemble/index.vue new file mode 100644 index 0000000..8a28884 --- /dev/null +++ b/src/views/warehouse/disassemble/index.vue @@ -0,0 +1,242 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/warehouse/shipments/components/AddEditOtherShipmentsModal.vue b/src/views/warehouse/shipments/components/AddEditOtherShipmentsModal.vue new file mode 100644 index 0000000..72ea158 --- /dev/null +++ b/src/views/warehouse/shipments/components/AddEditOtherShipmentsModal.vue @@ -0,0 +1,713 @@ + + + + + \ No newline at end of file diff --git a/src/views/warehouse/shipments/components/ViewOtherShipmentsModal.vue b/src/views/warehouse/shipments/components/ViewOtherShipmentsModal.vue new file mode 100644 index 0000000..d91e85c --- /dev/null +++ b/src/views/warehouse/shipments/components/ViewOtherShipmentsModal.vue @@ -0,0 +1,173 @@ + + + diff --git a/src/views/warehouse/shipments/index.vue b/src/views/warehouse/shipments/index.vue new file mode 100644 index 0000000..0f9d2b0 --- /dev/null +++ b/src/views/warehouse/shipments/index.vue @@ -0,0 +1,240 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/warehouse/shipments/otherShipments.data.ts b/src/views/warehouse/shipments/otherShipments.data.ts new file mode 100644 index 0000000..076a6ef --- /dev/null +++ b/src/views/warehouse/shipments/otherShipments.data.ts @@ -0,0 +1,186 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {getCustomerList} from "@/api/basic/customer"; +import {getUserOperatorList} from "@/api/sys/user"; + +export const columns: BasicColumn[] = [ + { + title: '客户', + dataIndex: 'customerName', + width: 170, + }, + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 130, + }, + { + title: '商品信息', + dataIndex: 'productInfo', + width: 150, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 100, + }, + { + title: '金额合计', + dataIndex: 'totalAmount', + width: 70, + }, + { + title: '操作员', + dataIndex: 'operator', + width: 70, + }, + { + title: '状态', + dataIndex: 'status', + width: 70, + }, +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { span: 7 }, + }, + { + label: '客户', + field: 'customerId', + component: 'ApiSelect', + componentProps: { + api: getCustomerList, + resultField: 'data', + labelField: 'customerName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '操作员', + field: 'operatorId', + component: 'ApiSelect', + componentProps: { + api: getUserOperatorList, + resultField: 'data', + labelField: 'name', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '单据状态', + field: 'status', + component: 'Select', + colProps: { + xl: 8, + xxl: 8, + }, + componentProps: { + options: [ + { label: '未审核', value: 0, key: 0 }, + { label: '已审核', value: 1, key: 1 }, + ], + }, + }, + { + label: '单据备注', + field: 'remark', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + } +] + +export const otherShipmentTableColumns: BasicColumn[] = [ + { + title: '仓库名称', + dataIndex: 'warehouseName', + width: 100, + }, + { + title: '条码', + dataIndex: 'barCode', + width: 120, + }, + { + title: '商品名称', + dataIndex: 'productName', + width: 150, + }, + { + title: '规格', + dataIndex: 'productStandard', + width: 100, + }, + { + title: '型号', + dataIndex: 'productModel', + width: 100, + }, + { + title: '扩展信息', + dataIndex: 'productExtendInfo', + width: 150, + }, + { + title: '库存', + dataIndex: 'stock', + width: 70, + }, + { + title: '单位', + dataIndex: 'productUnit', + width: 70, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 70, + }, + { + title: '单价', + dataIndex: 'unitPrice', + width: 70, + }, + { + title: '金额', + dataIndex: 'amount', + width: 70, + }, + { + title: '备注', + dataIndex: 'remark', + width: 130, + }, +] \ No newline at end of file diff --git a/src/views/warehouse/storage/components/AddEditOtherStorageModal.vue b/src/views/warehouse/storage/components/AddEditOtherStorageModal.vue new file mode 100644 index 0000000..9bf3e59 --- /dev/null +++ b/src/views/warehouse/storage/components/AddEditOtherStorageModal.vue @@ -0,0 +1,708 @@ + + + + + \ No newline at end of file diff --git a/src/views/warehouse/storage/components/ViewOtherStorageModal.vue b/src/views/warehouse/storage/components/ViewOtherStorageModal.vue new file mode 100644 index 0000000..db7e8a3 --- /dev/null +++ b/src/views/warehouse/storage/components/ViewOtherStorageModal.vue @@ -0,0 +1,173 @@ + + + diff --git a/src/views/warehouse/storage/index.vue b/src/views/warehouse/storage/index.vue new file mode 100644 index 0000000..71cf737 --- /dev/null +++ b/src/views/warehouse/storage/index.vue @@ -0,0 +1,240 @@ + +
    +
    + + \ No newline at end of file diff --git a/src/views/warehouse/storage/otherStorage.data.ts b/src/views/warehouse/storage/otherStorage.data.ts new file mode 100644 index 0000000..2c754f5 --- /dev/null +++ b/src/views/warehouse/storage/otherStorage.data.ts @@ -0,0 +1,186 @@ +import {FormSchema} from "@/components/Form"; +import {BasicColumn} from "@/components/Table"; +import {getSupplierList} from "@/api/basic/supplier"; +import {getUserOperatorList} from "@/api/sys/user"; + +export const columns: BasicColumn[] = [ + { + title: '供应商', + dataIndex: 'supplierName', + width: 170, + }, + { + title: '单据编号', + dataIndex: 'receiptNumber', + width: 130, + }, + { + title: '商品信息', + dataIndex: 'productInfo', + width: 150, + }, + { + title: '单据日期', + dataIndex: 'receiptDate', + width: 130, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 100, + }, + { + title: '金额合计', + dataIndex: 'totalAmount', + width: 70, + }, + { + title: '操作员', + dataIndex: 'operator', + width: 70, + }, + { + title: '状态', + dataIndex: 'status', + width: 70, + }, +] + +export const searchFormSchema: FormSchema[] = [ + { + label: '单据编号', + field: 'receiptNumber', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + field: '[startDate, endDate]', + label: '单据日期', + component: 'RangePicker', + componentProps: { + format: 'YYYY/MM/DD', + placeholder: ['开始日期', '结束日期'], + }, + colProps: { span: 7 }, + }, + { + label: '供应商', + field: 'supplierId', + component: 'ApiSelect', + componentProps: { + api: getSupplierList, + resultField: 'data', + labelField: 'supplierName', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '操作员', + field: 'operatorId', + component: 'ApiSelect', + componentProps: { + api: getUserOperatorList, + resultField: 'data', + labelField: 'name', + valueField: 'id', + }, + colProps: { + xl: 8, + xxl: 8, + }, + }, + { + label: '单据状态', + field: 'status', + component: 'Select', + colProps: { + xl: 8, + xxl: 8, + }, + componentProps: { + options: [ + { label: '未审核', value: 0, key: 0 }, + { label: '已审核', value: 1, key: 1 }, + ], + }, + }, + { + label: '单据备注', + field: 'remark', + component: 'Input', + colProps: { + xl: 8, + xxl: 8, + }, + } +] + +export const otherStorageTableColumns: BasicColumn[] = [ + { + title: '仓库名称', + dataIndex: 'warehouseName', + width: 100, + }, + { + title: '条码', + dataIndex: 'barCode', + width: 120, + }, + { + title: '商品名称', + dataIndex: 'productName', + width: 150, + }, + { + title: '规格', + dataIndex: 'productStandard', + width: 100, + }, + { + title: '型号', + dataIndex: 'productModel', + width: 100, + }, + { + title: '扩展信息', + dataIndex: 'productExtendInfo', + width: 150, + }, + { + title: '库存', + dataIndex: 'stock', + width: 70, + }, + { + title: '单位', + dataIndex: 'productUnit', + width: 70, + }, + { + title: '数量', + dataIndex: 'productNumber', + width: 70, + }, + { + title: '单价', + dataIndex: 'unitPrice', + width: 70, + }, + { + title: '金额', + dataIndex: 'amount', + width: 70, + }, + { + title: '备注', + dataIndex: 'remark', + width: 130, + }, +] \ No newline at end of file diff --git a/src/views/workflow/bpmn/index.vue b/src/views/workflow/bpmn/index.vue new file mode 100644 index 0000000..90f5905 --- /dev/null +++ b/src/views/workflow/bpmn/index.vue @@ -0,0 +1,206 @@ + + + + + \ No newline at end of file diff --git a/src/views/workflow/bpmn/zh.ts b/src/views/workflow/bpmn/zh.ts new file mode 100644 index 0000000..21c9ded --- /dev/null +++ b/src/views/workflow/bpmn/zh.ts @@ -0,0 +1,271 @@ +const translations = { + + "Name":"名称", + "Value":"值", + "ID":"唯一标识(ID)", + "General":"基础属性", + + "Activate the create/remove space tool": "启动创建/删除空间工具", + "Activate the global connect tool": "启动全局连接工具", + "Activate the hand tool": "启动手动工具", + "Activate the lasso tool": "启动套索工具", + "Ad-hoc": "Ad-hoc子流程", + "Add Lane above": "添加到通道之上", + "Add Lane below": "添加到通道之下", + "Append ConditionIntermediateCatchEvent": "添加中间条件捕获事件", + "Append element": "添加元素", + "Append EndEvent": "添加结束事件", + "Append Gateway": "添加网关", + "Append Intermediate/Boundary Event": "添加中间/边界事件", + "Append MessageIntermediateCatchEvent": "添加消息中间捕获事件", + "Append ReceiveTask": "添加接收任务", + "Append SignalIntermediateCatchEvent": "添加信号中间捕获事件", + "Append Task": "添加任务", + "Append TimerIntermediateCatchEvent": "添加定时器中间捕获事件", + "Append compensation activity": "追加补偿活动", + "Append {type}": "追加 {type}", + "Boundary Event": "边界事件", + "Business Rule Task": "规则任务", + "Call Activity": "引用流程", + "Cancel Boundary Event": "取消边界事件", + "Cancel End Event": "取消结束事件", + "Change type": "更改类型", + "Collapsed Pool": "折叠池", + "Collection": "集合", + "Compensation Boundary Event": "补偿边界事件", + "Compensation End Event": "结束补偿事件", + "Compensation Intermediate Throw Event": "中间补偿抛出事件", + "Compensation Start Event": "补偿启动事件", + "Complex Gateway": "复杂网关", + "Conditional Boundary Event": "条件边界事件", + "Conditional Boundary Event (non-interrupting)": "条件边界事件 (非中断)", + "Conditional Flow": "条件流", + "Conditional Intermediate Catch Event": "中间条件捕获事件", + "Conditional Start Event": "条件启动事件", + "Conditional Start Event (non-interrupting)": "条件启动事件 (非中断)", + "Connect using Association": "文本关联", + "Connect using DataInputAssociation": "数据关联", + "Connect using Sequence/MessageFlow or Association": "消息关联", + "Create IntermediateThrowEvent/BoundaryEvent": "创建中间抛出/边界事件", + "Create DataObjectReference": "创建数据对象引用", + "Create DataStoreReference": "创建数据存储引用", + "Create element": "创建元素", + "Create EndEvent": "创建结束事件", + "Create Gateway": "创建网关", + "Create Group": "创建组", + "Create Intermediate/Boundary Event": "创建中间/边界事件", + "Create Pool/Participant": "创建池/参与者", + "Create StartEvent": "创建开始事件", + "Create Task": "创建任务", + "Create expanded SubProcess": "创建可折叠子流程", + "Create {type}": "创建 {type}", + "Data": "数据", + "Data Object Reference": "数据对象引用", + "Data Store Reference": "数据存储引用", + "Default Flow": "默认流", + "Divide into three Lanes": "分成三条通道", + "Divide into two Lanes": "分成两条通道", + "Empty Pool": "空泳道", + "Empty Pool (removes content)": "清空泳道(删除内容)", + "End Event": "结束事件", + "Error Boundary Event": "错误边界事件", + "Error End Event": "结束错误事件", + "Error Start Event": "错误启动事件", + "Escalation Boundary Event": "升级边界事件", + "Escalation Boundary Event (non-interrupting)": "升级边界事件 (非中断)", + "Escalation End Event": "结束升级事件", + "Escalation Intermediate Throw Event": "中间升级抛出事件", + "Escalation Start Event": "升级启动事件", + "Escalation Start Event (non-interrupting)": "升级启动事件 (非中断)", + "Events": "事件", + "Event Sub Process": "事件子流程", + "Event based Gateway": "事件网关", + "Exclusive Gateway": "独占网关", + "Expanded Pool": "展开泳道", + "Gateways": "网关", + "Inclusive Gateway": "包容网关", + "Intermediate Throw Event": "中间抛出事件", + "Link Intermediate Catch Event": "中间链接捕获事件", + "Link Intermediate Throw Event": "中间链接抛出事件", + "Loop": "循环", + "Manual Task": "手动任务", + "Message Boundary Event": "消息边界事件", + "Message Boundary Event (non-interrupting)": "消息边界事件 (非中断)", + "Message End Event": "结束消息事件", + "Message Intermediate Catch Event": "中间消息捕获事件", + "Message Intermediate Throw Event": "中间消息抛出事件", + "Message Start Event": "消息启动事件", + "Message Start Event (non-interrupting)": "消息启动事件 (非中断)", + "Parallel Gateway": "并行网关", + "Parallel Multi Instance": "并行多实例", + "Participants": "参与者", + "Participant Multiplicity": "参与者多重性", + "Receive Task": "接受任务", + "Remove": "移除", + "Script Task": "脚本任务", + "Send Task": "发送任务", + "Sequence Flow": "顺序流", + "Sequential Multi Instance": "串行多实例", + "Service Task": "服务任务", + "Signal Boundary Event": "信号边界事件", + "Signal Boundary Event (non-interrupting)": "信号边界事件 (非中断)", + "Signal End Event": "结束信号事件", + "Signal Intermediate Catch Event": "中间信号捕获事件", + "Signal Intermediate Throw Event": "中间信号抛出事件", + "Signal Start Event": "信号启动事件", + "Signal Start Event (non-interrupting)": "信号启动事件 (非中断)", + "Start Event": "开始事件", + "Sub Process": "子流程", + "Sub Processes": "子流程", + "Sub Process (collapsed)": "可折叠子流程", + "Sub Process (expanded)": "可展开子流程", + "Task": "任务", + "Tasks": "任务", + "Terminate End Event": "终止边界事件", + "Timer Boundary Event": "定时边界事件", + "Timer Boundary Event (non-interrupting)": "定时边界事件 (非中断)", + "Timer Intermediate Catch Event": "中间定时捕获事件", + "Timer Start Event": "定时启动事件", + "Timer Start Event (non-interrupting)": "定时启动事件 (非中断)", + "Transaction": "事务", + "User Task": "用户任务", + "already rendered {element}": "{element} 已呈现", + "diagram not part of bpmn:Definitions": "图表不是 bpmn:Definitions 的一部分", + "element required": "需要元素", + "correcting missing bpmnElement on {plane} to {rootElement}": "在 {plane} 上更正缺失的 bpmnElement 为 {rootElement}", + "element {element} referenced by {referenced}#{property} not yet drawn": "元素 {element} 的引用 {referenced}#{property} 尚未绘制", + "failed to import {element}": "{element} 导入失败", + "flow elements must be children of pools/participants": "元素必须是池/参与者的子级", + "more than {count} child lanes": "超过 {count} 条通道", + "missing {semantic}#attachedToRef": "在 {element} 中缺少 {semantic}#attachedToRef", + "multiple DI elements defined for {element}": "为 {element} 定义了多个 DI 元素", + "no bpmnElement referenced in {element}": "{element} 中没有引用 bpmnElement", + "no diagram to display": "没有要显示的图表", + "no shape type specified": "未指定形状类型", + "no parent for {element} in {parent}": "在 {element} 中没有父元素 {parent}", + "no process or collaboration to display": "没有可显示的流程或协作", + "out of bounds release": "越界释放", + "Version tag":"版本标记", + "Change element":"改变元素", + "Documentation":"文档", + "PROCESS":"流程", + "Element documentation":"元素文档说明", + "User assignment":"分配用户", + "History cleanup":"历史记录清理", + "Time to live":"历史记录生存时间", + "Tasklist":"任务列表", + "Candidate starter":"候选启动器", + "Candidate starter groups":"候选启动组", + "Specify more than one group as a comma separated list.":"多个组用','分隔.", + "Candidate starter users":"候选发起人", + "Specify more than one user as a comma separated list.":"多个用户用','分隔.", + "External task":"外部任务", + "Startable":"可启动(Startable)", + "Executable":"可直接执行", + "Job execution":"作业执行", + "Priority":"优先级", + "Forms":"表单", + "Execution listeners":"执行侦听器", + "Extension properties":"扩展属性", + "Event type":"事件类型", + "Listener type":"侦听器类型", + "Field injection":"字段注入", + "Start initiator":"开始发起人", + "Initiator":"发起人", + "Asynchronous continuations":"异步延续", + "Before":"之前", + "After":"之后", + "Inputs":"输入", + "Outputs":"输出", + "Local variable name":"局部变量名称", + "Assignment type":"分配类型", + "Format":"格式", + "Type":"类型", + "Expression":"表达式(Expression)", + "Script":"脚本(Script)", + "Delegate expression":"委托表达式(Delegate expression)", + "Java class":"Java类(Java class)", + "start":"开始(start)", + "end":"结束(end)", + "Start typing \"${}\" to create an expression.":"开始键入\"${}\"以创建表达式.", + "Process variable name":"过程变量名称", + "List values":"列表值", + "Map entries":"映射条目", + "Key":"键", + "Values":"值", + "Form reference":"引用表单ID", + "Binding":"结合", + "Version":"版本", + "Form fields":"表单字段", + "Form key":"表单ID", + "Embedded or External Task Forms":"拓展表单", + "Camunda Forms":"标准表单", + "Generated Task Forms":"内置表单", + "Refers to the process variable name":"指的是(引用)过程变量名称", + "Label":"标签", + "Default value":"默认值", + "Constraints":"限制", + "Properties":"属性", + "Config":"配置", + "Implementation":"实施", + "Field injections":"字段注入", + "Task listeners":"任务侦听器", + "Listener ID":"侦听器ID", + "Message":"消息", + "Global message reference":"引用全局消息ID", + "Result variable":"结果变量", + "Resource":"资源", + "External resource":"外部资源", + "Inline script":"内联脚本", + "Process variables":"过程变量", + "Global signal reference":"引用全局信号ID", + "Signal":"信号", + "Called element":"被调用元素", + "In mapping propagation":"在映射传播中", + "Propagate all variables":"传播所有变量", + "Out mapping propagation":"向外映射传播", + "In mappings":"在映射中", + "Source":"来源", + "Target":"目标", + "Local":"局部的(Local)", + "Out mappings":"输出映射", + "Link":"链接", + "Timer":"定时器", + "Retry time cycle":"重试时间周期", + "Variable name":"变量名称", + "Condition Expression":"条件表达式", + "Condition":"条件", + "Process documentation":"流程文档", + "Assignee":"委托人", + "Candidate groups":"候选组", + "Candidate users":"候选用户", + "Due date":"期限", + "The due date as an EL expression (e.g. ${someDate}) or an ISO date (e.g. 2015-06-26T09:54:00).":"到期日期为EL表达式(例如${someDate})或ISO日期(例如2015-06-26T09:54:00)", + "Follow up date":"跟进日期", + "The follow up date as an EL expression (e.g. ${someDate}) or an ISO date (e.g. 2015-06-26T09:54:00).":"作为EL表达式(例如${someDate})或ISO日期(例如2015-06-26T09:54:00)的跟进日期", + "Connector ID":"连接器ID", + "Connector inputs":"连接器输入", + "Connector outputs":"连接器输出", + "Topic":"主题", + "Errors":"错误", + "Global error reference":"引用全局错误ID", + "Throw expression":"Throw表达式", + "Decision reference":"引用决策ID", + "Tenant ID":"租户ID", + "Multi-instance":"多实例", + "Loop cardinality":"循环基数", + "Completion condition":"完成条件", + "Element variable":"元素变量", + "Asynchronous before":"异步之前", + "Asynchronous after":"异步之后", +}; + +export const customTranslate = (template, replacements) =>{ + replacements = replacements || {}; + // Translate + template = translations[template] || template; + // Replace + return template.replace(/{([^}]+)}/g, (_, key)=> { + return replacements[key] || '{' + key + '}'; + }); +} \ No newline at end of file diff --git a/test.txt b/test.txt deleted file mode 100644 index 56a6051..0000000 --- a/test.txt +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..2062338 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@vben/ts-config/vue-app.json", + "compilerOptions": { + "baseUrl": ".", + "types": ["vite/client", "unplugin-vue-define-options/macros-global"], + "paths": { + "/@/*": ["src/*"], + "/#/*": ["types/*"], + "@/*": ["src/*"], + "#/*": ["types/*"] + }, + "declaration": false + }, + "include": [ + "tests/**/*.ts", + "src/**/*.ts", + "src/**/*.d.ts", + "src/**/*.tsx", + "src/**/*.vue", + "types/**/*.d.ts", + "types/**/*.ts", + "build/**/*.ts", + "build/**/*.d.ts", + "mock/**/*.ts", + "vite.config.ts" + ], + "exclude": ["node_modules", "tests/server/**/*.ts", "dist", "**/*.js"] +} diff --git a/turbo.json b/turbo.json new file mode 100644 index 0000000..bf5b89b --- /dev/null +++ b/turbo.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://turborepo.org/schema.json", + "pipeline": { + "build": { + "dependsOn": ["^build"], + "outputs": ["dist/**"] + }, + "stub": {}, + "lint": {}, + "clean": { + "cache": false + }, + "dev": { + "cache": false, + "persistent": true + } + } +} diff --git a/types/axios.d.ts b/types/axios.d.ts new file mode 100644 index 0000000..05fe0ab --- /dev/null +++ b/types/axios.d.ts @@ -0,0 +1,56 @@ +export type ErrorMessageMode = 'none' | 'modal' | 'message' | 'notice' | undefined; +export type SuccessMessageMode = ErrorMessageMode; + +export interface RequestOptions { + // Splicing request parameters to url + joinParamsToUrl?: boolean; + // Format request parameter time + formatDate?: boolean; + // Whether to process the request result + isTransformResponse?: boolean; + // Whether to return native response headers + // For example: use this attribute when you need to get the response headers + isReturnNativeResponse?: boolean; + // Whether to join url + joinPrefix?: boolean; + // Interface address, use the default apiUrl if you leave it blank + apiUrl?: string; + // 请求拼接路径 + urlPrefix?: string; + // Error message prompt type + errorMessageMode?: ErrorMessageMode; + // Success message prompt type + successMessageMode?: SuccessMessageMode; + // Whether to add a timestamp + joinTime?: boolean; + ignoreCancelToken?: boolean; + // Whether to send token in header + withToken?: boolean; + // 请求重试机制 + retryRequest?: RetryRequest; +} + +export interface RetryRequest { + isOpenRetry: boolean; + count: number; + waitTime: number; +} +export interface Result { + code: string; + type: 'success' | 'error' | 'warning'; + msg: string; + result: T; +} + +// multipart/form-data: upload file +export interface UploadFileParams { + // Other parameters + data?: Recordable; + // File parameter interface field name + name?: string; + // file name + file: File | Blob; + // file name + filename?: string; + [key: string]: any; +} diff --git a/types/codemirror.d.ts b/types/codemirror.d.ts new file mode 100644 index 0000000..38df0c1 --- /dev/null +++ b/types/codemirror.d.ts @@ -0,0 +1 @@ +declare module '@codemirror/lang-json'; diff --git a/types/config.d.ts b/types/config.d.ts new file mode 100644 index 0000000..8041e50 --- /dev/null +++ b/types/config.d.ts @@ -0,0 +1,162 @@ +import { MenuTypeEnum, MenuModeEnum, TriggerEnum, MixSidebarTriggerEnum } from '/@/enums/menuEnum'; +import { + ContentEnum, + PermissionModeEnum, + ThemeEnum, + RouterTransitionEnum, + SettingButtonPositionEnum, + SessionTimeoutProcessingEnum, +} from '/@/enums/appEnum'; + +import { CacheTypeEnum } from '/@/enums/cacheEnum'; + +export type LocaleType = 'zh_CN' | 'en' | 'ru' | 'ja' | 'ko'; + +export interface MenuSetting { + bgColor: string; + fixed: boolean; + collapsed: boolean; + siderHidden: boolean; + canDrag: boolean; + show: boolean; + hidden: boolean; + split: boolean; + menuWidth: number; + mode: MenuModeEnum; + type: MenuTypeEnum; + theme: ThemeEnum; + topMenuAlign: 'start' | 'center' | 'end'; + trigger: TriggerEnum; + accordion: boolean; + closeMixSidebarOnChange: boolean; + collapsedShowTitle: boolean; + mixSideTrigger: MixSidebarTriggerEnum; + mixSideFixed: boolean; +} + +export interface MultiTabsSetting { + cache: boolean; + show: boolean; + showQuick: boolean; + canDrag: boolean; + showRedo: boolean; + showFold: boolean; +} + +export interface HeaderSetting { + bgColor: string; + fixed: boolean; + show: boolean; + theme: ThemeEnum; + // Turn on full screen + showFullScreen: boolean; + // Whether to show the lock screen + useLockPage: boolean; + // Show document button + showDoc: boolean; + // Show message center button + showNotice: boolean; + showSearch: boolean; +} + +export interface LocaleSetting { + showPicker: boolean; + // Current language + locale: LocaleType; + // default language + fallback: LocaleType; + // available Locales + availableLocales: LocaleType[]; +} + +export interface TransitionSetting { + // Whether to open the page switching animation + enable: boolean; + // Route basic switching animation + basicTransition: RouterTransitionEnum; + // Whether to open page switching loading + openPageLoading: boolean; + // Whether to open the top progress bar + openNProgress: boolean; +} + +export interface ProjectConfig { + // Storage location of permission related information + permissionCacheType: CacheTypeEnum; + // Whether to show the configuration button + showSettingButton: boolean; + // Whether to show the theme switch button + showDarkModeToggle: boolean; + // Configure where the button is displayed + settingButtonPosition: SettingButtonPositionEnum; + // Permission mode + permissionMode: PermissionModeEnum; + // Session timeout processing + sessionTimeoutProcessing: SessionTimeoutProcessingEnum; + // Website gray mode, open for possible mourning dates + grayMode: boolean; + // Whether to turn on the color weak mode + colorWeak: boolean; + // Theme color + themeColor: string; + + // The main interface is displayed in full screen, the menu is not displayed, and the top + fullContent: boolean; + // content width + contentMode: ContentEnum; + // Whether to display the logo + showLogo: boolean; + // Whether to show the global footer + showFooter: boolean; + // menuType: MenuTypeEnum; + headerSetting: HeaderSetting; + // menuSetting + menuSetting: MenuSetting; + // Multi-tab settings + multiTabsSetting: MultiTabsSetting; + // Animation configuration + transitionSetting: TransitionSetting; + // pageLayout whether to enable keep-alive + openKeepAlive: boolean; + // Lock screen time + lockTime: number; + // Show breadcrumbs + showBreadCrumb: boolean; + // Show breadcrumb icon + showBreadCrumbIcon: boolean; + // Use error-handler-plugin + useErrorHandle: boolean; + // Whether to open back to top + useOpenBackTop: boolean; + // Is it possible to embed iframe pages + canEmbedIFramePage: boolean; + // Whether to delete unclosed messages and notify when switching the interface + closeMessageOnSwitch: boolean; + // Whether to cancel the http request that has been sent but not responded when switching the interface. + removeAllHttpPending: boolean; +} + +export interface GlobConfig { + // Site title + title: string; + // Service interface url + apiUrl: string; + // Upload url + uploadUrl?: string; + // Service interface url prefix + urlPrefix?: string; + // Project abbreviation + shortName: string; +} +export interface GlobEnvConfig { + // Site title + VITE_GLOB_APP_TITLE: string; + // Service interface url + VITE_GLOB_API_URL: string; + // Service interface url prefix + VITE_GLOB_API_URL_PREFIX?: string; + // Project abbreviation + VITE_GLOB_APP_SHORT_NAME: string; + // Upload url + VITE_GLOB_UPLOAD_URL?: string; +} diff --git a/types/global.d.ts b/types/global.d.ts new file mode 100644 index 0000000..07c689c --- /dev/null +++ b/types/global.d.ts @@ -0,0 +1,91 @@ +import type { + ComponentRenderProxy, + VNode, + VNodeChild, + ComponentPublicInstance, + FunctionalComponent, + PropType as VuePropType, +} from 'vue'; + +declare global { + const __APP_INFO__: { + pkg: { + name: string; + version: string; + dependencies: Recordable; + devDependencies: Recordable; + }; + lastBuildTime: string; + }; + // declare interface Window { + // // Global vue app instance + // __APP__: App; + // } + + // vue + declare type PropType = VuePropType; + declare type VueNode = VNodeChild | JSX.Element; + + export type Writable = { + -readonly [P in keyof T]: T[P]; + }; + + declare type Nullable = T | null; + declare type NonNullable = T extends null | undefined ? never : T; + declare type Recordable = Record; + declare type ReadonlyRecordable = { + readonly [key: string]: T; + }; + declare type Indexable = { + [key: string]: T; + }; + declare type DeepPartial = { + [P in keyof T]?: DeepPartial; + }; + declare type TimeoutHandle = ReturnType; + declare type IntervalHandle = ReturnType; + + declare interface ChangeEvent extends Event { + target: HTMLInputElement; + } + + declare interface WheelEvent { + path?: EventTarget[]; + } + interface ImportMetaEnv extends ViteEnv { + __: unknown; + } + + declare interface ViteEnv { + VITE_USE_MOCK: boolean; + VITE_PUBLIC_PATH: string; + VITE_GLOB_APP_TITLE: string; + VITE_BUILD_COMPRESS: 'gzip' | 'brotli' | 'none'; + } + + declare function parseInt(s: string | number, radix?: number): number; + + declare function parseFloat(string: string | number): number; + + namespace JSX { + // tslint:disable no-empty-interface + type Element = VNode; + // tslint:disable no-empty-interface + type ElementClass = ComponentRenderProxy; + interface ElementAttributesProperty { + $props: any; + } + interface IntrinsicElements { + [elem: string]: any; + } + interface IntrinsicAttributes { + [elem: string]: any; + } + } +} + +declare module 'vue' { + export type JSXComponent = + | { new (): ComponentPublicInstance } + | FunctionalComponent; +} diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 0000000..23baddf --- /dev/null +++ b/types/index.d.ts @@ -0,0 +1,27 @@ +declare interface Fn { + (...arg: T[]): R; +} + +declare interface PromiseFn { + (...arg: T[]): Promise; +} + +declare type RefType = T | null; + +declare type LabelValueOptions = { + label: string; + value: any; + [key: string]: string | number | boolean; +}[]; + +declare type EmitType = (event: string | any, ...args: any[]) => void; + +declare type TargetContext = '_self' | '_blank'; + +declare interface ComponentElRef { + $el: T; +} + +declare type ComponentRef = ComponentElRef | null; + +declare type ElRef = Nullable; diff --git a/types/module.d.ts b/types/module.d.ts new file mode 100644 index 0000000..61a0c34 --- /dev/null +++ b/types/module.d.ts @@ -0,0 +1,18 @@ +declare module '*.vue' { + import { DefineComponent } from 'vue'; + + const Component: DefineComponent<{}, {}, any>; + export default Component; +} + +declare module 'ant-design-vue/es/locale/*' { + import { Locale } from 'ant-design-vue/types/locale-provider'; + + const locale: Locale & ReadonlyRecordable; + export default locale as Locale & ReadonlyRecordable; +} + +declare module 'virtual:*' { + const result: any; + export default result; +} diff --git a/types/store.d.ts b/types/store.d.ts new file mode 100644 index 0000000..8228d90 --- /dev/null +++ b/types/store.d.ts @@ -0,0 +1,48 @@ +import { ErrorTypeEnum } from '/@/enums/exceptionEnum'; +import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum'; +import { RoleInfo } from '/@/api/sys/model/userModel'; + +// Lock screen information +export interface LockInfo { + // Password required + pwd?: string | undefined; + // Is it locked? + isLock?: boolean; +} + +// Error-log information +export interface ErrorLogInfo { + // Type of error + type: ErrorTypeEnum; + // Error file + file: string; + // Error name + name?: string; + // Error message + message: string; + // Error stack + stack?: string; + // Error detail + detail: string; + // Error url + url: string; + // Error time + time?: string; +} + +export interface UserInfo { + userId: string | number; + username: string; + name: string; + avatar: string; + desc?: string; + homePath?: string; + roles: RoleInfo[]; +} + +export interface BeforeMiniState { + menuCollapsed?: boolean; + menuSplit?: boolean; + menuMode?: MenuModeEnum; + menuType?: MenuTypeEnum; +} diff --git a/types/tree.d.ts b/types/tree.d.ts new file mode 100644 index 0000000..799e69a --- /dev/null +++ b/types/tree.d.ts @@ -0,0 +1 @@ +declare module '@axolo/tree-array'; diff --git a/types/utils.d.ts b/types/utils.d.ts new file mode 100644 index 0000000..6500d44 --- /dev/null +++ b/types/utils.d.ts @@ -0,0 +1,5 @@ +import type { ComputedRef, Ref } from 'vue'; + +export type DynamicProps = { + [P in keyof T]: Ref | T[P] | ComputedRef; +}; diff --git a/types/vue-router.d.ts b/types/vue-router.d.ts new file mode 100644 index 0000000..0890b55 --- /dev/null +++ b/types/vue-router.d.ts @@ -0,0 +1,47 @@ +import { RoleEnum } from '/@/enums/roleEnum'; + +export {}; + +declare module 'vue-router' { + interface RouteMeta extends Record { + sort?: number; + // title + title: string; + // dynamic router level. + dynamicLevel?: number; + // dynamic router real route path (For performance). + realPath?: string; + // Whether to ignore permissions + ignoreAuth?: boolean; + // role info + roles?: RoleEnum[]; + // Whether not to cache + ignoreKeepAlive?: boolean; + // Is it fixed on tab + affix?: boolean; + // icon on tab + icon?: string; + frameSrc?: string; + // current page transition + transitionName?: string; + // Whether the route has been dynamically added + hideBreadcrumb?: boolean; + // Hide submenu + hideChildrenInMenu?: boolean; + // Carrying parameters + carryParam?: boolean; + // Used internally to mark single-level menus + single?: boolean; + // Currently active menu + currentActiveMenu?: string; + // Never show in tab + hideTab?: boolean; + // Never show in menu + hideMenu?: boolean; + isLink?: boolean; + // only build for Menu + ignoreRoute?: boolean; + // Hide path for children + hidePathForChildren?: boolean; + } +} diff --git a/types/vueuseCore.d.ts b/types/vueuseCore.d.ts new file mode 100644 index 0000000..f0e8592 --- /dev/null +++ b/types/vueuseCore.d.ts @@ -0,0 +1 @@ +declare module '@vueuse/core'; diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..df310f8 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,32 @@ +import { defineApplicationConfig } from '@vben/vite-config'; + +export default defineApplicationConfig({ + overrides: { + optimizeDeps: { + include: [ + 'echarts/core', + 'echarts/charts', + 'echarts/components', + 'echarts/renderers', + 'qrcode', + '@iconify/iconify', + 'ant-design-vue/es/locale/zh_CN', + 'ant-design-vue/es/locale/en_US', + ], + }, + server: { + port: 7000, + proxy: { + '/erp-api': { + // target: 'http://localhost:8088', + target: 'https://erp.wansen.cloud', + // https://erp.wansen.cloud + changeOrigin: true, + ws: true, + // rewrite: (path) => path.replace(/^\/api/, ''), + // only https + } + }, + }, + }, +}); diff --git a/wansenai-logo.png b/wansenai-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..1d9126382e1bb4b4ea8db27066e9137250435a6f GIT binary patch literal 7551 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