diff --git a/.env b/.env
index 1077d067..8b541732 100644
--- a/.env
+++ b/.env
@@ -1,15 +1,5 @@
-VITE_DM_API_URL=http://localhost:3000
+VITE_DM_SOCKET_URL=http://localhost:3000
+VITE_EDGECREATOR_SOCKET_URL=http://localhost:3001
VITE_DM_URL=http://localhost:8001
-VITE_EDGECREATOR_API_URL=http://localhost:3001
VITE_EDGES_URL=http://localhost:8001/edges
VITE_FONT_SEARCH_URL=https://www.myfonts.com/WhatTheFont/
-
-CLOUDINARY_URL=cloudinary://955445841324817:fqXP5YDdv8n1vwNjzgDRlFHDVto@dl7hskxab
-FONT_BASE_URL=https://www.myfonts.com/fonts/
-FONT_IMAGE_GEN_URL=https://render.myfonts.net/fonts/font_rend.php
-FONT_PRODUCT_BASE_URL=https://www.myfonts.com/products/
-
-# Used only in the backend, so with the api directory as basis
-EDGES_PATH=../DucksManager/edges
-
-TOKEN_SECRET=3543c30fe79047b4f73cfb61aa1eb52cb3173de4b3941e0fc4ec1b127bbeed6019695a1a453a81c33c2eea964ccc577e69c7df994124bd2751e262a311ea23a1
diff --git a/.eslintcache b/.eslintcache
deleted file mode 100644
index 32d185e6..00000000
--- a/.eslintcache
+++ /dev/null
@@ -1 +0,0 @@
-[{"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/_utils.ts":"1","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/axios-helper.ts":"2","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/generate-route-types.ts":"3","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/index.ts":"4","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/_auth.ts":"5","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/_express-call.ts":"6","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/_upload_utils.ts":"7","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/fs/base64.ts":"8","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/fs/browse/:imageType/:country/:magazine.ts":"9","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/fs/browseEdges.ts":"10","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/fs/generateDefaultEdge.ts":"11","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/fs/save.ts":"12","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/fs/text.ts":"13","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/fs/upload-base64.ts":"14","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/fs/upload.ts":"15","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/axios-helper.ts":"16","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/App.vue":"17","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/ConfirmEditMultipleValues.vue":"18","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/Dimensions.vue":"19","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/EdgeCanvas.vue":"20","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/EdgeGallery.vue":"21","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/EdgeLink.vue":"22","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/FormColorInputRow.vue":"23","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/FormInputRow.vue":"24","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/Gallery.vue":"25","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/IssueSelect.vue":"26","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/ModelEdit.vue":"27","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/MultipleTargetOptions.vue":"28","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/Popover.vue":"29","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/PositionHelper.vue":"30","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/PublishedEdge.vue":"31","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/SaveModelButton.vue":"32","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/SessionInfo.vue":"33","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/TopBar.vue":"34","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/Upload.vue":"35","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/from-dm/Issue.vue":"36","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/from-dm/Medal.vue":"37","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/from-dm/MedalProgress.vue":"38","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/from-dm/Publication.vue":"39","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/from-dm/UploadableEdgesCarousel.vue":"40","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/ArcCircleRender.vue":"41","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/FillRender.vue":"42","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/GradientRender.vue":"43","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/ImageRender.vue":"44","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/PolygonRender.vue":"45","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/RectangleRender.vue":"46","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/StapleRender.vue":"47","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/TextRender.vue":"48","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useBase64Legacy.ts":"49","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useCondition.ts":"50","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useLegacyDb.ts":"51","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useLocales.ts":"52","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useMedal.ts":"53","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useModelLoad.ts":"54","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useRedirect.ts":"55","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useSaveEdge.ts":"56","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useStepOptions.ts":"57","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useSurroundingEdge.ts":"58","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useSvgUtils.ts":"59","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useTextTemplate.ts":"60","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/i18n.ts":"61","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/layouts/default.vue":"62","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/main.ts":"63","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/pages/[...all].vue":"64","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/pages/edit/[...all].vue":"65","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/pages/edit/new.vue":"66","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/pages/upload.vue":"67","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/api.ts":"68","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/coa.ts":"69","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/collection.ts":"70","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/edgeCatalog.ts":"71","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/editingStep.ts":"72","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/hoveredStep.ts":"73","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/images.ts":"74","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/main.ts":"75","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/renders.ts":"76","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/step.ts":"77","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/ui.ts":"78","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/users.ts":"79","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/EdgeDimensions.ts":"80","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/GalleryItem.ts":"81","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/LegacyComponent.ts":"82","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/OptionNameAndValue.ts":"83","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/OptionValue.ts":"84","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/Step.ts":"85","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/StepOptionBaseProps.ts":"86","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/StepOptions.ts":"87","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/StepsPerIssuenumber.ts":"88","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/Call.ts":"89","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/Crop.ts":"90","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/ExportPaths.ts":"91","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/ModelContributor.ts":"92","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/SessionUser.ts":"93","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/SimpleUser.ts":"94","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/routes.ts":"95"},{"size":243,"mtime":1715520653186},{"size":3171,"mtime":1715520653187},{"size":3162,"mtime":1715520653187},{"size":1377,"mtime":1715520653187},{"size":2299,"mtime":1715520653187},{"size":334,"mtime":1715520653187},{"size":243,"mtime":1715520653187,"results":"96","hashOfConfig":"97"},{"size":1026,"mtime":1715520653188,"results":"98","hashOfConfig":"97"},{"size":776,"mtime":1715520653188},{"size":1383,"mtime":1715520653188},{"size":1815,"mtime":1715520653188},{"size":3097,"mtime":1715520653188},{"size":3195,"mtime":1715520653188},{"size":1458,"mtime":1715520653188},{"size":6515,"mtime":1715520653188},{"size":3171,"mtime":1715520653189},{"size":1010,"mtime":1715520653213},{"size":828,"mtime":1715520653213,"results":"99","hashOfConfig":"97"},{"size":1472,"mtime":1715520653214},{"size":6433,"mtime":1715520653214},{"size":4963,"mtime":1715520653214},{"size":899,"mtime":1715520653214,"results":"100","hashOfConfig":"97"},{"size":6207,"mtime":1715520653214},{"size":3166,"mtime":1715520653214},{"size":3845,"mtime":1715520653214},{"size":7716,"mtime":1715520653214},{"size":13855,"mtime":1715520653214},{"size":361,"mtime":1715520653214,"results":"101","hashOfConfig":"97"},{"size":1384,"mtime":1715520653215,"results":"102","hashOfConfig":"97"},{"size":348,"mtime":1715520653215,"results":"103","hashOfConfig":"97"},{"size":674,"mtime":1715520653215,"results":"104","hashOfConfig":"97"},{"size":8600,"mtime":1715527625768,"results":"105","hashOfConfig":"97"},{"size":1076,"mtime":1715520653215,"results":"106","hashOfConfig":"97"},{"size":10820,"mtime":1715520653215},{"size":2815,"mtime":1715520653215},{"size":1308,"mtime":1715520653215,"results":"107","hashOfConfig":"97"},{"size":4870,"mtime":1715520653215},{"size":2197,"mtime":1715520653215,"results":"108","hashOfConfig":"97"},{"size":747,"mtime":1715520653215,"results":"109","hashOfConfig":"97"},{"size":1735,"mtime":1715520653216,"results":"110","hashOfConfig":"97"},{"size":1252,"mtime":1715520653216,"results":"111","hashOfConfig":"97"},{"size":502,"mtime":1715520653216,"results":"112","hashOfConfig":"97"},{"size":1431,"mtime":1715520653216,"results":"113","hashOfConfig":"97"},{"size":1725,"mtime":1715520653216},{"size":2111,"mtime":1715520653216},{"size":752,"mtime":1715520653216,"results":"114","hashOfConfig":"97"},{"size":2383,"mtime":1715520653216},{"size":7224,"mtime":1715520653216},{"size":1096,"mtime":1715520653216},{"size":1885,"mtime":1715520653217},{"size":8117,"mtime":1715520653217},{"size":431,"mtime":1715520653217,"results":"115","hashOfConfig":"97"},{"size":2446,"mtime":1715520653217},{"size":9057,"mtime":1715520653217},{"size":687,"mtime":1715520653217},{"size":1484,"mtime":1715520653217},{"size":4748,"mtime":1715520653217},{"size":734,"mtime":1715520653217,"results":"116","hashOfConfig":"97"},{"size":1522,"mtime":1715520653217},{"size":602,"mtime":1715520653217},{"size":647,"mtime":1715520653217},{"size":41,"mtime":1715520653218,"results":"117","hashOfConfig":"97"},{"size":1104,"mtime":1715524761349,"results":"118","hashOfConfig":"97"},{"size":8982,"mtime":1715520653218},{"size":10805,"mtime":1715520653218},{"size":1480,"mtime":1715520653218},{"size":8773,"mtime":1715520653218},{"size":307,"mtime":1715520653218},{"size":4606,"mtime":1715520653218},{"size":4267,"mtime":1715520653218},{"size":11307,"mtime":1715520653218},{"size":1477,"mtime":1715520653218},{"size":191,"mtime":1715520653219,"results":"119","hashOfConfig":"97"},{"size":219,"mtime":1715520653219,"results":"120","hashOfConfig":"97"},{"size":7764,"mtime":1715527536204},{"size":1385,"mtime":1715520653219,"results":"121","hashOfConfig":"97"},{"size":10442,"mtime":1715520653219},{"size":463,"mtime":1715520653219,"results":"122","hashOfConfig":"97"},{"size":581,"mtime":1715520653219,"results":"123","hashOfConfig":"97"},{"size":71,"mtime":1715520653219,"results":"124","hashOfConfig":"97"},{"size":123,"mtime":1715520653219,"results":"125","hashOfConfig":"97"},{"size":1706,"mtime":1715520653219,"results":"126","hashOfConfig":"97"},{"size":136,"mtime":1715520653219,"results":"127","hashOfConfig":"97"},{"size":72,"mtime":1715520653220,"results":"128","hashOfConfig":"97"},{"size":101,"mtime":1715520653220,"results":"129","hashOfConfig":"97"},{"size":188,"mtime":1715520653220,"results":"130","hashOfConfig":"97"},{"size":119,"mtime":1715520653220,"results":"131","hashOfConfig":"97"},{"size":96,"mtime":1715520653220,"results":"132","hashOfConfig":"97"},{"size":952,"mtime":1715520653220},{"size":192,"mtime":1715520653220,"results":"133","hashOfConfig":"97"},{"size":73,"mtime":1715520653220,"results":"134","hashOfConfig":"97"},{"size":239,"mtime":1715520653220},{"size":287,"mtime":1715520653220,"results":"135","hashOfConfig":"97"},{"size":107,"mtime":1715520653220,"results":"136","hashOfConfig":"97"},{"size":2701,"mtime":1715520653221,"results":"137","hashOfConfig":"97"},{"filePath":"138","messages":"139","suppressedMessages":"140","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"qjf7lk",{"filePath":"141","messages":"142","suppressedMessages":"143","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"144","messages":"145","suppressedMessages":"146","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"147","messages":"148","suppressedMessages":"149","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"150","messages":"151","suppressedMessages":"152","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"153","messages":"154","suppressedMessages":"155","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"156","messages":"157","suppressedMessages":"158","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"159","messages":"160","suppressedMessages":"161","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"162","messages":"163","suppressedMessages":"164","errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"165","messages":"166","suppressedMessages":"167","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"168","messages":"169","suppressedMessages":"170","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"171","messages":"172","suppressedMessages":"173","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"174","messages":"175","suppressedMessages":"176","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"177","messages":"178","suppressedMessages":"179","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"180","messages":"181","suppressedMessages":"182","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"183","messages":"184","suppressedMessages":"185","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"186","messages":"187","suppressedMessages":"188","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"189","messages":"190","suppressedMessages":"191","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"192","messages":"193","suppressedMessages":"194","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"195","messages":"196","suppressedMessages":"197","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"198","messages":"199","suppressedMessages":"200","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"201","messages":"202","suppressedMessages":"203","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"204","messages":"205","suppressedMessages":"206","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"207","messages":"208","suppressedMessages":"209","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"210","messages":"211","suppressedMessages":"212","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"213","messages":"214","suppressedMessages":"215","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"216","messages":"217","suppressedMessages":"218","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"219","messages":"220","suppressedMessages":"221","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"222","messages":"223","suppressedMessages":"224","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"225","messages":"226","suppressedMessages":"227","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"228","messages":"229","suppressedMessages":"230","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"231","messages":"232","suppressedMessages":"233","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"234","messages":"235","suppressedMessages":"236","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"237","messages":"238","suppressedMessages":"239","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"240","messages":"241","suppressedMessages":"242","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"243","messages":"244","suppressedMessages":"245","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"246","messages":"247","suppressedMessages":"248","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"249","messages":"250","suppressedMessages":"251","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"252","messages":"253","suppressedMessages":"254","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"255","messages":"256","suppressedMessages":"257","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"258","messages":"259","suppressedMessages":"260","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/_upload_utils.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/fs/base64.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/ConfirmEditMultipleValues.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/EdgeLink.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/MultipleTargetOptions.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/Popover.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/PositionHelper.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/PublishedEdge.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/SaveModelButton.vue",["261"],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/SessionInfo.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/from-dm/Issue.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/from-dm/MedalProgress.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/from-dm/Publication.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/from-dm/UploadableEdgesCarousel.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/ArcCircleRender.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/FillRender.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/GradientRender.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/RectangleRender.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useLocales.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useSurroundingEdge.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/layouts/default.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/main.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/hoveredStep.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/images.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/renders.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/ui.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/users.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/EdgeDimensions.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/GalleryItem.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/LegacyComponent.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/OptionNameAndValue.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/OptionValue.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/Step.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/StepOptionBaseProps.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/StepOptions.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/StepsPerIssuenumber.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/Crop.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/ExportPaths.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/SessionUser.ts",[],["262"],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/SimpleUser.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/routes.ts",[],[],{"ruleId":"263","severity":2,"message":"264","line":152,"column":7,"nodeType":"265","messageId":"266","endLine":152,"endColumn":19},{"ruleId":"267","severity":2,"message":"268","line":10,"column":3,"nodeType":"269","messageId":"270","endLine":14,"endColumn":4,"suppressions":"271"},"@typescript-eslint/no-unused-vars","'progressLeft' is assigned a value but never used.","Identifier","unusedVar","@typescript-eslint/no-namespace","ES2015 module syntax is preferred over namespaces.","TSModuleDeclaration","moduleSyntaxIsPreferred",["272"],{"kind":"273","justification":"274"},"directive",""]
\ No newline at end of file
diff --git a/.eslintrc-auto-import.json b/.eslintrc-auto-import.json
new file mode 100644
index 00000000..055835b3
--- /dev/null
+++ b/.eslintrc-auto-import.json
@@ -0,0 +1,323 @@
+{
+ "globals": {
+ "Component": true,
+ "ComponentPublicInstance": true,
+ "ComputedRef": true,
+ "EffectScope": true,
+ "ExtractDefaultPropTypes": true,
+ "ExtractPropTypes": true,
+ "ExtractPublicPropTypes": true,
+ "InjectionKey": true,
+ "IssueSuggestionList": true,
+ "PropType": true,
+ "Ref": true,
+ "VNode": true,
+ "WritableComputedRef": true,
+ "acceptHMRUpdate": true,
+ "asyncComputed": true,
+ "autoResetRef": true,
+ "availableLocales": true,
+ "computed": true,
+ "computedAsync": true,
+ "computedEager": true,
+ "computedInject": true,
+ "computedWithControl": true,
+ "controlledComputed": true,
+ "controlledRef": true,
+ "createApp": true,
+ "createEventHook": true,
+ "createGlobalState": true,
+ "createInjectionState": true,
+ "createPinia": true,
+ "createReactiveFn": true,
+ "createReusableTemplate": true,
+ "createSharedComposable": true,
+ "createTemplatePromise": true,
+ "createUnrefFn": true,
+ "customRef": true,
+ "debouncedRef": true,
+ "debouncedWatch": true,
+ "defineAsyncComponent": true,
+ "defineComponent": true,
+ "defineStore": true,
+ "eagerComputed": true,
+ "edgecreatorSocketInjectionKey": true,
+ "effectScope": true,
+ "exclude": true,
+ "extendRef": true,
+ "getActivePinia": true,
+ "getCurrentInstance": true,
+ "getCurrentLocaleShortKey": true,
+ "getCurrentScope": true,
+ "h": true,
+ "ignorableWatch": true,
+ "inject": true,
+ "injectLocal": true,
+ "isDefined": true,
+ "isProxy": true,
+ "isReactive": true,
+ "isReadonly": true,
+ "isRef": true,
+ "makeDestructurable": true,
+ "mapActions": true,
+ "mapGetters": true,
+ "mapState": true,
+ "mapStores": true,
+ "mapWritableState": true,
+ "markRaw": true,
+ "nextTick": true,
+ "onActivated": true,
+ "onBeforeMount": true,
+ "onBeforeRouteLeave": true,
+ "onBeforeRouteUpdate": true,
+ "onBeforeUnmount": true,
+ "onBeforeUpdate": true,
+ "onClickOutside": true,
+ "onDeactivated": true,
+ "onErrorCaptured": true,
+ "onKeyStroke": true,
+ "onLongPress": true,
+ "onMounted": true,
+ "onRenderTracked": true,
+ "onRenderTriggered": true,
+ "onScopeDispose": true,
+ "onServerPrefetch": true,
+ "onStartTyping": true,
+ "onUnmounted": true,
+ "onUpdated": true,
+ "pausableWatch": true,
+ "provide": true,
+ "provideLocal": true,
+ "reactify": true,
+ "reactifyObject": true,
+ "reactive": true,
+ "reactiveComputed": true,
+ "reactiveOmit": true,
+ "reactivePick": true,
+ "readonly": true,
+ "ref": true,
+ "refAutoReset": true,
+ "refDebounced": true,
+ "refDefault": true,
+ "refThrottled": true,
+ "refWithControl": true,
+ "resolveComponent": true,
+ "resolveRef": true,
+ "resolveUnref": true,
+ "setActivePinia": true,
+ "setMapStoreSuffix": true,
+ "shallowReactive": true,
+ "shallowReadonly": true,
+ "shallowRef": true,
+ "storeToRefs": true,
+ "syncRef": true,
+ "syncRefs": true,
+ "templateRef": true,
+ "throttledRef": true,
+ "throttledWatch": true,
+ "toRaw": true,
+ "toReactive": true,
+ "toRef": true,
+ "toRefs": true,
+ "toValue": true,
+ "triggerRef": true,
+ "tryOnBeforeMount": true,
+ "tryOnBeforeUnmount": true,
+ "tryOnMounted": true,
+ "tryOnScopeDispose": true,
+ "tryOnUnmounted": true,
+ "unref": true,
+ "unrefElement": true,
+ "until": true,
+ "useActiveElement": true,
+ "useAnimate": true,
+ "useArrayDifference": true,
+ "useArrayEvery": true,
+ "useArrayFilter": true,
+ "useArrayFind": true,
+ "useArrayFindIndex": true,
+ "useArrayFindLast": true,
+ "useArrayIncludes": true,
+ "useArrayJoin": true,
+ "useArrayMap": true,
+ "useArrayReduce": true,
+ "useArraySome": true,
+ "useArrayUnique": true,
+ "useAsyncQueue": true,
+ "useAsyncState": true,
+ "useAttrs": true,
+ "useBase64": true,
+ "useBase64Legacy": true,
+ "useBattery": true,
+ "useBluetooth": true,
+ "useBreakpoints": true,
+ "useBroadcastChannel": true,
+ "useBrowserLocation": true,
+ "useCached": true,
+ "useClipboard": true,
+ "useClipboardItems": true,
+ "useCloned": true,
+ "useColorMode": true,
+ "useCondition": true,
+ "useConfirmDialog": true,
+ "useCounter": true,
+ "useCssModule": true,
+ "useCssVar": true,
+ "useCssVars": true,
+ "useCurrentElement": true,
+ "useCycleList": true,
+ "useDark": true,
+ "useDateFormat": true,
+ "useDebounce": true,
+ "useDebounceFn": true,
+ "useDebouncedRefHistory": true,
+ "useDeviceMotion": true,
+ "useDeviceOrientation": true,
+ "useDevicePixelRatio": true,
+ "useDevicesList": true,
+ "useDisplayMedia": true,
+ "useDocumentVisibility": true,
+ "useDraggable": true,
+ "useDropZone": true,
+ "useEdgecreatorSocket": true,
+ "useElementBounding": true,
+ "useElementByPoint": true,
+ "useElementHover": true,
+ "useElementSize": true,
+ "useElementVisibility": true,
+ "useEventBus": true,
+ "useEventListener": true,
+ "useEventSource": true,
+ "useEyeDropper": true,
+ "useFavicon": true,
+ "useFetch": true,
+ "useFileDialog": true,
+ "useFileSystemAccess": true,
+ "useFocus": true,
+ "useFocusWithin": true,
+ "useFps": true,
+ "useFullscreen": true,
+ "useGamepad": true,
+ "useGeolocation": true,
+ "useIdle": true,
+ "useImage": true,
+ "useInfiniteScroll": true,
+ "useIntersectionObserver": true,
+ "useInterval": true,
+ "useIntervalFn": true,
+ "useKeyModifier": true,
+ "useLastChanged": true,
+ "useLegacyDb": true,
+ "useLink": true,
+ "useLocalStorage": true,
+ "useMagicKeys": true,
+ "useManualRefHistory": true,
+ "useMedal": true,
+ "useMediaControls": true,
+ "useMediaQuery": true,
+ "useMemoize": true,
+ "useMemory": true,
+ "useModelLoad": true,
+ "useMounted": true,
+ "useMouse": true,
+ "useMouseInElement": true,
+ "useMousePressed": true,
+ "useMutationObserver": true,
+ "useNavigatorLanguage": true,
+ "useNetwork": true,
+ "useNow": true,
+ "useObjectUrl": true,
+ "useOffsetPagination": true,
+ "useOnline": true,
+ "usePageLeave": true,
+ "useParallax": true,
+ "useParentElement": true,
+ "usePerformanceObserver": true,
+ "usePermission": true,
+ "usePointer": true,
+ "usePointerLock": true,
+ "usePointerSwipe": true,
+ "usePreferredColorScheme": true,
+ "usePreferredContrast": true,
+ "usePreferredDark": true,
+ "usePreferredLanguages": true,
+ "usePreferredReducedMotion": true,
+ "usePrevious": true,
+ "useRafFn": true,
+ "useRedirect": true,
+ "useRefHistory": true,
+ "useResizeObserver": true,
+ "useRoute": true,
+ "useRouter": true,
+ "useSaveEdge": true,
+ "useScreenOrientation": true,
+ "useScreenSafeArea": true,
+ "useScriptTag": true,
+ "useScroll": true,
+ "useScrollLock": true,
+ "useSessionStorage": true,
+ "useShare": true,
+ "useSlots": true,
+ "useSorted": true,
+ "useSpeechRecognition": true,
+ "useSpeechSynthesis": true,
+ "useStepOptions": true,
+ "useStepper": true,
+ "useStorage": true,
+ "useStorageAsync": true,
+ "useStyleTag": true,
+ "useSupported": true,
+ "useSurroundingEdge": true,
+ "useSvgUtils": true,
+ "useSwipe": true,
+ "useTemplateRefsList": true,
+ "useTextDirection": true,
+ "useTextSelection": true,
+ "useTextTemplate": true,
+ "useTextareaAutosize": true,
+ "useThrottle": true,
+ "useThrottleFn": true,
+ "useThrottledRefHistory": true,
+ "useTimeAgo": true,
+ "useTimeout": true,
+ "useTimeoutFn": true,
+ "useTimeoutPoll": true,
+ "useTimestamp": true,
+ "useTitle": true,
+ "useToNumber": true,
+ "useToString": true,
+ "useToggle": true,
+ "useTransition": true,
+ "useUrlSearchParams": true,
+ "useUserMedia": true,
+ "useVModel": true,
+ "useVModels": true,
+ "useVibrate": true,
+ "useVirtualList": true,
+ "useWakeLock": true,
+ "useWebNotification": true,
+ "useWebSocket": true,
+ "useWebWorker": true,
+ "useWebWorkerFn": true,
+ "useWindowFocus": true,
+ "useWindowScroll": true,
+ "useWindowSize": true,
+ "watch": true,
+ "watchArray": true,
+ "watchAtMost": true,
+ "watchDebounced": true,
+ "watchDeep": true,
+ "watchEffect": true,
+ "watchIgnorable": true,
+ "watchImmediate": true,
+ "watchOnce": true,
+ "watchPausable": true,
+ "watchPostEffect": true,
+ "watchSyncEffect": true,
+ "watchThrottled": true,
+ "watchTriggerable": true,
+ "watchWithFilter": true,
+ "whenever": true,
+ "useI18n": true
+ }
+}
diff --git a/.eslintrc.js b/.eslintrc.json
similarity index 71%
rename from .eslintrc.js
rename to .eslintrc.json
index 6204c7f3..627ccf4c 100644
--- a/.eslintrc.js
+++ b/.eslintrc.json
@@ -1,5 +1,5 @@
-module.exports = {
- extends: [
+{
+ "extends": [
// add more generic rulesets here, such as:
// 'eslint:recommended',
"plugin:vue/vue3-recommended",
@@ -7,19 +7,19 @@ module.exports = {
"prettier",
"plugin:@typescript-eslint/recommended"
],
- parser: "vue-eslint-parser",
- parserOptions: {
- parser: "@typescript-eslint/parser",
- project: true,
- extraFileExtensions: [".vue"]
+ "parser": "vue-eslint-parser",
+ "parserOptions": {
+ "parser": "@typescript-eslint/parser",
+ "project": true,
+ "extraFileExtensions": [".vue"]
},
- overrides: [
+ "overrides": [
{
- files: ["*.ts", "*.vue"]
+ "files": ["*.ts", "*.vue"]
}
],
- root: true,
- rules: {
+ "root": true,
+ "rules": {
"@typescript-eslint/no-floating-promises": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"simple-import-sort/exports": "error",
@@ -31,26 +31,27 @@ module.exports = {
"vue/no-v-text-v-html-on-component": "off",
"vue/define-emits-declaration": "error",
"vue/define-props-declaration": "error",
+ "@typescript-eslint/consistent-type-imports": "error",
"vue/component-name-in-template-casing": [
"error",
"kebab-case",
{
- registeredComponentsOnly: true,
- ignores: []
+ "registeredComponentsOnly": true,
+ "ignores": []
}
]
},
- plugins: [
+ "plugins": [
"simple-import-sort",
"prettier",
"@typescript-eslint",
"unused-imports"
],
- ignorePatterns: [
+ "ignorePatterns": [
"**/node_modules",
"**/dist",
"*.d.ts",
"vendor",
"vite.config.ts"
]
-};
+}
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 66823a65..f7662aff 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -4,14 +4,20 @@ on:
workflow_dispatch:
push:
branches:
- - 'nuxt-to-vue3-and-express'
+ - "websocket"
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- name: Check out repository
- uses: actions/checkout@master
+ uses: actions/checkout@v3
+ with:
+ repository: ducksmanager/core
+ submodules: recursive
+
+ - name: Debug
+ run: pwd && ls -la
- name: Download .env file
uses: nicklasfrahm/scp-action@main
@@ -25,10 +31,10 @@ jobs:
target: .env.prod
- name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v2
+ uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
- uses: docker/login-action@v2.1.0
+ uses: docker/login-action@v3
with:
registry: ghcr.io
username: bperel
@@ -37,22 +43,24 @@ jobs:
- name: Build and push app
uses: docker/build-push-action@v3
with:
- context: .
+ context: ./apps/edgecreator
platforms: linux/x86_64
+ file: ./apps/edgecreator/Dockerfile
push: true
- target: app
cache-from: type=registry,ref=ghcr.io/bperel/edgecreator-app:buildcache
cache-to: type=registry,ref=ghcr.io/bperel/edgecreator-app:buildcache,mode=max
tags: |
ghcr.io/bperel/edgecreator-app:latest
+ - uses: oven-sh/setup-bun@v1
+ - run: cd apps/edgecreator/api && bun build ./index.ts --outdir dist --minify --target node
+
- name: Build and push api
uses: docker/build-push-action@v3
with:
- context: .
+ context: ./apps/edgecreator/api
platforms: linux/x86_64
push: true
- target: api
cache-from: type=registry,ref=ghcr.io/bperel/edgecreator-api:buildcache
cache-to: type=registry,ref=ghcr.io/bperel/edgecreator-api:buildcache,mode=max
tags: |
@@ -66,7 +74,7 @@ jobs:
fingerprint: ${{ secrets.PRODUCTION_SSH_FINGERPRINT }}
username: ${{ secrets.PRODUCTION_SSH_USER }}
key: ${{ secrets.PRODUCTION_SSH_KEY }}
- source: docker-compose.yml
+ source: apps/edgecreator/docker-compose.yml
target: /home/bperel/workspace/EdgeCreator2/docker-compose.yml
- name: Upload Sentry config
@@ -77,7 +85,7 @@ jobs:
fingerprint: ${{ secrets.PRODUCTION_SSH_FINGERPRINT }}
username: ${{ secrets.PRODUCTION_SSH_USER }}
key: ${{ secrets.PRODUCTION_SSH_KEY }}
- source: config/sentry-relay/config.yml
+ source: apps/edgecreator/config/sentry-relay/config.yml
target: /home/bperel/workspace/EdgeCreator2/config/sentry-relay/config.yml
- name: Upload Sentry project config
@@ -88,11 +96,11 @@ jobs:
fingerprint: ${{ secrets.PRODUCTION_SSH_FINGERPRINT }}
username: ${{ secrets.PRODUCTION_SSH_USER }}
key: ${{ secrets.PRODUCTION_SSH_KEY }}
- source: config/sentry-relay/projects/5595460.json
+ source: apps/edgecreator/config/sentry-relay/projects/5595460.json
target: /home/bperel/workspace/EdgeCreator2/config/sentry-relay/projects/5595460.json
- name: Recreate container
- uses: appleboy/ssh-action@v0.1.7
+ uses: appleboy/ssh-action@v1.0.3
env:
DOCKER_REGISTRY_TOKEN: ${{ secrets.DOCKER_REGISTRY_TOKEN }}
with:
diff --git a/.gitignore b/.gitignore
index a3ab6e36..50479f84 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,4 +23,6 @@ dist-ssr
*.sln
*.sw?
-.env.*
\ No newline at end of file
+.env.*
+.eslintcache
+/*.d.ts
diff --git a/.prettierrc.js b/.prettierrc.js
deleted file mode 100644
index f053ebf7..00000000
--- a/.prettierrc.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = {};
diff --git a/Dockerfile b/Dockerfile
index b1291406..f29af659 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,58 +1,6 @@
-FROM node:16 as pnpm
+FROM nginx
+LABEL org.opencontainers.image.authors="Bruno Perel"
+WORKDIR /usr/share/nginx/html
-RUN npm i -g pnpm
-
-FROM pnpm AS app-install
-
-WORKDIR /app
-COPY package.json pnpm-lock.yaml .eslintrc.js ./
-RUN pnpm i
-
-FROM app-install AS api-build
-
-WORKDIR /app/api
-
-COPY api/package.json api/pnpm-lock.yaml ./
-RUN pnpm i
-
-COPY .env.prod ./.env
-
-COPY types /app/types
-COPY api .
-RUN mv tsconfig.prod.json tsconfig.json
-RUN mkdir dm_types && cp -r node_modules/ducksmanager/types/* dm_types/
-RUN mkdir prisma_clients && cp -r node_modules/ducksmanager/api/dist/prisma/* prisma_clients/
-RUN sed -i 's#../api/dist/prisma#~prisma_clients#g' dm_types/*.ts
-RUN pnpm run generate-route-types
-RUN pnpm run build
-
-FROM app-install AS app-build
-
-WORKDIR /app
-
-COPY . .
-COPY .env.prod ./.env
-COPY --from=api-build /app/api api
-COPY --from=api-build /app/types/routes.ts types/routes.ts
-RUN pnpm run build
-
-FROM nginx AS app
-LABEL org.opencontainers.image.authors="admin@ducksmanager.net"
-
-COPY nginx.conf /etc/nginx/nginx.conf
-COPY --from=app-build /app/dist /usr/share/nginx/html
-
-FROM pnpm AS api
-LABEL org.opencontainers.image.authors="admin@ducksmanager.net"
-
-WORKDIR /app
-
-COPY --from=api-build /app/api/package*.json /app/api/.env /app/
-RUN pnpm install --production
-
-COPY --from=api-build /app/api/dist /app/
-
-EXPOSE 3000
-
-WORKDIR /app/api
-CMD ["node", "index.js"]
+COPY --from=dm-build /prod/edgecreator/dist /usr/share/nginx/html
+# COPY apps/web/nginx.conf /etc/nginx/nginx.conf
\ No newline at end of file
diff --git a/api/.env b/api/.env
new file mode 100644
index 00000000..8262f1ef
--- /dev/null
+++ b/api/.env
@@ -0,0 +1,11 @@
+CLOUDINARY_URL=cloudinary://955445841324817:fqXP5YDdv8n1vwNjzgDRlFHDVto@dl7hskxab
+FONT_BASE_URL=https://www.myfonts.com/fonts/
+FONT_IMAGE_GEN_URL=https://render.myfonts.net/fonts/font_rend.php
+FONT_PRODUCT_BASE_URL=https://www.myfonts.com/products/
+
+# Used only in the backend, so with the api directory as basis
+EDGES_PATH=../DucksManager/edges
+
+TOKEN_SECRET=3543c30fe79047b4f73cfb61aa1eb52cb3173de4b3941e0fc4ec1b127bbeed6019695a1a453a81c33c2eea964ccc577e69c7df994124bd2751e262a311ea23a1
+
+DM_SOCKET_URL=http://localhost:3000
diff --git a/api/Dockerfile b/api/Dockerfile
new file mode 100644
index 00000000..37c612b1
--- /dev/null
+++ b/api/Dockerfile
@@ -0,0 +1,11 @@
+FROM pnpm
+LABEL org.opencontainers.image.authors="Bruno Perel"
+WORKDIR /app
+
+RUN apt update && apt install -y imagemagick && apt clean && rm -rf /var/lib/apt/lists/*
+
+COPY dist/index.js /app/index.mjs
+
+EXPOSE 3000
+
+CMD ["node", "index.mjs"]
diff --git a/api/assets/default.svg b/api/assets/default.svg
new file mode 100644
index 00000000..e8d8338c
--- /dev/null
+++ b/api/assets/default.svg
@@ -0,0 +1,18 @@
+
\ No newline at end of file
diff --git a/api/axios-helper.ts b/api/axios-helper.ts
deleted file mode 100644
index 5fe4882c..00000000
--- a/api/axios-helper.ts
+++ /dev/null
@@ -1,112 +0,0 @@
-import { useCookies } from "@vueuse/integrations/useCookies";
-import axios, {
- AxiosInstance,
- AxiosResponse,
- InternalAxiosRequestConfig,
-} from "axios";
-import { AxiosCacheInstance } from "axios-cache-interceptor";
-
-import { Call, ContractWithMethodAndUrl } from "~types/Call";
-
-export const addUrlParamsRequestInterceptor = <
- Type extends AxiosInstance | AxiosCacheInstance,
->(
- axiosInstance: Type,
-) => {
- axiosInstance.interceptors.request.use(
- (config: InternalAxiosRequestConfig) => {
- if (config.url) {
- const currentUrl = new URL(config.url, config.baseURL);
- currentUrl.pathname = Object.entries(
- config.urlParams ?? ({} as Record),
- ).reduce(
- (pathname, [k, v]) =>
- pathname.replace(`:${k}`, encodeURIComponent(v)),
- currentUrl.pathname,
- );
- return {
- ...config,
- baseURL: `${currentUrl.protocol}//${currentUrl.host}`,
- url: currentUrl.pathname,
- };
- }
- return config;
- },
- );
- return axiosInstance;
-};
-
-declare module "axios" {
- interface InternalAxiosRequestConfig {
- urlParams?: Record | undefined;
- }
-
- interface AxiosRequestConfig {
- urlParams?: Record | undefined;
- }
-}
-
-type MyCall = Call;
-
-export const call = >(
- instance: AxiosInstance | AxiosCacheInstance,
- contract: Contract,
-): Promise> =>
- instance.request({
- method: contract.getMethod(),
- url: contract.getUrl(),
- params: contract.call?.query || undefined,
- urlParams: contract.call?.params ?? undefined,
- data: (contract.call?.reqBody as never) || undefined,
- });
-
-export const getChunkedRequests = async <
- Contract extends ContractWithMethodAndUrl,
->({
- callFn,
- valuesToChunk,
- chunkSize,
-}: {
- callFn: (chunk: string) => Promise>;
- valuesToChunk: string[];
- chunkSize: number;
- chunkOnQueryParam?: boolean;
- parameterName?: string;
-}): Promise => {
- const slices = Array.from(
- { length: Math.ceil(valuesToChunk.length / chunkSize) },
- (_, i) => valuesToChunk.slice(i * chunkSize, i * chunkSize + chunkSize),
- );
- let acc: Contract["resBody"] = (await callFn(slices[0].join(","))).data;
- for (const slice of slices.slice(1)) {
- acc = Array.isArray(acc)
- ? [
- ...(acc as never[]),
- ...((await callFn(slice.join(","))).data as never[]),
- ]
- : {
- ...(acc as Record),
- ...((await callFn(slice.join(","))).data as Record),
- };
- }
- return acc;
-};
-
-export const createAxios = (baseURL: string) => {
- const newInstance = axios.create({ baseURL });
-
- newInstance.interceptors.request.use(
- (config) => {
- const token: string = useCookies().get("token");
- if (token) {
- config.headers.Authorization = `Bearer ${token}`;
- }
- return config;
- },
- (error) => Promise.reject(error),
- );
-
- addUrlParamsRequestInterceptor(newInstance);
-
- return newInstance;
-};
diff --git a/api/generate-route-types.ts b/api/generate-route-types.ts
deleted file mode 100644
index e8eeb596..00000000
--- a/api/generate-route-types.ts
+++ /dev/null
@@ -1,105 +0,0 @@
-import express from "express";
-import { router } from "express-file-routing";
-import { readdirSync, readFileSync, writeFileSync } from "fs";
-
-const app = express();
-
-interface Route {
- path: string | RegExp;
- methods: Record;
-}
-const routes: Route[] = [];
-
-(async () => {
- app.use("/", await router({ directory: `${process.cwd()}/routes` }));
- app._router.stack.forEach(
- (middleware: {
- route: Route;
- name: string;
- handle: { stack: [{ route: Route }] };
- }) => {
- if (typeof middleware.route?.path === "string") {
- // routes registered directly on the app
- routes.push(middleware.route);
- } else if (middleware.name === "router") {
- // router middleware
- middleware.handle.stack.forEach((handler) => {
- if (typeof handler.route?.path === "string") {
- routes.push(handler.route);
- }
- });
- }
- },
- );
-
- const imports: string[] = [
- "// noinspection ES6PreferShortImport",
- "",
- 'import { ContractWithMethodAndUrl } from "./Call";',
- ];
- imports.push(
- readdirSync("../types")
- .filter((file) => file.endsWith(".ts") && /^[A-Z]/.test(file[0]))
- .map(
- (file) =>
- `import { ${[
- ...readFileSync(`../types/${file}`)
- .toString()
- .matchAll(/(?:(?<=export type )|(?<=export interface ))\w+/g)!,
- ].join(", ")} } from "./${file.replace(/\.ts$/, "")}";`,
- )
- .join("\n"),
- );
- const types: string[] = [];
-
- let routeClassList = {} as Record;
- routes.forEach((route) => {
- routeClassList = Object.keys(route.methods)
- .filter((method) => ["get", "post", "delete", "put"].includes(method))
- .reduce((acc, method) => {
- const realMethod = method === "delete" ? "del" : method;
- const routePathWithMethod = `${method.toUpperCase()} ${
- route.path as string
- }`;
-
- let routeFile;
- const routeBasePath = `routes/${(route.path as string).replace(
- /^\//,
- "",
- )}`;
- try {
- routeFile = readFileSync(`${routeBasePath}/index.ts`);
- } catch (e) {
- routeFile = readFileSync(`${routeBasePath}.ts`);
- }
- const callType = new RegExp(
- `export const ${realMethod} =.+?ExpressCall<( *.+?)>[ \\n]*\\) =>`,
- "gms",
- ).exec(routeFile.toString())![1];
-
- acc[routePathWithMethod] =
- ` extends ContractWithMethodAndUrl<${callType}> {
- static readonly method = "${method}";
- static readonly url = "${route.path as string}";
- }`;
- return acc;
- }, routeClassList);
- });
- writeFileSync(
- "../types/routes.ts",
- [
- imports.join("\n"),
- types.join("\n"),
- Object.entries(routeClassList)
- .map(
- ([routePathWithMethod, callback]) =>
- `export class ${routePathWithMethod
- .replaceAll("/", "__")
- .replaceAll(/ /g, "")
- .replaceAll(/:/g, "$")
- .replaceAll(/-/g, "_")} ${callback}`,
- )
- .join("\n"),
- ].join("\n"),
- );
-})();
diff --git a/api/generateDefaultEdge.ts b/api/generateDefaultEdge.ts
new file mode 100644
index 00000000..393bdc9b
--- /dev/null
+++ b/api/generateDefaultEdge.ts
@@ -0,0 +1,51 @@
+import { exec } from "child_process";
+import type { Request, Response } from "express";
+import { readFileSync } from "fs";
+import { pipeline } from "stream";
+
+const corsHeaders = {
+ "Access-Control-Allow-Origin": "*",
+ "Access-Control-Allow-Credentials": "true",
+ "Access-Control-Allow-Methods": "GET, OPTIONS",
+ "Access-Control-Allow-Headers":
+ "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With," +
+ "If-Modified-Since,Cache-Control,Content-Type,x-dm-user,x-dm-pass",
+};
+export const get = (req: Request, res: Response) => {
+ const { countrycode, magazinecode, issuenumber, extension } = req.params!;
+
+ if (countrycode && extension !== "png") {
+ res.writeHead(404, corsHeaders);
+ res.end("");
+ return;
+ }
+ const text = `${countrycode}/${magazinecode} ${issuenumber}`;
+
+ const convert = exec("convert svg:- png:-", {
+ encoding: "buffer",
+ });
+
+ convert.stdin!.write(
+ Buffer.from(
+ readFileSync("assets/default.svg")
+ .toString()
+ .replace("My text", decodeURIComponent(text)),
+ "utf8"
+ )
+ );
+ convert.stdin!.end();
+
+ res.setHeader("Content-Type", "image/png");
+
+ pipeline(convert.stdout!, res, (err) => {
+ if (err) {
+ console.error("Pipeline failed", err);
+ res.status(500).send("Conversion failed");
+ }
+ });
+};
+
+export const options = (req: Request, res: Response) => {
+ res.writeHead(200, corsHeaders);
+ return res.end();
+};
diff --git a/api/index.ts b/api/index.ts
index 8f829b5a..a22fa121 100644
--- a/api/index.ts
+++ b/api/index.ts
@@ -1,19 +1,21 @@
import * as Sentry from "@sentry/node";
-import bodyParser from "body-parser";
-import cookieParser from "cookie-parser";
-import cors from "cors";
import dotenv from "dotenv";
import express from "express";
-import { router } from "express-file-routing";
+import { createServer } from "http";
+import multer from "multer";
+import { Server } from "socket.io";
-const parseForm = bodyParser.json();
-import {
- authenticateToken,
- checkUserIsAdminForExportOrIsEditorForSaveOrIsFirstFileForModel,
- checkUserIsAdminOrEditor,
- injectTokenIfValid,
-} from "~routes/_auth";
+import { OptionalAuthMiddleware } from "~dm-services/auth/util";
+import type { SessionUser } from "~dm-types/SessionUser";
+import * as generateDefaultEdge from "./generateDefaultEdge";
+import { instrument } from "@socket.io/admin-ui";
+
+import browse from "./services/browse";
+import imageInfo from "./services/image-info";
+import save from "./services/save";
+import text from "./services/text";
+import uploadServices, { upload } from "./services/upload";
dotenv.config({
path: "../.env",
});
@@ -24,36 +26,81 @@ Sentry.init({
dsn: process.env.SENTRY_DSN,
});
+class ServerWithUser extends Server<
+ Record,
+ Record,
+ Record,
+ { user?: SessionUser }
+> {}
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+(BigInt.prototype as any).toJSON = function () {
+ const int = Number.parseInt(this.toString());
+ return int ?? this.toString();
+};
+
+dotenv.config({
+ path: "./.env",
+});
+
+Sentry.init({
+ dsn: process.env.SENTRY_DSN,
+});
+
const app = express();
-app.use(
- Sentry.Handlers.requestHandler({
- user: ["id", "username"],
- }) as express.RequestHandler,
-);
-app.use(
- cors({
- optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
- }),
+app.get("/upload", (req, res) => {
+ if (req.method === "POST") {
+ multer({
+ dest: "/tmp/",
+ limits: {
+ fileSize: 3 * 1024 * 1024,
+ files: 1,
+ },
+ }).array("files");
+ upload(req, res);
+ } else {
+ res.writeHead(405);
+ }
+});
+
+app.get(
+ "/default-edge/edges/:countrycode/gen/:magazinecode([^.]+).:issuenumber([^.]+).:extension(svg|png)",
+ (req, res) => {
+ if (req.method === "OPTIONS") {
+ generateDefaultEdge.options(req, res);
+ } else if (req.method === "GET") {
+ multer({
+ dest: "/tmp/",
+ limits: {
+ fileSize: 3 * 1024 * 1024,
+ files: 1,
+ },
+ }).array("files");
+ generateDefaultEdge.get(req, res);
+ } else {
+ res.writeHead(405);
+ }
+ }
);
-app.use(cookieParser());
-
-app.all(/^.+$/, injectTokenIfValid);
-app.all(/^\/fs\/save$/, [
- authenticateToken,
- parseForm,
- checkUserIsAdminForExportOrIsEditorForSaveOrIsFirstFileForModel,
-]);
-app.all(/^\/fs\/(text|upload|upload-base64)$/, [
- authenticateToken,
- checkUserIsAdminOrEditor,
-]);
-
-app.use(Sentry.Handlers.errorHandler() as express.ErrorRequestHandler);
-
-(async () => {
- app.use("/", await router({ directory: `${process.cwd()}/routes` }));
- app.listen(port, () =>
- console.log(`EdgeCreator API listening on port ${port}`),
- );
-})();
+const httpServer = createServer(app);
+const io = new ServerWithUser(httpServer, {
+ cors: {
+ origin: "*",
+ },
+});
+
+instrument(io, {
+ auth: false,
+});
+
+httpServer.listen(port);
+console.log(`WebSocket open on port ${port}`);
+
+io.use(OptionalAuthMiddleware);
+
+text(io);
+browse(io);
+imageInfo(io);
+save(io);
+uploadServices(io);
diff --git a/api/nodemon.json b/api/nodemon.json
deleted file mode 100644
index bf2459af..00000000
--- a/api/nodemon.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "ignore": ["node_modules"],
- "watch": ["."],
- "exec": "npm start",
- "ext": "ts"
-}
diff --git a/api/package.json b/api/package.json
index 98035a41..0724599d 100644
--- a/api/package.json
+++ b/api/package.json
@@ -1,45 +1,44 @@
{
- "name": "dm-api",
+ "name": "~edgecreator-api",
+ "type": "module",
"version": "1.0.0",
"scripts": {
"clean": "rm -rf dist",
- "build": "rm -rf dist/api dist/types && tsc && tsc-alias",
- "start": "tsx index.ts",
- "dev": "nodemon",
- "generate-route-types": "tsx generate-route-types.ts",
- "generate-route-types:clean": "tsx generate-route-types.ts && cd .. && node_modules/.bin/eslint --fix types/routes.ts"
+ "build": "rm -rf dist && tsc && tsc-alias",
+ "postbuild": "cp -r ../../../packages/prisma-clients/dist/client_* dist/packages/prisma-clients",
+ "dev": "concurrently -n bun,tsc \"bun --inspect run --hot index.ts\" \"tsc --noEmit --watch\""
},
"dependencies": {
"@sentry/node": "^7.114.0",
+ "@socket.io/admin-ui": "^0.5.1",
"@vueuse/integrations": "^10.9.0",
"axios": "^1.6.8",
- "body-parser": "^1.20.2",
"cloudinary": "^1.41.3",
- "cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
- "ducksmanager": "^0.0.51",
"express": "^4.19.2",
- "express-file-routing": "^3.0.3",
"i18n": "^0.15.1",
"image-size": "^1.1.1",
"jsonwebtoken": "^9.0.2",
"multer": "1.4.5-lts.1",
"node-base64-image": "^2.0.6",
- "nodemon": "^2.0.22",
- "sharp": "^0.33.3",
- "universal-cookie": "^4.0.4"
+ "socket.io": "^4.7.5",
+ "socket.io-client": "^4.7.5",
+ "universal-cookie": "^4.0.4",
+ "~api": "workspace:*",
+ "~dm-types": "workspace:*",
+ "~prisma-clients": "workspace:*",
+ "~socket.io-client-services": "workspace:*",
+ "~socket.io-services": "workspace:*"
},
"devDependencies": {
- "@types/body-parser": "^1.19.5",
- "@types/busboy": "^1.5.4",
- "@types/cookie-parser": "^1.4.7",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/i18n": "^0.13.12",
"@types/jsonwebtoken": "^9.0.6",
"@types/multer": "^1.4.11",
"@types/node": "^18.19.33",
+ "concurrently": "^8.2.2",
"tsc-alias": "^1.8.9",
"tsx": "^4.10.1",
"typescript": "^5.4.5"
diff --git a/api/pnpm-lock.yaml b/api/pnpm-lock.yaml
index 11ec40ca..ea7ad8b1 100644
--- a/api/pnpm-lock.yaml
+++ b/api/pnpm-lock.yaml
@@ -10,37 +10,28 @@ importers:
dependencies:
'@sentry/node':
specifier: ^7.114.0
- version: 7.114.0
+ version: 7.116.0
+ '@socket.io/admin-ui':
+ specifier: ^0.5.1
+ version: 0.5.1(socket.io@4.7.5)
'@vueuse/integrations':
specifier: ^10.9.0
- version: 10.9.0(axios@1.6.8)(universal-cookie@4.0.4)(vue@3.3.4)
+ version: 10.9.0(axios@1.7.0)(universal-cookie@4.0.4)(vue@3.3.4)
axios:
specifier: ^1.6.8
- version: 1.6.8
- body-parser:
- specifier: ^1.20.2
- version: 1.20.2
+ version: 1.7.0
cloudinary:
specifier: ^1.41.3
version: 1.41.3
- cookie-parser:
- specifier: ^1.4.6
- version: 1.4.6
cors:
specifier: ^2.8.5
version: 2.8.5
dotenv:
specifier: ^16.4.5
version: 16.4.5
- ducksmanager:
- specifier: ^0.0.51
- version: 0.0.51
express:
specifier: ^4.19.2
version: 4.19.2
- express-file-routing:
- specifier: ^3.0.3
- version: 3.0.3(express@4.19.2)
i18n:
specifier: ^0.15.1
version: 0.15.1
@@ -56,25 +47,31 @@ importers:
node-base64-image:
specifier: ^2.0.6
version: 2.0.6
- nodemon:
- specifier: ^2.0.22
- version: 2.0.22
- sharp:
- specifier: ^0.33.3
- version: 0.33.3
+ socket.io:
+ specifier: ^4.7.5
+ version: 4.7.5
+ socket.io-client:
+ specifier: ^4.7.5
+ version: 4.7.5
universal-cookie:
specifier: ^4.0.4
version: 4.0.4
+ ~api:
+ specifier: workspace:*
+ version: link:../../../packages/api
+ ~dm-types:
+ specifier: workspace:*
+ version: link:../../../packages/types
+ ~prisma-clients:
+ specifier: workspace:*
+ version: link:../../../packages/prisma-clients
+ ~socket.io-client-services:
+ specifier: workspace:*
+ version: link:../../../packages/socket.io-client-services
+ ~socket.io-services:
+ specifier: workspace:*
+ version: link:../../../packages/socket.io-services
devDependencies:
- '@types/body-parser':
- specifier: ^1.19.5
- version: 1.19.5
- '@types/busboy':
- specifier: ^1.5.4
- version: 1.5.4
- '@types/cookie-parser':
- specifier: ^1.4.7
- version: 1.4.7
'@types/cors':
specifier: ^2.8.17
version: 2.8.17
@@ -93,37 +90,41 @@ importers:
'@types/node':
specifier: ^18.19.33
version: 18.19.33
+ concurrently:
+ specifier: ^8.2.2
+ version: 8.2.2
tsc-alias:
specifier: ^1.8.9
- version: 1.8.9
+ version: 1.8.10
tsx:
specifier: ^4.10.1
- version: 4.10.1
+ version: 4.10.5
typescript:
specifier: ^5.4.5
version: 5.4.5
packages:
- '@babel/helper-string-parser@7.22.5':
- resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==}
+ '@babel/helper-string-parser@7.24.1':
+ resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==}
engines: {node: '>=6.9.0'}
- '@babel/helper-validator-identifier@7.22.5':
- resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==}
+ '@babel/helper-validator-identifier@7.24.5':
+ resolution: {integrity: sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==}
engines: {node: '>=6.9.0'}
- '@babel/parser@7.22.7':
- resolution: {integrity: sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==}
+ '@babel/parser@7.24.5':
+ resolution: {integrity: sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==}
engines: {node: '>=6.0.0'}
hasBin: true
- '@babel/types@7.22.5':
- resolution: {integrity: sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==}
+ '@babel/runtime@7.24.5':
+ resolution: {integrity: sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==}
engines: {node: '>=6.9.0'}
- '@emnapi/runtime@1.1.1':
- resolution: {integrity: sha512-3bfqkzuR1KLx57nZfjr2NLnFOobvyS0aTszaEGCGqmYMVDRaGvgIZbjGSV/MHSSmLgQ/b9JFHQ5xm5WRZYd+XQ==}
+ '@babel/types@7.24.5':
+ resolution: {integrity: sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==}
+ engines: {node: '>=6.9.0'}
'@esbuild/aix-ppc64@0.20.2':
resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==}
@@ -263,124 +264,11 @@ packages:
cpu: [x64]
os: [win32]
- '@img/sharp-darwin-arm64@0.33.3':
- resolution: {integrity: sha512-FaNiGX1MrOuJ3hxuNzWgsT/mg5OHG/Izh59WW2mk1UwYHUwtfbhk5QNKYZgxf0pLOhx9ctGiGa2OykD71vOnSw==}
- engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [arm64]
- os: [darwin]
-
- '@img/sharp-darwin-x64@0.33.3':
- resolution: {integrity: sha512-2QeSl7QDK9ru//YBT4sQkoq7L0EAJZA3rtV+v9p8xTKl4U1bUqTIaCnoC7Ctx2kCjQgwFXDasOtPTCT8eCTXvw==}
- engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [x64]
- os: [darwin]
-
- '@img/sharp-libvips-darwin-arm64@1.0.2':
- resolution: {integrity: sha512-tcK/41Rq8IKlSaKRCCAuuY3lDJjQnYIW1UXU1kxcEKrfL8WR7N6+rzNoOxoQRJWTAECuKwgAHnPvqXGN8XfkHA==}
- engines: {macos: '>=11', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [arm64]
- os: [darwin]
-
- '@img/sharp-libvips-darwin-x64@1.0.2':
- resolution: {integrity: sha512-Ofw+7oaWa0HiiMiKWqqaZbaYV3/UGL2wAPeLuJTx+9cXpCRdvQhCLG0IH8YGwM0yGWGLpsF4Su9vM1o6aer+Fw==}
- engines: {macos: '>=10.13', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [x64]
- os: [darwin]
-
- '@img/sharp-libvips-linux-arm64@1.0.2':
- resolution: {integrity: sha512-x7kCt3N00ofFmmkkdshwj3vGPCnmiDh7Gwnd4nUwZln2YjqPxV1NlTyZOvoDWdKQVDL911487HOueBvrpflagw==}
- engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [arm64]
- os: [linux]
-
- '@img/sharp-libvips-linux-arm@1.0.2':
- resolution: {integrity: sha512-iLWCvrKgeFoglQxdEwzu1eQV04o8YeYGFXtfWU26Zr2wWT3q3MTzC+QTCO3ZQfWd3doKHT4Pm2kRmLbupT+sZw==}
- engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [arm]
- os: [linux]
-
- '@img/sharp-libvips-linux-s390x@1.0.2':
- resolution: {integrity: sha512-cmhQ1J4qVhfmS6szYW7RT+gLJq9dH2i4maq+qyXayUSn9/3iY2ZeWpbAgSpSVbV2E1JUL2Gg7pwnYQ1h8rQIog==}
- engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [s390x]
- os: [linux]
-
- '@img/sharp-libvips-linux-x64@1.0.2':
- resolution: {integrity: sha512-E441q4Qdb+7yuyiADVi5J+44x8ctlrqn8XgkDTwr4qPJzWkaHwD489iZ4nGDgcuya4iMN3ULV6NwbhRZJ9Z7SQ==}
- engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [x64]
- os: [linux]
-
- '@img/sharp-libvips-linuxmusl-arm64@1.0.2':
- resolution: {integrity: sha512-3CAkndNpYUrlDqkCM5qhksfE+qSIREVpyoeHIU6jd48SJZViAmznoQQLAv4hVXF7xyUB9zf+G++e2v1ABjCbEQ==}
- engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [arm64]
- os: [linux]
-
- '@img/sharp-libvips-linuxmusl-x64@1.0.2':
- resolution: {integrity: sha512-VI94Q6khIHqHWNOh6LLdm9s2Ry4zdjWJwH56WoiJU7NTeDwyApdZZ8c+SADC8OH98KWNQXnE01UdJ9CSfZvwZw==}
- engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [x64]
- os: [linux]
-
- '@img/sharp-linux-arm64@0.33.3':
- resolution: {integrity: sha512-Zf+sF1jHZJKA6Gor9hoYG2ljr4wo9cY4twaxgFDvlG0Xz9V7sinsPp8pFd1XtlhTzYo0IhDbl3rK7P6MzHpnYA==}
- engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [arm64]
- os: [linux]
-
- '@img/sharp-linux-arm@0.33.3':
- resolution: {integrity: sha512-Q7Ee3fFSC9P7vUSqVEF0zccJsZ8GiiCJYGWDdhEjdlOeS9/jdkyJ6sUSPj+bL8VuOYFSbofrW0t/86ceVhx32w==}
- engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [arm]
- os: [linux]
-
- '@img/sharp-linux-s390x@0.33.3':
- resolution: {integrity: sha512-vFk441DKRFepjhTEH20oBlFrHcLjPfI8B0pMIxGm3+yilKyYeHEVvrZhYFdqIseSclIqbQ3SnZMwEMWonY5XFA==}
- engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [s390x]
- os: [linux]
-
- '@img/sharp-linux-x64@0.33.3':
- resolution: {integrity: sha512-Q4I++herIJxJi+qmbySd072oDPRkCg/SClLEIDh5IL9h1zjhqjv82H0Seupd+q2m0yOfD+/fJnjSoDFtKiHu2g==}
- engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [x64]
- os: [linux]
-
- '@img/sharp-linuxmusl-arm64@0.33.3':
- resolution: {integrity: sha512-qnDccehRDXadhM9PM5hLvcPRYqyFCBN31kq+ErBSZtZlsAc1U4Z85xf/RXv1qolkdu+ibw64fUDaRdktxTNP9A==}
- engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [arm64]
- os: [linux]
-
- '@img/sharp-linuxmusl-x64@0.33.3':
- resolution: {integrity: sha512-Jhchim8kHWIU/GZ+9poHMWRcefeaxFIs9EBqf9KtcC14Ojk6qua7ghKiPs0sbeLbLj/2IGBtDcxHyjCdYWkk2w==}
- engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [x64]
- os: [linux]
-
- '@img/sharp-wasm32@0.33.3':
- resolution: {integrity: sha512-68zivsdJ0koE96stdUfM+gmyaK/NcoSZK5dV5CAjES0FUXS9lchYt8LAB5rTbM7nlWtxaU/2GON0HVN6/ZYJAQ==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [wasm32]
-
- '@img/sharp-win32-ia32@0.33.3':
- resolution: {integrity: sha512-CyimAduT2whQD8ER4Ux7exKrtfoaUiVr7HG0zZvO0XTFn2idUWljjxv58GxNTkFb8/J9Ub9AqITGkJD6ZginxQ==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [ia32]
- os: [win32]
-
- '@img/sharp-win32-x64@0.33.3':
- resolution: {integrity: sha512-viT4fUIDKnli3IfOephGnolMzhz5VaTvDRkYqtZxOMIoMQ4MrAziO7pT1nVnOt2FAm7qW5aa+CCc13aEY6Le0g==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [x64]
- os: [win32]
-
'@jridgewell/sourcemap-codec@1.4.15':
resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
- '@messageformat/core@3.2.0':
- resolution: {integrity: sha512-ppbb/7OYqg/t4WdFk8VAfZEV2sNUq3+7VeBAo5sKFhmF786sh6gB7fUeXa2qLTDIcTHS49HivTBN7QNOU5OFTg==}
+ '@messageformat/core@3.3.0':
+ resolution: {integrity: sha512-YcXd3remTDdeMxAlbvW6oV9d/01/DZ8DHUFwSttO3LMzIZj3iO0NRw+u1xlsNNORFI+u0EQzD52ZX3+Udi0T3g==}
'@messageformat/date-skeleton@1.0.1':
resolution: {integrity: sha512-jPXy8fg+WMPIgmGjxSlnGJn68h/2InfT0TNSkVx0IGXgp4ynnvYkbZ51dGWmGySEK+pBiYUttbQdu5XEqX5CRg==}
@@ -406,56 +294,64 @@ packages:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
- '@sentry-internal/tracing@7.114.0':
- resolution: {integrity: sha512-dOuvfJN7G+3YqLlUY4HIjyWHaRP8vbOgF+OsE5w2l7ZEn1rMAaUbPntAR8AF9GBA6j2zWNoSo8e7GjbJxVofSg==}
+ '@sentry-internal/tracing@7.116.0':
+ resolution: {integrity: sha512-y5ppEmoOlfr77c/HqsEXR72092qmGYS4QE5gSz5UZFn9CiinEwGfEorcg2xIrrCuU7Ry/ZU2VLz9q3xd04drRA==}
engines: {node: '>=8'}
- '@sentry/core@7.114.0':
- resolution: {integrity: sha512-YnanVlmulkjgZiVZ9BfY9k6I082n+C+LbZo52MTvx3FY6RE5iyiPMpaOh67oXEZRWcYQEGm+bKruRxLVP6RlbA==}
+ '@sentry/core@7.116.0':
+ resolution: {integrity: sha512-J6Wmjjx+o7RwST0weTU1KaKUAlzbc8MGkJV1rcHM9xjNTWTva+nrcCM3vFBagnk2Gm/zhwv3h0PvWEqVyp3U1Q==}
engines: {node: '>=8'}
- '@sentry/integrations@7.114.0':
- resolution: {integrity: sha512-BJIBWXGKeIH0ifd7goxOS29fBA8BkEgVVCahs6xIOXBjX1IRS6PmX0zYx/GP23nQTfhJiubv2XPzoYOlZZmDxg==}
+ '@sentry/integrations@7.116.0':
+ resolution: {integrity: sha512-UZb60gaF+7veh1Yv79RiGvgGYOnU6xA97H+hI6tKgc1uT20YpItO4X56Vhp0lvyEyUGFZzBRRH1jpMDPNGPkqw==}
engines: {node: '>=8'}
- '@sentry/node@7.114.0':
- resolution: {integrity: sha512-cqvi+OHV1Hj64mIGHoZtLgwrh1BG6ntcRjDLlVNMqml5rdTRD3TvG21579FtlqHlwZpbpF7K5xkwl8e5KL2hGw==}
+ '@sentry/node@7.116.0':
+ resolution: {integrity: sha512-HB/4TrJWbnu6swNzkid+MlwzLwY/D/klGt3R0aatgrgWPo2jJm6bSl4LUT39Cr2eg5I1gsREQtXE2mAlC6gm8w==}
engines: {node: '>=8'}
- '@sentry/types@7.114.0':
- resolution: {integrity: sha512-tsqkkyL3eJtptmPtT0m9W/bPLkU7ILY7nvwpi1hahA5jrM7ppoU0IMaQWAgTD+U3rzFH40IdXNBFb8Gnqcva4w==}
+ '@sentry/types@7.116.0':
+ resolution: {integrity: sha512-QCCvG5QuQrwgKzV11lolNQPP2k67Q6HHD9vllZ/C4dkxkjoIym8Gy+1OgAN3wjsR0f/kG9o5iZyglgNpUVRapQ==}
engines: {node: '>=8'}
- '@sentry/utils@7.114.0':
- resolution: {integrity: sha512-319N90McVpupQ6vws4+tfCy/03AdtsU0MurIE4+W5cubHME08HtiEWlfacvAxX+yuKFhvdsO4K4BB/dj54ideg==}
+ '@sentry/utils@7.116.0':
+ resolution: {integrity: sha512-Vn9fcvwTq91wJvCd7WTMWozimqMi+dEZ3ie3EICELC2diONcN16ADFdzn65CQQbYwmUzRjN9EjDN2k41pKZWhQ==}
engines: {node: '>=8'}
- '@types/body-parser@1.19.5':
- resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==}
+ '@socket.io/admin-ui@0.5.1':
+ resolution: {integrity: sha512-1dlGL2FGm6T+uL1e6iDvbo2eCINwvW7iVbjIblwh5kPPRM1SP8lmZrbFZf4QNJ/cqQ+JLcx49eXGM9WAB4TK7w==}
+ peerDependencies:
+ socket.io: '>=3.1.0'
+
+ '@socket.io/component-emitter@3.1.2':
+ resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==}
- '@types/busboy@1.5.4':
- resolution: {integrity: sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==}
+ '@types/bcryptjs@2.4.6':
+ resolution: {integrity: sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ==}
- '@types/connect@3.4.35':
- resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==}
+ '@types/body-parser@1.19.5':
+ resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==}
- '@types/cookie-parser@1.4.7':
- resolution: {integrity: sha512-Fvuyi354Z+uayxzIGCwYTayFKocfV7TuDYZClCdIP9ckhvAu/ixDtCB6qx2TT0FKjPLf1f3P/J1rgf6lPs64mw==}
+ '@types/connect@3.4.38':
+ resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==}
'@types/cookie@0.3.3':
resolution: {integrity: sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==}
+ '@types/cookie@0.4.1':
+ resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==}
+
'@types/cors@2.8.17':
resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==}
- '@types/express-serve-static-core@4.17.35':
- resolution: {integrity: sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==}
+ '@types/express-serve-static-core@4.19.0':
+ resolution: {integrity: sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==}
'@types/express@4.17.21':
resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==}
- '@types/http-errors@2.0.1':
- resolution: {integrity: sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==}
+ '@types/http-errors@2.0.4':
+ resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==}
'@types/i18n@0.13.12':
resolution: {integrity: sha512-iAd2QjKh+0ToBXocmCS3m38GskiaGzmSV1MTQz2GaOraqSqBiLf46J7u3EGINl+st+Uk4lO3OL7QyIjTJlrWIg==}
@@ -463,32 +359,26 @@ packages:
'@types/jsonwebtoken@9.0.6':
resolution: {integrity: sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw==}
- '@types/mime@1.3.2':
- resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==}
-
- '@types/mime@3.0.1':
- resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==}
+ '@types/mime@1.3.5':
+ resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==}
'@types/multer@1.4.11':
resolution: {integrity: sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w==}
- '@types/node@16.18.38':
- resolution: {integrity: sha512-6sfo1qTulpVbkxECP+AVrHV9OoJqhzCsfTNp5NIG+enM4HyM3HvZCO798WShIXBN0+QtDIcutJCjsVYnQP5rIQ==}
-
'@types/node@18.19.33':
resolution: {integrity: sha512-NR9+KrpSajr2qBVp/Yt5TU/rp+b5Mayi3+OlMlcg2cVCfRmcG5PWZ7S4+MG9PZ5gWBoc9Pd0BKSRViuBCRPu0A==}
- '@types/qs@6.9.7':
- resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==}
+ '@types/qs@6.9.15':
+ resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==}
- '@types/range-parser@1.2.4':
- resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==}
+ '@types/range-parser@1.2.7':
+ resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==}
- '@types/send@0.17.1':
- resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==}
+ '@types/send@0.17.4':
+ resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==}
- '@types/serve-static@1.15.2':
- resolution: {integrity: sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==}
+ '@types/serve-static@1.15.7':
+ resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==}
'@types/web-bluetooth@0.0.20':
resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
@@ -575,13 +465,18 @@ packages:
'@vueuse/shared@10.9.0':
resolution: {integrity: sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==}
- abbrev@1.1.1:
- resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
-
accepts@1.3.8:
resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==}
engines: {node: '>= 0.6'}
+ ansi-regex@5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+
+ ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+
anymatch@3.1.3:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'}
@@ -602,14 +497,18 @@ packages:
axios@1.6.0:
resolution: {integrity: sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==}
- axios@1.6.8:
- resolution: {integrity: sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==}
+ axios@1.7.0:
+ resolution: {integrity: sha512-IiB0wQeKyPRdsFVhBgIo31FbzOyf2M6wYl7/NVutFwFBRMiAbjNiydJIHKeLmPugF4kJLfA1uWZ82Is2QzqqFA==}
- balanced-match@1.0.2:
- resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+ base64id@2.0.0:
+ resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==}
+ engines: {node: ^4.5.0 || >= 5.9}
- binary-extensions@2.2.0:
- resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
+ bcryptjs@2.4.3:
+ resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==}
+
+ binary-extensions@2.3.0:
+ resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
engines: {node: '>=8'}
body-parser@1.20.2:
@@ -619,9 +518,6 @@ packages:
boolean@3.2.0:
resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==}
- brace-expansion@1.1.11:
- resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
-
braces@3.0.2:
resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
engines: {node: '>=8'}
@@ -640,15 +536,24 @@ packages:
resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
engines: {node: '>= 0.8'}
- call-bind@1.0.2:
- resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
+ call-bind@1.0.7:
+ resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
+ engines: {node: '>= 0.4'}
+
+ chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
- chokidar@3.5.3:
- resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
+ chokidar@3.6.0:
+ resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
- cloudinary-core@2.13.0:
- resolution: {integrity: sha512-Nt0Q5I2FtenmJghtC4YZ3MZZbGg1wLm84SsxcuVwZ83OyJqG9CNIGp86CiI6iDv3QobaqBUpOT7vg+HqY5HxEA==}
+ cliui@8.0.1:
+ resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
+ engines: {node: '>=12'}
+
+ cloudinary-core@2.13.1:
+ resolution: {integrity: sha512-z53GPNWnvU0Zi+ns8CIVbZBfj7ps/++zDvwIyiFuq5p1MoK+KUCg0k5mBceDDHTnx1gHmHUd9aohS+gDxPNt6w==}
peerDependencies:
lodash: '>=4.0'
@@ -663,13 +568,6 @@ packages:
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
- color-string@1.9.1:
- resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
-
- color@4.2.3:
- resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
- engines: {node: '>=12.5.0'}
-
combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
@@ -678,13 +576,15 @@ packages:
resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==}
engines: {node: ^12.20.0 || >=14}
- concat-map@0.0.1:
- resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
-
concat-stream@1.6.2:
resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==}
engines: {'0': node >= 0.8}
+ concurrently@8.2.2:
+ resolution: {integrity: sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==}
+ engines: {node: ^14.13.0 || >=16.0.0}
+ hasBin: true
+
content-disposition@0.5.4:
resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
engines: {node: '>= 0.6'}
@@ -693,17 +593,9 @@ packages:
resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==}
engines: {node: '>= 0.6'}
- cookie-parser@1.4.6:
- resolution: {integrity: sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==}
- engines: {node: '>= 0.8.0'}
-
cookie-signature@1.0.6:
resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==}
- cookie@0.4.1:
- resolution: {integrity: sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==}
- engines: {node: '>= 0.6'}
-
cookie@0.4.2:
resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==}
engines: {node: '>= 0.6'}
@@ -712,8 +604,8 @@ packages:
resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==}
engines: {node: '>= 0.6'}
- core-js@3.31.1:
- resolution: {integrity: sha512-2sKLtfq1eFST7l7v62zaqXacPc7uG8ZAya8ogijLhTtaKNcpzpB4TMoTw2Si+8GYKRwFPMMtUT0263QFWFfqyQ==}
+ core-js@3.37.1:
+ resolution: {integrity: sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==}
core-util-is@1.0.3:
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
@@ -722,8 +614,12 @@ packages:
resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
engines: {node: '>= 0.10'}
- csstype@3.1.2:
- resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
+ csstype@3.1.3:
+ resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
+
+ date-fns@2.30.0:
+ resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==}
+ engines: {node: '>=0.11'}
debug@2.6.9:
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
@@ -733,14 +629,6 @@ packages:
supports-color:
optional: true
- debug@3.2.7:
- resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
- peerDependencies:
- supports-color: '*'
- peerDependenciesMeta:
- supports-color:
- optional: true
-
debug@4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'}
@@ -750,6 +638,10 @@ packages:
supports-color:
optional: true
+ define-data-property@1.1.4:
+ resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
+ engines: {node: '>= 0.4'}
+
delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
@@ -762,10 +654,6 @@ packages:
resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==}
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
- detect-libc@2.0.3:
- resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
- engines: {node: '>=8'}
-
dir-glob@3.0.1:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
engines: {node: '>=8'}
@@ -774,24 +662,47 @@ packages:
resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==}
engines: {node: '>=12'}
- ducksmanager@0.0.51:
- resolution: {integrity: sha512-0BFbwMOAQv0wEhF/ezoxdQrAh5iwAGZYwVbMlq70PsrNeuhCqnI2D9VcW1Dch1COUlA/OgtKknzRD14lJhg4Jw==}
-
ecdsa-sig-formatter@1.0.11:
resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==}
ee-first@1.1.1:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
+ emoji-regex@8.0.0:
+ resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+
encodeurl@1.0.2:
resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==}
engines: {node: '>= 0.8'}
+ engine.io-client@6.5.3:
+ resolution: {integrity: sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==}
+
+ engine.io-parser@5.2.2:
+ resolution: {integrity: sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==}
+ engines: {node: '>=10.0.0'}
+
+ engine.io@6.5.4:
+ resolution: {integrity: sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==}
+ engines: {node: '>=10.2.0'}
+
+ es-define-property@1.0.0:
+ resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==}
+ engines: {node: '>= 0.4'}
+
+ es-errors@1.3.0:
+ resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
+ engines: {node: '>= 0.4'}
+
esbuild@0.20.2:
resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==}
engines: {node: '>=12'}
hasBin: true
+ escalade@3.1.2:
+ resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==}
+ engines: {node: '>=6'}
+
escape-html@1.0.3:
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
@@ -802,25 +713,20 @@ packages:
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
engines: {node: '>= 0.6'}
- express-file-routing@3.0.3:
- resolution: {integrity: sha512-0936IhPc64moJHAG1Fz3SLCi0Upt6ahsbocrC6hdPUgmHY2018wjVrbln0HP67JoWFUdmmzypYiIHjF898s0hA==}
- peerDependencies:
- express: '>4.1.2'
-
express@4.19.2:
resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==}
engines: {node: '>= 0.10.0'}
- fast-glob@3.3.0:
- resolution: {integrity: sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==}
+ fast-glob@3.3.2:
+ resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
engines: {node: '>=8.6.0'}
fast-printf@1.6.9:
resolution: {integrity: sha512-FChq8hbz65WMj4rstcQsFB0O7Cy++nmbNfLYnD9cYv2cRn8EG6k/MGn9kO/tjO66t09DLDugj3yL+V2o6Qftrg==}
engines: {node: '>=10.0'}
- fastq@1.15.0:
- resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==}
+ fastq@1.17.1:
+ resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
fill-range@7.0.1:
resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
@@ -830,15 +736,6 @@ packages:
resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==}
engines: {node: '>= 0.8'}
- follow-redirects@1.15.2:
- resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
- engines: {node: '>=4.0'}
- peerDependencies:
- debug: '*'
- peerDependenciesMeta:
- debug:
- optional: true
-
follow-redirects@1.15.6:
resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==}
engines: {node: '>=4.0'}
@@ -860,21 +757,21 @@ packages:
resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==}
engines: {node: '>= 0.6'}
- fsevents@2.3.2:
- resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
- engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
- os: [darwin]
-
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
- function-bind@1.1.1:
- resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
+ function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+
+ get-caller-file@2.0.5:
+ resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
+ engines: {node: 6.* || 8.* || >= 10.*}
- get-intrinsic@1.2.1:
- resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==}
+ get-intrinsic@1.2.4:
+ resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
+ engines: {node: '>= 0.4'}
get-tsconfig@4.7.5:
resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==}
@@ -887,21 +784,27 @@ packages:
resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
engines: {node: '>=10'}
- has-flag@3.0.0:
- resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
- engines: {node: '>=4'}
+ gopd@1.0.1:
+ resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
+
+ has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
+ has-property-descriptors@1.0.2:
+ resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
- has-proto@1.0.1:
- resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==}
+ has-proto@1.0.3:
+ resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==}
engines: {node: '>= 0.4'}
has-symbols@1.0.3:
resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
engines: {node: '>= 0.4'}
- has@1.0.3:
- resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
- engines: {node: '>= 0.4.0'}
+ hasown@2.0.2:
+ resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
+ engines: {node: '>= 0.4'}
http-errors@2.0.0:
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
@@ -915,11 +818,8 @@ packages:
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
engines: {node: '>=0.10.0'}
- ignore-by-default@1.0.1:
- resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==}
-
- ignore@5.2.4:
- resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==}
+ ignore@5.3.1:
+ resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==}
engines: {node: '>= 4'}
image-size@1.1.1:
@@ -937,9 +837,6 @@ packages:
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
engines: {node: '>= 0.10'}
- is-arrayish@0.3.2:
- resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
-
is-binary-path@2.1.0:
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
engines: {node: '>=8'}
@@ -948,6 +845,10 @@ packages:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
+ is-fullwidth-code-point@3.0.0:
+ resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
+ engines: {node: '>=8'}
+
is-glob@4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
@@ -999,16 +900,11 @@ packages:
lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
- lru-cache@6.0.0:
- resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
- engines: {node: '>=10'}
-
- magic-string@0.30.1:
- resolution: {integrity: sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==}
- engines: {node: '>=12'}
+ magic-string@0.30.10:
+ resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==}
- make-plural@7.3.0:
- resolution: {integrity: sha512-/K3BC0KIsO+WK2i94LkMPv3wslMrazrQhfi5We9fMbLlLjzoOSJWr7TAdupLlDWaJcWxwoNosBkhFDejiu5VDw==}
+ make-plural@7.4.0:
+ resolution: {integrity: sha512-4/gC9KVNTV6pvYg2gFeQYTW3mWaoJt7WZE5vrp1KnQDgW92JtYZnzmZT81oj/dUTqAIu0ufI2x3dkgu3bB1tYg==}
math-interval-parser@2.0.1:
resolution: {integrity: sha512-VmlAmb0UJwlvMyx8iPhXUDnVW1F9IrGEd9CIOmv+XL8AErCUUuozoDMrgImvnYt2A+53qVX/tPW6YJurMKYsvA==}
@@ -1046,9 +942,6 @@ packages:
engines: {node: '>=4'}
hasBin: true
- minimatch@3.1.2:
- resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
-
minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
@@ -1080,8 +973,8 @@ packages:
resolution: {integrity: sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg==}
engines: {node: '>=12.0.0'}
- nanoid@3.3.6:
- resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==}
+ nanoid@3.3.7:
+ resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
@@ -1093,15 +986,6 @@ packages:
resolution: {integrity: sha512-fUioszu6tGacTl5QkUI1CERjg1y5loOwSMb2LMiHt98DMkWxirhVg35kEnLghbeLQjZ9Mik5NbaV881jcC2tow==}
engines: {node: '>=16'}
- nodemon@2.0.22:
- resolution: {integrity: sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==}
- engines: {node: '>=8.10.0'}
- hasBin: true
-
- nopt@1.0.10:
- resolution: {integrity: sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==}
- hasBin: true
-
normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
@@ -1110,8 +994,8 @@ packages:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
- object-inspect@1.12.3:
- resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==}
+ object-inspect@1.13.1:
+ resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==}
on-finished@2.4.1:
resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
@@ -1128,18 +1012,19 @@ packages:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
- picocolors@1.0.0:
- resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
+ picocolors@1.0.1:
+ resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==}
picomatch@2.3.1:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
- plimit-lit@1.5.0:
- resolution: {integrity: sha512-Eb/MqCb1Iv/ok4m1FqIXqvUKPISufcjZ605hl3KM/n8GaX8zfhtgdLwZU3vKjuHGh2O9Rjog/bHTq8ofIShdng==}
+ plimit-lit@1.6.1:
+ resolution: {integrity: sha512-B7+VDyb8Tl6oMJT9oSO2CW8XC/T4UcJGrwOVoNGwOQsQYhlpfajmrMj5xeejqaASq3V/EqThyOeATEOMuSEXiA==}
+ engines: {node: '>=12'}
- postcss@8.4.26:
- resolution: {integrity: sha512-jrXHFF8iTloAenySjM/ob3gSj7pCu0Ji49hnjqzsgSRa50hkWCKD0HQ+gMNJkW38jBI68MpAAg7ZWwHwX8NMMw==}
+ postcss@8.4.38:
+ resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==}
engines: {node: ^10 || ^12 || >=14}
process-nextick-args@2.0.1:
@@ -1152,9 +1037,6 @@ packages:
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
- pstree.remy@1.1.8:
- resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==}
-
q@1.5.1:
resolution: {integrity: sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==}
engines: {node: '>=0.6.0', teleport: '>=0.2.0'}
@@ -1163,8 +1045,9 @@ packages:
resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==}
engines: {node: '>=0.6'}
- queue-lit@1.5.0:
- resolution: {integrity: sha512-IslToJ4eiCEE9xwMzq3viOO5nH8sUWUCwoElrhNMozzr9IIt2qqvB4I+uHu/zJTQVqc9R5DFwok4ijNK1pU3fA==}
+ queue-lit@1.5.2:
+ resolution: {integrity: sha512-tLc36IOPeMAubu8BkW8YDBV+WyIgKlYU7zUNs0J5Vk9skSZ4JfGlPOqplP0aHdfv7HL0B2Pg6nwiq60Qc6M2Hw==}
+ engines: {node: '>=12'}
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
@@ -1187,6 +1070,13 @@ packages:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'}
+ regenerator-runtime@0.14.1:
+ resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
+
+ require-directory@2.1.1:
+ resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
+ engines: {node: '>=0.10.0'}
+
resolve-pkg-maps@1.0.0:
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
@@ -1197,6 +1087,9 @@ packages:
run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+ rxjs@7.8.1:
+ resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==}
+
safe-buffer@5.1.2:
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
@@ -1209,19 +1102,6 @@ packages:
safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
- semver@5.7.2:
- resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
- hasBin: true
-
- semver@7.0.0:
- resolution: {integrity: sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==}
- hasBin: true
-
- semver@7.5.4:
- resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==}
- engines: {node: '>=10'}
- hasBin: true
-
semver@7.6.2:
resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==}
engines: {node: '>=10'}
@@ -1235,31 +1115,46 @@ packages:
resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==}
engines: {node: '>= 0.8.0'}
+ set-function-length@1.2.2:
+ resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
+ engines: {node: '>= 0.4'}
+
setprototypeof@1.2.0:
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
- sharp@0.33.3:
- resolution: {integrity: sha512-vHUeXJU1UvlO/BNwTpT0x/r53WkLUVxrmb5JTgW92fdFCFk0ispLMAeu/jPO2vjkXM1fYUi3K7/qcLF47pwM1A==}
- engines: {libvips: '>=8.15.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ shell-quote@1.8.1:
+ resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==}
- side-channel@1.0.4:
- resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
-
- simple-swizzle@0.2.2:
- resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
-
- simple-update-notifier@1.1.0:
- resolution: {integrity: sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==}
- engines: {node: '>=8.10.0'}
+ side-channel@1.0.6:
+ resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==}
+ engines: {node: '>= 0.4'}
slash@3.0.0:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'}
- source-map-js@1.0.2:
- resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
+ socket.io-adapter@2.5.4:
+ resolution: {integrity: sha512-wDNHGXGewWAjQPt3pyeYBtpWSq9cLE5UW1ZUPL/2eGK9jtse/FpXib7epSTsz0Q0m+6sg6Y4KtcFTlah1bdOVg==}
+
+ socket.io-client@4.7.5:
+ resolution: {integrity: sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==}
+ engines: {node: '>=10.0.0'}
+
+ socket.io-parser@4.2.4:
+ resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==}
+ engines: {node: '>=10.0.0'}
+
+ socket.io@4.7.5:
+ resolution: {integrity: sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==}
+ engines: {node: '>=10.2.0'}
+
+ source-map-js@1.2.0:
+ resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==}
engines: {node: '>=0.10.0'}
+ spawn-command@0.0.2:
+ resolution: {integrity: sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==}
+
statuses@2.0.1:
resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
engines: {node: '>= 0.8'}
@@ -1268,12 +1163,24 @@ packages:
resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
engines: {node: '>=10.0.0'}
+ string-width@4.2.3:
+ resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
+ engines: {node: '>=8'}
+
string_decoder@1.1.1:
resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
- supports-color@5.5.0:
- resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
- engines: {node: '>=4'}
+ strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+
+ supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+
+ supports-color@8.1.1:
+ resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
+ engines: {node: '>=10'}
to-fast-properties@2.0.0:
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
@@ -1287,19 +1194,19 @@ packages:
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
engines: {node: '>=0.6'}
- touch@3.1.0:
- resolution: {integrity: sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==}
+ tree-kill@1.2.2:
+ resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
hasBin: true
- tsc-alias@1.8.9:
- resolution: {integrity: sha512-Bkxu+LlUp/VG2qkcXGmj9wBkJuJID0mEC9t+bZaEbl9kyk/QJX6uo8/+z8DxTqUoqKPcbSApO2Ep42bsIVm9DA==}
+ tsc-alias@1.8.10:
+ resolution: {integrity: sha512-Ibv4KAWfFkFdKJxnWfVtdOmB0Zi1RJVxcbPGiCDsFpCQSsmpWyuzHG3rQyI5YkobWwxFPEyQfu1hdo4qLG2zPw==}
hasBin: true
tslib@2.6.2:
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
- tsx@4.10.1:
- resolution: {integrity: sha512-G+CcyTOopwhuI81FU+KpzGN5UBhHgGEDlGt8mHAXKxv8pDGr6WI7hI7aRjTRol5WzFVsSNuzl3ekCZ0eLIJlEQ==}
+ tsx@4.10.5:
+ resolution: {integrity: sha512-twDSbf7Gtea4I2copqovUiNTEDrT8XNFXsuHpfGbdpW/z9ZW4fTghzzhAG0WfrCuJmJiOEY1nLIjq4u3oujRWQ==}
engines: {node: '>=18.0.0'}
hasBin: true
@@ -1315,9 +1222,6 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
- undefsafe@2.0.5:
- resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==}
-
undici-types@5.26.5:
resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
@@ -1353,33 +1257,61 @@ packages:
vue@3.3.4:
resolution: {integrity: sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==}
+ wrap-ansi@7.0.0:
+ resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
+ engines: {node: '>=10'}
+
+ ws@8.11.0:
+ resolution: {integrity: sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==}
+ engines: {node: '>=10.0.0'}
+ peerDependencies:
+ bufferutil: ^4.0.1
+ utf-8-validate: ^5.0.2
+ peerDependenciesMeta:
+ bufferutil:
+ optional: true
+ utf-8-validate:
+ optional: true
+
+ xmlhttprequest-ssl@2.0.0:
+ resolution: {integrity: sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==}
+ engines: {node: '>=0.4.0'}
+
xtend@4.0.2:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
engines: {node: '>=0.4'}
- yallist@4.0.0:
- resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
+ y18n@5.0.8:
+ resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
+ engines: {node: '>=10'}
+
+ yargs-parser@21.1.1:
+ resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
+ engines: {node: '>=12'}
+
+ yargs@17.7.2:
+ resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
+ engines: {node: '>=12'}
snapshots:
- '@babel/helper-string-parser@7.22.5': {}
+ '@babel/helper-string-parser@7.24.1': {}
- '@babel/helper-validator-identifier@7.22.5': {}
+ '@babel/helper-validator-identifier@7.24.5': {}
- '@babel/parser@7.22.7':
+ '@babel/parser@7.24.5':
dependencies:
- '@babel/types': 7.22.5
+ '@babel/types': 7.24.5
- '@babel/types@7.22.5':
+ '@babel/runtime@7.24.5':
dependencies:
- '@babel/helper-string-parser': 7.22.5
- '@babel/helper-validator-identifier': 7.22.5
- to-fast-properties: 2.0.0
+ regenerator-runtime: 0.14.1
- '@emnapi/runtime@1.1.1':
+ '@babel/types@7.24.5':
dependencies:
- tslib: 2.6.2
- optional: true
+ '@babel/helper-string-parser': 7.24.1
+ '@babel/helper-validator-identifier': 7.24.5
+ to-fast-properties: 2.0.0
'@esbuild/aix-ppc64@0.20.2':
optional: true
@@ -1450,90 +1382,15 @@ snapshots:
'@esbuild/win32-x64@0.20.2':
optional: true
- '@img/sharp-darwin-arm64@0.33.3':
- optionalDependencies:
- '@img/sharp-libvips-darwin-arm64': 1.0.2
- optional: true
-
- '@img/sharp-darwin-x64@0.33.3':
- optionalDependencies:
- '@img/sharp-libvips-darwin-x64': 1.0.2
- optional: true
-
- '@img/sharp-libvips-darwin-arm64@1.0.2':
- optional: true
-
- '@img/sharp-libvips-darwin-x64@1.0.2':
- optional: true
-
- '@img/sharp-libvips-linux-arm64@1.0.2':
- optional: true
-
- '@img/sharp-libvips-linux-arm@1.0.2':
- optional: true
-
- '@img/sharp-libvips-linux-s390x@1.0.2':
- optional: true
-
- '@img/sharp-libvips-linux-x64@1.0.2':
- optional: true
-
- '@img/sharp-libvips-linuxmusl-arm64@1.0.2':
- optional: true
-
- '@img/sharp-libvips-linuxmusl-x64@1.0.2':
- optional: true
-
- '@img/sharp-linux-arm64@0.33.3':
- optionalDependencies:
- '@img/sharp-libvips-linux-arm64': 1.0.2
- optional: true
-
- '@img/sharp-linux-arm@0.33.3':
- optionalDependencies:
- '@img/sharp-libvips-linux-arm': 1.0.2
- optional: true
-
- '@img/sharp-linux-s390x@0.33.3':
- optionalDependencies:
- '@img/sharp-libvips-linux-s390x': 1.0.2
- optional: true
-
- '@img/sharp-linux-x64@0.33.3':
- optionalDependencies:
- '@img/sharp-libvips-linux-x64': 1.0.2
- optional: true
-
- '@img/sharp-linuxmusl-arm64@0.33.3':
- optionalDependencies:
- '@img/sharp-libvips-linuxmusl-arm64': 1.0.2
- optional: true
-
- '@img/sharp-linuxmusl-x64@0.33.3':
- optionalDependencies:
- '@img/sharp-libvips-linuxmusl-x64': 1.0.2
- optional: true
-
- '@img/sharp-wasm32@0.33.3':
- dependencies:
- '@emnapi/runtime': 1.1.1
- optional: true
-
- '@img/sharp-win32-ia32@0.33.3':
- optional: true
-
- '@img/sharp-win32-x64@0.33.3':
- optional: true
-
'@jridgewell/sourcemap-codec@1.4.15': {}
- '@messageformat/core@3.2.0':
+ '@messageformat/core@3.3.0':
dependencies:
'@messageformat/date-skeleton': 1.0.1
'@messageformat/number-skeleton': 1.2.0
'@messageformat/parser': 5.1.0
'@messageformat/runtime': 3.0.1
- make-plural: 7.3.0
+ make-plural: 7.4.0
safe-identifier: 0.4.2
'@messageformat/date-skeleton@1.0.1': {}
@@ -1546,7 +1403,7 @@ snapshots:
'@messageformat/runtime@3.0.1':
dependencies:
- make-plural: 7.3.0
+ make-plural: 7.4.0
'@nodelib/fs.scandir@2.1.5':
dependencies:
@@ -1558,122 +1415,125 @@ snapshots:
'@nodelib/fs.walk@1.2.8':
dependencies:
'@nodelib/fs.scandir': 2.1.5
- fastq: 1.15.0
+ fastq: 1.17.1
- '@sentry-internal/tracing@7.114.0':
+ '@sentry-internal/tracing@7.116.0':
dependencies:
- '@sentry/core': 7.114.0
- '@sentry/types': 7.114.0
- '@sentry/utils': 7.114.0
+ '@sentry/core': 7.116.0
+ '@sentry/types': 7.116.0
+ '@sentry/utils': 7.116.0
- '@sentry/core@7.114.0':
+ '@sentry/core@7.116.0':
dependencies:
- '@sentry/types': 7.114.0
- '@sentry/utils': 7.114.0
+ '@sentry/types': 7.116.0
+ '@sentry/utils': 7.116.0
- '@sentry/integrations@7.114.0':
+ '@sentry/integrations@7.116.0':
dependencies:
- '@sentry/core': 7.114.0
- '@sentry/types': 7.114.0
- '@sentry/utils': 7.114.0
+ '@sentry/core': 7.116.0
+ '@sentry/types': 7.116.0
+ '@sentry/utils': 7.116.0
localforage: 1.10.0
- '@sentry/node@7.114.0':
+ '@sentry/node@7.116.0':
dependencies:
- '@sentry-internal/tracing': 7.114.0
- '@sentry/core': 7.114.0
- '@sentry/integrations': 7.114.0
- '@sentry/types': 7.114.0
- '@sentry/utils': 7.114.0
+ '@sentry-internal/tracing': 7.116.0
+ '@sentry/core': 7.116.0
+ '@sentry/integrations': 7.116.0
+ '@sentry/types': 7.116.0
+ '@sentry/utils': 7.116.0
- '@sentry/types@7.114.0': {}
+ '@sentry/types@7.116.0': {}
- '@sentry/utils@7.114.0':
+ '@sentry/utils@7.116.0':
dependencies:
- '@sentry/types': 7.114.0
+ '@sentry/types': 7.116.0
- '@types/body-parser@1.19.5':
+ '@socket.io/admin-ui@0.5.1(socket.io@4.7.5)':
dependencies:
- '@types/connect': 3.4.35
- '@types/node': 16.18.38
+ '@types/bcryptjs': 2.4.6
+ bcryptjs: 2.4.3
+ debug: 4.3.4
+ socket.io: 4.7.5
+ transitivePeerDependencies:
+ - supports-color
- '@types/busboy@1.5.4':
- dependencies:
- '@types/node': 16.18.38
+ '@socket.io/component-emitter@3.1.2': {}
- '@types/connect@3.4.35':
+ '@types/bcryptjs@2.4.6': {}
+
+ '@types/body-parser@1.19.5':
dependencies:
- '@types/node': 16.18.38
+ '@types/connect': 3.4.38
+ '@types/node': 18.19.33
- '@types/cookie-parser@1.4.7':
+ '@types/connect@3.4.38':
dependencies:
- '@types/express': 4.17.21
+ '@types/node': 18.19.33
'@types/cookie@0.3.3': {}
+ '@types/cookie@0.4.1': {}
+
'@types/cors@2.8.17':
dependencies:
- '@types/node': 16.18.38
+ '@types/node': 18.19.33
- '@types/express-serve-static-core@4.17.35':
+ '@types/express-serve-static-core@4.19.0':
dependencies:
- '@types/node': 16.18.38
- '@types/qs': 6.9.7
- '@types/range-parser': 1.2.4
- '@types/send': 0.17.1
+ '@types/node': 18.19.33
+ '@types/qs': 6.9.15
+ '@types/range-parser': 1.2.7
+ '@types/send': 0.17.4
'@types/express@4.17.21':
dependencies:
'@types/body-parser': 1.19.5
- '@types/express-serve-static-core': 4.17.35
- '@types/qs': 6.9.7
- '@types/serve-static': 1.15.2
+ '@types/express-serve-static-core': 4.19.0
+ '@types/qs': 6.9.15
+ '@types/serve-static': 1.15.7
- '@types/http-errors@2.0.1': {}
+ '@types/http-errors@2.0.4': {}
'@types/i18n@0.13.12': {}
'@types/jsonwebtoken@9.0.6':
dependencies:
- '@types/node': 16.18.38
-
- '@types/mime@1.3.2': {}
+ '@types/node': 18.19.33
- '@types/mime@3.0.1': {}
+ '@types/mime@1.3.5': {}
'@types/multer@1.4.11':
dependencies:
'@types/express': 4.17.21
- '@types/node@16.18.38': {}
-
'@types/node@18.19.33':
dependencies:
undici-types: 5.26.5
- '@types/qs@6.9.7': {}
+ '@types/qs@6.9.15': {}
- '@types/range-parser@1.2.4': {}
+ '@types/range-parser@1.2.7': {}
- '@types/send@0.17.1':
+ '@types/send@0.17.4':
dependencies:
- '@types/mime': 1.3.2
- '@types/node': 16.18.38
+ '@types/mime': 1.3.5
+ '@types/node': 18.19.33
- '@types/serve-static@1.15.2':
+ '@types/serve-static@1.15.7':
dependencies:
- '@types/http-errors': 2.0.1
- '@types/mime': 3.0.1
- '@types/node': 16.18.38
+ '@types/http-errors': 2.0.4
+ '@types/node': 18.19.33
+ '@types/send': 0.17.4
'@types/web-bluetooth@0.0.20': {}
'@vue/compiler-core@3.3.4':
dependencies:
- '@babel/parser': 7.22.7
+ '@babel/parser': 7.24.5
'@vue/shared': 3.3.4
estree-walker: 2.0.2
- source-map-js: 1.0.2
+ source-map-js: 1.2.0
'@vue/compiler-dom@3.3.4':
dependencies:
@@ -1682,16 +1542,16 @@ snapshots:
'@vue/compiler-sfc@3.3.4':
dependencies:
- '@babel/parser': 7.22.7
+ '@babel/parser': 7.24.5
'@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.1
- postcss: 8.4.26
- source-map-js: 1.0.2
+ magic-string: 0.30.10
+ postcss: 8.4.38
+ source-map-js: 1.2.0
'@vue/compiler-ssr@3.3.4':
dependencies:
@@ -1700,11 +1560,11 @@ snapshots:
'@vue/reactivity-transform@3.3.4':
dependencies:
- '@babel/parser': 7.22.7
+ '@babel/parser': 7.24.5
'@vue/compiler-core': 3.3.4
'@vue/shared': 3.3.4
estree-walker: 2.0.2
- magic-string: 0.30.1
+ magic-string: 0.30.10
'@vue/reactivity@3.3.4':
dependencies:
@@ -1719,7 +1579,7 @@ snapshots:
dependencies:
'@vue/runtime-core': 3.3.4
'@vue/shared': 3.3.4
- csstype: 3.1.2
+ csstype: 3.1.3
'@vue/server-renderer@3.3.4(vue@3.3.4)':
dependencies:
@@ -1739,13 +1599,13 @@ snapshots:
- '@vue/composition-api'
- vue
- '@vueuse/integrations@10.9.0(axios@1.6.8)(universal-cookie@4.0.4)(vue@3.3.4)':
+ '@vueuse/integrations@10.9.0(axios@1.7.0)(universal-cookie@4.0.4)(vue@3.3.4)':
dependencies:
'@vueuse/core': 10.9.0(vue@3.3.4)
'@vueuse/shared': 10.9.0(vue@3.3.4)
vue-demi: 0.14.7(vue@3.3.4)
optionalDependencies:
- axios: 1.6.8
+ axios: 1.7.0
universal-cookie: 4.0.4
transitivePeerDependencies:
- '@vue/composition-api'
@@ -1760,13 +1620,17 @@ snapshots:
- '@vue/composition-api'
- vue
- abbrev@1.1.1: {}
-
accepts@1.3.8:
dependencies:
mime-types: 2.1.35
negotiator: 0.6.3
+ ansi-regex@5.0.1: {}
+
+ ansi-styles@4.3.0:
+ dependencies:
+ color-convert: 2.0.1
+
anymatch@3.1.3:
dependencies:
normalize-path: 3.0.0
@@ -1782,13 +1646,13 @@ snapshots:
axios@1.6.0:
dependencies:
- follow-redirects: 1.15.2
+ follow-redirects: 1.15.6
form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies:
- debug
- axios@1.6.8:
+ axios@1.7.0:
dependencies:
follow-redirects: 1.15.6
form-data: 4.0.0
@@ -1796,9 +1660,11 @@ snapshots:
transitivePeerDependencies:
- debug
- balanced-match@1.0.2: {}
+ base64id@2.0.0: {}
- binary-extensions@2.2.0: {}
+ bcryptjs@2.4.3: {}
+
+ binary-extensions@2.3.0: {}
body-parser@1.20.2:
dependencies:
@@ -1819,11 +1685,6 @@ snapshots:
boolean@3.2.0: {}
- brace-expansion@1.1.11:
- dependencies:
- balanced-match: 1.0.2
- concat-map: 0.0.1
-
braces@3.0.2:
dependencies:
fill-range: 7.0.1
@@ -1838,12 +1699,20 @@ snapshots:
bytes@3.1.2: {}
- call-bind@1.0.2:
+ call-bind@1.0.7:
dependencies:
- function-bind: 1.1.1
- get-intrinsic: 1.2.1
+ es-define-property: 1.0.0
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+ get-intrinsic: 1.2.4
+ set-function-length: 1.2.2
- chokidar@3.5.3:
+ chalk@4.1.2:
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+
+ chokidar@3.6.0:
dependencies:
anymatch: 3.1.3
braces: 3.0.2
@@ -1853,16 +1722,22 @@ snapshots:
normalize-path: 3.0.0
readdirp: 3.6.0
optionalDependencies:
- fsevents: 2.3.2
+ fsevents: 2.3.3
- cloudinary-core@2.13.0(lodash@4.17.21):
+ cliui@8.0.1:
+ dependencies:
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+ wrap-ansi: 7.0.0
+
+ cloudinary-core@2.13.1(lodash@4.17.21):
dependencies:
lodash: 4.17.21
cloudinary@1.41.3:
dependencies:
- cloudinary-core: 2.13.0(lodash@4.17.21)
- core-js: 3.31.1
+ cloudinary-core: 2.13.1(lodash@4.17.21)
+ core-js: 3.37.1
lodash: 4.17.21
q: 1.5.1
@@ -1872,24 +1747,12 @@ snapshots:
color-name@1.1.4: {}
- color-string@1.9.1:
- dependencies:
- color-name: 1.1.4
- simple-swizzle: 0.2.2
-
- color@4.2.3:
- dependencies:
- color-convert: 2.0.1
- color-string: 1.9.1
-
combined-stream@1.0.8:
dependencies:
delayed-stream: 1.0.0
commander@9.5.0: {}
- concat-map@0.0.1: {}
-
concat-stream@1.6.2:
dependencies:
buffer-from: 1.1.2
@@ -1897,26 +1760,31 @@ snapshots:
readable-stream: 2.3.8
typedarray: 0.0.6
+ concurrently@8.2.2:
+ dependencies:
+ chalk: 4.1.2
+ date-fns: 2.30.0
+ lodash: 4.17.21
+ rxjs: 7.8.1
+ shell-quote: 1.8.1
+ spawn-command: 0.0.2
+ supports-color: 8.1.1
+ tree-kill: 1.2.2
+ yargs: 17.7.2
+
content-disposition@0.5.4:
dependencies:
safe-buffer: 5.2.1
content-type@1.0.5: {}
- cookie-parser@1.4.6:
- dependencies:
- cookie: 0.4.1
- cookie-signature: 1.0.6
-
cookie-signature@1.0.6: {}
- cookie@0.4.1: {}
-
cookie@0.4.2: {}
cookie@0.6.0: {}
- core-js@3.31.1: {}
+ core-js@3.37.1: {}
core-util-is@1.0.3: {}
@@ -1925,46 +1793,85 @@ snapshots:
object-assign: 4.1.1
vary: 1.1.2
- csstype@3.1.2: {}
+ csstype@3.1.3: {}
- debug@2.6.9:
+ date-fns@2.30.0:
dependencies:
- ms: 2.0.0
+ '@babel/runtime': 7.24.5
- debug@3.2.7(supports-color@5.5.0):
+ debug@2.6.9:
dependencies:
- ms: 2.1.3
- optionalDependencies:
- supports-color: 5.5.0
+ ms: 2.0.0
debug@4.3.4:
dependencies:
ms: 2.1.2
+ define-data-property@1.1.4:
+ dependencies:
+ es-define-property: 1.0.0
+ es-errors: 1.3.0
+ gopd: 1.0.1
+
delayed-stream@1.0.0: {}
depd@2.0.0: {}
destroy@1.2.0: {}
- detect-libc@2.0.3: {}
-
dir-glob@3.0.1:
dependencies:
path-type: 4.0.0
dotenv@16.4.5: {}
- ducksmanager@0.0.51: {}
-
ecdsa-sig-formatter@1.0.11:
dependencies:
safe-buffer: 5.2.1
ee-first@1.1.1: {}
+ emoji-regex@8.0.0: {}
+
encodeurl@1.0.2: {}
+ engine.io-client@6.5.3:
+ dependencies:
+ '@socket.io/component-emitter': 3.1.2
+ debug: 4.3.4
+ engine.io-parser: 5.2.2
+ ws: 8.11.0
+ xmlhttprequest-ssl: 2.0.0
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ engine.io-parser@5.2.2: {}
+
+ engine.io@6.5.4:
+ dependencies:
+ '@types/cookie': 0.4.1
+ '@types/cors': 2.8.17
+ '@types/node': 18.19.33
+ accepts: 1.3.8
+ base64id: 2.0.0
+ cookie: 0.4.2
+ cors: 2.8.5
+ debug: 4.3.4
+ engine.io-parser: 5.2.2
+ ws: 8.11.0
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ es-define-property@1.0.0:
+ dependencies:
+ get-intrinsic: 1.2.4
+
+ es-errors@1.3.0: {}
+
esbuild@0.20.2:
optionalDependencies:
'@esbuild/aix-ppc64': 0.20.2
@@ -1991,16 +1898,14 @@ snapshots:
'@esbuild/win32-ia32': 0.20.2
'@esbuild/win32-x64': 0.20.2
+ escalade@3.1.2: {}
+
escape-html@1.0.3: {}
estree-walker@2.0.2: {}
etag@1.8.1: {}
- express-file-routing@3.0.3(express@4.19.2):
- dependencies:
- express: 4.19.2
-
express@4.19.2:
dependencies:
accepts: 1.3.8
@@ -2037,7 +1942,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
- fast-glob@3.3.0:
+ fast-glob@3.3.2:
dependencies:
'@nodelib/fs.stat': 2.0.5
'@nodelib/fs.walk': 1.2.8
@@ -2049,7 +1954,7 @@ snapshots:
dependencies:
boolean: 3.2.0
- fastq@1.15.0:
+ fastq@1.17.1:
dependencies:
reusify: 1.0.4
@@ -2069,8 +1974,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- follow-redirects@1.15.2: {}
-
follow-redirects@1.15.6: {}
form-data@4.0.0:
@@ -2083,20 +1986,20 @@ snapshots:
fresh@0.5.2: {}
- fsevents@2.3.2:
- optional: true
-
fsevents@2.3.3:
optional: true
- function-bind@1.1.1: {}
+ function-bind@1.1.2: {}
+
+ get-caller-file@2.0.5: {}
- get-intrinsic@1.2.1:
+ get-intrinsic@1.2.4:
dependencies:
- function-bind: 1.1.1
- has: 1.0.3
- has-proto: 1.0.1
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+ has-proto: 1.0.3
has-symbols: 1.0.3
+ hasown: 2.0.2
get-tsconfig@4.7.5:
dependencies:
@@ -2110,20 +2013,28 @@ snapshots:
dependencies:
array-union: 2.1.0
dir-glob: 3.0.1
- fast-glob: 3.3.0
- ignore: 5.2.4
+ fast-glob: 3.3.2
+ ignore: 5.3.1
merge2: 1.4.1
slash: 3.0.0
- has-flag@3.0.0: {}
+ gopd@1.0.1:
+ dependencies:
+ get-intrinsic: 1.2.4
+
+ has-flag@4.0.0: {}
+
+ has-property-descriptors@1.0.2:
+ dependencies:
+ es-define-property: 1.0.0
- has-proto@1.0.1: {}
+ has-proto@1.0.3: {}
has-symbols@1.0.3: {}
- has@1.0.3:
+ hasown@2.0.2:
dependencies:
- function-bind: 1.1.1
+ function-bind: 1.1.2
http-errors@2.0.0:
dependencies:
@@ -2135,10 +2046,10 @@ snapshots:
i18n@0.15.1:
dependencies:
- '@messageformat/core': 3.2.0
+ '@messageformat/core': 3.3.0
debug: 4.3.4
fast-printf: 1.6.9
- make-plural: 7.3.0
+ make-plural: 7.4.0
math-interval-parser: 2.0.1
mustache: 4.2.0
transitivePeerDependencies:
@@ -2148,9 +2059,7 @@ snapshots:
dependencies:
safer-buffer: 2.1.2
- ignore-by-default@1.0.1: {}
-
- ignore@5.2.4: {}
+ ignore@5.3.1: {}
image-size@1.1.1:
dependencies:
@@ -2162,14 +2071,14 @@ snapshots:
ipaddr.js@1.9.1: {}
- is-arrayish@0.3.2: {}
-
is-binary-path@2.1.0:
dependencies:
- binary-extensions: 2.2.0
+ binary-extensions: 2.3.0
is-extglob@2.1.1: {}
+ is-fullwidth-code-point@3.0.0: {}
+
is-glob@4.0.3:
dependencies:
is-extglob: 2.1.1
@@ -2189,7 +2098,7 @@ snapshots:
lodash.isstring: 4.0.1
lodash.once: 4.1.1
ms: 2.1.3
- semver: 7.5.4
+ semver: 7.6.2
jwa@1.4.1:
dependencies:
@@ -2226,15 +2135,11 @@ snapshots:
lodash@4.17.21: {}
- lru-cache@6.0.0:
- dependencies:
- yallist: 4.0.0
-
- magic-string@0.30.1:
+ magic-string@0.30.10:
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
- make-plural@7.3.0: {}
+ make-plural@7.4.0: {}
math-interval-parser@2.0.1: {}
@@ -2259,10 +2164,6 @@ snapshots:
mime@1.6.0: {}
- minimatch@3.1.2:
- dependencies:
- brace-expansion: 1.1.11
-
minimist@1.2.8: {}
mkdirp@0.5.6:
@@ -2291,7 +2192,7 @@ snapshots:
mylas@2.1.13: {}
- nanoid@3.3.6: {}
+ nanoid@3.3.7: {}
negotiator@0.6.3: {}
@@ -2301,28 +2202,11 @@ snapshots:
transitivePeerDependencies:
- debug
- nodemon@2.0.22:
- dependencies:
- chokidar: 3.5.3
- debug: 3.2.7(supports-color@5.5.0)
- ignore-by-default: 1.0.1
- minimatch: 3.1.2
- pstree.remy: 1.1.8
- semver: 5.7.2
- simple-update-notifier: 1.1.0
- supports-color: 5.5.0
- touch: 3.1.0
- undefsafe: 2.0.5
-
- nopt@1.0.10:
- dependencies:
- abbrev: 1.1.1
-
normalize-path@3.0.0: {}
object-assign@4.1.1: {}
- object-inspect@1.12.3: {}
+ object-inspect@1.13.1: {}
on-finished@2.4.1:
dependencies:
@@ -2334,19 +2218,19 @@ snapshots:
path-type@4.0.0: {}
- picocolors@1.0.0: {}
+ picocolors@1.0.1: {}
picomatch@2.3.1: {}
- plimit-lit@1.5.0:
+ plimit-lit@1.6.1:
dependencies:
- queue-lit: 1.5.0
+ queue-lit: 1.5.2
- postcss@8.4.26:
+ postcss@8.4.38:
dependencies:
- nanoid: 3.3.6
- picocolors: 1.0.0
- source-map-js: 1.0.2
+ nanoid: 3.3.7
+ picocolors: 1.0.1
+ source-map-js: 1.2.0
process-nextick-args@2.0.1: {}
@@ -2357,15 +2241,13 @@ snapshots:
proxy-from-env@1.1.0: {}
- pstree.remy@1.1.8: {}
-
q@1.5.1: {}
qs@6.11.0:
dependencies:
- side-channel: 1.0.4
+ side-channel: 1.0.6
- queue-lit@1.5.0: {}
+ queue-lit@1.5.2: {}
queue-microtask@1.2.3: {}
@@ -2396,6 +2278,10 @@ snapshots:
dependencies:
picomatch: 2.3.1
+ regenerator-runtime@0.14.1: {}
+
+ require-directory@2.1.1: {}
+
resolve-pkg-maps@1.0.0: {}
reusify@1.0.4: {}
@@ -2404,6 +2290,10 @@ snapshots:
dependencies:
queue-microtask: 1.2.3
+ rxjs@7.8.1:
+ dependencies:
+ tslib: 2.6.2
+
safe-buffer@5.1.2: {}
safe-buffer@5.2.1: {}
@@ -2412,14 +2302,6 @@ snapshots:
safer-buffer@2.1.2: {}
- semver@5.7.2: {}
-
- semver@7.0.0: {}
-
- semver@7.5.4:
- dependencies:
- lru-cache: 6.0.0
-
semver@7.6.2: {}
send@0.18.0:
@@ -2449,63 +2331,98 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ set-function-length@1.2.2:
+ dependencies:
+ define-data-property: 1.1.4
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+ get-intrinsic: 1.2.4
+ gopd: 1.0.1
+ has-property-descriptors: 1.0.2
+
setprototypeof@1.2.0: {}
- sharp@0.33.3:
+ shell-quote@1.8.1: {}
+
+ side-channel@1.0.6:
dependencies:
- color: 4.2.3
- detect-libc: 2.0.3
- semver: 7.6.2
- optionalDependencies:
- '@img/sharp-darwin-arm64': 0.33.3
- '@img/sharp-darwin-x64': 0.33.3
- '@img/sharp-libvips-darwin-arm64': 1.0.2
- '@img/sharp-libvips-darwin-x64': 1.0.2
- '@img/sharp-libvips-linux-arm': 1.0.2
- '@img/sharp-libvips-linux-arm64': 1.0.2
- '@img/sharp-libvips-linux-s390x': 1.0.2
- '@img/sharp-libvips-linux-x64': 1.0.2
- '@img/sharp-libvips-linuxmusl-arm64': 1.0.2
- '@img/sharp-libvips-linuxmusl-x64': 1.0.2
- '@img/sharp-linux-arm': 0.33.3
- '@img/sharp-linux-arm64': 0.33.3
- '@img/sharp-linux-s390x': 0.33.3
- '@img/sharp-linux-x64': 0.33.3
- '@img/sharp-linuxmusl-arm64': 0.33.3
- '@img/sharp-linuxmusl-x64': 0.33.3
- '@img/sharp-wasm32': 0.33.3
- '@img/sharp-win32-ia32': 0.33.3
- '@img/sharp-win32-x64': 0.33.3
-
- side-channel@1.0.4:
- dependencies:
- call-bind: 1.0.2
- get-intrinsic: 1.2.1
- object-inspect: 1.12.3
-
- simple-swizzle@0.2.2:
- dependencies:
- is-arrayish: 0.3.2
-
- simple-update-notifier@1.1.0:
- dependencies:
- semver: 7.0.0
+ call-bind: 1.0.7
+ es-errors: 1.3.0
+ get-intrinsic: 1.2.4
+ object-inspect: 1.13.1
slash@3.0.0: {}
- source-map-js@1.0.2: {}
+ socket.io-adapter@2.5.4:
+ dependencies:
+ debug: 4.3.4
+ ws: 8.11.0
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ socket.io-client@4.7.5:
+ dependencies:
+ '@socket.io/component-emitter': 3.1.2
+ debug: 4.3.4
+ engine.io-client: 6.5.3
+ socket.io-parser: 4.2.4
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ socket.io-parser@4.2.4:
+ dependencies:
+ '@socket.io/component-emitter': 3.1.2
+ debug: 4.3.4
+ transitivePeerDependencies:
+ - supports-color
+
+ socket.io@4.7.5:
+ dependencies:
+ accepts: 1.3.8
+ base64id: 2.0.0
+ cors: 2.8.5
+ debug: 4.3.4
+ engine.io: 6.5.4
+ socket.io-adapter: 2.5.4
+ socket.io-parser: 4.2.4
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ source-map-js@1.2.0: {}
+
+ spawn-command@0.0.2: {}
statuses@2.0.1: {}
streamsearch@1.1.0: {}
+ string-width@4.2.3:
+ dependencies:
+ emoji-regex: 8.0.0
+ is-fullwidth-code-point: 3.0.0
+ strip-ansi: 6.0.1
+
string_decoder@1.1.1:
dependencies:
safe-buffer: 5.1.2
- supports-color@5.5.0:
+ strip-ansi@6.0.1:
+ dependencies:
+ ansi-regex: 5.0.1
+
+ supports-color@7.2.0:
+ dependencies:
+ has-flag: 4.0.0
+
+ supports-color@8.1.1:
dependencies:
- has-flag: 3.0.0
+ has-flag: 4.0.0
to-fast-properties@2.0.0: {}
@@ -2515,23 +2432,20 @@ snapshots:
toidentifier@1.0.1: {}
- touch@3.1.0:
- dependencies:
- nopt: 1.0.10
+ tree-kill@1.2.2: {}
- tsc-alias@1.8.9:
+ tsc-alias@1.8.10:
dependencies:
- chokidar: 3.5.3
+ chokidar: 3.6.0
commander: 9.5.0
globby: 11.1.0
mylas: 2.1.13
normalize-path: 3.0.0
- plimit-lit: 1.5.0
+ plimit-lit: 1.6.1
- tslib@2.6.2:
- optional: true
+ tslib@2.6.2: {}
- tsx@4.10.1:
+ tsx@4.10.5:
dependencies:
esbuild: 0.20.2
get-tsconfig: 4.7.5
@@ -2547,8 +2461,6 @@ snapshots:
typescript@5.4.5: {}
- undefsafe@2.0.5: {}
-
undici-types@5.26.5: {}
universal-cookie@4.0.4:
@@ -2576,6 +2488,28 @@ snapshots:
'@vue/server-renderer': 3.3.4(vue@3.3.4)
'@vue/shared': 3.3.4
+ wrap-ansi@7.0.0:
+ dependencies:
+ ansi-styles: 4.3.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+
+ ws@8.11.0: {}
+
+ xmlhttprequest-ssl@2.0.0: {}
+
xtend@4.0.2: {}
- yallist@4.0.0: {}
+ y18n@5.0.8: {}
+
+ yargs-parser@21.1.1: {}
+
+ yargs@17.7.2:
+ dependencies:
+ cliui: 8.0.1
+ escalade: 3.1.2
+ 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
diff --git a/api/routes/_express-call.ts b/api/routes/_express-call.ts
deleted file mode 100644
index 696698ef..00000000
--- a/api/routes/_express-call.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { Busboy } from "busboy";
-import { Request, Response } from "express";
-
-export type ExpressCall<
- T extends {
- resBody?: object;
- params?: object;
- reqBody?: object;
- query?: object;
- },
-> = [
- Request & {
- busboy: Busboy;
- },
-
- Response,
-];
diff --git a/api/routes/fs/base64.ts b/api/routes/fs/base64.ts
deleted file mode 100644
index d2f396fe..00000000
--- a/api/routes/fs/base64.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import axios from "axios";
-import sizeOf from "image-size";
-
-import { ExpressCall } from "~routes/_express-call";
-
-export const get = async (
- ...[req, res]: ExpressCall<{
- resBody: {
- dimensions: { width: number; height: number };
- base64: string;
- url: string;
- };
- query: { targetUrl: string };
- }>
-) => {
- const targetUrl = req.query.targetUrl;
- const url = targetUrl.startsWith("https://res.cloudinary.com")
- ? targetUrl
- : `${process.env.VITE_EDGES_URL!}/${targetUrl}`;
-
- const response = await axios.get(url);
- if (response.status === 200) {
- try {
- const buffer = Buffer.from(response.data);
- const dimensions = sizeOf(buffer) as { width: number; height: number };
- const base64 = `data:${
- response.headers["Content-Type"]
- };base64,${buffer.toString()}`;
- return res.json({ dimensions, base64, url });
- } catch (e) {
- console.error(`${targetUrl} : ${e as string}`);
- res.writeHead(404);
- return res.end();
- }
- }
-};
diff --git a/api/routes/fs/browse/:imageType/:country/:magazine.ts b/api/routes/fs/browse/:imageType/:country/:magazine.ts
deleted file mode 100644
index a3dc54ef..00000000
--- a/api/routes/fs/browse/:imageType/:country/:magazine.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import fs from "fs";
-
-import { ExpressCall } from "~routes/_express-call";
-
-export const get = (
- ...[req, res]: ExpressCall<{
- params: {
- imageType: "elements" | "photos";
- country: string;
- magazine: string;
- };
- resBody: string[];
- }>
-) => {
- const { country, imageType, magazine } = req.params;
- if (
- !/^(elements)|(photos)$/.test(imageType) ||
- !/^[a-z]+$/.test(country) ||
- !/^[-A-Z0-9]+$/.test(magazine)
- ) {
- res.writeHead(400);
- return res.end();
- }
- try {
- return res.json(
- fs
- .readdirSync(`${process.env.EDGES_PATH!}/${country}/${imageType}`)
- .filter((item) =>
- new RegExp(`(?:^|[. ])${magazine}(?:[. ]|$)`).test(item),
- ),
- );
- } catch (e) {
- return res.json([]);
- }
-};
diff --git a/api/routes/fs/browseEdges.ts b/api/routes/fs/browseEdges.ts
deleted file mode 100644
index 7e88ac98..00000000
--- a/api/routes/fs/browseEdges.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import fs from "fs";
-import path from "path";
-
-import { ExpressCall } from "~routes/_express-call";
-
-const edgesPath = `${process.env.PWD!}/../${process.env.EDGES_PATH!}`;
-const REGEX_IS_BROWSABLE_FILE = /^[-+(). _A-Za-z\d]+$/;
-const REGEX_IS_SVG_FILE = /^_?.+\.svg$/;
-export const get = (
- ...[, res]: ExpressCall<{
- resBody: {
- current: { filename: string; mtime: string }[];
- published: { filename: string; mtime: string }[];
- };
- }>
-) => {
- const findInDir = (dir: string) => {
- try {
- const files = fs.readdirSync(dir);
- const filteredFiles = files.filter((file) =>
- REGEX_IS_BROWSABLE_FILE.test(file),
- );
- for (const file of filteredFiles) {
- const filePath = path.join(dir, file);
- if (!file.includes(".")) {
- findInDir(filePath);
- } else if (REGEX_IS_SVG_FILE.test(file)) {
- const edgeStatus = file.startsWith("_") ? "current" : "published";
- fileList[edgeStatus].push({
- filename: filePath.replace(/.+\/edges\//, ""),
- mtime: fs.statSync(filePath).mtime.toISOString(),
- });
- }
- }
- } catch (e) {
- console.error(e);
- }
- };
-
- const fileList = {
- current: [] as { filename: string; mtime: string }[],
- published: [] as { filename: string; mtime: string }[],
- };
- findInDir(edgesPath);
- return res.json(fileList);
-};
diff --git a/api/routes/fs/generateDefaultEdge.ts b/api/routes/fs/generateDefaultEdge.ts
deleted file mode 100644
index a8b68197..00000000
--- a/api/routes/fs/generateDefaultEdge.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import fs from "fs";
-import sharp from "sharp";
-
-import { ExpressCall } from "~routes/_express-call";
-// eslint-disable-next-line max-len
-const REGEX_EDGE_URL =
- /^edges\/(?[^/]+)\/gen\/_?(?[^.]+)\.(?[^.]+)\.(?[^?]+)?(?:\?.+)?$/;
-
-const corsHeaders = {
- "Access-Control-Allow-Origin": "*",
- "Access-Control-Allow-Credentials": "true",
- "Access-Control-Allow-Methods": "GET, OPTIONS",
- "Access-Control-Allow-Headers":
- "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With," +
- "If-Modified-Since,Cache-Control,Content-Type,x-dm-user,x-dm-pass",
-};
-export const get = (
- ...[req, res]: ExpressCall<{
- resBody: {
- current: string[];
- published: string[];
- };
- }>
-) => {
- const input = req.url.replace(/^\//, "");
- let text;
- const match = input.match(REGEX_EDGE_URL);
- if (match) {
- const { countryCode, magazineCode, issueNumber, extension } = match.groups!;
-
- if (countryCode && extension !== "png") {
- res.writeHead(404, corsHeaders);
- res.end("");
- return;
- }
- text = `${countryCode}/${magazineCode} ${issueNumber}`;
- } else {
- text = input;
- }
-
- const content = Buffer.from(
- fs
- .readFileSync("assets/default.svg")
- .toString()
- .replace("My text", decodeURIComponent(text)),
- "utf8",
- );
- sharp(content).toBuffer((error, buffer) => {
- if (error) {
- res.writeHead(500, corsHeaders);
- return res.end(`Error : ${JSON.stringify({ error })}`);
- }
- res.writeHead(200, { ...corsHeaders, "Content-Type": "image/png" });
- return res.end(buffer);
- });
-};
-
-export const options = (
- ...[, res]: ExpressCall<{
- resBody: {
- current: string[];
- published: string[];
- };
- }>
-) => {
- res.writeHead(200, corsHeaders);
- return res.end();
-};
diff --git a/api/routes/fs/save.ts b/api/routes/fs/save.ts
deleted file mode 100644
index 006ff7c0..00000000
--- a/api/routes/fs/save.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-import fs from "fs";
-import path from "path";
-import sharp from "sharp";
-
-import { getSvgPath } from "~/_utils";
-import {
- PUT__edgecreator__publish__$country__$magazine__$issuenumber,
- PUT__edgecreator__submit,
-} from "~dm_types/routes";
-import { ExpressCall } from "~routes/_express-call";
-import { ExportPaths } from "~types/ExportPaths";
-import { ModelContributor } from "~types/ModelContributor";
-
-import { call, createAxios } from "../../axios-helper";
-
-const dmApi = createAxios(process.env.VITE_DM_API_URL!);
-// const edgesPath = `${process.env.PWD}/../${process.env.EDGES_PATH!}`;
-
-export const post = async (
- ...[req, res]: ExpressCall<{
- resBody: { paths: ExportPaths; isNew: boolean };
- reqBody: {
- runExport: boolean;
- runSubmit: boolean;
- country: string;
- magazine: string;
- issuenumber: string;
- contributors: ModelContributor[];
- content: string;
- };
- }>
-) => {
- const {
- runExport,
- runSubmit,
- country,
- magazine,
- issuenumber,
- contributors,
- content,
- } = req.body;
- const svgPath = getSvgPath(runExport, country, magazine, issuenumber);
-
- const publicationcode = `${country}/${magazine}`;
-
- fs.mkdirSync(path.dirname(svgPath), { recursive: true });
- fs.writeFileSync(svgPath, content);
- let paths: ExportPaths = { svgPath };
- if (runExport) {
- const pngPath = svgPath.replace(".svg", ".png");
- try {
- await sharp(svgPath).png().toFile(pngPath);
- } catch (error: unknown) {
- res.writeHead(500);
- return res.end({ error });
- }
-
- paths = { ...paths, pngPath };
-
- const designers = contributors
- .filter(({ contributionType }) => contributionType === "createur")
- .map(({ user }) => user.username);
-
- const photographers = contributors
- .filter(({ contributionType }) => contributionType === "photographe")
- .map(({ user }) => user.username);
-
- try {
- const { isNew } = (
- await call(
- dmApi,
- new PUT__edgecreator__publish__$country__$magazine__$issuenumber({
- params: { country, magazine, issuenumber },
- reqBody: {
- designers,
- photographers,
- },
- }),
- )
- ).data;
- try {
- fs.unlinkSync(getSvgPath(false, country, magazine, issuenumber));
- } catch (error) {
- if ((error as { code?: string }).code === "ENOENT") {
- console.log("No temporary SVG file to delete was found");
- } else {
- res.writeHead(500);
- return res.end({ error });
- }
- }
-
- return res.json({ paths, isNew });
- } catch (e) {
- res.writeHead(500);
- return res.end({ error: e });
- }
- } else {
- if (runSubmit) {
- try {
- await call(
- dmApi,
- new PUT__edgecreator__submit({
- reqBody: {
- publicationcode,
- issuenumber,
- },
- }),
- );
- } catch (error) {
- res.writeHead(500);
- return res.end({ error });
- }
- }
- return res.json({ paths, isNew: false });
- }
-};
diff --git a/api/routes/fs/text.ts b/api/routes/fs/text.ts
deleted file mode 100644
index 93a537b4..00000000
--- a/api/routes/fs/text.ts
+++ /dev/null
@@ -1,119 +0,0 @@
-import axios from "axios";
-import { v2 as cloudinary } from "cloudinary";
-
-import { ExpressCall } from "~routes/_express-call";
-
-const sessionHashes: Record = {};
-
-export const get = async (
- ...[req, res]: ExpressCall<{
- resBody:
- | {
- width: number;
- height: number;
- url: string;
- }
- | { error: string };
- query: {
- color: string;
- colorBackground: string;
- width: number;
- font: string;
- text: string;
- };
- }>
-) => {
- const { color, colorBackground, width, font, text } = req.query;
- const context: Record = {
- color,
- colorBackground,
- width,
- text,
- };
- await cloudinary.search
- .expression(
- `tags=${font} AND ${Object.keys(context)
- .reduce(
- (acc, key) => [...acc, `context.${key}="${String(context[key])}"`],
- [],
- )
- .join(" AND ")}`,
- )
- .execute()
- .then(
- ({
- resources,
- }: {
- resources: { width: number; height: number; secure_url: string }[];
- }) => {
- if (resources.length) {
- console.log(`Found an existing text`);
- const { width, height, secure_url: url } = resources[0];
- return res.json({ width, height, url });
- } else {
- console.log(`Found no existing text, generating text image...`);
- generateImage(req.query)
- .then(({ width, height, secure_url: url }) => {
- console.log(`Text image generated: url=${url}`);
- return res.json({ width, height, url });
- })
- .catch((response: Error) => {
- res.status(500).send({ error: response.message });
- });
- }
- },
- )
- .catch((e) => {
- console.error(e);
- });
-};
-
-const generateImage = (parameters: {
- color: string;
- colorBackground: string;
- width: number;
- font: string;
- text: string;
-}) =>
- axios
- .get(
- parameters.font.includes("/")
- ? process.env.FONT_BASE_URL!
- : `${process.env.FONT_PRODUCT_BASE_URL!}${parameters.font}`,
- )
- .then(({ data }: { data: string }) => {
- const sessionHashMatch = data.match(/(?<=font_rend.php\?id=)[a-z\d]+/);
- if (sessionHashMatch) {
- sessionHashes[parameters.font] = sessionHashMatch[0];
- } else {
- throw new Error(
- `No session ID found in URL ${process.env.FONT_BASE_URL!}${
- parameters.font
- }`,
- );
- }
- })
- .then(() =>
- cloudinary.uploader.upload(
- `${process.env.FONT_IMAGE_GEN_URL!}?${new URLSearchParams({
- id: sessionHashes[parameters.font],
- rbe: "fixed",
- rt: parameters.text,
- fg: parameters.color,
- bg: parameters.colorBackground,
- }).toString()}`,
- {
- folder: "texts",
- async: false,
- tags: [parameters.font],
- context: parameters,
- },
- (error, result) => {
- if (error) {
- console.error(error);
- }
- const { width, height, secure_url: url } = result!;
- return { width, height, url };
- },
- ),
- );
diff --git a/api/routes/fs/upload-base64.ts b/api/routes/fs/upload-base64.ts
deleted file mode 100644
index 295de977..00000000
--- a/api/routes/fs/upload-base64.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import { decode } from "node-base64-image";
-
-import { PUT__edgecreator__multiple_edge_photo__v2 } from "~dm_types/routes";
-import { ExpressCall } from "~routes/_express-call";
-import { getNextAvailableFile } from "~routes/_upload_utils";
-
-import { call, createAxios } from "../../axios-helper";
-const edgesPath: string = process.env.EDGES_PATH!;
-
-const dmApi = createAxios(process.env.VITE_DM_API_URL!);
-export const post = async (
- ...[req, res]: ExpressCall<{
- resBody: { fileName: string };
- reqBody: {
- data: string;
- country: string;
- magazine: string;
- issuenumber: string;
- };
- }>
-) => {
- const { country, issuenumber, magazine, data } = req.body;
- const path = `${edgesPath}/${country}/photos`;
- const tentativeFileName = `${magazine}.${issuenumber}.photo`;
- const fileName = getNextAvailableFile(
- `${path}/${tentativeFileName}`,
- "jpg",
- ).match(/\/([^/]+)$/)![1];
-
- await decode(data, {
- fname: `${path}/${fileName.replace(/.jpg$/, "")}`,
- ext: "jpg",
- });
-
- try {
- const publicationcode = `${country}/${magazine}`;
-
- await call(
- dmApi,
- new PUT__edgecreator__multiple_edge_photo__v2({
- reqBody: {
- publicationcode,
- issuenumber,
- },
- }),
- );
- } catch (e) {
- res.writeHead(500);
- return res.end(e);
- }
-
- res.writeHead(200, {
- Connection: "close",
- "Content-Type": "application/text",
- });
- return res.json({ fileName });
-};
diff --git a/api/routes/fs/upload.ts b/api/routes/fs/upload.ts
deleted file mode 100644
index 36feec45..00000000
--- a/api/routes/fs/upload.ts
+++ /dev/null
@@ -1,256 +0,0 @@
-import crypto from "crypto";
-import fs from "fs";
-import multer from "multer";
-import { dirname } from "path";
-
-import { getUserCredentials } from "~routes/_auth";
-import { ExpressCall } from "~routes/_express-call";
-import { getNextAvailableFile } from "~routes/_upload_utils";
-
-import { call, createAxios } from "../../axios-helper";
-const dmApi = createAxios(process.env.VITE_DM_API_URL!);
-import {
- GET__edgecreator__elements__images__$filename,
- GET__edgecreator__multiple_edge_photo__check_today_limit,
- GET__edgecreator__multiple_edge_photo__hash__$hash,
- PUT__edgecreator__multiple_edge_photo,
-} from "~dm_types/routes";
-
-const edgesPath: string = process.env.EDGES_PATH!;
-
-const upload = multer({
- dest: "/tmp/",
- limits: {
- fileSize: 3 * 1024 * 1024,
- files: 1,
- },
-});
-
-export const post = [
- upload.array("files"),
- async (
- ...[req, res]: ExpressCall<{
- resBody: { fileName: string }[];
- reqBody: {
- photo: boolean;
- multiple: boolean;
- edge: {
- country: string;
- magazine: string;
- issuenumber: string;
- };
- };
- }>
- ) => {
- const userCredentials = getUserCredentials(req.user!);
-
- let allowedMimeTypes: string[];
-
- const {
- photo: isEdgePhoto,
- multiple: isMultipleEdgePhoto,
- edge,
- } = req.body;
- const files = req.files! as Express.Multer.File[];
- const targetFilesnames = [];
- for (const {
- originalname: filename,
- mimetype: mimetype,
- path: temporaryPath,
- } of files) {
- allowedMimeTypes = isEdgePhoto
- ? ["image/jpg", "image/jpeg"]
- : ["image/png"];
-
- const targetFilename = getTargetFilename(
- filename,
- isMultipleEdgePhoto,
- edge,
- isEdgePhoto,
- );
- try {
- const { hash } = await validateUpload(
- mimetype,
- targetFilename,
- allowedMimeTypes,
- isEdgePhoto,
- userCredentials,
- edge,
- temporaryPath,
- );
- saveFile(temporaryPath, targetFilename);
- await storePhotoHash(targetFilename, hash);
- targetFilesnames.push(
- targetFilename.replace(
- process.env.EDGES_PATH!,
- process.env.VITE_EDGES_URL!,
- ),
- );
- } catch (e: unknown) {
- res.writeHead(400, {
- Connection: "close",
- "Content-Type": "application/json",
- });
- res.end((e as Error).message);
- }
- }
- res.writeHead(200, { Connection: "close" });
- return res.json(targetFilesnames.map((fileName) => ({ fileName })));
- },
-];
-
-const getTargetFilename = (
- filename: string,
- isMultipleEdgePhoto: boolean,
- edge: {
- country: string;
- magazine: string;
- issuenumber: string;
- },
- isEdgePhoto: boolean,
-) => {
- filename = filename.normalize("NFD").replace(/[\u0300-\u036F]/g, "");
-
- if (isMultipleEdgePhoto) {
- return getNextAvailableFile(
- `${edgesPath}/tranches_multiples/photo.multiple`,
- "jpg",
- );
- } else {
- const { country, issuenumber, magazine } = edge;
- if (isEdgePhoto) {
- return getNextAvailableFile(
- `${edgesPath}/${country}/photos/${magazine}.${issuenumber}.photo`,
- "jpg",
- );
- } else {
- return `${edgesPath}/${country}/elements/${
- filename.includes(magazine) ? filename : `${magazine}.${filename}`
- }`;
- }
- }
-};
-
-const validateUpload = async (
- mimetype: string,
- filename: string,
- allowedMimeTypes: string[],
- isEdgePhoto: boolean,
- userCredentials: Record,
- edge: {
- country: string;
- magazine: string;
- issuenumber: string;
- },
- filePath: string,
-): Promise<{ hash: string }> => {
- if (!allowedMimeTypes.includes(mimetype)) {
- throw new Error(
- JSON.stringify({
- error:
- "Invalid file type: {mimetype}, the following types are allowed: {allowedMimeTypes}",
- placeholders: { mimetype, allowedMimeTypes },
- }),
- );
- }
- const { hash } = readContentsAndCalculateHash(filePath);
- if (isEdgePhoto) {
- if (await hasReachedDailyUploadLimit()) {
- throw new Error(
- JSON.stringify({
- error: "You have reached your daily upload limit",
- }),
- );
- }
- if (await hasAlreadySentPhoto(hash)) {
- throw new Error(
- JSON.stringify({ error: "You have already sent this photo" }),
- );
- }
- } else {
- // await readFile(filestream);
- const otherElementUses = await getFilenameUsagesInOtherModels(
- filename,
- edge,
- );
- if (fs.existsSync(filename) && otherElementUses.length) {
- throw new Error(
- JSON.stringify({
- error:
- "This file name is already used in other models, please rename your file",
- placeholders: {
- otherElementUses: JSON.stringify(otherElementUses),
- },
- }),
- );
- }
- }
- return { hash };
-};
-
-const hasReachedDailyUploadLimit = async () =>
- (
- await call(
- dmApi,
- new GET__edgecreator__multiple_edge_photo__check_today_limit(),
- )
- ).data.uploadedFilesToday.length > 10;
-
-const hasAlreadySentPhoto = async (hash: string) =>
- (
- await call(
- dmApi,
- new GET__edgecreator__multiple_edge_photo__hash__$hash({
- params: {
- hash,
- },
- }),
- )
- ).data !== undefined;
-
-const readContentsAndCalculateHash = (
- fileName: string,
-): { contents: Buffer; hash: string } => {
- const fileBuffer = fs.readFileSync(fileName);
- const hashSum = crypto.createHash("sha256");
- hashSum.update(fileBuffer);
-
- return { contents: fileBuffer, hash: hashSum.digest("hex") };
-};
-
-const getFilenameUsagesInOtherModels = async (
- filename: string,
- currentModel: { country: string; magazine: string; issuenumber: string },
-) =>
- (
- await call(
- dmApi,
- new GET__edgecreator__elements__images__$filename({
- params: {
- filename,
- },
- }),
- )
- ).data.filter(
- (otherUse) =>
- currentModel.country !== otherUse.country ||
- currentModel.magazine !== otherUse.magazine ||
- currentModel.issuenumber !== otherUse.issuenumberStart,
- );
-
-const saveFile = (temporaryPath: string, finalPath: string) => {
- fs.mkdirSync(dirname(finalPath), { recursive: true });
- fs.renameSync(temporaryPath, finalPath);
-};
-
-const storePhotoHash = async (filename: string, hash: string) => {
- await call(
- dmApi,
- new PUT__edgecreator__multiple_edge_photo({
- reqBody: {
- hash,
- filename,
- },
- }),
- );
-};
diff --git a/api/routes/_auth.ts b/api/services/_auth.ts
similarity index 68%
rename from api/routes/_auth.ts
rename to api/services/_auth.ts
index 5b44f7ad..0f5b08e3 100644
--- a/api/routes/_auth.ts
+++ b/api/services/_auth.ts
@@ -1,42 +1,19 @@
-import { Request, Response } from "express";
+import type { Request, Response } from "express";
import fs from "fs";
import jwt from "jsonwebtoken";
import { getSvgPath } from "~/_utils";
-import { User } from "~types/SessionUser";
+import { SessionUser } from "~dm-types/SessionUser";
-export const getUserCredentials = (user: User) => ({
+export const getUserCredentials = (user: SessionUser) => ({
"x-dm-user": user.username,
"x-dm-pass": user.hashedPassword,
});
-export const authenticateToken = (
- req: Request,
- res: Response,
- next: CallableFunction,
-) => {
- const authHeader = req.headers.authorization;
- const token = authHeader?.split(" ")?.[1];
-
- if (token == null) return res.sendStatus(401);
-
- jwt.verify(
- token,
- process.env.TOKEN_SECRET!,
- (err: unknown, user: unknown) => {
- if (err) {
- return res.sendStatus(401);
- }
- req.user = user as User;
- next();
- },
- );
-};
-
export const checkUserIsAdminForExportOrIsEditorForSaveOrIsFirstFileForModel = (
req: Request,
res: Response,
- next: CallableFunction,
+ next: CallableFunction
) => {
const { runExport, country, magazine, issuenumber } = req.body as {
runExport: boolean;
@@ -63,7 +40,7 @@ export const checkUserIsAdminForExportOrIsEditorForSaveOrIsFirstFileForModel = (
export const checkUserIsAdminOrEditor = (
req: Request,
res: Response,
- next: CallableFunction,
+ next: CallableFunction
) => {
const user = req.user;
if (!(user && ["Admin", "Edition"].includes(user.privileges.EdgeCreator))) {
@@ -75,7 +52,7 @@ export const checkUserIsAdminOrEditor = (
export const injectTokenIfValid = (
req: Request,
_: Response,
- next: CallableFunction,
+ next: CallableFunction
) => {
const authHeader = req.headers.authorization;
const token = authHeader?.split(" ")[1];
@@ -88,12 +65,12 @@ export const injectTokenIfValid = (
process.env.TOKEN_SECRET!,
(err: unknown, user: unknown) => {
if (user) {
- req.user = user as User;
+ req.user = user as SessionUser;
} else {
console.log(`Invalid token: ${err as string}`);
}
next();
- },
+ }
);
}
};
diff --git a/api/routes/_upload_utils.ts b/api/services/_upload_utils.ts
similarity index 100%
rename from api/routes/_upload_utils.ts
rename to api/services/_upload_utils.ts
diff --git a/api/services/browse/index.ts b/api/services/browse/index.ts
new file mode 100644
index 00000000..bc24ae7d
--- /dev/null
+++ b/api/services/browse/index.ts
@@ -0,0 +1,76 @@
+import { readdirSync, statSync } from "fs";
+import path from "path";
+import type { Namespace, Server } from "socket.io";
+
+import type Events from "./types";
+import { namespaceEndpoint } from "./types";
+const edgesPath = `${process.env.PWD!}/../${process.env.EDGES_PATH!}`;
+const REGEX_IS_BROWSABLE_FILE = /^[-+(). _A-Za-z\d]+$/;
+const REGEX_IS_SVG_FILE = /^_?.+\.svg$/;
+
+const findInDir = (dir: string) => {
+ const fileList = {
+ current: [] as { filename: string; mtime: string }[],
+ published: [] as { filename: string; mtime: string }[],
+ };
+ try {
+ const files = readdirSync(dir);
+ const filteredFiles = files.filter((file) =>
+ REGEX_IS_BROWSABLE_FILE.test(file),
+ );
+ for (const file of filteredFiles) {
+ const filePath = path.join(dir, file);
+ if (!file.includes(".")) {
+ findInDir(filePath);
+ } else if (REGEX_IS_SVG_FILE.test(file)) {
+ const edgeStatus = file.startsWith("_") ? "current" : "published";
+ fileList[edgeStatus].push({
+ filename: filePath.replace(/.+\/edges\//, ""),
+ mtime: statSync(filePath).mtime.toISOString(),
+ });
+ }
+ }
+ } catch (e) {
+ return Promise.reject(e);
+ }
+ return Promise.resolve(fileList);
+};
+
+export default (io: Server) => {
+ (io.of(namespaceEndpoint) as Namespace).on("connection", (socket) => {
+ console.log("connected to browse");
+
+ socket.on("listEdgeModels", async (callback) => {
+ findInDir(edgesPath)
+ .then((results) => callback({ results }))
+ .catch((errorDetails) =>
+ callback({
+ error: "Generic error",
+ errorDetails: errorDetails as string,
+ }),
+ );
+ });
+
+ socket.on("listEdgeParts", async (parameters, callback) => {
+ const { country, imageType, magazine } = parameters;
+ if (
+ !/^(elements)|(photos)$/.test(imageType) ||
+ !/^[a-z]+$/.test(country) ||
+ !/^[-A-Z0-9]+$/.test(magazine)
+ ) {
+ callback({ error: "Invalid parameters" });
+ }
+ try {
+ callback({
+ results: readdirSync(
+ `${process.env.EDGES_PATH!}/${country}/${imageType}`,
+ ).filter((item) =>
+ new RegExp(`(?:^|[. ])${magazine}(?:[. ]|$)`).test(item),
+ ),
+ });
+ } catch (e) {
+ callback({ results: [] });
+ }
+ });
+ });
+};
diff --git a/api/services/browse/types.ts b/api/services/browse/types.ts
new file mode 100644
index 00000000..81f60a93
--- /dev/null
+++ b/api/services/browse/types.ts
@@ -0,0 +1,36 @@
+import type { Errorable } from "~socket.io-services/types";
+
+export const namespaceEndpoint = "/save";
+export default abstract class {
+ static namespaceEndpoint = namespaceEndpoint;
+
+ abstract listEdgeModels: (
+ callback: (
+ value: Errorable<
+ {
+ results: {
+ current: { filename: string; mtime: string }[];
+ published: { filename: string; mtime: string }[];
+ };
+ },
+ "Generic error"
+ >,
+ ) => void,
+ ) => void;
+
+ abstract listEdgeParts: (
+ parameters: {
+ imageType: "elements" | "photos";
+ country: string;
+ magazine: string;
+ },
+ callback: (
+ value: Errorable<
+ {
+ results: string[];
+ },
+ "Generic error" | "Invalid parameters"
+ >,
+ ) => void,
+ ) => void;
+}
diff --git a/api/services/image-info/index.ts b/api/services/image-info/index.ts
new file mode 100644
index 00000000..6817aa58
--- /dev/null
+++ b/api/services/image-info/index.ts
@@ -0,0 +1,37 @@
+import axios from "axios";
+import sizeOf from "image-size";
+import type { Namespace, Server } from "socket.io";
+
+import type Events from "./types";
+import { namespaceEndpoint } from "./types";
+export default (io: Server) => {
+ (io.of(namespaceEndpoint) as Namespace).on("connection", (socket) => {
+ console.log("connected to text");
+
+ socket.on("getImageInfo", async (targetUrl, callback) => {
+ const url = targetUrl.startsWith("https://res.cloudinary.com")
+ ? targetUrl
+ : `${process.env.EDGES_URL!}/${targetUrl}`;
+
+ const response = await axios.get(url);
+ if (response.status === 200) {
+ try {
+ const buffer = Buffer.from(response.data);
+ const dimensions = sizeOf(buffer) as {
+ width: number;
+ height: number;
+ };
+ const base64 = `data:${
+ response.headers["Content-Type"]
+ };base64,${buffer.toString()}`;
+ callback({ results: { dimensions, base64, url } });
+ } catch (e) {
+ callback({
+ error: "Cloudinary error",
+ errorDetails: `${targetUrl} : ${e as string}`,
+ });
+ }
+ }
+ });
+ });
+};
diff --git a/api/services/image-info/types.ts b/api/services/image-info/types.ts
new file mode 100644
index 00000000..5ac3f5a1
--- /dev/null
+++ b/api/services/image-info/types.ts
@@ -0,0 +1,22 @@
+import type { Errorable } from "~socket.io-services/types";
+
+export const namespaceEndpoint = "/image-info";
+export default abstract class {
+ static namespaceEndpoint = namespaceEndpoint;
+
+ abstract getImageInfo: (
+ targetUrl: string,
+ callback: (
+ value: Errorable<
+ {
+ results: {
+ dimensions: { width: number; height: number };
+ base64: string;
+ url: string;
+ };
+ },
+ "Cloudinary error"
+ >,
+ ) => void,
+ ) => void;
+}
diff --git a/api/services/save/index.ts b/api/services/save/index.ts
new file mode 100644
index 00000000..b4bff8e1
--- /dev/null
+++ b/api/services/save/index.ts
@@ -0,0 +1,91 @@
+import { mkdirSync, unlinkSync, writeFileSync } from "fs";
+import path from "path";
+import type { Namespace } from "socket.io";
+import type { Server } from "socket.io";
+
+import { getSvgPath } from "~/_utils";
+import EdgeCreatorServices from "~dm-services/edgecreator/types";
+import { useSocket } from "~socket.io-client-services";
+import type { ExportPaths } from "~types/ExportPaths";
+
+import type Events from "./types";
+import { namespaceEndpoint } from "./types";
+import { exec } from "child_process";
+
+const socket = useSocket(process.env.DM_SOCKET_URL!);
+const { services: edgeCreatorServices } =
+ socket.addNamespace(
+ EdgeCreatorServices.namespaceEndpoint
+ );
+export default (io: Server) => {
+ (io.of(namespaceEndpoint) as Namespace).on("connection", (socket) => {
+ console.log("connected to save");
+
+ socket.on("saveEdge", async (parameters, callback) => {
+ const {
+ runExport,
+ runSubmit,
+ country,
+ magazine,
+ issuenumber,
+ contributors,
+ content,
+ } = parameters;
+ const svgPath = getSvgPath(runExport, country, magazine, issuenumber);
+
+ const publicationcode = `${country}/${magazine}`;
+
+ mkdirSync(path.dirname(svgPath), { recursive: true });
+ writeFileSync(svgPath, content);
+ let paths: ExportPaths = { svgPath };
+ if (runExport) {
+ const pngPath = svgPath.replace(".svg", ".png");
+
+ exec(`convert ${svgPath} ${pngPath}`);
+
+ paths = { ...paths, pngPath };
+
+ const designers = contributors
+ .filter(({ contributionType }) => contributionType === "createur")
+ .map(({ user }) => user.username);
+
+ const photographers = contributors
+ .filter(({ contributionType }) => contributionType === "photographe")
+ .map(({ user }) => user.username);
+
+ const publicationResult = await edgeCreatorServices.publishEdge({
+ publicationcode,
+ issuenumber,
+ designers,
+ photographers,
+ });
+ if (publicationResult.error) {
+ callback({
+ error: "Generic error",
+ errorDetails: publicationResult.errorDetails as string,
+ });
+ return;
+ }
+ try {
+ unlinkSync(getSvgPath(false, country, magazine, issuenumber));
+ } catch (errorDetails) {
+ if ((errorDetails as { code?: string }).code === "ENOENT") {
+ console.log("No temporary SVG file to delete was found");
+ } else {
+ callback({
+ error: "Generic error",
+ errorDetails: errorDetails as string,
+ });
+ }
+ }
+
+ callback({ results: { paths, isNew: publicationResult.isNew } });
+ } else {
+ if (runSubmit) {
+ await edgeCreatorServices.submitEdge(publicationcode, issuenumber);
+ }
+ callback({ results: { paths, isNew: false } });
+ }
+ });
+ });
+};
diff --git a/api/services/save/types.ts b/api/services/save/types.ts
new file mode 100644
index 00000000..0373596a
--- /dev/null
+++ b/api/services/save/types.ts
@@ -0,0 +1,28 @@
+import type { Errorable } from "~socket.io-services/types";
+import type { ExportPaths } from "~types/ExportPaths";
+import type { ModelContributor } from "~types/ModelContributor";
+
+export const namespaceEndpoint = "/save";
+export default abstract class {
+ static namespaceEndpoint = namespaceEndpoint;
+
+ abstract saveEdge: (
+ parameters: {
+ runExport: boolean;
+ runSubmit: boolean;
+ country: string;
+ magazine: string;
+ issuenumber: string;
+ contributors: ModelContributor[];
+ content: string;
+ },
+ callback: (
+ value: Errorable<
+ {
+ results: { paths: ExportPaths; isNew: boolean };
+ },
+ "Generic error"
+ >,
+ ) => void,
+ ) => void;
+}
diff --git a/api/services/text/index.ts b/api/services/text/index.ts
new file mode 100644
index 00000000..8007125f
--- /dev/null
+++ b/api/services/text/index.ts
@@ -0,0 +1,123 @@
+import axios from "axios";
+import { v2 as cloudinary } from "cloudinary";
+import type { Namespace, Server } from "socket.io";
+
+import type Events from "./types";
+import { namespaceEndpoint } from "./types";
+
+const sessionHashes: Record = {};
+
+const generateImage = (parameters: {
+ color: string;
+ colorBackground: string;
+ width: number;
+ font: string;
+ text: string;
+}) =>
+ axios
+ .get(
+ parameters.font.includes("/")
+ ? process.env.FONT_BASE_URL!
+ : `${process.env.FONT_PRODUCT_BASE_URL!}${parameters.font}`,
+ )
+ .then(({ data }: { data: string }) => {
+ const sessionHashMatch = data.match(/(?<=font_rend.php\?id=)[a-z\d]+/);
+ if (sessionHashMatch) {
+ sessionHashes[parameters.font] = sessionHashMatch[0];
+ } else {
+ throw new Error(
+ `No session ID found in URL ${process.env.FONT_BASE_URL!}${
+ parameters.font
+ }`,
+ );
+ }
+ })
+ .catch((response: Error) => {
+ return Promise.reject(response);
+ })
+ .then(() =>
+ cloudinary.uploader.upload(
+ `${process.env.FONT_IMAGE_GEN_URL!}?${new URLSearchParams({
+ id: sessionHashes[parameters.font],
+ rbe: "fixed",
+ rt: parameters.text,
+ fg: parameters.color,
+ bg: parameters.colorBackground,
+ }).toString()}`,
+ {
+ folder: "texts",
+ async: false,
+ tags: [parameters.font],
+ context: parameters,
+ },
+ (error, result) => {
+ if (error) {
+ console.error(error);
+ }
+ const { width, height, secure_url: url } = result!;
+ Promise.resolve({ width, height, url });
+ },
+ ),
+ );
+
+export default (io: Server) => {
+ (io.of(namespaceEndpoint) as Namespace).on("connection", (socket) => {
+ console.log("connected to text");
+
+ socket.on("getText", async (parameters, callback) => {
+ const { color, colorBackground, width, font, text } = parameters;
+ const context: Record = {
+ color,
+ colorBackground,
+ width,
+ text,
+ };
+ await cloudinary.search
+ .expression(
+ `tags=${font} AND ${Object.keys(context)
+ .reduce(
+ (acc, key) => [
+ ...acc,
+ `context.${key}="${String(context[key])}"`,
+ ],
+ [],
+ )
+ .join(" AND ")}`,
+ )
+ .execute()
+ .then(
+ ({
+ resources,
+ }: {
+ resources: {
+ width: number;
+ height: number;
+ secure_url: string;
+ }[];
+ }) => {
+ if (resources.length) {
+ console.log(`Found an existing text`);
+ const { width, height, secure_url: url } = resources[0];
+ callback({ results: { width, height, url } });
+ } else {
+ console.log(`Found no existing text, generating text image...`);
+ generateImage(parameters)
+ .then(({ width, height, secure_url: url }) => {
+ console.log(`Text image generated: url=${url}`);
+ callback({ results: { width, height, url } });
+ })
+ .catch((response: Error) => {
+ callback({
+ error: "Image generation error",
+ errorDetails: response.message,
+ });
+ });
+ }
+ },
+ )
+ .catch((e) => {
+ console.error(e);
+ });
+ });
+ });
+};
diff --git a/api/services/text/types.ts b/api/services/text/types.ts
new file mode 100644
index 00000000..c7163d77
--- /dev/null
+++ b/api/services/text/types.ts
@@ -0,0 +1,28 @@
+import type { Errorable } from "~socket.io-services/types";
+
+export const namespaceEndpoint = "/text";
+export default abstract class {
+ static namespaceEndpoint = namespaceEndpoint;
+
+ abstract getText: (
+ parameters: {
+ color: string;
+ colorBackground: string;
+ width: number;
+ font: string;
+ text: string;
+ },
+ callback: (
+ value: Errorable<
+ {
+ results: {
+ width: number;
+ height: number;
+ url: string;
+ };
+ },
+ "Image generation error"
+ >,
+ ) => void,
+ ) => void;
+}
diff --git a/api/services/upload/index.ts b/api/services/upload/index.ts
new file mode 100644
index 00000000..7ee9f7df
--- /dev/null
+++ b/api/services/upload/index.ts
@@ -0,0 +1,243 @@
+import crypto from "crypto";
+import type { Request, Response } from "express";
+import fs from "fs";
+import { decode } from "node-base64-image";
+import { dirname } from "path";
+import type { Namespace, Server } from "socket.io";
+
+import { getUserCredentials } from "~/services/_auth";
+import EdgeCreatorServices from "~dm-services/edgecreator/types";
+import { EventCalls, useSocket } from "~socket.io-client-services";
+
+import { getNextAvailableFile } from "../_upload_utils";
+import type Events from "./types";
+import { namespaceEndpoint } from "./types";
+
+const edgesPath: string = process.env.EDGES_PATH!;
+
+let edgeCreatorServices: EventCalls;
+
+export default (io: Server) => {
+ (io.of(namespaceEndpoint) as Namespace).on("connection", (socket) => {
+ const dmSocket = useSocket(process.env.DM_SOCKET_URL!);
+ ({ services: edgeCreatorServices } =
+ dmSocket.addNamespace(
+ EdgeCreatorServices.namespaceEndpoint
+ ));
+ console.log("connected to upload");
+
+ socket.on("uploadFromBase64", async (parameters, callback) => {
+ const { country, issuenumber, magazine, data } = parameters;
+ const path = `${edgesPath}/${country}/photos`;
+ const tentativeFileName = `${magazine}.${issuenumber}.photo`;
+ const fileName = getNextAvailableFile(
+ `${path}/${tentativeFileName}`,
+ "jpg"
+ ).match(/\/([^/]+)$/)![1];
+
+ await decode(data, {
+ fname: `${path}/${fileName.replace(/.jpg$/, "")}`,
+ ext: "jpg",
+ });
+
+ await edgeCreatorServices.sendNewEdgePhotoEmail(
+ `${country}/${magazine}`,
+ issuenumber
+ );
+
+ callback({ fileName });
+ });
+ });
+};
+
+export const upload = async (
+ req: Request<
+ Record,
+ {
+ photo: boolean;
+ multiple: boolean;
+ edge: {
+ country: string;
+ magazine: string;
+ issuenumber: string;
+ };
+ }
+ >,
+ res: Response
+) => {
+ const userCredentials = getUserCredentials(req.user!);
+
+ let allowedMimeTypes: string[];
+
+ const { photo: isEdgePhoto, multiple: isMultipleEdgePhoto, edge } = req.body;
+ const files = req.files! as Express.Multer.File[];
+ const targetFilesnames = [];
+ for (const {
+ originalname: filename,
+ mimetype: mimetype,
+ path: temporaryPath,
+ } of files) {
+ allowedMimeTypes = isEdgePhoto
+ ? ["image/jpg", "image/jpeg"]
+ : ["image/png"];
+
+ const targetFilename = getTargetFilename(
+ filename,
+ isMultipleEdgePhoto,
+ edge,
+ isEdgePhoto
+ );
+ try {
+ const { hash } = await validateUpload(
+ mimetype,
+ targetFilename,
+ allowedMimeTypes,
+ isEdgePhoto,
+ userCredentials,
+ edge,
+ temporaryPath
+ );
+ saveFile(temporaryPath, targetFilename);
+ await storePhotoHash(targetFilename, hash);
+ targetFilesnames.push(
+ targetFilename.replace(
+ process.env.EDGES_PATH!,
+ process.env.VITE_EDGES_URL!
+ )
+ );
+ } catch (e: unknown) {
+ res.writeHead(400, {
+ Connection: "close",
+ "Content-Type": "application/json",
+ });
+ res.end((e as Error).message);
+ }
+ }
+ res.writeHead(200, { Connection: "close" });
+ return res.json(targetFilesnames.map((fileName) => ({ fileName })));
+};
+
+const getTargetFilename = (
+ filename: string,
+ isMultipleEdgePhoto: boolean,
+ edge: {
+ country: string;
+ magazine: string;
+ issuenumber: string;
+ },
+ isEdgePhoto: boolean
+) => {
+ filename = filename.normalize("NFD").replace(/[\u0300-\u036F]/g, "");
+
+ if (isMultipleEdgePhoto) {
+ return getNextAvailableFile(
+ `${edgesPath}/tranches_multiples/photo.multiple`,
+ "jpg"
+ );
+ } else {
+ const { country, issuenumber, magazine } = edge;
+ if (isEdgePhoto) {
+ return getNextAvailableFile(
+ `${edgesPath}/${country}/photos/${magazine}.${issuenumber}.photo`,
+ "jpg"
+ );
+ } else {
+ return `${edgesPath}/${country}/elements/${
+ filename.includes(magazine) ? filename : `${magazine}.${filename}`
+ }`;
+ }
+ }
+};
+
+const validateUpload = async (
+ mimetype: string,
+ filename: string,
+ allowedMimeTypes: string[],
+ isEdgePhoto: boolean,
+ userCredentials: Record,
+ edge: {
+ country: string;
+ magazine: string;
+ issuenumber: string;
+ },
+ filePath: string
+): Promise<{ hash: string }> => {
+ if (!allowedMimeTypes.includes(mimetype)) {
+ throw new Error(
+ JSON.stringify({
+ error:
+ "Invalid file type: {mimetype}, the following types are allowed: {allowedMimeTypes}",
+ placeholders: { mimetype, allowedMimeTypes },
+ })
+ );
+ }
+ const { hash } = readContentsAndCalculateHash(filePath);
+ if (isEdgePhoto) {
+ if (await hasReachedDailyUploadLimit()) {
+ throw new Error(
+ JSON.stringify({
+ error: "You have reached your daily upload limit",
+ })
+ );
+ }
+ if (await hasAlreadySentPhoto(hash)) {
+ throw new Error(
+ JSON.stringify({ error: "You have already sent this photo" })
+ );
+ }
+ } else {
+ // await readFile(filestream);
+ const otherElementUses = await getFilenameUsagesInOtherModels(
+ filename,
+ edge
+ );
+ if (fs.existsSync(filename) && otherElementUses.length) {
+ throw new Error(
+ JSON.stringify({
+ error:
+ "This file name is already used in other models, please rename your file",
+ placeholders: {
+ otherElementUses: JSON.stringify(otherElementUses),
+ },
+ })
+ );
+ }
+ }
+ return { hash };
+};
+
+const hasReachedDailyUploadLimit = async () =>
+ (await edgeCreatorServices.checkTodayLimit()).uploadedFilesToday.length > 10;
+
+const hasAlreadySentPhoto = async (hash: string) =>
+ (await edgeCreatorServices.getImageByHash(hash)) === null;
+
+const readContentsAndCalculateHash = (
+ fileName: string
+): { contents: Buffer; hash: string } => {
+ const fileBuffer = fs.readFileSync(fileName);
+ const hashSum = crypto.createHash("sha256");
+ hashSum.update(fileBuffer);
+
+ return { contents: fileBuffer, hash: hashSum.digest("hex") };
+};
+
+const getFilenameUsagesInOtherModels = async (
+ filename: string,
+ currentModel: { country: string; magazine: string; issuenumber: string }
+) =>
+ (await edgeCreatorServices.getImagesFromFilename(filename)).filter(
+ (otherUse) =>
+ currentModel.country !== otherUse.country ||
+ currentModel.magazine !== otherUse.magazine ||
+ currentModel.issuenumber !== otherUse.issuenumberStart
+ );
+
+const saveFile = (temporaryPath: string, finalPath: string) => {
+ fs.mkdirSync(dirname(finalPath), { recursive: true });
+ fs.renameSync(temporaryPath, finalPath);
+};
+
+const storePhotoHash = async (filename: string, hash: string) => {
+ await edgeCreatorServices.createElementImage(hash, filename);
+};
diff --git a/api/services/upload/types.ts b/api/services/upload/types.ts
new file mode 100644
index 00000000..7fa97bfc
--- /dev/null
+++ b/api/services/upload/types.ts
@@ -0,0 +1,23 @@
+import type { Errorable } from "~socket.io-services/types";
+
+export const namespaceEndpoint = "/save";
+export default abstract class {
+ static namespaceEndpoint = namespaceEndpoint;
+
+ abstract uploadFromBase64: (
+ parameters: {
+ data: string;
+ country: string;
+ magazine: string;
+ issuenumber: string;
+ },
+ callback: (
+ value: Errorable<
+ {
+ fileName: string;
+ },
+ "Generic error"
+ >,
+ ) => void,
+ ) => void;
+}
diff --git a/api/tsconfig.json b/api/tsconfig.json
index fc48b799..504bee56 100644
--- a/api/tsconfig.json
+++ b/api/tsconfig.json
@@ -2,11 +2,10 @@
"compilerOptions": {
"baseUrl": ".",
"module": "ESNext",
- "target": "es2020",
- "lib": ["DOM", "ESNext"],
+ "target": "es2018",
+ "lib": ["ESNext"],
"strict": true,
- "jsx": "preserve",
- "esModuleInterop": true,
+ "esModuleInterop": true,
"skipLibCheck": true,
"moduleResolution": "node",
"resolveJsonModule": true,
@@ -15,13 +14,16 @@
"allowJs": true,
"forceConsistentCasingInFileNames": true,
"outDir": "./dist",
+ "preserveWatchOutput": true,
"paths": {
"~/*": ["./*"],
"~types/*": ["../types/*"],
- "~dm_types/*": ["./node_modules/ducksmanager/types/*"],
- "~prisma/*": ["./node_modules/ducksmanager/types/*"],
- "~prisma_clients/*": ["node_modules/ducksmanager/api/dist/prisma/*"],
- "~routes/*": ["./routes/*"]
+ "~dm-services/*": ["../../../packages/api/services/*"],
+ "~dm-types/*": ["../../../packages/types/*"],
+ "~prisma-clients": ["../../../packages/prisma-clients"],
+ "~prisma-clients/*": ["../../../packages/prisma-clients/*"],
+ "~socket.io-services/*": ["../../../packages/socket.io-services/*"],
+ "~socket.io-client-services": ["../../../packages/socket.io-client-services"]
}
},
"exclude": ["node_modules"],
diff --git a/api/tsconfig.prod.json b/api/tsconfig.prod.json
deleted file mode 100644
index 71c9fe02..00000000
--- a/api/tsconfig.prod.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
- "compilerOptions": {
- "baseUrl": ".",
- "module": "commonjs",
- "target": "es2018",
- "lib": [
- "DOM",
- "ESNext"
- ],
- "strict": true,
- "jsx": "preserve",
- "esModuleInterop": true,
- "skipLibCheck": true,
- "moduleResolution": "node",
- "resolveJsonModule": true,
- "noUnusedLocals": true,
- "strictNullChecks": true,
- "allowJs": true,
- "forceConsistentCasingInFileNames": true,
- "outDir": "./dist",
- "paths": {
- "~/*": [
- "*"
- ],
- "~types/*": [
- "../types/*"
- ],
- "~dm_types/*": [
- "./dm_types/*"
- ],
- "~prisma/*": [
- "./dm_types/*"
- ],
- "~prisma_clients/*": [
- "./prisma_clients/*"
- ],
- "~routes/*": [
- "./routes/*"
- ]
- }
- },
- "include": [
- "*.ts",
- "routes/**/*.ts",
- "dm_types/**/*.ts",
- "prisma_clients/*"
- ]
-}
\ No newline at end of file
diff --git a/auto-imports.d.ts b/auto-imports.d.ts
deleted file mode 100644
index 5a368798..00000000
--- a/auto-imports.d.ts
+++ /dev/null
@@ -1,932 +0,0 @@
-/* eslint-disable */
-/* prettier-ignore */
-// @ts-nocheck
-// noinspection JSUnusedGlobalSymbols
-// Generated by unplugin-auto-import
-export {}
-declare global {
- const $: typeof import('vue/macros')['$']
- const $$: typeof import('vue/macros')['$$']
- const $computed: typeof import('vue/macros')['$computed']
- const $customRef: typeof import('vue/macros')['$customRef']
- const $ref: typeof import('vue/macros')['$ref']
- const $shallowRef: typeof import('vue/macros')['$shallowRef']
- const $toRef: typeof import('vue/macros')['$toRef']
- const EffectScope: typeof import('vue')['EffectScope']
- const GET__fs__base64: typeof import('./types/routes')['GET__fs__base64']
- const GET__fs__browseEdges: typeof import('./types/routes')['GET__fs__browseEdges']
- const GET__fs__browse__$imageType__$country__$magazine: typeof import('./types/routes')['GET__fs__browse__$imageType__$country__$magazine']
- const GET__fs__generateDefaultEdge: typeof import('./types/routes')['GET__fs__generateDefaultEdge']
- const GET__fs__text: typeof import('./types/routes')['GET__fs__text']
- const POST__fs__save: typeof import('./types/routes')['POST__fs__save']
- const POST__fs__upload: typeof import('./types/routes')['POST__fs__upload']
- const POST__fs__upload_base64: typeof import('./types/routes')['POST__fs__upload_base64']
- const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
- const autoResetRef: typeof import('@vueuse/core')['autoResetRef']
- const availableLocales: typeof import('./src/composables/useLocales')['availableLocales']
- const computed: typeof import('vue')['computed']
- const computedAsync: typeof import('@vueuse/core')['computedAsync']
- const computedEager: typeof import('@vueuse/core')['computedEager']
- const computedInject: typeof import('@vueuse/core')['computedInject']
- const computedWithControl: typeof import('@vueuse/core')['computedWithControl']
- const controlledComputed: typeof import('@vueuse/core')['controlledComputed']
- const controlledRef: typeof import('@vueuse/core')['controlledRef']
- const createApp: typeof import('vue')['createApp']
- const createEventHook: typeof import('@vueuse/core')['createEventHook']
- const createGlobalState: typeof import('@vueuse/core')['createGlobalState']
- const createInjectionState: typeof import('@vueuse/core')['createInjectionState']
- const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn']
- const createReusableTemplate: typeof import('@vueuse/core')['createReusableTemplate']
- const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable']
- const createTemplatePromise: typeof import('@vueuse/core')['createTemplatePromise']
- const createUnrefFn: typeof import('@vueuse/core')['createUnrefFn']
- const customRef: typeof import('vue')['customRef']
- const debouncedRef: typeof import('@vueuse/core')['debouncedRef']
- const debouncedWatch: typeof import('@vueuse/core')['debouncedWatch']
- const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
- const defineComponent: typeof import('vue')['defineComponent']
- const eagerComputed: typeof import('@vueuse/core')['eagerComputed']
- const effectScope: typeof import('vue')['effectScope']
- const extendRef: typeof import('@vueuse/core')['extendRef']
- const getCurrentInstance: typeof import('vue')['getCurrentInstance']
- const getCurrentLocaleShortKey: typeof import('./src/composables/useLocales')['getCurrentLocaleShortKey']
- const getCurrentScope: typeof import('vue')['getCurrentScope']
- const h: typeof import('vue')['h']
- const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch']
- const inject: typeof import('vue')['inject']
- const isDefined: typeof import('@vueuse/core')['isDefined']
- const isProxy: typeof import('vue')['isProxy']
- const isReactive: typeof import('vue')['isReactive']
- const isReadonly: typeof import('vue')['isReadonly']
- const isRef: typeof import('vue')['isRef']
- const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable']
- const markRaw: typeof import('vue')['markRaw']
- const nextTick: typeof import('vue')['nextTick']
- const onActivated: typeof import('vue')['onActivated']
- const onBeforeMount: typeof import('vue')['onBeforeMount']
- const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']
- const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']
- const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
- const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
- const onClickOutside: typeof import('@vueuse/core')['onClickOutside']
- const onDeactivated: typeof import('vue')['onDeactivated']
- const onErrorCaptured: typeof import('vue')['onErrorCaptured']
- const onKeyStroke: typeof import('@vueuse/core')['onKeyStroke']
- const onLongPress: typeof import('@vueuse/core')['onLongPress']
- const onMounted: typeof import('vue')['onMounted']
- const onRenderTracked: typeof import('vue')['onRenderTracked']
- const onRenderTriggered: typeof import('vue')['onRenderTriggered']
- const onScopeDispose: typeof import('vue')['onScopeDispose']
- const onServerPrefetch: typeof import('vue')['onServerPrefetch']
- const onStartTyping: typeof import('@vueuse/core')['onStartTyping']
- const onUnmounted: typeof import('vue')['onUnmounted']
- const onUpdated: typeof import('vue')['onUpdated']
- const pausableWatch: typeof import('@vueuse/core')['pausableWatch']
- const provide: typeof import('vue')['provide']
- const reactify: typeof import('@vueuse/core')['reactify']
- const reactifyObject: typeof import('@vueuse/core')['reactifyObject']
- const reactive: typeof import('vue')['reactive']
- const reactiveComputed: typeof import('@vueuse/core')['reactiveComputed']
- const reactiveOmit: typeof import('@vueuse/core')['reactiveOmit']
- const reactivePick: typeof import('@vueuse/core')['reactivePick']
- const readonly: typeof import('vue')['readonly']
- const ref: typeof import('vue')['ref']
- const refAutoReset: typeof import('@vueuse/core')['refAutoReset']
- const refDebounced: typeof import('@vueuse/core')['refDebounced']
- const refDefault: typeof import('@vueuse/core')['refDefault']
- const refThrottled: typeof import('@vueuse/core')['refThrottled']
- const refWithControl: typeof import('@vueuse/core')['refWithControl']
- const resolveComponent: typeof import('vue')['resolveComponent']
- const resolveRef: typeof import('@vueuse/core')['resolveRef']
- const resolveUnref: typeof import('@vueuse/core')['resolveUnref']
- const shallowReactive: typeof import('vue')['shallowReactive']
- const shallowReadonly: typeof import('vue')['shallowReadonly']
- const shallowRef: typeof import('vue')['shallowRef']
- const syncRef: typeof import('@vueuse/core')['syncRef']
- const syncRefs: typeof import('@vueuse/core')['syncRefs']
- const templateRef: typeof import('@vueuse/core')['templateRef']
- const throttledRef: typeof import('@vueuse/core')['throttledRef']
- const throttledWatch: typeof import('@vueuse/core')['throttledWatch']
- const toRaw: typeof import('vue')['toRaw']
- const toReactive: typeof import('@vueuse/core')['toReactive']
- const toRef: typeof import('vue')['toRef']
- const toRefs: typeof import('vue')['toRefs']
- const toValue: typeof import('vue')['toValue']
- const triggerRef: typeof import('vue')['triggerRef']
- const tryOnBeforeMount: typeof import('@vueuse/core')['tryOnBeforeMount']
- const tryOnBeforeUnmount: typeof import('@vueuse/core')['tryOnBeforeUnmount']
- const tryOnMounted: typeof import('@vueuse/core')['tryOnMounted']
- const tryOnScopeDispose: typeof import('@vueuse/core')['tryOnScopeDispose']
- const tryOnUnmounted: typeof import('@vueuse/core')['tryOnUnmounted']
- const unref: typeof import('vue')['unref']
- const unrefElement: typeof import('@vueuse/core')['unrefElement']
- const until: typeof import('@vueuse/core')['until']
- const useActiveElement: typeof import('@vueuse/core')['useActiveElement']
- const useAnimate: typeof import('@vueuse/core')['useAnimate']
- const useArrayDifference: typeof import('@vueuse/core')['useArrayDifference']
- const useArrayEvery: typeof import('@vueuse/core')['useArrayEvery']
- const useArrayFilter: typeof import('@vueuse/core')['useArrayFilter']
- const useArrayFind: typeof import('@vueuse/core')['useArrayFind']
- const useArrayFindIndex: typeof import('@vueuse/core')['useArrayFindIndex']
- const useArrayFindLast: typeof import('@vueuse/core')['useArrayFindLast']
- const useArrayIncludes: typeof import('@vueuse/core')['useArrayIncludes']
- const useArrayJoin: typeof import('@vueuse/core')['useArrayJoin']
- const useArrayMap: typeof import('@vueuse/core')['useArrayMap']
- const useArrayReduce: typeof import('@vueuse/core')['useArrayReduce']
- const useArraySome: typeof import('@vueuse/core')['useArraySome']
- const useArrayUnique: typeof import('@vueuse/core')['useArrayUnique']
- const useAsyncQueue: typeof import('@vueuse/core')['useAsyncQueue']
- const useAsyncState: typeof import('@vueuse/core')['useAsyncState']
- const useAttrs: typeof import('vue')['useAttrs']
- const useBase64: typeof import('@vueuse/core')['useBase64']
- const useBase64Legacy: typeof import('./src/composables/useBase64Legacy')['default']
- const useBattery: typeof import('@vueuse/core')['useBattery']
- const useBluetooth: typeof import('@vueuse/core')['useBluetooth']
- const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints']
- const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel']
- const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation']
- const useCached: typeof import('@vueuse/core')['useCached']
- const useClipboard: typeof import('@vueuse/core')['useClipboard']
- const useCloned: typeof import('@vueuse/core')['useCloned']
- const useColorMode: typeof import('@vueuse/core')['useColorMode']
- const useCondition: typeof import('./src/composables/useCondition')['default']
- const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog']
- const useCounter: typeof import('@vueuse/core')['useCounter']
- const useCssModule: typeof import('vue')['useCssModule']
- const useCssVar: typeof import('@vueuse/core')['useCssVar']
- const useCssVars: typeof import('vue')['useCssVars']
- const useCurrentElement: typeof import('@vueuse/core')['useCurrentElement']
- const useCycleList: typeof import('@vueuse/core')['useCycleList']
- const useDark: typeof import('@vueuse/core')['useDark']
- const useDateFormat: typeof import('@vueuse/core')['useDateFormat']
- const useDebounce: typeof import('@vueuse/core')['useDebounce']
- const useDebounceFn: typeof import('@vueuse/core')['useDebounceFn']
- const useDebouncedRefHistory: typeof import('@vueuse/core')['useDebouncedRefHistory']
- const useDeviceMotion: typeof import('@vueuse/core')['useDeviceMotion']
- const useDeviceOrientation: typeof import('@vueuse/core')['useDeviceOrientation']
- const useDevicePixelRatio: typeof import('@vueuse/core')['useDevicePixelRatio']
- const useDevicesList: typeof import('@vueuse/core')['useDevicesList']
- const useDisplayMedia: typeof import('@vueuse/core')['useDisplayMedia']
- const useDocumentVisibility: typeof import('@vueuse/core')['useDocumentVisibility']
- const useDraggable: typeof import('@vueuse/core')['useDraggable']
- const useDropZone: typeof import('@vueuse/core')['useDropZone']
- const useElementBounding: typeof import('@vueuse/core')['useElementBounding']
- const useElementByPoint: typeof import('@vueuse/core')['useElementByPoint']
- const useElementHover: typeof import('@vueuse/core')['useElementHover']
- const useElementSize: typeof import('@vueuse/core')['useElementSize']
- const useElementVisibility: typeof import('@vueuse/core')['useElementVisibility']
- const useEventBus: typeof import('@vueuse/core')['useEventBus']
- const useEventListener: typeof import('@vueuse/core')['useEventListener']
- const useEventSource: typeof import('@vueuse/core')['useEventSource']
- const useEyeDropper: typeof import('@vueuse/core')['useEyeDropper']
- const useFavicon: typeof import('@vueuse/core')['useFavicon']
- const useFetch: typeof import('@vueuse/core')['useFetch']
- const useFileDialog: typeof import('@vueuse/core')['useFileDialog']
- const useFileSystemAccess: typeof import('@vueuse/core')['useFileSystemAccess']
- const useFocus: typeof import('@vueuse/core')['useFocus']
- const useFocusWithin: typeof import('@vueuse/core')['useFocusWithin']
- const useFps: typeof import('@vueuse/core')['useFps']
- const useFullscreen: typeof import('@vueuse/core')['useFullscreen']
- const useGamepad: typeof import('@vueuse/core')['useGamepad']
- const useGeolocation: typeof import('@vueuse/core')['useGeolocation']
- const useIdle: typeof import('@vueuse/core')['useIdle']
- const useImage: typeof import('@vueuse/core')['useImage']
- const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll']
- const useIntersectionObserver: typeof import('@vueuse/core')['useIntersectionObserver']
- const useInterval: typeof import('@vueuse/core')['useInterval']
- const useIntervalFn: typeof import('@vueuse/core')['useIntervalFn']
- const useKeyModifier: typeof import('@vueuse/core')['useKeyModifier']
- const useLastChanged: typeof import('@vueuse/core')['useLastChanged']
- const useLegacyDb: typeof import('./src/composables/useLegacyDb')['default']
- const useLink: typeof import('vue-router')['useLink']
- const useLocalStorage: typeof import('@vueuse/core')['useLocalStorage']
- const useMagicKeys: typeof import('@vueuse/core')['useMagicKeys']
- const useManualRefHistory: typeof import('@vueuse/core')['useManualRefHistory']
- const useMedal: typeof import('./src/composables/useMedal')['default']
- const useMediaControls: typeof import('@vueuse/core')['useMediaControls']
- const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery']
- const useMemoize: typeof import('@vueuse/core')['useMemoize']
- const useMemory: typeof import('@vueuse/core')['useMemory']
- const useModelLoad: typeof import('./src/composables/useModelLoad')['default']
- const useMounted: typeof import('@vueuse/core')['useMounted']
- const useMouse: typeof import('@vueuse/core')['useMouse']
- const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement']
- const useMousePressed: typeof import('@vueuse/core')['useMousePressed']
- const useMutationObserver: typeof import('@vueuse/core')['useMutationObserver']
- const useNavigatorLanguage: typeof import('@vueuse/core')['useNavigatorLanguage']
- const useNetwork: typeof import('@vueuse/core')['useNetwork']
- const useNow: typeof import('@vueuse/core')['useNow']
- const useObjectUrl: typeof import('@vueuse/core')['useObjectUrl']
- const useOffsetPagination: typeof import('@vueuse/core')['useOffsetPagination']
- const useOnline: typeof import('@vueuse/core')['useOnline']
- const usePageLeave: typeof import('@vueuse/core')['usePageLeave']
- const useParallax: typeof import('@vueuse/core')['useParallax']
- const useParentElement: typeof import('@vueuse/core')['useParentElement']
- const usePerformanceObserver: typeof import('@vueuse/core')['usePerformanceObserver']
- const usePermission: typeof import('@vueuse/core')['usePermission']
- const usePointer: typeof import('@vueuse/core')['usePointer']
- const usePointerLock: typeof import('@vueuse/core')['usePointerLock']
- const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe']
- const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme']
- const usePreferredContrast: typeof import('@vueuse/core')['usePreferredContrast']
- const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark']
- const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages']
- const usePreferredReducedMotion: typeof import('@vueuse/core')['usePreferredReducedMotion']
- const usePrevious: typeof import('@vueuse/core')['usePrevious']
- const useRafFn: typeof import('@vueuse/core')['useRafFn']
- const useRedirect: typeof import('./src/composables/useRedirect')['default']
- const useRefHistory: typeof import('@vueuse/core')['useRefHistory']
- const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver']
- const useRoute: typeof import('vue-router')['useRoute']
- const useRouter: typeof import('vue-router')['useRouter']
- const useSaveEdge: typeof import('./src/composables/useSaveEdge')['default']
- const useScreenOrientation: typeof import('@vueuse/core')['useScreenOrientation']
- const useScreenSafeArea: typeof import('@vueuse/core')['useScreenSafeArea']
- const useScriptTag: typeof import('@vueuse/core')['useScriptTag']
- const useScroll: typeof import('@vueuse/core')['useScroll']
- const useScrollLock: typeof import('@vueuse/core')['useScrollLock']
- const useSessionStorage: typeof import('@vueuse/core')['useSessionStorage']
- const useShare: typeof import('@vueuse/core')['useShare']
- const useSlots: typeof import('vue')['useSlots']
- const useSorted: typeof import('@vueuse/core')['useSorted']
- const useSpeechRecognition: typeof import('@vueuse/core')['useSpeechRecognition']
- const useSpeechSynthesis: typeof import('@vueuse/core')['useSpeechSynthesis']
- const useStepOptions: typeof import('./src/composables/useStepOptions')['useStepOptions']
- const useStepper: typeof import('@vueuse/core')['useStepper']
- const useStorage: typeof import('@vueuse/core')['useStorage']
- const useStorageAsync: typeof import('@vueuse/core')['useStorageAsync']
- const useStyleTag: typeof import('@vueuse/core')['useStyleTag']
- const useSupported: typeof import('@vueuse/core')['useSupported']
- const useSurroundingEdge: typeof import('./src/composables/useSurroundingEdge')['default']
- const useSvgUtils: typeof import('./src/composables/useSvgUtils')['default']
- const useSwipe: typeof import('@vueuse/core')['useSwipe']
- const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList']
- const useTextDirection: typeof import('@vueuse/core')['useTextDirection']
- const useTextSelection: typeof import('@vueuse/core')['useTextSelection']
- const useTextTemplate: typeof import('./src/composables/useTextTemplate')['default']
- const useTextareaAutosize: typeof import('@vueuse/core')['useTextareaAutosize']
- const useThrottle: typeof import('@vueuse/core')['useThrottle']
- const useThrottleFn: typeof import('@vueuse/core')['useThrottleFn']
- const useThrottledRefHistory: typeof import('@vueuse/core')['useThrottledRefHistory']
- const useTimeAgo: typeof import('@vueuse/core')['useTimeAgo']
- const useTimeout: typeof import('@vueuse/core')['useTimeout']
- const useTimeoutFn: typeof import('@vueuse/core')['useTimeoutFn']
- const useTimeoutPoll: typeof import('@vueuse/core')['useTimeoutPoll']
- const useTimestamp: typeof import('@vueuse/core')['useTimestamp']
- const useTitle: typeof import('@vueuse/core')['useTitle']
- const useToNumber: typeof import('@vueuse/core')['useToNumber']
- const useToString: typeof import('@vueuse/core')['useToString']
- const useToggle: typeof import('@vueuse/core')['useToggle']
- const useTransition: typeof import('@vueuse/core')['useTransition']
- const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams']
- const useUserMedia: typeof import('@vueuse/core')['useUserMedia']
- const useVModel: typeof import('@vueuse/core')['useVModel']
- const useVModels: typeof import('@vueuse/core')['useVModels']
- const useVibrate: typeof import('@vueuse/core')['useVibrate']
- const useVirtualList: typeof import('@vueuse/core')['useVirtualList']
- const useWakeLock: typeof import('@vueuse/core')['useWakeLock']
- const useWebNotification: typeof import('@vueuse/core')['useWebNotification']
- const useWebSocket: typeof import('@vueuse/core')['useWebSocket']
- const useWebWorker: typeof import('@vueuse/core')['useWebWorker']
- const useWebWorkerFn: typeof import('@vueuse/core')['useWebWorkerFn']
- const useWindowFocus: typeof import('@vueuse/core')['useWindowFocus']
- const useWindowScroll: typeof import('@vueuse/core')['useWindowScroll']
- const useWindowSize: typeof import('@vueuse/core')['useWindowSize']
- const watch: typeof import('vue')['watch']
- const watchArray: typeof import('@vueuse/core')['watchArray']
- const watchAtMost: typeof import('@vueuse/core')['watchAtMost']
- const watchDebounced: typeof import('@vueuse/core')['watchDebounced']
- const watchDeep: typeof import('@vueuse/core')['watchDeep']
- const watchEffect: typeof import('vue')['watchEffect']
- const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable']
- const watchImmediate: typeof import('@vueuse/core')['watchImmediate']
- const watchOnce: typeof import('@vueuse/core')['watchOnce']
- const watchPausable: typeof import('@vueuse/core')['watchPausable']
- const watchPostEffect: typeof import('vue')['watchPostEffect']
- const watchSyncEffect: typeof import('vue')['watchSyncEffect']
- const watchThrottled: typeof import('@vueuse/core')['watchThrottled']
- const watchTriggerable: typeof import('@vueuse/core')['watchTriggerable']
- const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter']
- const whenever: typeof import('@vueuse/core')['whenever']
-}
-// for type re-export
-declare global {
- // @ts-ignore
- export type { Component, ComponentPublicInstance, ComputedRef, InjectionKey, PropType, Ref, VNode } from 'vue'
-}
-// for vue template auto import
-import { UnwrapRef } from 'vue'
-declare module 'vue' {
- interface ComponentCustomProperties {
- readonly $$: UnwrapRef
- readonly $: UnwrapRef
- readonly $computed: UnwrapRef
- readonly $customRef: UnwrapRef
- readonly $ref: UnwrapRef
- readonly $shallowRef: UnwrapRef
- readonly $toRef: UnwrapRef
- readonly EffectScope: UnwrapRef
- readonly GET__fs__base64: UnwrapRef
- readonly GET__fs__browseEdges: UnwrapRef
- readonly GET__fs__browse__$imageType__$country__$magazine: UnwrapRef
- readonly GET__fs__generateDefaultEdge: UnwrapRef
- readonly GET__fs__text: UnwrapRef
- readonly POST__fs__save: UnwrapRef
- readonly POST__fs__upload: UnwrapRef
- readonly POST__fs__upload_base64: UnwrapRef
- readonly asyncComputed: UnwrapRef
- readonly autoResetRef: UnwrapRef
- readonly availableLocales: UnwrapRef
- readonly computed: UnwrapRef
- readonly computedAsync: UnwrapRef
- readonly computedEager: UnwrapRef
- readonly computedInject: UnwrapRef
- readonly computedWithControl: UnwrapRef
- readonly controlledComputed: UnwrapRef
- readonly controlledRef: UnwrapRef
- readonly createApp: UnwrapRef
- readonly createEventHook: UnwrapRef
- readonly createGlobalState: UnwrapRef
- readonly createInjectionState: UnwrapRef
- readonly createReactiveFn: UnwrapRef
- readonly createReusableTemplate: UnwrapRef
- readonly createSharedComposable: UnwrapRef
- readonly createTemplatePromise: UnwrapRef
- readonly createUnrefFn: UnwrapRef
- readonly customRef: UnwrapRef
- readonly debouncedRef: UnwrapRef
- readonly debouncedWatch: UnwrapRef
- readonly defineAsyncComponent: UnwrapRef
- readonly defineComponent: UnwrapRef
- readonly eagerComputed: UnwrapRef
- readonly effectScope: UnwrapRef
- readonly extendRef: UnwrapRef
- readonly getCurrentInstance: UnwrapRef
- readonly getCurrentLocaleShortKey: UnwrapRef
- readonly getCurrentScope: UnwrapRef
- readonly h: UnwrapRef
- readonly ignorableWatch: UnwrapRef
- readonly inject: UnwrapRef
- readonly isDefined: UnwrapRef
- readonly isProxy: UnwrapRef
- readonly isReactive: UnwrapRef
- readonly isReadonly: UnwrapRef
- readonly isRef: UnwrapRef
- readonly makeDestructurable: UnwrapRef
- readonly markRaw: UnwrapRef
- readonly nextTick: UnwrapRef
- readonly onActivated: UnwrapRef
- readonly onBeforeMount: UnwrapRef
- readonly onBeforeRouteLeave: UnwrapRef
- readonly onBeforeRouteUpdate: UnwrapRef
- readonly onBeforeUnmount: UnwrapRef
- readonly onBeforeUpdate: UnwrapRef
- readonly onClickOutside: UnwrapRef
- readonly onDeactivated: UnwrapRef
- readonly onErrorCaptured: UnwrapRef
- readonly onKeyStroke: UnwrapRef
- readonly onLongPress: UnwrapRef
- readonly onMounted: UnwrapRef
- readonly onRenderTracked: UnwrapRef
- readonly onRenderTriggered: UnwrapRef
- readonly onScopeDispose: UnwrapRef
- readonly onServerPrefetch: UnwrapRef
- readonly onStartTyping: UnwrapRef
- readonly onUnmounted: UnwrapRef
- readonly onUpdated: UnwrapRef
- readonly pausableWatch: UnwrapRef
- readonly provide: UnwrapRef
- readonly reactify: UnwrapRef
- readonly reactifyObject: UnwrapRef
- readonly reactive: UnwrapRef
- readonly reactiveComputed: UnwrapRef
- readonly reactiveOmit: UnwrapRef
- readonly reactivePick: UnwrapRef
- readonly readonly: UnwrapRef
- readonly ref: UnwrapRef
- readonly refAutoReset: UnwrapRef
- readonly refDebounced: UnwrapRef
- readonly refDefault: UnwrapRef
- readonly refThrottled: UnwrapRef
- readonly refWithControl: UnwrapRef
- readonly resolveComponent: UnwrapRef
- readonly resolveRef: UnwrapRef
- readonly resolveUnref: UnwrapRef
- readonly shallowReactive: UnwrapRef
- readonly shallowReadonly: UnwrapRef
- readonly shallowRef: UnwrapRef
- readonly syncRef: UnwrapRef
- readonly syncRefs: UnwrapRef
- readonly templateRef: UnwrapRef
- readonly throttledRef: UnwrapRef
- readonly throttledWatch: UnwrapRef
- readonly toRaw: UnwrapRef
- readonly toReactive: UnwrapRef
- readonly toRef: UnwrapRef
- readonly toRefs: UnwrapRef
- readonly toValue: UnwrapRef
- readonly triggerRef: UnwrapRef
- readonly tryOnBeforeMount: UnwrapRef
- readonly tryOnBeforeUnmount: UnwrapRef
- readonly tryOnMounted: UnwrapRef
- readonly tryOnScopeDispose: UnwrapRef
- readonly tryOnUnmounted: UnwrapRef
- readonly unref: UnwrapRef
- readonly unrefElement: UnwrapRef
- readonly until: UnwrapRef
- readonly useActiveElement: UnwrapRef
- readonly useAnimate: UnwrapRef
- readonly useArrayDifference: UnwrapRef
- readonly useArrayEvery: UnwrapRef
- readonly useArrayFilter: UnwrapRef
- readonly useArrayFind: UnwrapRef
- readonly useArrayFindIndex: UnwrapRef
- readonly useArrayFindLast: UnwrapRef
- readonly useArrayIncludes: UnwrapRef
- readonly useArrayJoin: UnwrapRef
- readonly useArrayMap: UnwrapRef
- readonly useArrayReduce: UnwrapRef
- readonly useArraySome: UnwrapRef
- readonly useArrayUnique: UnwrapRef
- readonly useAsyncQueue: UnwrapRef
- readonly useAsyncState: UnwrapRef
- readonly useAttrs: UnwrapRef
- readonly useBase64: UnwrapRef
- readonly useBase64Legacy: UnwrapRef
- readonly useBattery: UnwrapRef
- readonly useBluetooth: UnwrapRef
- readonly useBreakpoints: UnwrapRef
- readonly useBroadcastChannel: UnwrapRef
- readonly useBrowserLocation: UnwrapRef
- readonly useCached: UnwrapRef
- readonly useClipboard: UnwrapRef
- readonly useCloned: UnwrapRef
- readonly useColorMode: UnwrapRef
- readonly useCondition: UnwrapRef
- readonly useConfirmDialog: UnwrapRef
- readonly useCounter: UnwrapRef
- readonly useCssModule: UnwrapRef
- readonly useCssVar: UnwrapRef
- readonly useCssVars: UnwrapRef
- readonly useCurrentElement: UnwrapRef
- readonly useCycleList: UnwrapRef
- readonly useDark: UnwrapRef
- readonly useDateFormat: UnwrapRef
- readonly useDebounce: UnwrapRef
- readonly useDebounceFn: UnwrapRef
- readonly useDebouncedRefHistory: UnwrapRef
- readonly useDeviceMotion: UnwrapRef
- readonly useDeviceOrientation: UnwrapRef
- readonly useDevicePixelRatio: UnwrapRef
- readonly useDevicesList: UnwrapRef
- readonly useDisplayMedia: UnwrapRef
- readonly useDocumentVisibility: UnwrapRef
- readonly useDraggable: UnwrapRef
- readonly useDropZone: UnwrapRef
- readonly useElementBounding: UnwrapRef
- readonly useElementByPoint: UnwrapRef
- readonly useElementHover: UnwrapRef
- readonly useElementSize: UnwrapRef
- readonly useElementVisibility: UnwrapRef
- readonly useEventBus: UnwrapRef
- readonly useEventListener: UnwrapRef
- readonly useEventSource: UnwrapRef
- readonly useEyeDropper: UnwrapRef
- readonly useFavicon: UnwrapRef
- readonly useFetch: UnwrapRef
- readonly useFileDialog: UnwrapRef
- readonly useFileSystemAccess: UnwrapRef
- readonly useFocus: UnwrapRef
- readonly useFocusWithin: UnwrapRef
- readonly useFps: UnwrapRef
- readonly useFullscreen: UnwrapRef
- readonly useGamepad: UnwrapRef
- readonly useGeolocation: UnwrapRef
- readonly useIdle: UnwrapRef
- readonly useImage: UnwrapRef
- readonly useInfiniteScroll: UnwrapRef
- readonly useIntersectionObserver: UnwrapRef
- readonly useInterval: UnwrapRef
- readonly useIntervalFn: UnwrapRef
- readonly useKeyModifier: UnwrapRef
- readonly useLastChanged: UnwrapRef
- readonly useLegacyDb: UnwrapRef
- readonly useLink: UnwrapRef
- readonly useLocalStorage: UnwrapRef
- readonly useMagicKeys: UnwrapRef
- readonly useManualRefHistory: UnwrapRef
- readonly useMedal: UnwrapRef
- readonly useMediaControls: UnwrapRef
- readonly useMediaQuery: UnwrapRef
- readonly useMemoize: UnwrapRef
- readonly useMemory: UnwrapRef
- readonly useModelLoad: UnwrapRef
- readonly useMounted: UnwrapRef
- readonly useMouse: UnwrapRef
- readonly useMouseInElement: UnwrapRef
- readonly useMousePressed: UnwrapRef
- readonly useMutationObserver: UnwrapRef
- readonly useNavigatorLanguage: UnwrapRef
- readonly useNetwork: UnwrapRef
- readonly useNow: UnwrapRef
- readonly useObjectUrl: UnwrapRef
- readonly useOffsetPagination: UnwrapRef