From 704fb6cee1731f14abb3308b6b05bab9e9b6e58c Mon Sep 17 00:00:00 2001 From: Saimon8420 Date: Thu, 6 Feb 2025 20:37:17 +0600 Subject: [PATCH] some bugs fixed and some part of ui changed --- .env | 2 +- components.json | 2 +- jsconfig.json | 14 +- package-lock.json | 1455 ++++++++++++++++- package.json | 9 +- src/App.jsx | 59 +- src/Home.jsx | 76 + src/api/authApi.ts | 24 + src/api/projectApi.ts | 139 ++ src/api/uploadApi.ts | 57 + src/components/ActionButtons.jsx | 99 +- src/components/AspectCanvas.jsx | 240 --- src/components/Canvas.jsx | 98 -- src/components/Canvas/Canvas.jsx | 90 +- src/components/CanvasSetting.jsx | 479 +++--- .../Context/authContext/AuthContext.js | 5 + .../Context/authContext/AuthProvider.jsx | 18 + src/components/EachComponent/UploadImage.jsx | 184 ++- src/components/FabricCanvas.jsx | 69 - src/components/Layouts/LeftSidebar.jsx | 2 +- src/components/Layouts/SheetLeftPanel.jsx | 79 - src/components/Layouts/SheetRightPanel.jsx | 88 - src/components/ObjectPanel.jsx | 151 -- src/components/ObjectShortcut.jsx | 49 +- src/components/Pages/NotFound.jsx | 30 + src/components/Pages/UnAuthenticated.jsx | 32 + src/components/Panel/EditorPanel.jsx | 2 +- src/components/Panel/TopBar.jsx | 12 +- src/components/SaveCanvas.jsx | 305 ++++ src/components/ui/textarea.jsx | 2 +- src/hooks/use-toast.js | 6 +- src/index.css | 2 +- src/main.jsx | 30 +- src/vite-env.d.ts | 10 + tailwind.config.js | 119 +- vite.config.js | 3 + 36 files changed, 2785 insertions(+), 1256 deletions(-) create mode 100644 src/Home.jsx create mode 100644 src/api/authApi.ts create mode 100644 src/api/projectApi.ts create mode 100644 src/api/uploadApi.ts delete mode 100644 src/components/AspectCanvas.jsx delete mode 100644 src/components/Canvas.jsx create mode 100644 src/components/Context/authContext/AuthContext.js create mode 100644 src/components/Context/authContext/AuthProvider.jsx delete mode 100644 src/components/FabricCanvas.jsx delete mode 100644 src/components/Layouts/SheetLeftPanel.jsx delete mode 100644 src/components/Layouts/SheetRightPanel.jsx delete mode 100644 src/components/ObjectPanel.jsx create mode 100644 src/components/Pages/NotFound.jsx create mode 100644 src/components/Pages/UnAuthenticated.jsx create mode 100644 src/components/SaveCanvas.jsx create mode 100644 src/vite-env.d.ts diff --git a/.env b/.env index a576e9b..afa66d4 100644 --- a/.env +++ b/.env @@ -1 +1 @@ -VITE_GOOGLE_FONT_API_KEY=AIzaSyBPOYGT26jwMjlDuf6sM5JwaZDkiYigeQg \ No newline at end of file +VITE_SERVER_URL=http://localhost:3000/api \ No newline at end of file diff --git a/components.json b/components.json index 4e01167..ebf7e6e 100644 --- a/components.json +++ b/components.json @@ -6,7 +6,7 @@ "tailwind": { "config": "tailwind.config.js", "css": "src/index.css", - "baseColor": "slate", + "baseColor": "neutral", "cssVariables": true, "prefix": "" }, diff --git a/jsconfig.json b/jsconfig.json index 93740c2..3255bae 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -1,22 +1,10 @@ { "compilerOptions": { - "target": "ES2020", - "useDefineForClassFields": true, - "lib": [ - "ES2020", - "DOM", - "DOM.Iterable" - ], - "module": "ESNext", - "skipLibCheck": true, "baseUrl": ".", "paths": { "@/*": [ "./src/*" ] } - }, - "include": [ - "src" - ], + } } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 0eb8dc6..c636f69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,8 @@ "@radix-ui/react-tabs": "^1.1.2", "@radix-ui/react-toast": "^1.2.4", "@radix-ui/react-tooltip": "^1.1.4", - "class-variance-authority": "^0.7.0", + "@tanstack/react-query": "^5.66.0", + "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "fabric": "^5.3.0", "lodash": "^4.17.21", @@ -34,9 +35,11 @@ "react-icons": "^5.4.0", "react-image-file-resizer": "^0.4.8", "react-rnd": "^10.4.13", + "react-router-dom": "^7.1.5", "react-tooltip": "^5.28.0", "react-window": "^1.8.10", - "tailwind-merge": "^2.5.4", + "shadcn-ui": "^0.9.4", + "tailwind-merge": "^2.6.0", "tailwind-scrollbar": "^3.1.0", "tailwind-scrollbar-hide": "^1.3.1", "tailwindcss-animate": "^1.0.7", @@ -44,6 +47,8 @@ }, "devDependencies": { "@eslint/js": "^9.13.0", + "@tanstack/eslint-plugin-query": "^5.66.0", + "@tanstack/react-query-devtools": "^5.66.0", "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", "@vitejs/plugin-react": "^4.3.3", @@ -76,7 +81,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -86,11 +90,25 @@ "node": ">=6.0.0" } }, + "node_modules/@antfu/ni": { + "version": "0.21.12", + "resolved": "https://registry.npmjs.org/@antfu/ni/-/ni-0.21.12.tgz", + "integrity": "sha512-2aDL3WUv8hMJb2L3r/PIQWsTLyq7RQr3v9xD16fiz6O8ys1xEyLhhTOv8gxtZvJiTzjTF5pHoArvRdesGL1DMQ==", + "license": "MIT", + "bin": { + "na": "bin/na.mjs", + "nci": "bin/nci.mjs", + "ni": "bin/ni.mjs", + "nlx": "bin/nlx.mjs", + "nr": "bin/nr.mjs", + "nu": "bin/nu.mjs", + "nun": "bin/nun.mjs" + } + }, "node_modules/@babel/code-frame": { "version": "7.26.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.25.9", @@ -105,7 +123,6 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.3.tgz", "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -115,7 +132,6 @@ "version": "7.26.0", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", - "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", @@ -143,14 +159,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", - "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", - "dev": true, + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz", + "integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.26.3", - "@babel/types": "^7.26.3", + "@babel/parser": "^7.26.5", + "@babel/types": "^7.26.5", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -159,11 +174,22 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-compilation-targets": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/compat-data": "^7.25.9", @@ -176,11 +202,44 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-module-imports": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", - "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.25.9", @@ -194,7 +253,6 @@ "version": "7.26.0", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.25.9", @@ -208,12 +266,53 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-plugin-utils": { + "node_modules/@babel/helper-optimise-call-expression": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", - "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", - "dev": true, + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", + "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz", + "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==", + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.26.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, "engines": { "node": ">=6.9.0" } @@ -222,7 +321,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -232,7 +330,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -242,7 +339,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -252,7 +348,6 @@ "version": "7.26.0", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", - "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.25.9", @@ -263,13 +358,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", - "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", - "dev": true, + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.7.tgz", + "integrity": "sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w==", "license": "MIT", "dependencies": { - "@babel/types": "^7.26.3" + "@babel/types": "^7.26.7" }, "bin": { "parser": "bin/babel-parser.js" @@ -278,6 +372,21 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", + "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-react-jsx-self": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", @@ -310,6 +419,25 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.7.tgz", + "integrity": "sha512-5cJurntg+AT+cgelGP9Bt788DKiAw9gIMSMU2NJrLAilnj0m8WZWUNZPSLOmadYsujHutpgElO+50foX+ib/Wg==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-syntax-typescript": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/runtime": { "version": "7.26.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", @@ -326,7 +454,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.25.9", @@ -338,17 +465,16 @@ } }, "node_modules/@babel/traverse": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.3.tgz", - "integrity": "sha512-yTmc8J+Sj8yLzwr4PD5Xb/WF3bOYu2C2OoSZPzbuqRm4n98XirsbzaX+GloeO376UnSYIYJ4NCanwV5/ugZkwA==", - "dev": true, + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.7.tgz", + "integrity": "sha512-1x1sgeyRLC3r5fQOM0/xtQKsYjyxmFjaOrLJNtZ81inNjyJHGIolTULPiSc/2qe1/qfpFLisLQYFnnZl7QoedA==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.3", - "@babel/parser": "^7.26.3", + "@babel/generator": "^7.26.5", + "@babel/parser": "^7.26.7", "@babel/template": "^7.25.9", - "@babel/types": "^7.26.3", + "@babel/types": "^7.26.7", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -360,17 +486,15 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/types": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", - "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", - "dev": true, + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.7.tgz", + "integrity": "sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -3213,6 +3337,78 @@ "@swc/counter": "^0.1.3" } }, + "node_modules/@tanstack/eslint-plugin-query": { + "version": "5.66.0", + "resolved": "https://registry.npmjs.org/@tanstack/eslint-plugin-query/-/eslint-plugin-query-5.66.0.tgz", + "integrity": "sha512-CzZhBxicLDuuSJbkZ4nPcuBqWnhLu72Zt9p/7qLQ93BepVnZJV6ZDlBLBuN5eg7YRACwECPLsntnwo1zuhgseQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.18.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + } + }, + "node_modules/@tanstack/query-core": { + "version": "5.66.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.66.0.tgz", + "integrity": "sha512-J+JeBtthiKxrpzUu7rfIPDzhscXF2p5zE/hVdrqkACBP8Yu0M96mwJ5m/8cPPYQE9aRNvXztXHlNwIh4FEeMZw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/query-devtools": { + "version": "5.65.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.65.0.tgz", + "integrity": "sha512-g5y7zc07U9D3esMdqUfTEVu9kMHoIaVBsD0+M3LPdAdD710RpTcLiNvJY1JkYXqkq9+NV+CQoemVNpQPBXVsJg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.66.0", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.66.0.tgz", + "integrity": "sha512-z3sYixFQJe8hndFnXgWu7C79ctL+pI0KAelYyW+khaNJ1m22lWrhJU2QrsTcRKMuVPtoZvfBYrTStIdKo+x0Xw==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.66.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, + "node_modules/@tanstack/react-query-devtools": { + "version": "5.66.0", + "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.66.0.tgz", + "integrity": "sha512-uB57wA2YZaQ2fPcFW0E9O1zAGDGSbRKRx84uMk/86VyU9jWVxvJ3Uzp+zNm+nZJYsuekCIo2opTdgNuvM3cKgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tanstack/query-devtools": "5.65.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@tanstack/react-query": "^5.66.0", + "react": "^18 || ^19" + } + }, "node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", @@ -3223,6 +3419,57 @@ "node": ">= 10" } }, + "node_modules/@ts-morph/common": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.19.0.tgz", + "integrity": "sha512-Unz/WHmd4pGax91rdIKWi51wnVUW11QttMEPpBiBgIewnc9UQIX7UDLxr5vRlqeByXCwhkF6VabSsI0raWcyAQ==", + "license": "MIT", + "dependencies": { + "fast-glob": "^3.2.12", + "minimatch": "^7.4.3", + "mkdirp": "^2.1.6", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@ts-morph/common/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@ts-morph/common/node_modules/minimatch": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", + "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@ts-morph/common/node_modules/mkdirp": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz", + "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==", + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -3268,6 +3515,12 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", @@ -3310,6 +3563,146 @@ "@types/react": "*" } }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.23.0.tgz", + "integrity": "sha512-OGqo7+dXHqI7Hfm+WqkZjKjsiRtFUQHPdGMXzk5mYXhJUedO7e/Y7i8AK3MyLMgZR93TX4bIzYrfyVjLC+0VSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.23.0", + "@typescript-eslint/visitor-keys": "8.23.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.23.0.tgz", + "integrity": "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.23.0.tgz", + "integrity": "sha512-LcqzfipsB8RTvH8FX24W4UUFk1bl+0yTOf9ZA08XngFwMg4Kj8A+9hwz8Cr/ZS4KwHrmo9PJiLZkOt49vPnuvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.23.0", + "@typescript-eslint/visitor-keys": "8.23.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.23.0.tgz", + "integrity": "sha512-uB/+PSo6Exu02b5ZEiVtmY6RVYO7YU5xqgzTIVZwTHvvK3HsL8tZZHFaTLFtRG3CsV4A5mhOv+NZx5BlhXPyIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.23.0", + "@typescript-eslint/types": "8.23.0", + "@typescript-eslint/typescript-estree": "8.23.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.23.0.tgz", + "integrity": "sha512-oWWhcWDLwDfu++BGTZcmXWqpwtkwb5o7fxUIGksMQQDSdPW9prsSnfIOZMlsj4vBOSrcnjIUZMiIjODgGosFhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.23.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@vitejs/plugin-react": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz", @@ -3520,7 +3913,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, "license": "Python-2.0" }, "node_modules/aria-hidden": { @@ -3672,6 +4064,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/ast-types": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", + "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -3748,6 +4152,26 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -3760,6 +4184,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3794,7 +4229,6 @@ "version": "4.24.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", - "dev": true, "funding": [ { "type": "opencollective", @@ -3823,6 +4257,30 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/buffer-builder": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/buffer-builder/-/buffer-builder-0.2.0.tgz", @@ -3854,7 +4312,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -3873,7 +4330,6 @@ "version": "1.0.30001686", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001686.tgz", "integrity": "sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==", - "dev": true, "funding": [ { "type": "opencollective", @@ -3987,6 +4443,42 @@ "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", "license": "MIT" }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "license": "MIT", + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -3996,6 +4488,12 @@ "node": ">=6" } }, + "node_modules/code-block-writer": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-12.0.0.tgz", + "integrity": "sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==", + "license": "MIT" + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -4071,9 +4569,43 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, "license": "MIT" }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "license": "MIT", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -4134,6 +4666,15 @@ "devOptional": true, "license": "MIT" }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/data-urls": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", @@ -4221,7 +4762,6 @@ "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "devOptional": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -4262,6 +4802,18 @@ "dev": true, "license": "MIT" }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -4337,6 +4889,15 @@ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", "license": "Apache-2.0" }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", @@ -4380,7 +4941,6 @@ "version": "1.5.69", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.69.tgz", "integrity": "sha512-zz4e7EbJqqtdQtwt61ZYKrfEYlV0HpGbIGRVFGOO9YBZIhg0BDXtBcWxpqyAm6oyPl2Zp8tc5FrPpCZQH/Yazg==", - "dev": true, "license": "ISC" }, "node_modules/emoji-regex": { @@ -4389,6 +4949,15 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, "node_modules/es-abstract": { "version": "1.23.5", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.5.tgz", @@ -4599,7 +5168,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -4809,7 +5377,6 @@ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "license": "BSD-2-Clause", - "optional": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -4864,6 +5431,29 @@ "node": ">=0.10.0" } }, + "node_modules/execa": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", + "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, "node_modules/fabric": { "version": "5.4.2", "resolved": "https://registry.npmjs.org/fabric/-/fabric-5.4.2.tgz", @@ -4935,6 +5525,29 @@ "reusify": "^1.0.4" } }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -5063,6 +5676,18 @@ "node": ">= 6" } }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/fraction.js": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", @@ -5077,6 +5702,29 @@ "url": "https://github.com/sponsors/rawify" } }, + "node_modules/fs-extra": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs-extra/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -5195,7 +5843,6 @@ "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -5230,6 +5877,18 @@ "node": ">=6" } }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-symbol-description": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", @@ -5325,6 +5984,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", @@ -5464,6 +6129,15 @@ "node": ">= 6" } }, + "node_modules/human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=14.18.0" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -5477,6 +6151,26 @@ "node": ">=0.10.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -5498,7 +6192,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, "license": "MIT", "dependencies": { "parent-module": "^1.0.0", @@ -5537,8 +6230,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC", - "optional": true + "license": "ISC" }, "node_modules/internal-slot": { "version": "1.0.7", @@ -5581,6 +6273,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, "node_modules/is-async-function": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", @@ -5764,6 +6462,18 @@ "node": ">=0.10.0" } }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-map": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", @@ -5871,6 +6581,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.0.tgz", @@ -5922,6 +6644,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-weakmap": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", @@ -6029,7 +6763,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -6089,7 +6822,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", - "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -6105,6 +6837,12 @@ "dev": true, "license": "MIT" }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -6123,7 +6861,6 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, "license": "MIT", "bin": { "json5": "lib/cli.js" @@ -6132,6 +6869,27 @@ "node": ">=6" } }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonfile/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -6158,6 +6916,15 @@ "json-buffer": "3.0.1" } }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -6219,6 +6986,34 @@ "dev": true, "license": "MIT" }, + "node_modules/log-symbols": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", + "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", + "license": "MIT", + "dependencies": { + "chalk": "^5.0.0", + "is-unicode-supported": "^1.1.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -6235,7 +7030,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, "license": "ISC", "dependencies": { "yallist": "^3.0.2" @@ -6272,6 +7066,12 @@ "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", "license": "MIT" }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -6317,6 +7117,18 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mimic-response": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", @@ -6343,6 +7155,15 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/minipass": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", @@ -6403,7 +7224,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "devOptional": true, "license": "MIT" }, "node_modules/mz": { @@ -6449,6 +7269,25 @@ "dev": true, "license": "MIT" }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -6499,7 +7338,6 @@ "version": "2.0.18", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", - "dev": true, "license": "MIT" }, "node_modules/nopt": { @@ -6537,6 +7375,33 @@ "node": ">=0.10.0" } }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/npmlog": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", @@ -6680,6 +7545,21 @@ "wrappy": "1" } }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -6698,6 +7578,68 @@ "node": ">= 0.8.0" } }, + "node_modules/ora": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-6.3.1.tgz", + "integrity": "sha512-ERAyNnZOfqM+Ao3RAvIXkYh5joP220yf59gVe2X/cI6SiCxIdi4c9HZKZD8R6q/RDXEje1THBju6iExiSsgJaQ==", + "license": "MIT", + "dependencies": { + "chalk": "^5.0.0", + "cli-cursor": "^4.0.0", + "cli-spinners": "^2.6.1", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^1.1.0", + "log-symbols": "^5.1.0", + "stdin-discarder": "^0.1.0", + "strip-ansi": "^7.0.1", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -6740,7 +7682,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "license": "MIT", "dependencies": { "callsites": "^3.0.0" @@ -6749,6 +7690,24 @@ "node": ">=6" } }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", @@ -6756,6 +7715,12 @@ "license": "MIT", "optional": true }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "license": "MIT" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -6813,6 +7778,15 @@ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "license": "ISC" }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -7029,6 +8003,19 @@ "node": ">= 0.8.0" } }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -7264,6 +8251,46 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "license": "0BSD" }, + "node_modules/react-router": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.1.5.tgz", + "integrity": "sha512-8BUF+hZEU4/z/JD201yK6S+UYhsf58bzYIDq2NS1iGpwxSXDu7F+DeGSkIXMFBuHZB21FSiCzEcUb18cQNdRkA==", + "license": "MIT", + "dependencies": { + "@types/cookie": "^0.6.0", + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0", + "turbo-stream": "2.4.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.1.5.tgz", + "integrity": "sha512-/4f9+up0Qv92D3bB8iN5P1s3oHAepSGa9h5k6tpTFlixTTskJZwKGhJ6vRJ277tLD1zuaZTt95hyGWV1Z37csQ==", + "license": "MIT", + "dependencies": { + "react-router": "7.1.5" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/react-style-singleton": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", @@ -7332,7 +8359,6 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "license": "MIT", - "optional": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -7354,6 +8380,22 @@ "node": ">=8.10.0" } }, + "node_modules/recast": { + "version": "0.23.9", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.9.tgz", + "integrity": "sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==", + "license": "MIT", + "dependencies": { + "ast-types": "^0.16.1", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tiny-invariant": "^1.3.3", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">= 4" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.7.tgz", @@ -7430,12 +8472,51 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" } }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -7571,8 +8652,7 @@ "url": "https://feross.org/support" } ], - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/safe-regex-test": { "version": "1.0.3", @@ -8026,7 +9106,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "devOptional": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -8039,6 +9118,12 @@ "license": "ISC", "optional": true }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "license": "MIT" + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -8073,6 +9158,98 @@ "node": ">= 0.4" } }, + "node_modules/shadcn-ui": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/shadcn-ui/-/shadcn-ui-0.9.4.tgz", + "integrity": "sha512-75nqu4+y4mlhNXGfHPoPd1r2fgqGQgSEPzPe8TV39WRinafKHuBX2xkgoQOwu+NhiRPKV5TrRSCZ5ytGrFU1oQ==", + "license": "MIT", + "dependencies": { + "@antfu/ni": "^0.21.4", + "@babel/core": "^7.22.1", + "@babel/parser": "^7.22.6", + "@babel/plugin-transform-typescript": "^7.22.5", + "chalk": "5.2.0", + "commander": "^10.0.0", + "cosmiconfig": "^8.1.3", + "diff": "^5.1.0", + "execa": "^7.0.0", + "fast-glob": "^3.3.2", + "fs-extra": "^11.1.0", + "https-proxy-agent": "^6.2.0", + "lodash": "^4.17.21", + "node-fetch": "^3.3.0", + "ora": "^6.1.2", + "prompts": "^2.4.2", + "recast": "^0.23.2", + "ts-morph": "^18.0.0", + "tsconfig-paths": "^4.2.0", + "zod": "^3.20.2" + }, + "bin": { + "shadcn-ui": "dist/index.js" + } + }, + "node_modules/shadcn-ui/node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/shadcn-ui/node_modules/chalk": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz", + "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/shadcn-ui/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/shadcn-ui/node_modules/https-proxy-agent": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-6.2.1.tgz", + "integrity": "sha512-ONsE3+yfZF2caH5+bJlcddtWqNI3Gvs5A38+ngvljxaBiRXRswym2c7yf8UAeFpRFKjFNHIFEHqR/OLAWJzyiA==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/shadcn-ui/node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -8117,8 +9294,7 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC", - "optional": true + "license": "ISC" }, "node_modules/simple-concat": { "version": "1.0.1", @@ -8153,12 +9329,17 @@ "simple-concat": "^1.0.0" } }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "license": "BSD-3-Clause", - "optional": true, "engines": { "node": ">=0.10.0" } @@ -8172,12 +9353,26 @@ "node": ">=0.10.0" } }, + "node_modules/stdin-discarder": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.1.0.tgz", + "integrity": "sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==", + "license": "MIT", + "dependencies": { + "bl": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "license": "MIT", - "optional": true, "dependencies": { "safe-buffer": "~5.2.0" } @@ -8326,6 +9521,27 @@ "node": ">=8" } }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -8470,9 +9686,9 @@ } }, "node_modules/tailwind-merge": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.5.tgz", - "integrity": "sha512-0LXunzzAZzo0tEPxV3I297ffKZPlKDrjj7NXphC8V5ak9yHC5zRmxnOe2m/Rd/7ivsOMJe3JZ2JVocoDdQTRBA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.0.tgz", + "integrity": "sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==", "license": "MIT", "funding": { "type": "github", @@ -8609,6 +9825,12 @@ "node": ">=0.8" } }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -8650,18 +9872,61 @@ "node": ">=12" } }, + "node_modules/ts-api-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", + "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", "license": "Apache-2.0" }, + "node_modules/ts-morph": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-18.0.0.tgz", + "integrity": "sha512-Kg5u0mk19PIIe4islUI/HWRvm9bC1lHejK4S0oh1zaZ77TMZAEmQC0sHQYiu2RgCQFZKXz1fMVi/7nOOeirznA==", + "license": "MIT", + "dependencies": { + "@ts-morph/common": "~0.19.0", + "code-block-writer": "^12.0.0" + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/turbo-stream": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz", + "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==", + "license": "ISC" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -8753,6 +10018,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typescript": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "devOptional": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -8783,7 +10063,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", - "dev": true, "funding": [ { "type": "opencollective", @@ -8971,6 +10250,24 @@ "node": ">=12" } }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, "node_modules/webfontloader": { "version": "1.6.28", "resolved": "https://registry.npmjs.org/webfontloader/-/webfontloader-1.6.28.tgz", @@ -9293,7 +10590,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, "license": "ISC" }, "node_modules/yaml": { @@ -9320,6 +10616,15 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "3.24.1", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", + "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index 75aa933..e5721ee 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,8 @@ "@radix-ui/react-tabs": "^1.1.2", "@radix-ui/react-toast": "^1.2.4", "@radix-ui/react-tooltip": "^1.1.4", - "class-variance-authority": "^0.7.0", + "@tanstack/react-query": "^5.66.0", + "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "fabric": "^5.3.0", "lodash": "^4.17.21", @@ -36,9 +37,11 @@ "react-icons": "^5.4.0", "react-image-file-resizer": "^0.4.8", "react-rnd": "^10.4.13", + "react-router-dom": "^7.1.5", "react-tooltip": "^5.28.0", "react-window": "^1.8.10", - "tailwind-merge": "^2.5.4", + "shadcn-ui": "^0.9.4", + "tailwind-merge": "^2.6.0", "tailwind-scrollbar": "^3.1.0", "tailwind-scrollbar-hide": "^1.3.1", "tailwindcss-animate": "^1.0.7", @@ -46,6 +49,8 @@ }, "devDependencies": { "@eslint/js": "^9.13.0", + "@tanstack/eslint-plugin-query": "^5.66.0", + "@tanstack/react-query-devtools": "^5.66.0", "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", "@vitejs/plugin-react": "^4.3.3", diff --git a/src/App.jsx b/src/App.jsx index a8c57dd..525f4fb 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,21 +1,10 @@ -import { useContext, useEffect } from "react"; +import { useEffect } from "react"; import "./App.css"; -// import Canvas from "./components/Canvas"; import WebFont from "webfontloader"; -// import Header from "./components/Layouts/Header"; -// import SheetRightPanel from "./components/Layouts/SheetRightPanel"; -// import SheetLeftPanel from "./components/Layouts/SheetLeftPanel"; -// import CanvasCapture from "./components/CanvasCapture"; -// import { Toaster } from "./components/ui/toaster"; -import { Sidebar } from "./components/Layouts/LeftSidebar"; -// import TextPanel from "./components/Panel/TextPanel"; -import { TopBar } from "./components/Panel/TopBar"; -import { ActionButtons } from "./components/ActionButtons"; -import EditorPanel from "./components/Panel/EditorPanel"; -import CanvasContext from "./components/Context/canvasContext/CanvasContext"; -import Canvas from "./components/Canvas/Canvas"; -import ActiveObjectContext from "./components/Context/activeObject/ObjectContext"; -import CanvasCapture from "./components/CanvasCapture"; +import { Routes, Route } from "react-router-dom"; +import { Home } from "./Home"; +import NotFound from "./components/Pages/NotFound"; +import Unauthenticated from "./components/Pages/UnAuthenticated"; function App() { useEffect(() => { @@ -76,39 +65,13 @@ function App() { }); }, []); - const { selectedPanel } = useContext(CanvasContext); - const { activeObject } = useContext(ActiveObjectContext); - return ( - //
- // - // - //
- // - - //
- //
- // - // - //
- //
- //
-
- - {selectedPanel !== "" && } -
- {" "} - {/* Changed */} - {activeObject && } - -
- {" "} - {/* Added wrapper */} - -
- -
-
+ + } /> + } /> + } /> + } /> + ); } diff --git a/src/Home.jsx b/src/Home.jsx new file mode 100644 index 0000000..6b4a77f --- /dev/null +++ b/src/Home.jsx @@ -0,0 +1,76 @@ +import { useContext, useEffect } from 'react' +import ActiveObjectContext from './components/Context/activeObject/ObjectContext'; +import { TopBar } from './components/Panel/TopBar'; +import { ActionButtons } from './components/ActionButtons'; +import { Sidebar } from './components/Layouts/LeftSidebar'; +import EditorPanel from './components/Panel/EditorPanel'; +import Canvas from './components/Canvas/Canvas'; +import CanvasCapture from './components/CanvasCapture'; +import { useParams } from 'react-router-dom'; +import { useQuery } from '@tanstack/react-query'; +import { generateToken } from './api/authApi'; +import { useNavigate } from "react-router-dom"; +import { Toaster } from '@/components/ui/toaster'; + +export const Home = () => { + const { activeObject } = useContext(ActiveObjectContext); + const params = useParams(); + const getToken = localStorage.getItem('canvas_token'); + + const { id } = params; + const navigate = useNavigate(); + + const { data, isLoading } = useQuery({ + queryKey: ['get-token'], + queryFn: () => generateToken(id), + enabled: !getToken + }) + console.log(data); + + useEffect(() => { + if (!getToken && !isLoading) { + navigate("/unAuthenticated"); + } + if (getToken && !isLoading && data?.status === 201) { + navigate("/"); + } + }, [getToken, navigate, isLoading, data]) + + return ( +
+ { + isLoading &&
Loading...
+ } + {!isLoading && + <> + +
+ { + activeObject && + } +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ +
+ {/* canvas capture part */} + +
+ + } +
+ ) +} diff --git a/src/api/authApi.ts b/src/api/authApi.ts new file mode 100644 index 0000000..daaaef4 --- /dev/null +++ b/src/api/authApi.ts @@ -0,0 +1,24 @@ +export const generateToken = async (id: string) => { + try { + const url = `${import.meta.env.VITE_SERVER_URL}/auth/generate-token/${id}`; + const response = await fetch(url, { + method: 'GET', + credentials: 'include', + }); + const data = await response.json(); + if (data?.token) { + localStorage.setItem('canvas_token', data.token); + // Remove the token from the response data + const { token, ...restData } = data; + return restData; // Return modified data without token + } + else if (!data?.token) { + localStorage.removeItem("canvas_token"); + return data; + } + return data; + } catch (error) { + console.error('Un-authenticated:', error); + throw error; + } +} \ No newline at end of file diff --git a/src/api/projectApi.ts b/src/api/projectApi.ts new file mode 100644 index 0000000..4289d2c --- /dev/null +++ b/src/api/projectApi.ts @@ -0,0 +1,139 @@ +interface Project { + id: string, + name: string; + description: string; + object: JSON; + preview_url: string; +} + +export const getProjects = async () => { + try { + const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/projects`, { + method: 'GET', + credentials: 'include', + headers: { 'Content-Type': 'application/json' }, + }) + const data = await response.json(); + if (data?.token) { + localStorage.setItem('canvas_token', data.token); + // Remove the token from the response data + const { token, ...restData } = data; + return restData; // Return modified data without token + } + else if (!data?.token) { + localStorage.removeItem("canvas_token"); + return data; + } + return data; + } catch (error) { + console.error('Failed to get projects:', error); + throw error; + } +} + +export const getProjectById = async (projectId: string) => { + try { + const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/projects/each/${projectId}`, { + method: 'GET', + credentials: 'include', + headers: { 'Content-Type': 'application/json' }, + }) + const data = await response.json(); + if (data?.token) { + localStorage.setItem('canvas_token', data.token); + // Remove the token from the response data + const { token, ...restData } = data; + return restData; // Return modified data without token + } + else if (!data?.token) { + localStorage.removeItem("canvas_token"); + return data; + } + return data; + } catch (error) { + console.error('Failed to get project by ID:', error); + throw error; + } +} + +export const createProject = async () => { + try { + const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/projects/create`, { + method: 'POST', + credentials: 'include', + headers: { 'Content-Type': 'application/json' }, + }); + + const data = await response.json(); + if (data?.token) { + localStorage.setItem('canvas_token', data.token); + // Remove the token from the response data + const { token, ...restData } = data; + return restData; // Return modified data without token + } + else if (!data?.token) { + localStorage.removeItem("canvas_token"); + return data; + } + return data; + } catch (error) { + console.error('Failed to create project:', error); + throw error; + } +}; + +export const updateProject = async (body: Project) => { + try { + const { id, name, description, object, preview_url } = body; + + const project = { name, description, object, preview_url }; + + const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/projects/update/${id}`, { + method: 'PUT', + credentials: 'include', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(project), + }) + const data = await response.json(); + if (data?.token) { + localStorage.setItem('canvas_token', data.token); + // Remove the token from the response data + const { token, ...restData } = data; + return restData; // Return modified data without token + } + else if (!data?.token) { + localStorage.removeItem("canvas_token"); + return data; + } + return data; + } catch (error) { + console.error('Failed to update project:', error); + throw error; + } +} + +export const deleteProject = async (projectId: string) => { + try { + const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/projects/delete/${projectId}`, { + method: 'DELETE', + credentials: 'include', + headers: { 'Content-Type': 'application/json' }, + }) + const data = await response.json(); + if (data?.token) { + localStorage.setItem('canvas_token', data.token); + // Remove the token from the response data + const { token, ...restData } = data; + return restData; // Return modified data without token + } + else if (!data?.token) { + localStorage.removeItem("canvas_token"); + return data; + } + return data; + } catch (error) { + console.error('Failed to delete project:', error); + throw error; + } +} + diff --git a/src/api/uploadApi.ts b/src/api/uploadApi.ts new file mode 100644 index 0000000..63da16b --- /dev/null +++ b/src/api/uploadApi.ts @@ -0,0 +1,57 @@ +interface body { + file: File, + id: string, +} + +export const uploadImage = async (body: body) => { + try { + const { file, id } = body; + const formData = new FormData(); + formData.append('file', file); + formData.append('id', id); + const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/uploads/add`, { + method: 'POST', + credentials: 'include', + body: formData + }) + const data = await response.json(); + if (data?.token) { + localStorage.setItem('canvas_token', data.token); + // Remove the token from the response data + const { token, ...restData } = data; + return restData; // Return modified data without token + } + else if (!data?.token) { + localStorage.removeItem("canvas_token"); + return data; + } + return data; + } catch (error) { + console.error('Error uploading file:', error); + throw error; + } +} + +export const deleteImage = async (imgUrl: string) => { + try { + const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/uploads/delete?url=${imgUrl}`, { + method: 'DELETE', + credentials: 'include', + }) + const data = await response.json(); + if (data?.token) { + localStorage.setItem('canvas_token', data.token); + // Remove the token from the response data + const { token, ...restData } = data; + return restData; // Return modified data without token + } + else if (!data?.token) { + localStorage.removeItem("canvas_token"); + return data; + } + return data; + } catch (error) { + console.error("Error deleting file:", error); + throw error; + } +} \ No newline at end of file diff --git a/src/components/ActionButtons.jsx b/src/components/ActionButtons.jsx index ea45bed..0cc85e2 100644 --- a/src/components/ActionButtons.jsx +++ b/src/components/ActionButtons.jsx @@ -30,7 +30,7 @@ const aspectRatios = [ export function ActionButtons() { const { setCaptureOpen } = useContext(OpenContext); - const { setCanvasRatio, canvasRatio } = useContext(CanvasContext); + const { setCanvasRatio, canvasRatio, setSelectedPanel } = useContext(CanvasContext); const handleRatioChange = (newRatio) => { setCanvasRatio(newRatio); }; @@ -56,44 +56,91 @@ export function ActionButtons() { -
{ setCaptureOpen(true); }} > + + + + + + + +
diff --git a/src/components/AspectCanvas.jsx b/src/components/AspectCanvas.jsx deleted file mode 100644 index 74c4b15..0000000 --- a/src/components/AspectCanvas.jsx +++ /dev/null @@ -1,240 +0,0 @@ -import { useState, useEffect, useContext } from 'react' -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" -import { AspectRatio } from "@/components/ui/aspect-ratio" -import CanvasContext from './Context/canvasContext/CanvasContext' -import OpenContext from './Context/openContext/OpenContext'; -import { Settings, Download, Share2, Settings2 } from "lucide-react"; -import { Card, CardContent } from './ui/card'; -import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './ui/tooltip'; -import { Button } from './ui/button'; -import { Separator } from './ui/separator'; -import { ObjectShortcut } from './ObjectShortcut'; - -const aspectRatios = [ - { value: "1:1", label: "Square (1:1)" }, - { value: "4:3", label: "Standard (4:3)" }, - { value: "3:2", label: "Classic (3:2)" }, - { value: "16:9", label: "Widescreen (16:9)" }, - { value: "9:16", label: "Portrait (9:16)" }, - { value: "21:9", label: "Ultrawide (21:9)" }, - { value: "32:9", label: "Super Ultrawide (32:9)" }, - { value: "1.85:1", label: "Cinema Standard (1.85:1)" }, - { value: "2.39:1", label: "Anamorphic Widescreen (2.39:1)" }, - { value: "2.76:1", label: "Ultra Panavision 70 (2.76:1)" }, - { value: "5:4", label: "Large Format (5:4)" }, - { value: "7:5", label: "Artistic Format (7:5)" }, - { value: "11:8.5", label: "Letter Size (11:8.5)" }, - { value: "3:4", label: "Portrait (3:4)" }, - { value: "1.91:1", label: "Facebook Ads (1.91:1)" } -]; - -export function AspectCanvas() { - const { setLeftPanelOpen, setRightPanelOpen, setOpenPanel, setCaptureOpen, setOpenSetting, setOpenObjectPanel, rightPanelOpen } = useContext(OpenContext); - const [selectedRatio, setSelectedRatio] = useState("4:3"); - - const { canvasRef, canvas, setCanvas, fabricCanvasRef, setCanvasHeight, setCanvasWidth, setScreenWidth } = useContext(CanvasContext); - - useEffect(() => { - import('fabric').then((fabricModule) => { - window.fabric = fabricModule.fabric; - }); - }, []); - - const getRatioValue = (ratio) => { - const [width, height] = ratio.split(':').map(Number) - return width / height - } - - useEffect(() => { - const updateCanvasSize = () => { - if (canvasRef.current && canvas) { - // Update canvas dimensions - const newWidth = canvasRef?.current?.offsetWidth; - const newHeight = canvasRef?.current?.offsetHeight; - - canvas.setWidth(newWidth); - canvas.setHeight(newHeight); - setCanvasWidth(newWidth); - setCanvasHeight(newHeight); - - // Adjust the background image to fit the updated canvas size - const bgImage = canvas.backgroundImage; - if (bgImage) { - // Calculate scaling factors for width and height - const scaleX = newWidth / bgImage.width; - const scaleY = newHeight / bgImage.height; - - // Use the larger scale to cover the entire canvas - const scale = Math.max(scaleX, scaleY); - - // Apply scale and position the image - bgImage.scaleX = scale; - bgImage.scaleY = scale; - bgImage.left = 0; // Align left - bgImage.top = 0; // Align top - - // Update the background image - canvas.setBackgroundImage(bgImage, canvas.renderAll.bind(canvas)); - } else { - // Render the canvas if no background image - canvas.renderAll(); - } - } - - setScreenWidth(document.getElementById("root").offsetWidth); - - // Handle responsive behavior for panels - if (document.getElementById("root").offsetWidth <= 640) { - setLeftPanelOpen(false); - setRightPanelOpen(false); - } - if (document.getElementById("root").offsetWidth > 640) { - setOpenObjectPanel(false); - setOpenSetting(false); - } - }; - // Initial setup - updateCanvasSize(); - - // Listen for window resize - window.addEventListener('resize', updateCanvasSize); - - // Cleanup listener on unmount - return () => window.removeEventListener('resize', updateCanvasSize); - }, [setCanvasWidth, setCanvasHeight, selectedRatio, canvasRef, canvas, setLeftPanelOpen, setOpenObjectPanel, setRightPanelOpen, rightPanelOpen, setScreenWidth, setOpenSetting]); - - useEffect(() => { - if (window.fabric) { - if (fabricCanvasRef?.current) { - fabricCanvasRef?.current.dispose() - } - // Set styles directly on the canvas element - const canvasElement = document.getElementById('fabric-canvas') - if (canvasElement) { - canvasElement.classList.add('fabric-canvas-container') // Add the CSS class - } - - fabricCanvasRef.current = new window.fabric.Canvas('fabric-canvas', { - width: canvasRef?.current?.offsetWidth, - height: canvasRef?.current?.offsetWidth, - backgroundColor: "#ffffff", - }) - - setCanvas(fabricCanvasRef?.current); - } - }, []) - - const handleRatioChange = (newRatio) => { - setSelectedRatio(newRatio) - } - - return ( - - -
- -
- - - - - - -

Open Panel

-
-
-
- -
-
- - - - - - -

Open Settings

-
-
-
-
- - - - - - - -

Download

-
-
-
- - - - - - - -

Share (Coming soon)

-
-
-
-
-
- -
- - - -
- -
-
- -

Changing the canvas size.

-
-
-
-
- -
- -
- -
- - - - -
- -
-
- -
-
- ) -} - - - diff --git a/src/components/Canvas.jsx b/src/components/Canvas.jsx deleted file mode 100644 index d4bf066..0000000 --- a/src/components/Canvas.jsx +++ /dev/null @@ -1,98 +0,0 @@ -import { useEffect, useCallback, useContext } from 'react'; -import CanvasContext from './Context/canvasContext/CanvasContext'; -import ActiveObjectContext from './Context/activeObject/ObjectContext'; -import OpenContext from './Context/openContext/OpenContext'; -import CanvasSetting from './CanvasSetting'; -import { EditPanel } from './EditPanel'; -import ObjectPanel from './ObjectPanel'; -import { AspectCanvas } from './AspectCanvas'; - -const Canvas = () => { - const { canvas } = useContext(CanvasContext); - - const { openSetting, openObjectPanel, openPanel } = useContext(OpenContext); - - const { setActiveObject } = useContext(ActiveObjectContext); - - useEffect(() => { - if (!canvas) return; // Ensure canvas is available - - // Event handler for mouse down - const handleMouseDown = (event) => { - const target = event.target; // Get the clicked target - const activeObject = canvas.getActiveObject(); // Get the active object - - if (target) { - if (target.type === 'group') { - setActiveObject(activeObject); - } else { - setActiveObject(activeObject); - } - } else { - setActiveObject(activeObject); - } - }; - - // Attach the event listener - canvas.on('mouse:down', handleMouseDown); - - // Cleanup function to remove the event listener - return () => { - canvas.off('mouse:down', handleMouseDown); // Remove the listener on unmount - }; - }, [canvas]); // Re-run only when canvas changes - - - const removeSelected = useCallback(() => { - const activeObject = canvas?.getActiveObject(); - const allObjects = canvas?.getObjects(); - - const textObjects = allObjects.filter((obj) => obj.type === 'textbox' || obj.type === 'text' || obj.type === 'i-text'); - - if (activeObject) { - canvas.remove(activeObject); - setActiveObject(null); - } - if (activeObject && textObjects?.length === 1) { - canvas.remove(activeObject); - setActiveObject(null); - } - if (activeObject.length > 1) { - canvas.remove(...activeObject); - setActiveObject(null); - } - }, [canvas, setActiveObject]); - - useEffect(() => { - const handleDeleteKey = (event) => { - if (event.key === 'Delete') { - removeSelected(); - } - }; - window.addEventListener('keydown', handleDeleteKey); - return () => { - window.removeEventListener('keydown', handleDeleteKey); - }; - }, [removeSelected]); - - return ( -
- - {openSetting && - - } - - { - openPanel && - - } - - {openObjectPanel && } - - {/* Main canvas */} - -
- ); -}; - -export default Canvas; diff --git a/src/components/Canvas/Canvas.jsx b/src/components/Canvas/Canvas.jsx index a10d625..07bea1f 100644 --- a/src/components/Canvas/Canvas.jsx +++ b/src/components/Canvas/Canvas.jsx @@ -7,25 +7,9 @@ import ActiveObjectContext from "../Context/activeObject/ObjectContext"; import { Slider } from "@/components/ui/slider"; export default function Canvas() { - const { - setLeftPanelOpen, - setRightPanelOpen, - setOpenSetting, - setOpenObjectPanel, - rightPanelOpen, - } = useContext(OpenContext); + const { setLeftPanelOpen, setRightPanelOpen, setOpenSetting, setOpenObjectPanel, rightPanelOpen } = useContext(OpenContext); - const { - canvasRef, - canvas, - setCanvas, - fabricCanvasRef, - canvasRatio, - setCanvasHeight, - setCanvasWidth, - setScreenWidth, - selectedPanel, - } = useContext(CanvasContext); + const { canvasRef, canvas, setCanvas, fabricCanvasRef, canvasRatio, setCanvasHeight, setCanvasWidth, setScreenWidth, selectedPanel } = useContext(CanvasContext); const { setActiveObject } = useContext(ActiveObjectContext); const [zoomLevel, setZoomLevel] = useState(100); @@ -57,21 +41,6 @@ export default function Canvas() { useEffect(() => { if (!canvas) return; - const handleMouseDown = (event) => { - const target = event.target; - const activeObject = canvas.getActiveObject(); - - if (target) { - if (target.type === "group") { - setActiveObject(activeObject); - } else { - setActiveObject(activeObject); - } - } else { - setActiveObject(activeObject); - } - }; - const handleWheel = (event) => { if (event.ctrlKey || event.metaKey) { event.preventDefault(); @@ -130,8 +99,6 @@ export default function Canvas() { const handleResize = () => { handleZoom(zoomLevel); }; - - canvas.on("mouse:down", handleMouseDown); const canvasContainer = document.getElementById("canvas-ref"); if (canvasContainer) { @@ -148,7 +115,6 @@ export default function Canvas() { } return () => { - canvas.off("mouse:down", handleMouseDown); if (canvasContainer) { canvasContainer.removeEventListener("wheel", handleWheel); canvasContainer.removeEventListener("touchstart", handleTouchStart); @@ -158,7 +124,7 @@ export default function Canvas() { window.removeEventListener("resize", handleResize); } }; - }, [canvas, setActiveObject, zoomLevel, handleZoom]); + }, [canvas, zoomLevel, handleZoom]); useEffect(() => { import("fabric").then((fabricModule) => { @@ -214,20 +180,7 @@ export default function Canvas() { updateCanvasSize(); window.addEventListener("resize", updateCanvasSize); return () => window.removeEventListener("resize", updateCanvasSize); - }, [ - setCanvasWidth, - setCanvasHeight, - canvasRatio, - canvasRef, - canvas, - setLeftPanelOpen, - setOpenObjectPanel, - setRightPanelOpen, - rightPanelOpen, - setScreenWidth, - setOpenSetting, - selectedPanel, - ]); + }, [setCanvasWidth, setCanvasHeight, canvasRatio, canvasRef, canvas, setLeftPanelOpen, setOpenObjectPanel, setRightPanelOpen, rightPanelOpen, setScreenWidth, setOpenSetting, selectedPanel]); useEffect(() => { if (window.fabric) { @@ -253,6 +206,35 @@ export default function Canvas() { } }, [canvasRef, fabricCanvasRef, setCanvas]); + // to set active object + useEffect(() => { + if (!canvas) return; // Ensure canvas is available + + // Event handler for mouse down + const handleMouseDown = (event) => { + const target = event.target; // Get the clicked target + const activeObject = canvas.getActiveObject(); // Get the active object + + if (target) { + if (target.type === 'group') { + setActiveObject(activeObject); + } else { + setActiveObject(activeObject); + } + } else { + setActiveObject(activeObject); + } + }; + + // Attach the event listener + canvas.on('mouse:down', handleMouseDown); + + // Cleanup function to remove the event listener + return () => { + canvas.off('mouse:down', handleMouseDown); // Remove the listener on unmount + }; + }, [canvas, setActiveObject]); + return ( <> {/* Zoom Controls */} @@ -269,10 +251,10 @@ export default function Canvas() {
{/* Canvas Container */} -
+
{ - const { canvas, canvasHeight, canvasWidth, screenWidth } = - useContext(CanvasContext); - const { setOpenSetting } = useContext(OpenContext); - const bgImgRef = useRef(null); + const { canvas } = useContext(CanvasContext); + const params = useParams(); + const { id } = params; + const { toast } = useToast(); + const navigate = useNavigate(); + const [bgImage, setBgImage] = useState(null); + const [bgOverLayImage, setBgOverLayImage] = useState(null); - const [canvasSettings, setCanvasSettings] = useState({ - width: canvas?.width, - height: canvas?.height, - perPixelTargetFind: true, // Enable per-pixel detection globally - targetFindTolerance: 4, // Adjust for leniency in pixel-perfect detection + // create empty project if no id is provided + useEffect(() => { + const createEmptyProject = async () => { + try { + const response = await createProject(); + console.log(response); + if (response?.data?.id) { + navigate(`/${response.data.id}`); + } + } catch (error) { + console.error("Project creation failed:", error); + } + }; + if (!id) { + createEmptyProject(); + } + }, [id, navigate]); + + // upload bg-image handler + const { mutate: uploadBackgroundImage } = useMutation({ + mutationFn: async ({ file, id }) => { + return await uploadImage({ file, id }); + }, + onSuccess: (data) => { + if (data?.status === 200) { + toast({ + title: data?.status, + description: data?.message + }); + setBgImage(data?.data[0]?.url); + + // Create an image element + const imgElement = new Image(); + + // Set the crossOrigin attribute BEFORE setting the src + imgElement.crossOrigin = "anonymous"; // This ensures CORS headers are sent + imgElement.src = data?.data[0]?.url; + + imgElement.onload = () => { + // Create a fabric.Image instance + const img = new fabric.Image(imgElement, { + scaleX: canvas.width / imgElement.width, + scaleY: canvas.height / imgElement.height, + }); + + // Set the background image on the canvas + canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas)); + }; + + imgElement.onerror = (error) => { + console.error('Failed to load image:', error); + toast({ + variant: "destructive", + title: "Image Load Error", + description: "Failed to load the image. Please try again." + }) + }; + } + else { + toast({ + variant: "destructive", + title: data?.status, + description: data?.message + }); + } + } + }) + + // handle bg-image remove + const { mutate: removeBackgroundMutate } = useMutation({ + mutationFn: async (url) => { + return await deleteImage(url); + }, + onSuccess: (data) => { + if (data?.status === 200) { + toast({ + title: data?.status, + description: data?.message + }) + canvas.backgroundImage = null; + canvas.renderAll(); + setBgImage(null); + } + else { + toast({ + variant: "destructive", + title: data?.status, + description: data?.message + }) + } + } }); - const handleChange = (key, value) => { - setCanvasSettings((prevSettings) => ({ - ...prevSettings, - [key]: value, - })); + // upload bg-overLayImage handler + const { mutate: uploadOverlayImage } = useMutation({ + mutationFn: async ({ file, id }) => { + return await uploadImage({ file, id }); + }, + onSuccess: (data) => { + if (data?.status === 200) { + toast({ + title: data?.status, + description: data?.message + }); + setBgOverLayImage(data?.data[0]?.url); + // Create an image element + const imgElement = new Image(); - // Update canvas dimensions - if (key === "width") { - canvas.setWidth(value); // Update canvas width - } else if (key === "height") { - canvas.setHeight(value); // Update canvas height + // Set the crossOrigin attribute BEFORE setting the src + imgElement.crossOrigin = "anonymous"; // This ensures CORS headers are sent + imgElement.src = data?.data[0]?.url; + + imgElement.onload = () => { + // Create a fabric.Image instance + const img = new fabric.Image(imgElement, { + scaleX: canvas.width / imgElement.width, + scaleY: canvas.height / imgElement.height, + }); + + // Set the background image on the canvas + canvas.setOverlayImage(img, canvas.renderAll.bind(canvas)); + }; + + imgElement.onerror = (error) => { + console.error('Failed to load image:', error); + toast({ + variant: "destructive", + title: "Image Load Error", + description: "Failed to load the image. Please try again." + }) + }; + + } + else { + toast({ + variant: "destructive", + title: data?.status, + description: data?.message + }); + } } + }) - // Adjust the background image to fit the updated canvas - const bgImage = canvas.backgroundImage; - if (bgImage) { - const canvasWidth = canvas.width; - const canvasHeight = canvas.height; - - // Calculate scaling factors for width and height - const scaleX = canvasWidth / bgImage.width; - const scaleY = canvasHeight / bgImage.height; - - // Choose the larger scale to cover the entire canvas - const scale = Math.max(scaleX, scaleY); - - // Apply the scale and center the image - bgImage.scaleX = scale; - bgImage.scaleY = scale; - bgImage.left = 0; // Align left - bgImage.top = 0; // Align top - - // Mark the background image as needing an update - canvas.setBackgroundImage(bgImage, canvas.renderAll.bind(canvas)); - } else { - canvas.renderAll(); // Render if no background image + // handle bg-overLayImage remove + const { mutate: removeOverLayMutate } = useMutation({ + mutationFn: async (url) => { + return await deleteImage(url); + }, + onSuccess: (data) => { + if (data?.status === 200) { + toast({ + title: data?.status, + description: data?.message + }) + canvas.overlayImage = null; + canvas.renderAll(); + setBgOverLayImage(null); + } + else { + toast({ + variant: "destructive", + title: data?.status, + description: data?.message + }) + } } - }; + }); const setBackgroundImage = (e) => { const file = e.target.files[0]; if (file) { - const blobUrl = URL.createObjectURL(file); - - // Create an image element - const imgElement = new Image(); - imgElement.src = blobUrl; - - imgElement.onload = () => { - // Create a fabric.Image instance - const img = new fabric.Image(imgElement, { - scaleX: canvas.width / imgElement.width, - scaleY: canvas.height / imgElement.height, - }); - - // Set the background image on the canvas - canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas)); - - // Revoke the object URL to free memory - URL.revokeObjectURL(blobUrl); - }; - - imgElement.onerror = () => { - console.error("Failed to load the image."); - URL.revokeObjectURL(blobUrl); - }; + uploadBackgroundImage({ file, id }) + } + else { + toast({ + variant: "destructive", + title: "Error", + description: "Please select a file", + }) } }; const setBackgroundOverlayImage = (e) => { const file = e.target.files[0]; if (file) { - const blobUrl = URL.createObjectURL(file); - - // Create an image element - const imgElement = new Image(); - imgElement.src = blobUrl; - - imgElement.onload = () => { - const img = new fabric.Image(imgElement, { - scaleX: canvas.width / imgElement.width, - scaleY: canvas.height / imgElement.height, - }); - - // Use setOverlayImage method to add the image as an overlay - canvas.setOverlayImage(img, () => { - canvas.renderAll(); - }); - - // Revoke the object URL after image is loaded and set - URL.revokeObjectURL(blobUrl); - }; + uploadOverlayImage({ file, id }) + } + else { + toast({ + variant: "destructive", + title: "Error", + description: "Please select a file", + }) } }; @@ -143,44 +244,52 @@ const CanvasSetting = () => { const removeBackgroundImage = () => { if (canvas) { - canvas.backgroundImage = null; - canvas.renderAll(); - } - if (bgImgRef.current) { - bgImgRef.current.value = ""; + const bgUrl = canvas.backgroundImage?.getSrc(); + console.log("background image from remove", bgUrl) + if (bgUrl) { + removeBackgroundMutate(bgUrl) + } + else { + toast({ + variant: "destructive", + title: "Error", + description: "No background image found", + }) + } } }; const removeBackgroundOverlayImage = () => { if (canvas) { - canvas.overlayImage = null; - canvas.renderAll(); + const overLayUrl = canvas.overlayImage?.getSrc(); + console.log("overlay image from remove", overLayUrl); + if (overLayUrl) { + removeOverLayMutate(overLayUrl); + } + else { + toast({ + variant: "destructive", + title: "Error", + description: "No overlay image found", + }) + } } }; - const rndValue = { - valueX: 0, - valueY: 20, - width: 250, - height: 0, - minWidth: 250, - maxWidth: 300, - minHeight: 0, - maxHeight: 400, - bound: "parent", - }; - const content = () => { - return ( + useEffect(() => { + if (canvas) { + const bgUrl = canvas.backgroundImage?.getSrc(); + setBgImage(bgUrl); + const overLayUrl = canvas.overlayImage?.getSrc(); + setBgOverLayImage(overLayUrl); + } + }, [canvas, setBgImage, setBgOverLayImage]) + + return ( +
- Canvas Setting{" "} - {" "} + Canvas Setting @@ -192,50 +301,74 @@ const CanvasSetting = () => {
+ { + bgImage && canvas_bg_image + }
- + { + !bgImage && + + } - + { + bgImage && + + }
+
+ { + bgImage ? : + } +
+ { + bgOverLayImage && canvas_bgOverLay_image + }
- + { + !bgOverLayImage && + + } - + { + bgOverLayImage && + + }
+
+ { + bgOverLayImage ? : + } {/* opacity */}
@@ -255,46 +388,16 @@ const CanvasSetting = () => { - {/* canvas size customization (width/height) */} -
-
- - { - if (canvasWidth > parseInt(e.target.value)) { - handleChange("width", parseInt(e.target.value, 10)); - } - }} - /> -
+ {/* Save canvas Component */} + { + id && + + } -
- - { - if (canvasHeight > parseInt(e.target.value)) { - handleChange("height", parseInt(e.target.value, 10)); - } - }} - /> -
-
- ); - }; - - return screenWidth <= 768 ? ( - {content()} - ) : ( -
{content()}
+
); }; diff --git a/src/components/Context/authContext/AuthContext.js b/src/components/Context/authContext/AuthContext.js new file mode 100644 index 0000000..a33a777 --- /dev/null +++ b/src/components/Context/authContext/AuthContext.js @@ -0,0 +1,5 @@ +import react from "react"; + +const AuthContext = react.createContext(); + +export default AuthContext; \ No newline at end of file diff --git a/src/components/Context/authContext/AuthProvider.jsx b/src/components/Context/authContext/AuthProvider.jsx new file mode 100644 index 0000000..d1d8fe6 --- /dev/null +++ b/src/components/Context/authContext/AuthProvider.jsx @@ -0,0 +1,18 @@ +import { useState } from "react"; +import AuthContext from "./authContext"; + +const AuthContextProvider = ({ children }) => { + const [user, setUser] = useState({ + token: null, + userId: null, + currentProjectId: null, + }); + + return ( + + {children} + + ); +} + +export default AuthContextProvider; \ No newline at end of file diff --git a/src/components/EachComponent/UploadImage.jsx b/src/components/EachComponent/UploadImage.jsx index 310bb38..753ab95 100644 --- a/src/components/EachComponent/UploadImage.jsx +++ b/src/components/EachComponent/UploadImage.jsx @@ -1,4 +1,4 @@ -import { useContext, useRef, useState } from "react"; +import { useContext, useEffect, useRef, useState } from "react"; import CanvasContext from "../Context/canvasContext/CanvasContext"; import { Button } from "@/components/ui/button"; import { fabric } from "fabric"; @@ -25,6 +25,11 @@ import { useDropzone } from "react-dropzone"; import ImageCustomization from "./Customization/ImageCustomization"; import { Separator } from "../ui/separator"; import ActiveObjectContext from "../Context/activeObject/ObjectContext"; +import { useNavigate, useParams } from "react-router-dom"; +import { useMutation } from "@tanstack/react-query"; +import { deleteImage, uploadImage } from "../../api/uploadApi"; +import { createProject } from "../../api/projectApi"; +import { useToast } from "../../hooks/use-toast"; const UploadImage = () => { const { canvas } = useContext(CanvasContext); @@ -37,9 +42,92 @@ const UploadImage = () => { const { activeObject, setActiveObject } = useContext(ActiveObjectContext); + const params = useParams(); + const { id } = params; + const [file, setFile] = useState(null); const [preview, setPreview] = useState(null); + const { toast } = useToast(); + const navigate = useNavigate(); + + // create empty project if no id is provided + useEffect(() => { + const createEmptyProject = async () => { + try { + const response = await createProject(); + if (response?.data?.id) { + navigate(`/${response.data.id}`); + } + } catch (error) { + console.error("Project creation failed:", error); + } + }; + if (!id) { + createEmptyProject(); + } + }, [id, navigate]); + + // upload image handler + const { mutate } = useMutation({ + mutationFn: async ({ file, id }) => { + return await uploadImage({ file, id }); + }, + onSuccess: (data) => { + if (data?.status === 200) { + toast({ + title: data?.status, + description: data?.message + }); + fabric.Image.fromURL( + data?.data[0]?.url, + (img) => { + img.applyFilters(); + img.scale(0.5); + img.set("top", canvas.width / 4); + img.set("left", canvas.height / 4); + canvas.add(img); + canvas.setActiveObject(img); + // Update the active object state + setActiveObject(img); + canvas.renderAll(); + }, + { crossOrigin: "anonymous" } + ); + } + else { + toast({ + variant: "destructive", + title: data?.status, + description: data?.message + }); + removeFile(); + } + } + }) + + // handle image remove + const { mutate: deleteMutate } = useMutation({ + mutationFn: async (url) => { + return await deleteImage(url); + }, + onSuccess: (data) => { + if (data?.status === 200) { + toast({ + title: data?.status, + description: data?.message + }) + } + else { + toast({ + variant: "destructive", + title: data?.status, + description: data?.message + }) + } + } + }); + const { getRootProps, getInputProps, isDragActive } = useDropzone({ accept: { "image/*": [".jpeg", ".png", ".gif", ".jpg", ".webp", ".svg"], @@ -55,7 +143,6 @@ const UploadImage = () => { // Create a preview URL const blobUrl = URL.createObjectURL(selectedFile); setFile(selectedFile); - setPreview(blobUrl); if (selectedFile.type === "image/svg+xml") { addImageToCanvas(selectedFile); @@ -94,45 +181,66 @@ const UploadImage = () => { fileInputRef.current.value = ""; } if (activeObject?.type === "image") { + const imgUrl = activeObject?._originalElement?.currentSrc; canvas.remove(activeObject); setActiveObject(null); canvas.renderAll(); + deleteMutate(imgUrl); } }; - const handleResize = (file, callback) => { - Resizer.imageFileResizer( - file, - width, - height, - format, - quality, - parseInt(rotation), - (resizedFile) => { - callback(resizedFile); - }, - "file" - ); + const handleResize = (selectedFile, callback) => { + const img = new Image(); + img.src = URL.createObjectURL(selectedFile); + + img.onload = () => { + let newWidth = width; // User-defined width + let newHeight = height; // User-defined height + + const aspectRatio = img.width / img.height; + + // If the user provided only one dimension, maintain aspect ratio + if (!width) { + newWidth = Math.round(newHeight * aspectRatio); + } else if (!height) { + newHeight = Math.round(newWidth / aspectRatio); + } + + Resizer.imageFileResizer( + selectedFile, + newWidth, // Use user-defined width or calculated width + newHeight, // Use user-defined height or calculated height + format, + quality, + parseInt(rotation), + (resizedFile) => { + callback(resizedFile); + }, + 'file' + ); + URL.revokeObjectURL(img.src); // Cleanup + }; + + img.onerror = () => { + console.error("Failed to load image for resizing."); + URL.revokeObjectURL(img.src); // Cleanup + }; }; - const addImageToCanvas = (file) => { - const blobUrl = URL.createObjectURL(file); - fabric.Image.fromURL(blobUrl, (img) => { - img.set({ - left: canvas.width / 4, - top: canvas.height / 4, - scaleX: 0.5, - scaleY: 0.5, - }); - canvas.add(img); - canvas.setActiveObject(img); - // Update the active object state - setActiveObject(img); - canvas.renderAll(); - URL.revokeObjectURL(blobUrl); - }); + const addImageToCanvas = (selectedFile) => { + mutate({ file: selectedFile, id }) }; + // useEffect for preview update + useEffect(() => { + if (activeObject?.type === "image") { + setPreview(activeObject._originalElement?.currentSrc); + } + else { + setPreview(null); + } + }, [activeObject]); + return ( @@ -223,19 +331,17 @@ const UploadImage = () => {

{isDragActive diff --git a/src/components/FabricCanvas.jsx b/src/components/FabricCanvas.jsx deleted file mode 100644 index 385cfbe..0000000 --- a/src/components/FabricCanvas.jsx +++ /dev/null @@ -1,69 +0,0 @@ -import React, { useEffect, useRef, useState } from 'react'; -import { fabric } from 'fabric'; - -const FabricCanvas = () => { - const canvasRef = useRef(null); - const [canvas, setCanvas] = useState(null); - - // Canvas settings - const canvasSettings = { - width: 800, - height: 600, - }; - - useEffect(() => { - // Initialize the canvas - const newCanvas = new fabric.Canvas(canvasRef.current, { - backgroundColor: 'black', - selection: true, - height: canvasSettings.height, - width: canvasSettings.width, - controlsAboveOverlay: true, - preserveObjectStacking: true, - }); - - // Create the clipping path (rectangle) - const clipPath = new fabric.Rect({ - width: 300, - height: 300, - left: (canvasSettings.width - 300) / 2, // Center horizontally - top: (canvasSettings.height - 300) / 2, // Center vertically - fill: 'transparent', // Transparent fill - stroke: 'red', // White outline - strokeWidth: 2, - absolutePositioned: true, // Important for clipping path - }); - - // Apply the clipPath to the canvas - newCanvas.clipPath = clipPath; - - // Add the clipping path to visualize it - newCanvas.add(clipPath); - - // Add a sample object to the canvas - const rect = new fabric.Rect({ - width: 100, - height: 100, - fill: 'orange', - left: 200, - top: 150, - }); - newCanvas.add(rect); - - // Save the canvas instance - setCanvas(newCanvas); - - // Clean up on unmount - return () => { - newCanvas.dispose(); - }; - }, []); - - return ( -

- -
- ); -}; - -export default FabricCanvas; diff --git a/src/components/Layouts/LeftSidebar.jsx b/src/components/Layouts/LeftSidebar.jsx index ed4de47..73f69d5 100644 --- a/src/components/Layouts/LeftSidebar.jsx +++ b/src/components/Layouts/LeftSidebar.jsx @@ -24,7 +24,7 @@ const sidebarItems = [ export function Sidebar() { const { selectedPanel, setSelectedPanel } = useContext(CanvasContext); return ( -
+
{sidebarItems.map((item) => { const Icon = item.icon; return ( diff --git a/src/components/Layouts/SheetLeftPanel.jsx b/src/components/Layouts/SheetLeftPanel.jsx deleted file mode 100644 index 63d09ce..0000000 --- a/src/components/Layouts/SheetLeftPanel.jsx +++ /dev/null @@ -1,79 +0,0 @@ -import { Sheet, SheetContent, SheetDescription } from '../ui/sheet'; -import AddShapes from './AddShapes'; -import { Separator } from '../ui/separator'; -import { Button } from '../ui/button'; -import { X, Store, Shapes, Upload } from "lucide-react"; -import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs'; -import AllIconsPage from '../EachComponent/Icons/AllIcons'; -import UploadImage from '../EachComponent/UploadImage'; -import { useContext } from 'react'; -import OpenContext from '../Context/openContext/OpenContext'; - -const left = "left"; - -const SheetLeftPanel = () => { - const { leftPanelOpen, setLeftPanelOpen } = useContext(OpenContext); - - // Prevent closing on outside clicks - const handleOpenChange = (isOpen) => { - if (!isOpen) { - // Do nothing when clicking outside - return; // Sheet won't close - } - setLeftPanelOpen(isOpen); // Update only on valid trigger - }; - - // Function to handle closing the sheet - const handleClose = () => { - setLeftPanelOpen(false); // Close when button is clicked - }; - - return ( - - - -

Your customizable, canvas playground.

- -
- - - - - - -

Shapes & Text

-
- - - -

Icons

-
- - - -

Image

-
-
- - - - - - - - - - - - - - -
-
-
- ) -} - -export default SheetLeftPanel \ No newline at end of file diff --git a/src/components/Layouts/SheetRightPanel.jsx b/src/components/Layouts/SheetRightPanel.jsx deleted file mode 100644 index b95b6b5..0000000 --- a/src/components/Layouts/SheetRightPanel.jsx +++ /dev/null @@ -1,88 +0,0 @@ -import { - Sheet, - SheetContent, - SheetDescription, - SheetHeader, - SheetTitle, -} from "@/components/ui/sheet" -import CustomizeShape from "../EachComponent/CustomizeShape"; -import { Separator } from "../ui/separator"; -import { Button } from "../ui/button"; -import { X } from "lucide-react"; -import { useContext, useEffect, useState } from "react"; -import ActiveObjectContext from "../Context/activeObject/ObjectContext"; -import OpenContext from "../Context/openContext/OpenContext"; -import CanvasSetting from "../CanvasSetting"; -import CollapsibleComponent from "../EachComponent/Customization/CollapsibleComponent"; -import { Card } from "../ui/card"; - -const SheetRightPanel = () => { - const { rightPanelOpen, setRightPanelOpen } = useContext(OpenContext) - - const { activeObject } = useContext(ActiveObjectContext); - - const [open, setOpen] = useState(false); - - useEffect(() => { - if (activeObject) { - setOpen(true); - } - }, [activeObject]) - - // Prevent closing on outside clicks - const handleOpenChange = (isOpen) => { - if (!isOpen) { - - // Do nothing when clicking outside - return; // Sheet won't close - } - setRightPanelOpen(isOpen); // Update only - }; - - // Function to handle closing the sheet - const handleClose = () => { - setRightPanelOpen(false); // Close when button is clicked - }; - - return ( - - - - - Edit Customization - - - - - Customize each shapes, and text as per your choice. - - - - - - -
-
- - -
- -
-
-
-
-
- - { - open ? :

No active object found

- } -
-
-
-
- ) -} - -export default SheetRightPanel; diff --git a/src/components/ObjectPanel.jsx b/src/components/ObjectPanel.jsx deleted file mode 100644 index 8968c9d..0000000 --- a/src/components/ObjectPanel.jsx +++ /dev/null @@ -1,151 +0,0 @@ -import { Button } from './ui/button' -import { Card, CardHeader, CardTitle } from './ui/card' -import { Collapsible, CollapsibleContent, CollapsibleTrigger } from './ui/collapsible' -import { Tabs, TabsContent, TabsList, TabsTrigger } from './ui/tabs' -import { useContext, useState } from 'react' -import { PencilRuler, Shapes, Store, Upload, ChevronDown, ChevronUp, X } from 'lucide-react'; -import OpenContext from './Context/openContext/OpenContext'; -import AllIconsPage from './EachComponent/Icons/AllIcons' -import { Separator } from './ui/separator' -import { ScrollArea } from './ui/scroll-area' -import AddShapes from './Layouts/AddShapes' -import UploadImage from './EachComponent/UploadImage' -import CustomizeShape from './EachComponent/CustomizeShape' -import RndComponent from './Layouts/RndComponent' - -const ObjectPanel = () => { - const [isCollapsed, setIsCollapsed] = useState(false); - const { tabValue, setTabValue, setOpenObjectPanel } = useContext(OpenContext); - - const rndValue = { - valueX: 0, - valueY: 20, - width: 250, - height: 0, - minWidth: 280, - maxWidth: 300, - minHeight: 0, - maxHeight: 500, - bound: "parent" - } - - return ( - - - -
- - Object Panel -
-
- - setIsCollapsed(!open)}> - - - - - - -
- setTabValue(value)} // Sync tab state with context - > - - - setTabValue("icons")} - > - - Icons - - - setTabValue("shapes")} - > - - Shapes - - - setTabValue("images")} - > - - Images - - - setTabValue("customize")} - > - - Customize - - - - {/* All icons */} - -
- -
-
- - {/* All shapes */} - -
- Shapes - - - - -
-
- - {/* Upload images */} - -
- Upload - - - - - - -
-
- - {/* Customization */} - -
- Object customization - - - - -
-
- -
- -
- -
- -
- -
- -
- ) -} - -export default ObjectPanel \ No newline at end of file diff --git a/src/components/ObjectShortcut.jsx b/src/components/ObjectShortcut.jsx index c99018e..40e376b 100644 --- a/src/components/ObjectShortcut.jsx +++ b/src/components/ObjectShortcut.jsx @@ -20,6 +20,9 @@ import { Layers, } from "lucide-react"; import { Popover, PopoverContent, PopoverTrigger } from "./ui/popover"; +import { useMutation } from "@tanstack/react-query"; +import { deleteImage } from "../api/uploadApi"; +import { toast } from "../hooks/use-toast"; export const ObjectShortcut = ({ value }) => { const { canvas } = useContext(CanvasContext); @@ -51,7 +54,11 @@ export const ObjectShortcut = ({ value }) => { setActiveObject(group); canvas.renderAll(); } else { - console.log("Select at least two objects"); + toast({ + title: "Select at least two objects", + description: "Please select at least two objects to group.", + variant: "destructive", + }) } }; @@ -136,6 +143,27 @@ export const ObjectShortcut = ({ value }) => { } }; + const { mutate: deleteMutate } = useMutation({ + mutationFn: async (url) => { + return await deleteImage(url); + }, + onSuccess: (data) => { + if (data?.status === 200) { + toast({ + title: data?.status, + description: data?.message + }) + } + else { + toast({ + variant: "destructive", + title: data?.status, + description: data?.message + }) + } + } + }); + // Remove Selected Element const removeSelected = useCallback(() => { const activeObject = canvas?.getActiveObject(); @@ -159,7 +187,15 @@ export const ObjectShortcut = ({ value }) => { canvas.remove(...activeObject); setActiveObject(null); } - }, [canvas, setActiveObject]); + + if (activeObject?.type === "image") { + const imgUrl = activeObject?._originalElement?.currentSrc; + canvas.remove(activeObject); + setActiveObject(null); + canvas.renderAll(); + deleteMutate(imgUrl); + } + }, [canvas, setActiveObject, deleteMutate]); // duplicating current objects const duplicating = () => { @@ -184,11 +220,10 @@ export const ObjectShortcut = ({ value }) => {
{multipleObjects && ( { + return ( +
+
+

404

+
+
+ ? +
+ +
+

Page Not Found

+

Oops! The page you are looking for does not exist or has been moved.

+ + Go Back to Dashboard + +
+
+
+
+ ) +} + +export default NotFound + diff --git a/src/components/Pages/UnAuthenticated.jsx b/src/components/Pages/UnAuthenticated.jsx new file mode 100644 index 0000000..4df26b2 --- /dev/null +++ b/src/components/Pages/UnAuthenticated.jsx @@ -0,0 +1,32 @@ +import { Lock } from "lucide-react" + +const Unauthenticated = () => { + return ( +
+
+
+
+ ! +
+ +
+

Access Denied

+

Authentication Required

+

+ Sorry, you need to be authenticated to access this page. Please log in to continue. +

+ + Go Back to Dashboard + +
+
+
+
+ ) +} + +export default Unauthenticated + diff --git a/src/components/Panel/EditorPanel.jsx b/src/components/Panel/EditorPanel.jsx index 092c183..ef328b0 100644 --- a/src/components/Panel/EditorPanel.jsx +++ b/src/components/Panel/EditorPanel.jsx @@ -50,7 +50,7 @@ const EditorPanel = () => { return ( <> {selectedPanel !== "" && ( -
+
{renderPanel()}
)} diff --git a/src/components/Panel/TopBar.jsx b/src/components/Panel/TopBar.jsx index 901de91..8e6da74 100644 --- a/src/components/Panel/TopBar.jsx +++ b/src/components/Panel/TopBar.jsx @@ -37,11 +37,10 @@ export function TopBar() { return (
setShowScrollButtons(true)} onMouseLeave={() => setShowScrollButtons(false)} > @@ -84,6 +83,7 @@ export function TopBar() { Add image + {/* canvas settings */}
+ {activeObject?.type !== "group" && ( @@ -206,6 +207,7 @@ export function TopBar() { )} + { + const { canvas } = useContext(CanvasContext); + const { setSelectedPanel } = useContext(CanvasContext); + const { setActiveObject } = useContext(ActiveObjectContext); + + const [saveCanvas, setSaveCanvas] = useState({ + name: "", + description: "", + preview_url: "", + }); + + const params = useParams(); + const { id } = params; + const { toast } = useToast(); + const navigate = useNavigate(); + + const queryClient = useQueryClient(); + + // to get each canvas_project data + const { data: projectData, isLoading: projectLoading } = useQuery({ + queryKey: ['project', id], + queryFn: async () => await getProjectById(id), + enabled: !!id, + }); + + // to update the project + const { mutate: projectUpdate, isPending } = useMutation({ + mutationFn: async ({ id, projectData }) => { + return await updateProject({ id, ...projectData }) + }, + onSuccess: (data) => { + if (data?.status === 200) { + toast({ + title: data?.status, + description: data?.message, + }) + console.log(data); + // Invalidate a single query key + queryClient.invalidateQueries({ queryKey: ["project", id] }); + + // to load the object into canvas + // canvas.loadFromJSON(data?.data?.object, () => { + // canvas.renderAll(); + // }, (err) => { + // console.error('Error loading object:', err); + // }); + } + else { + toast({ + title: data?.status, + description: data?.message, + variant: "destructive" + }) + } + } + }) + + // to delete the project + const { mutate: projectDelete, isPending: deletePending } = useMutation({ + mutationFn: async (id) => { + return await deleteProject(id) + }, + onSuccess: (data) => { + if (data?.status === 200) { + toast({ + title: data?.status, + description: data?.message, + }) + // Invalidate a single query key + queryClient.invalidateQueries({ queryKey: ["project", id] }); + setSelectedPanel(""); + navigate("/"); + // for clear canvas + canvas.clear(); + canvas.renderAll(); + canvas.setBackgroundColor("#ffffff", canvas.renderAll.bind(canvas)); + setActiveObject(null); + } + else { + toast({ + title: data?.status, + description: data?.message, + variant: "destructive" + }) + } + } + }) + + // to set projectData into state + useEffect(() => { + if (projectData?.data && !projectLoading && projectData?.data?.preview_url !== null) { + setSaveCanvas((prev) => ({ + ...prev, + name: projectData?.data?.name, + description: projectData?.data?.description, + preview_url: projectData?.data?.preview_url + })); + } + }, [projectData, projectLoading]); + + // upload preview-image handler + const { mutate: uploadCanvasImage, isPending: uploadCanvasPending } = useMutation({ + mutationFn: async ({ file, id }) => { + return await uploadImage({ file, id }); + }, + onSuccess: (data) => { + if (data?.status === 200) { + toast({ + title: data?.status, + description: data?.message + }); + console.log(data?.data[0]?.url); + handleSaveWithPreViewImage({ preview_url: data?.data[0]?.url, name: saveCanvas?.name, description: saveCanvas?.description }); + } + else { + toast({ + variant: "destructive", + title: data?.status, + description: data?.message + }); + } + } + }) + + // preview-image remove handler + const { mutate: removeCanvasImage, isPending: removeCanvasPending } = useMutation({ + mutationFn: async (url) => { + return await deleteImage(url); + }, + onSuccess: async (data) => { + console.log(data); + if (data?.status === 200) { + toast({ + title: data?.status, + description: data?.message + }) + const file = await captureImage(); + if (file) { + uploadCanvasImage({ file, id }); + } + } + else { + toast({ + variant: "destructive", + title: data?.status, + description: data?.message + }) + } + } + }); + + const handleSaveProject = async () => { + if (!saveCanvas?.name || saveCanvas?.name.trim() === "") { + toast({ + title: "Name error", + description: "Please enter a name for your project", + variant: "destructive" + }); + return; // Exit the function early + } + + // Check if preview_url is valid + + if (saveCanvas?.preview_url) { + try { + removeCanvasImage(saveCanvas?.preview_url); + console.log("Image removed", saveCanvas?.preview_url); + } catch (error) { + console.error("Error removing image:", error); + } + } else { + try { + console.log("Capturing image..."); + const file = await captureImage(); + console.log("Captured file:", file); + + if (file) { + uploadCanvasImage({ file, id }); + console.log("Image uploaded successfully"); + } + } catch (error) { + console.error("Error capturing image:", error); + } + } + }; + + // this will save the canvas as a json object + const handleSaveWithPreViewImage = (body) => { + const object = canvas.toJSON(['id', 'selectable']); // Include any custom properties you need + if (object?.objects?.length === 0) { + toast({ + title: "Canvas is empty", + description: "Please add some elements to your canvas", + variant: "destructive" + }); + } else { + const projectData = { ...body, object }; + // Wait for the project update before continuing + projectUpdate({ id, projectData }); + } + } + + // this will capture canvas so that it will be saved as a preview_image for each project + const captureImage = async () => { + if (!canvas) return; + + const width = canvas.width; + const height = canvas.height; + + // Create a temporary canvas + const tempCanvas = document.createElement('canvas'); + const tempCtx = tempCanvas.getContext('2d'); + + tempCanvas.width = width; + tempCanvas.height = height; + + // Convert canvas content to data URL + const dataUrl = canvas.toDataURL('image/jpeg', 1); + + return new Promise((resolve, reject) => { + const img = new Image(); + + // Set cross-origin attribute to avoid CORS issues + img.crossOrigin = "anonymous"; + img.src = dataUrl; + + img.onload = () => { + tempCtx.drawImage(img, 0, 0, width, height); + + // Generate final image as JPEG + const resizedDataUrl = tempCanvas.toDataURL('image/jpeg', 1); + + // Convert the data URL to Blob + fetch(resizedDataUrl) + .then(res => res.blob()) + .then(blob => { + const file = new File([blob], `PlanPostAi-capture.jpg`, { + type: 'image/jpeg', + }); + resolve(file); + }) + .catch(reject); + }; + + img.onerror = (error) => { + console.error("Image loading error:", error); + reject(error); + }; + }); + }; + + const handleDeleteProject = () => { + projectDelete(id); + } + + return ( +
+

Save Canvas

+
+ { + saveCanvas?.preview_url && + + } +
+
+ + setSaveCanvas({ ...saveCanvas, name: e.target.value })} + placeholder="Project name" + /> + +