From a95019424716de6d4f7aa7df6f29799db5894b38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Mur=C3=A7a?= Date: Thu, 10 Nov 2022 17:46:23 -0300 Subject: [PATCH] Initial commit --- .gitignore | 24 + .vscode/extensions.json | 3 + README.md | 47 ++ index.html | 25 + jsconfig.json | 33 ++ package-lock.json | 1078 +++++++++++++++++++++++++++++++++++++++ package.json | 19 + public/vite.svg | 1 + src/App.svelte | 22 + src/app.css | 29 ++ src/lib/Counter.svelte | 143 ++++++ src/lib/jdataview.js | 848 ++++++++++++++++++++++++++++++ src/lib/main.js | 64 +++ src/lib/pattern.js | 177 +++++++ src/lib/pesformat.js | 140 +++++ src/main.js | 8 + src/vite-env.d.ts | 2 + vite.config.js | 7 + 18 files changed, 2670 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/extensions.json create mode 100644 README.md create mode 100644 index.html create mode 100644 jsconfig.json create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/vite.svg create mode 100644 src/App.svelte create mode 100644 src/app.css create mode 100644 src/lib/Counter.svelte create mode 100644 src/lib/jdataview.js create mode 100644 src/lib/main.js create mode 100644 src/lib/pattern.js create mode 100644 src/lib/pesformat.js create mode 100644 src/main.js create mode 100644 src/vite-env.d.ts create mode 100644 vite.config.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..bdef820 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["svelte.svelte-vscode"] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..69c2ac5 --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +# Svelte + Vite + +This template should help get you started developing with Svelte in Vite. + +## Recommended IDE Setup + +[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). + +## Need an official Svelte framework? + +Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more. + +## Technical considerations + +**Why use this over SvelteKit?** + +- It brings its own routing solution which might not be preferable for some users. +- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app. + +This template contains as little as possible to get started with Vite + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project. + +Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate. + +**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?** + +Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information. + +**Why include `.vscode/extensions.json`?** + +Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project. + +**Why enable `checkJs` in the JS template?** + +It is likely that most cases of changing variable types in runtime are likely to be accidental, rather than deliberate. This provides advanced typechecking out of the box. Should you like to take advantage of the dynamically-typed nature of JavaScript, it is trivial to change the configuration. + +**Why is HMR not preserving my local component state?** + +HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr). + +If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. + +```js +// store.js +// An extremely simple external store +import { writable } from 'svelte/store' +export default writable(0) +``` diff --git a/index.html b/index.html new file mode 100644 index 0000000..96fb201 --- /dev/null +++ b/index.html @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + Embroidery Viewer + + + +
+ + + + \ No newline at end of file diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..e596c58 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "moduleResolution": "Node", + "target": "ESNext", + "module": "ESNext", + /** + * svelte-preprocess cannot figure out whether you have + * a value or a type, so tell TypeScript to enforce using + * `import type` instead of `import` for Types. + */ + "importsNotUsedAsValues": "error", + "isolatedModules": true, + "resolveJsonModule": true, + /** + * To have warnings / errors of the Svelte compiler at the + * correct position, enable source maps by default. + */ + "sourceMap": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + /** + * Typecheck JS in `.svelte` and `.js` files by default. + * Disable this if you'd like to use dynamic types. + */ + "checkJs": true + }, + /** + * Use global.d.ts instead of compilerOptions.types + * to avoid limiting type declarations. + */ + "include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"] +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..3e82b65 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1078 @@ +{ + "name": "embroidery-viewer", + "version": "0.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "embroidery-viewer", + "version": "0.0.0", + "dependencies": { + "jdataview": "^2.5.0" + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^1.1.0", + "svelte": "^3.52.0", + "vite": "^3.2.3" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.13.tgz", + "integrity": "sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.13.tgz", + "integrity": "sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.1.0.tgz", + "integrity": "sha512-cFRfEdztubtj1c/rYh7ArK7XCfFJn6wG6+J8/e9amFsKtEJILovoBrK0/mxt1AjPQg0vaX+fHPKvhx+q8mTPaQ==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "deepmerge": "^4.2.2", + "kleur": "^4.1.5", + "magic-string": "^0.26.7", + "svelte-hmr": "^0.15.0" + }, + "engines": { + "node": "^14.18.0 || >= 16" + }, + "peerDependencies": { + "diff-match-patch": "^1.0.5", + "svelte": "^3.44.0", + "vite": "^3.0.0" + }, + "peerDependenciesMeta": { + "diff-match-patch": { + "optional": true + } + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/esbuild": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.13.tgz", + "integrity": "sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.15.13", + "@esbuild/linux-loong64": "0.15.13", + "esbuild-android-64": "0.15.13", + "esbuild-android-arm64": "0.15.13", + "esbuild-darwin-64": "0.15.13", + "esbuild-darwin-arm64": "0.15.13", + "esbuild-freebsd-64": "0.15.13", + "esbuild-freebsd-arm64": "0.15.13", + "esbuild-linux-32": "0.15.13", + "esbuild-linux-64": "0.15.13", + "esbuild-linux-arm": "0.15.13", + "esbuild-linux-arm64": "0.15.13", + "esbuild-linux-mips64le": "0.15.13", + "esbuild-linux-ppc64le": "0.15.13", + "esbuild-linux-riscv64": "0.15.13", + "esbuild-linux-s390x": "0.15.13", + "esbuild-netbsd-64": "0.15.13", + "esbuild-openbsd-64": "0.15.13", + "esbuild-sunos-64": "0.15.13", + "esbuild-windows-32": "0.15.13", + "esbuild-windows-64": "0.15.13", + "esbuild-windows-arm64": "0.15.13" + } + }, + "node_modules/esbuild-android-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.13.tgz", + "integrity": "sha512-yRorukXBlokwTip+Sy4MYskLhJsO0Kn0/Fj43s1krVblfwP+hMD37a4Wmg139GEsMLl+vh8WXp2mq/cTA9J97g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.13.tgz", + "integrity": "sha512-TKzyymLD6PiVeyYa4c5wdPw87BeAiTXNtK6amWUcXZxkV51gOk5u5qzmDaYSwiWeecSNHamFsaFjLoi32QR5/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.13.tgz", + "integrity": "sha512-WAx7c2DaOS6CrRcoYCgXgkXDliLnFv3pQLV6GeW1YcGEZq2Gnl8s9Pg7ahValZkpOa0iE/ojRVQ87sbUhF1Cbg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.13.tgz", + "integrity": "sha512-U6jFsPfSSxC3V1CLiQqwvDuj3GGrtQNB3P3nNC3+q99EKf94UGpsG9l4CQ83zBs1NHrk1rtCSYT0+KfK5LsD8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.13.tgz", + "integrity": "sha512-whItJgDiOXaDG/idy75qqevIpZjnReZkMGCgQaBWZuKHoElDJC1rh7MpoUgupMcdfOd+PgdEwNQW9DAE6i8wyA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.13.tgz", + "integrity": "sha512-6pCSWt8mLUbPtygv7cufV0sZLeylaMwS5Fznj6Rsx9G2AJJsAjQ9ifA+0rQEIg7DwJmi9it+WjzNTEAzzdoM3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.13.tgz", + "integrity": "sha512-VbZdWOEdrJiYApm2kkxoTOgsoCO1krBZ3quHdYk3g3ivWaMwNIVPIfEE0f0XQQ0u5pJtBsnk2/7OPiCFIPOe/w==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.13.tgz", + "integrity": "sha512-rXmnArVNio6yANSqDQlIO4WiP+Cv7+9EuAHNnag7rByAqFVuRusLbGi2697A5dFPNXoO//IiogVwi3AdcfPC6A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.13.tgz", + "integrity": "sha512-Ac6LpfmJO8WhCMQmO253xX2IU2B3wPDbl4IvR0hnqcPrdfCaUa2j/lLMGTjmQ4W5JsJIdHEdW12dG8lFS0MbxQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.13.tgz", + "integrity": "sha512-alEMGU4Z+d17U7KQQw2IV8tQycO6T+rOrgW8OS22Ua25x6kHxoG6Ngry6Aq6uranC+pNWNMB6aHFPh7aTQdORQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.13.tgz", + "integrity": "sha512-47PgmyYEu+yN5rD/MbwS6DxP2FSGPo4Uxg5LwIdxTiyGC2XKwHhHyW7YYEDlSuXLQXEdTO7mYe8zQ74czP7W8A==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.13.tgz", + "integrity": "sha512-z6n28h2+PC1Ayle9DjKoBRcx/4cxHoOa2e689e2aDJSaKug3jXcQw7mM+GLg+9ydYoNzj8QxNL8ihOv/OnezhA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.13.tgz", + "integrity": "sha512-+Lu4zuuXuQhgLUGyZloWCqTslcCAjMZH1k3Xc9MSEJEpEFdpsSU0sRDXAnk18FKOfEjhu4YMGaykx9xjtpA6ow==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.13.tgz", + "integrity": "sha512-BMeXRljruf7J0TMxD5CIXS65y7puiZkAh+s4XFV9qy16SxOuMhxhVIXYLnbdfLrsYGFzx7U9mcdpFWkkvy/Uag==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.13.tgz", + "integrity": "sha512-EHj9QZOTel581JPj7UO3xYbltFTYnHy+SIqJVq6yd3KkCrsHRbapiPb0Lx3EOOtybBEE9EyqbmfW1NlSDsSzvQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.13.tgz", + "integrity": "sha512-nkuDlIjF/sfUhfx8SKq0+U+Fgx5K9JcPq1mUodnxI0x4kBdCv46rOGWbuJ6eof2n3wdoCLccOoJAbg9ba/bT2w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-sunos-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.13.tgz", + "integrity": "sha512-jVeu2GfxZQ++6lRdY43CS0Tm/r4WuQQ0Pdsrxbw+aOrHQPHV0+LNOLnvbN28M7BSUGnJnHkHm2HozGgNGyeIRw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-32": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.13.tgz", + "integrity": "sha512-XoF2iBf0wnqo16SDq+aDGi/+QbaLFpkiRarPVssMh9KYbFNCqPLlGAWwDvxEVz+ywX6Si37J2AKm+AXq1kC0JA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.13.tgz", + "integrity": "sha512-Et6htEfGycjDrtqb2ng6nT+baesZPYQIW+HUEHK4D1ncggNrDNk3yoboYQ5KtiVrw/JaDMNttz8rrPubV/fvPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.13.tgz", + "integrity": "sha512-3bv7tqntThQC9SWLRouMDmZnlOukBhOCTlkzNqzGCmrkCJI7io5LLjwJBOVY6kOUlIvdxbooNZwjtBvj+7uuVg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/jdataview": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/jdataview/-/jdataview-2.5.0.tgz", + "integrity": "sha512-ZJop3D5nyDcWPBPv4NPnhCvx3HgQNsCXMfw8gpNKY16BobgxmVF+kJ08aHuqk6bJQVeL2mkf6nDCcZPMompalw==" + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/magic-string": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz", + "integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.8" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/postcss": { + "version": "8.4.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", + "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svelte": { + "version": "3.52.0", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.52.0.tgz", + "integrity": "sha512-FxcnEUOAVfr10vDU5dVgJN19IvqeHQCS1zfe8vayTfis9A2t5Fhx+JDe5uv/C3j//bB1umpLJ6quhgs9xyUbCQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/svelte-hmr": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.0.tgz", + "integrity": "sha512-Aw21SsyoohyVn4yiKXWPNCSW2DQNH/76kvUnE9kpt4h9hcg9tfyQc6xshx9hzgMfGF0kVx0EGD8oBMWSnATeOg==", + "dev": true, + "engines": { + "node": "^12.20 || ^14.13.1 || >= 16" + }, + "peerDependencies": { + "svelte": ">=3.19.0" + } + }, + "node_modules/vite": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-3.2.3.tgz", + "integrity": "sha512-h8jl1TZ76eGs3o2dIBSsvXDLb1m/Ec1iej8ZMdz+PsaFUsftZeWe2CZOI3qogEsMNaywc17gu0q6cQDzh/weCQ==", + "dev": true, + "dependencies": { + "esbuild": "^0.15.9", + "postcss": "^8.4.18", + "resolve": "^1.22.1", + "rollup": "^2.79.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + } + }, + "dependencies": { + "@esbuild/android-arm": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.13.tgz", + "integrity": "sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.13.tgz", + "integrity": "sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag==", + "dev": true, + "optional": true + }, + "@sveltejs/vite-plugin-svelte": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.1.0.tgz", + "integrity": "sha512-cFRfEdztubtj1c/rYh7ArK7XCfFJn6wG6+J8/e9amFsKtEJILovoBrK0/mxt1AjPQg0vaX+fHPKvhx+q8mTPaQ==", + "dev": true, + "requires": { + "debug": "^4.3.4", + "deepmerge": "^4.2.2", + "kleur": "^4.1.5", + "magic-string": "^0.26.7", + "svelte-hmr": "^0.15.0" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "esbuild": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.13.tgz", + "integrity": "sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.15.13", + "@esbuild/linux-loong64": "0.15.13", + "esbuild-android-64": "0.15.13", + "esbuild-android-arm64": "0.15.13", + "esbuild-darwin-64": "0.15.13", + "esbuild-darwin-arm64": "0.15.13", + "esbuild-freebsd-64": "0.15.13", + "esbuild-freebsd-arm64": "0.15.13", + "esbuild-linux-32": "0.15.13", + "esbuild-linux-64": "0.15.13", + "esbuild-linux-arm": "0.15.13", + "esbuild-linux-arm64": "0.15.13", + "esbuild-linux-mips64le": "0.15.13", + "esbuild-linux-ppc64le": "0.15.13", + "esbuild-linux-riscv64": "0.15.13", + "esbuild-linux-s390x": "0.15.13", + "esbuild-netbsd-64": "0.15.13", + "esbuild-openbsd-64": "0.15.13", + "esbuild-sunos-64": "0.15.13", + "esbuild-windows-32": "0.15.13", + "esbuild-windows-64": "0.15.13", + "esbuild-windows-arm64": "0.15.13" + } + }, + "esbuild-android-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.13.tgz", + "integrity": "sha512-yRorukXBlokwTip+Sy4MYskLhJsO0Kn0/Fj43s1krVblfwP+hMD37a4Wmg139GEsMLl+vh8WXp2mq/cTA9J97g==", + "dev": true, + "optional": true + }, + "esbuild-android-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.13.tgz", + "integrity": "sha512-TKzyymLD6PiVeyYa4c5wdPw87BeAiTXNtK6amWUcXZxkV51gOk5u5qzmDaYSwiWeecSNHamFsaFjLoi32QR5/w==", + "dev": true, + "optional": true + }, + "esbuild-darwin-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.13.tgz", + "integrity": "sha512-WAx7c2DaOS6CrRcoYCgXgkXDliLnFv3pQLV6GeW1YcGEZq2Gnl8s9Pg7ahValZkpOa0iE/ojRVQ87sbUhF1Cbg==", + "dev": true, + "optional": true + }, + "esbuild-darwin-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.13.tgz", + "integrity": "sha512-U6jFsPfSSxC3V1CLiQqwvDuj3GGrtQNB3P3nNC3+q99EKf94UGpsG9l4CQ83zBs1NHrk1rtCSYT0+KfK5LsD8A==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.13.tgz", + "integrity": "sha512-whItJgDiOXaDG/idy75qqevIpZjnReZkMGCgQaBWZuKHoElDJC1rh7MpoUgupMcdfOd+PgdEwNQW9DAE6i8wyA==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.13.tgz", + "integrity": "sha512-6pCSWt8mLUbPtygv7cufV0sZLeylaMwS5Fznj6Rsx9G2AJJsAjQ9ifA+0rQEIg7DwJmi9it+WjzNTEAzzdoM3Q==", + "dev": true, + "optional": true + }, + "esbuild-linux-32": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.13.tgz", + "integrity": "sha512-VbZdWOEdrJiYApm2kkxoTOgsoCO1krBZ3quHdYk3g3ivWaMwNIVPIfEE0f0XQQ0u5pJtBsnk2/7OPiCFIPOe/w==", + "dev": true, + "optional": true + }, + "esbuild-linux-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.13.tgz", + "integrity": "sha512-rXmnArVNio6yANSqDQlIO4WiP+Cv7+9EuAHNnag7rByAqFVuRusLbGi2697A5dFPNXoO//IiogVwi3AdcfPC6A==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.13.tgz", + "integrity": "sha512-Ac6LpfmJO8WhCMQmO253xX2IU2B3wPDbl4IvR0hnqcPrdfCaUa2j/lLMGTjmQ4W5JsJIdHEdW12dG8lFS0MbxQ==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.13.tgz", + "integrity": "sha512-alEMGU4Z+d17U7KQQw2IV8tQycO6T+rOrgW8OS22Ua25x6kHxoG6Ngry6Aq6uranC+pNWNMB6aHFPh7aTQdORQ==", + "dev": true, + "optional": true + }, + "esbuild-linux-mips64le": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.13.tgz", + "integrity": "sha512-47PgmyYEu+yN5rD/MbwS6DxP2FSGPo4Uxg5LwIdxTiyGC2XKwHhHyW7YYEDlSuXLQXEdTO7mYe8zQ74czP7W8A==", + "dev": true, + "optional": true + }, + "esbuild-linux-ppc64le": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.13.tgz", + "integrity": "sha512-z6n28h2+PC1Ayle9DjKoBRcx/4cxHoOa2e689e2aDJSaKug3jXcQw7mM+GLg+9ydYoNzj8QxNL8ihOv/OnezhA==", + "dev": true, + "optional": true + }, + "esbuild-linux-riscv64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.13.tgz", + "integrity": "sha512-+Lu4zuuXuQhgLUGyZloWCqTslcCAjMZH1k3Xc9MSEJEpEFdpsSU0sRDXAnk18FKOfEjhu4YMGaykx9xjtpA6ow==", + "dev": true, + "optional": true + }, + "esbuild-linux-s390x": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.13.tgz", + "integrity": "sha512-BMeXRljruf7J0TMxD5CIXS65y7puiZkAh+s4XFV9qy16SxOuMhxhVIXYLnbdfLrsYGFzx7U9mcdpFWkkvy/Uag==", + "dev": true, + "optional": true + }, + "esbuild-netbsd-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.13.tgz", + "integrity": "sha512-EHj9QZOTel581JPj7UO3xYbltFTYnHy+SIqJVq6yd3KkCrsHRbapiPb0Lx3EOOtybBEE9EyqbmfW1NlSDsSzvQ==", + "dev": true, + "optional": true + }, + "esbuild-openbsd-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.13.tgz", + "integrity": "sha512-nkuDlIjF/sfUhfx8SKq0+U+Fgx5K9JcPq1mUodnxI0x4kBdCv46rOGWbuJ6eof2n3wdoCLccOoJAbg9ba/bT2w==", + "dev": true, + "optional": true + }, + "esbuild-sunos-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.13.tgz", + "integrity": "sha512-jVeu2GfxZQ++6lRdY43CS0Tm/r4WuQQ0Pdsrxbw+aOrHQPHV0+LNOLnvbN28M7BSUGnJnHkHm2HozGgNGyeIRw==", + "dev": true, + "optional": true + }, + "esbuild-windows-32": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.13.tgz", + "integrity": "sha512-XoF2iBf0wnqo16SDq+aDGi/+QbaLFpkiRarPVssMh9KYbFNCqPLlGAWwDvxEVz+ywX6Si37J2AKm+AXq1kC0JA==", + "dev": true, + "optional": true + }, + "esbuild-windows-64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.13.tgz", + "integrity": "sha512-Et6htEfGycjDrtqb2ng6nT+baesZPYQIW+HUEHK4D1ncggNrDNk3yoboYQ5KtiVrw/JaDMNttz8rrPubV/fvPQ==", + "dev": true, + "optional": true + }, + "esbuild-windows-arm64": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.13.tgz", + "integrity": "sha512-3bv7tqntThQC9SWLRouMDmZnlOukBhOCTlkzNqzGCmrkCJI7io5LLjwJBOVY6kOUlIvdxbooNZwjtBvj+7uuVg==", + "dev": true, + "optional": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "jdataview": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/jdataview/-/jdataview-2.5.0.tgz", + "integrity": "sha512-ZJop3D5nyDcWPBPv4NPnhCvx3HgQNsCXMfw8gpNKY16BobgxmVF+kJ08aHuqk6bJQVeL2mkf6nDCcZPMompalw==" + }, + "kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true + }, + "magic-string": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz", + "integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.8" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "postcss": { + "version": "8.4.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", + "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", + "dev": true, + "requires": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "svelte": { + "version": "3.52.0", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.52.0.tgz", + "integrity": "sha512-FxcnEUOAVfr10vDU5dVgJN19IvqeHQCS1zfe8vayTfis9A2t5Fhx+JDe5uv/C3j//bB1umpLJ6quhgs9xyUbCQ==", + "dev": true + }, + "svelte-hmr": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.0.tgz", + "integrity": "sha512-Aw21SsyoohyVn4yiKXWPNCSW2DQNH/76kvUnE9kpt4h9hcg9tfyQc6xshx9hzgMfGF0kVx0EGD8oBMWSnATeOg==", + "dev": true, + "requires": {} + }, + "vite": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-3.2.3.tgz", + "integrity": "sha512-h8jl1TZ76eGs3o2dIBSsvXDLb1m/Ec1iej8ZMdz+PsaFUsftZeWe2CZOI3qogEsMNaywc17gu0q6cQDzh/weCQ==", + "dev": true, + "requires": { + "esbuild": "^0.15.9", + "fsevents": "~2.3.2", + "postcss": "^8.4.18", + "resolve": "^1.22.1", + "rollup": "^2.79.1" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..b8e7a7a --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "embroidery-viewer", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^1.1.0", + "svelte": "^3.52.0", + "vite": "^3.2.3" + }, + "dependencies": { + "jdataview": "^2.5.0" + } +} diff --git a/public/vite.svg b/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/App.svelte b/src/App.svelte new file mode 100644 index 0000000..926e73b --- /dev/null +++ b/src/App.svelte @@ -0,0 +1,22 @@ + + +
+

Embroidery Viewer

+
+
+ +
+ + + diff --git a/src/app.css b/src/app.css new file mode 100644 index 0000000..11a731c --- /dev/null +++ b/src/app.css @@ -0,0 +1,29 @@ +:root { + font-family: Inter, Avenir, Helvetica, Arial, sans-serif; + font-size: 16px; + line-height: 24px; + font-weight: 400; + font-synthesis: none; + text-rendering: optimizeLegibility; + background-color: #f4f4f4; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +body { + display: flex; + justify-content: center; + margin: 0; + width: 100%; + min-height: 100vh; +} + +#app { + display: flex; + flex-direction: column; + align-items: center; + width: 80%; + background-color: #e5e5e5; + z-index: 10; +} \ No newline at end of file diff --git a/src/lib/Counter.svelte b/src/lib/Counter.svelte new file mode 100644 index 0000000..e2dab4f --- /dev/null +++ b/src/lib/Counter.svelte @@ -0,0 +1,143 @@ + + +
+

Upload files

+

Max file size is {maxFileSize/1000}kb. Accepted formats: {acceptedFiles.join(",")}.

+ +
+ + +
+ +
+ +
+ + diff --git a/src/lib/jdataview.js b/src/lib/jdataview.js new file mode 100644 index 0000000..cba667a --- /dev/null +++ b/src/lib/jdataview.js @@ -0,0 +1,848 @@ +// @ts-nocheck +// +// jDataView by Vjeux - Jan 2010 +// Continued by RReverser - Feb 2013 +// +// A unique way to work with a binary file in the browser +// http://github.com/jDataView/jDataView +// http://jDataView.github.io/ + +var compatibility = { + // NodeJS Buffer in v0.5.5 and newer + NodeBuffer: "Buffer" in globalThis && "readInt16LE" in Buffer.prototype, + DataView: + "DataView" in globalThis && + ("getFloat64" in DataView.prototype || // Chrome + "getFloat64" in new DataView(new ArrayBuffer(1))), // Node + ArrayBuffer: "ArrayBuffer" in globalThis, + PixelData: + "CanvasPixelArray" in globalThis && + "ImageData" in globalThis && + "document" in globalThis, +}; + +var createPixelData = function (byteLength, buffer) { + var data = createPixelData.context2d.createImageData( + (byteLength + 3) / 4, + 1 + ).data; + data.byteLength = byteLength; + if (buffer !== undefined) { + for (var i = 0; i < byteLength; i++) { + data[i] = buffer[i]; + } + } + return data; +}; +createPixelData.context2d = document.createElement("canvas").getContext("2d"); + +var dataTypes = { + Int8: 1, + Int16: 2, + Int32: 4, + Uint8: 1, + Uint16: 2, + Uint32: 4, + Float32: 4, + Float64: 8, +}; + +var nodeNaming = { + Int8: "Int8", + Int16: "Int16", + Int32: "Int32", + Uint8: "UInt8", + Uint16: "UInt16", + Uint32: "UInt32", + Float32: "Float", + Float64: "Double", +}; + +function arrayFrom(arrayLike, forceCopy) { + return !forceCopy && arrayLike instanceof Array + ? arrayLike + : Array.prototype.slice.call(arrayLike); +} + +function defined(value, defaultValue) { + return value !== undefined ? value : defaultValue; +} + +export function jDataView(buffer, byteOffset, byteLength, littleEndian) { + /* jshint validthis:true */ + + if (buffer instanceof jDataView) { + var result = buffer.slice(byteOffset, byteOffset + byteLength); + result._littleEndian = defined(littleEndian, result._littleEndian); + return result; + } + + if (!(this instanceof jDataView)) { + return new jDataView(buffer, byteOffset, byteLength, littleEndian); + } + + this.buffer = buffer = jDataView.wrapBuffer(buffer); + + // Check parameters and existing functionnalities + this._isArrayBuffer = + compatibility.ArrayBuffer && buffer instanceof ArrayBuffer; + this._isPixelData = + compatibility.PixelData && buffer instanceof CanvasPixelArray; + this._isDataView = compatibility.DataView && this._isArrayBuffer; + this._isNodeBuffer = compatibility.NodeBuffer && buffer instanceof Buffer; + + // Handle Type Errors + if ( + !this._isNodeBuffer && + !this._isArrayBuffer && + !this._isPixelData && + !(buffer instanceof Array) + ) { + throw new TypeError("jDataView buffer has an incompatible type"); + } + + // Default Values + this._littleEndian = !!littleEndian; + + var bufferLength = "byteLength" in buffer ? buffer.byteLength : buffer.length; + this.byteOffset = byteOffset = defined(byteOffset, 0); + this.byteLength = byteLength = defined(byteLength, bufferLength - byteOffset); + + if (!this._isDataView) { + this._checkBounds(byteOffset, byteLength, bufferLength); + } else { + this._view = new DataView(buffer, byteOffset, byteLength); + } + + // Create uniform methods (action wrappers) for the following data types + + this._engineAction = this._isDataView + ? this._dataViewAction + : this._isNodeBuffer + ? this._nodeBufferAction + : this._isArrayBuffer + ? this._arrayBufferAction + : this._arrayAction; +} + +function getCharCodes(string) { + if (compatibility.NodeBuffer) { + return new Buffer(string, "binary"); + } + + var Type = compatibility.ArrayBuffer ? Uint8Array : Array, + codes = new Type(string.length); + + for (var i = 0, length = string.length; i < length; i++) { + codes[i] = string.charCodeAt(i) & 0xff; + } + return codes; +} + +// mostly internal function for wrapping any supported input (String or Array-like) to best suitable buffer format +jDataView.wrapBuffer = function (buffer) { + switch (typeof buffer) { + case "number": + if (compatibility.NodeBuffer) { + buffer = new Buffer(buffer); + buffer.fill(0); + } else if (compatibility.ArrayBuffer) { + buffer = new Uint8Array(buffer).buffer; + } else if (compatibility.PixelData) { + buffer = createPixelData(buffer); + } else { + buffer = new Array(buffer); + for (var i = 0; i < buffer.length; i++) { + buffer[i] = 0; + } + } + return buffer; + + case "string": + buffer = getCharCodes(buffer); + /* falls through */ + default: + if ( + "length" in buffer && + !( + (compatibility.NodeBuffer && buffer instanceof Buffer) || + (compatibility.ArrayBuffer && buffer instanceof ArrayBuffer) || + (compatibility.PixelData && buffer instanceof CanvasPixelArray) + ) + ) { + if (compatibility.NodeBuffer) { + buffer = new Buffer(buffer); + } else if (compatibility.ArrayBuffer) { + if (!(buffer instanceof ArrayBuffer)) { + buffer = new Uint8Array(buffer).buffer; + // bug in Node.js <= 0.8: + if (!(buffer instanceof ArrayBuffer)) { + buffer = new Uint8Array(arrayFrom(buffer, true)).buffer; + } + } + } else if (compatibility.PixelData) { + buffer = createPixelData(buffer.length, buffer); + } else { + buffer = arrayFrom(buffer); + } + } + return buffer; + } +}; + +function pow2(n) { + return n >= 0 && n < 31 ? 1 << n : pow2[n] || (pow2[n] = Math.pow(2, n)); +} + +// left for backward compatibility +jDataView.createBuffer = function () { + return jDataView.wrapBuffer(arguments); +}; + +function Uint64(lo, hi) { + this.lo = lo; + this.hi = hi; +} + +jDataView.Uint64 = Uint64; + +Uint64.prototype = { + valueOf: function () { + return this.lo + pow2(32) * this.hi; + }, + + toString: function () { + return Number.prototype.toString.apply(this.valueOf(), arguments); + }, +}; + +Uint64.fromNumber = function (number) { + var hi = Math.floor(number / pow2(32)), + lo = number - hi * pow2(32); + + return new Uint64(lo, hi); +}; + +function Int64(lo, hi) { + Uint64.apply(this, arguments); +} + +jDataView.Int64 = Int64; + +Int64.prototype = + "create" in Object ? Object.create(Uint64.prototype) : new Uint64(); + +Int64.prototype.valueOf = function () { + if (this.hi < pow2(31)) { + return Uint64.prototype.valueOf.apply(this, arguments); + } + return -(pow2(32) - this.lo + pow2(32) * (pow2(32) - 1 - this.hi)); +}; + +Int64.fromNumber = function (number) { + var lo, hi; + if (number >= 0) { + var unsigned = Uint64.fromNumber(number); + lo = unsigned.lo; + hi = unsigned.hi; + } else { + hi = Math.floor(number / pow2(32)); + lo = number - hi * pow2(32); + hi += pow2(32); + } + return new Int64(lo, hi); +}; + +jDataView.prototype = { + _offset: 0, + _bitOffset: 0, + + compatibility: compatibility, + + _checkBounds: function (byteOffset, byteLength, maxLength) { + // Do additional checks to simulate DataView + if (typeof byteOffset !== "number") { + throw new TypeError("Offset is not a number."); + } + if (typeof byteLength !== "number") { + throw new TypeError("Size is not a number."); + } + if (byteLength < 0) { + throw new RangeError("Length is negative."); + } + if ( + byteOffset < 0 || + byteOffset + byteLength > defined(maxLength, this.byteLength) + ) { + throw new RangeError("Offsets are out of bounds."); + } + }, + + _action: function (type, isReadAction, byteOffset, littleEndian, value) { + return this._engineAction( + type, + isReadAction, + defined(byteOffset, this._offset), + defined(littleEndian, this._littleEndian), + value + ); + }, + + _dataViewAction: function ( + type, + isReadAction, + byteOffset, + littleEndian, + value + ) { + // Move the internal offset forward + this._offset = byteOffset + dataTypes[type]; + return isReadAction + ? this._view["get" + type](byteOffset, littleEndian) + : this._view["set" + type](byteOffset, value, littleEndian); + }, + + _nodeBufferAction: function ( + type, + isReadAction, + byteOffset, + littleEndian, + value + ) { + // Move the internal offset forward + this._offset = byteOffset + dataTypes[type]; + var nodeName = + nodeNaming[type] + + (type === "Int8" || type === "Uint8" ? "" : littleEndian ? "LE" : "BE"); + byteOffset += this.byteOffset; + return isReadAction + ? this.buffer["read" + nodeName](byteOffset) + : this.buffer["write" + nodeName](value, byteOffset); + }, + + _arrayBufferAction: function ( + type, + isReadAction, + byteOffset, + littleEndian, + value + ) { + var size = dataTypes[type], + TypedArray = globalThis[type + "Array"], + typedArray; + + littleEndian = defined(littleEndian, this._littleEndian); + + // ArrayBuffer: we use a typed array of size 1 from original buffer if alignment is good and from slice when it's not + if ( + size === 1 || + ((this.byteOffset + byteOffset) % size === 0 && littleEndian) + ) { + typedArray = new TypedArray(this.buffer, this.byteOffset + byteOffset, 1); + this._offset = byteOffset + size; + return isReadAction ? typedArray[0] : (typedArray[0] = value); + } else { + var bytes = new Uint8Array( + isReadAction + ? this.getBytes(size, byteOffset, littleEndian, true) + : size + ); + typedArray = new TypedArray(bytes.buffer, 0, 1); + + if (isReadAction) { + return typedArray[0]; + } else { + typedArray[0] = value; + this._setBytes(byteOffset, bytes, littleEndian); + } + } + }, + + _arrayAction: function (type, isReadAction, byteOffset, littleEndian, value) { + return isReadAction + ? this["_get" + type](byteOffset, littleEndian) + : this["_set" + type](byteOffset, value, littleEndian); + }, + + // Helpers + + _getBytes: function (length, byteOffset, littleEndian) { + littleEndian = defined(littleEndian, this._littleEndian); + byteOffset = defined(byteOffset, this._offset); + length = defined(length, this.byteLength - byteOffset); + + this._checkBounds(byteOffset, length); + + byteOffset += this.byteOffset; + + this._offset = byteOffset - this.byteOffset + length; + + var result = this._isArrayBuffer + ? new Uint8Array(this.buffer, byteOffset, length) + : (this.buffer.slice || Array.prototype.slice).call( + this.buffer, + byteOffset, + byteOffset + length + ); + + return littleEndian || length <= 1 ? result : arrayFrom(result).reverse(); + }, + + // wrapper for external calls (do not return inner buffer directly to prevent it's modifying) + getBytes: function (length, byteOffset, littleEndian, toArray) { + var result = this._getBytes( + length, + byteOffset, + defined(littleEndian, true) + ); + return toArray ? arrayFrom(result) : result; + }, + + _setBytes: function (byteOffset, bytes, littleEndian) { + var length = bytes.length; + + // needed for Opera + if (length === 0) { + return; + } + + littleEndian = defined(littleEndian, this._littleEndian); + byteOffset = defined(byteOffset, this._offset); + + this._checkBounds(byteOffset, length); + + if (!littleEndian && length > 1) { + bytes = arrayFrom(bytes, true).reverse(); + } + + byteOffset += this.byteOffset; + + if (this._isArrayBuffer) { + new Uint8Array(this.buffer, byteOffset, length).set(bytes); + } else { + if (this._isNodeBuffer) { + new Buffer(bytes).copy(this.buffer, byteOffset); + } else { + for (var i = 0; i < length; i++) { + this.buffer[byteOffset + i] = bytes[i]; + } + } + } + + this._offset = byteOffset - this.byteOffset + length; + }, + + setBytes: function (byteOffset, bytes, littleEndian) { + this._setBytes(byteOffset, bytes, defined(littleEndian, true)); + }, + + getString: function (byteLength, byteOffset, encoding) { + if (this._isNodeBuffer) { + byteOffset = defined(byteOffset, this._offset); + byteLength = defined(byteLength, this.byteLength - byteOffset); + + this._checkBounds(byteOffset, byteLength); + + this._offset = byteOffset + byteLength; + return this.buffer.toString( + encoding || "binary", + this.byteOffset + byteOffset, + this.byteOffset + this._offset + ); + } + var bytes = this._getBytes(byteLength, byteOffset, true), + string = ""; + byteLength = bytes.length; + for (var i = 0; i < byteLength; i++) { + string += String.fromCharCode(bytes[i]); + } + if (encoding === "utf8") { + string = decodeURIComponent(escape(string)); + } + return string; + }, + + setString: function (byteOffset, subString, encoding) { + if (this._isNodeBuffer) { + byteOffset = defined(byteOffset, this._offset); + this._checkBounds(byteOffset, subString.length); + this._offset = + byteOffset + + this.buffer.write( + subString, + this.byteOffset + byteOffset, + encoding || "binary" + ); + return; + } + if (encoding === "utf8") { + subString = unescape(encodeURIComponent(subString)); + } + this._setBytes(byteOffset, getCharCodes(subString), true); + }, + + getChar: function (byteOffset) { + return this.getString(1, byteOffset); + }, + + setChar: function (byteOffset, character) { + this.setString(byteOffset, character); + }, + + tell: function () { + return this._offset; + }, + + seek: function (byteOffset) { + this._checkBounds(byteOffset, 0); + /* jshint boss: true */ + return (this._offset = byteOffset); + }, + + skip: function (byteLength) { + return this.seek(this._offset + byteLength); + }, + + slice: function (start, end, forceCopy) { + function normalizeOffset(offset, byteLength) { + return offset < 0 ? offset + byteLength : offset; + } + + start = normalizeOffset(start, this.byteLength); + end = normalizeOffset(defined(end, this.byteLength), this.byteLength); + + return forceCopy + ? new jDataView( + this.getBytes(end - start, start, true, true), + undefined, + undefined, + this._littleEndian + ) + : new jDataView( + this.buffer, + this.byteOffset + start, + end - start, + this._littleEndian + ); + }, + + alignBy: function (byteCount) { + this._bitOffset = 0; + if (defined(byteCount, 1) !== 1) { + return this.skip(byteCount - (this._offset % byteCount || byteCount)); + } else { + return this._offset; + } + }, + + // Compatibility functions + + _getFloat64: function (byteOffset, littleEndian) { + var b = this._getBytes(8, byteOffset, littleEndian), + sign = 1 - 2 * (b[7] >> 7), + exponent = ((((b[7] << 1) & 0xff) << 3) | (b[6] >> 4)) - ((1 << 10) - 1), + // Binary operators such as | and << operate on 32 bit values, using + and Math.pow(2) instead + mantissa = + (b[6] & 0x0f) * pow2(48) + + b[5] * pow2(40) + + b[4] * pow2(32) + + b[3] * pow2(24) + + b[2] * pow2(16) + + b[1] * pow2(8) + + b[0]; + + if (exponent === 1024) { + if (mantissa !== 0) { + return NaN; + } else { + return sign * Infinity; + } + } + + if (exponent === -1023) { + // Denormalized + return sign * mantissa * pow2(-1022 - 52); + } + + return sign * (1 + mantissa * pow2(-52)) * pow2(exponent); + }, + + _getFloat32: function (byteOffset, littleEndian) { + var b = this._getBytes(4, byteOffset, littleEndian), + sign = 1 - 2 * (b[3] >> 7), + exponent = (((b[3] << 1) & 0xff) | (b[2] >> 7)) - 127, + mantissa = ((b[2] & 0x7f) << 16) | (b[1] << 8) | b[0]; + + if (exponent === 128) { + if (mantissa !== 0) { + return NaN; + } else { + return sign * Infinity; + } + } + + if (exponent === -127) { + // Denormalized + return sign * mantissa * pow2(-126 - 23); + } + + return sign * (1 + mantissa * pow2(-23)) * pow2(exponent); + }, + + _get64: function (Type, byteOffset, littleEndian) { + littleEndian = defined(littleEndian, this._littleEndian); + byteOffset = defined(byteOffset, this._offset); + + var parts = littleEndian ? [0, 4] : [4, 0]; + + for (var i = 0; i < 2; i++) { + parts[i] = this.getUint32(byteOffset + parts[i], littleEndian); + } + + this._offset = byteOffset + 8; + + return new Type(parts[0], parts[1]); + }, + + getInt64: function (byteOffset, littleEndian) { + return this._get64(Int64, byteOffset, littleEndian); + }, + + getUint64: function (byteOffset, littleEndian) { + return this._get64(Uint64, byteOffset, littleEndian); + }, + + _getInt32: function (byteOffset, littleEndian) { + var b = this._getBytes(4, byteOffset, littleEndian); + return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0]; + }, + + _getUint32: function (byteOffset, littleEndian) { + return this._getInt32(byteOffset, littleEndian) >>> 0; + }, + + _getInt16: function (byteOffset, littleEndian) { + return (this._getUint16(byteOffset, littleEndian) << 16) >> 16; + }, + + _getUint16: function (byteOffset, littleEndian) { + var b = this._getBytes(2, byteOffset, littleEndian); + return (b[1] << 8) | b[0]; + }, + + _getInt8: function (byteOffset) { + return (this._getUint8(byteOffset) << 24) >> 24; + }, + + _getUint8: function (byteOffset) { + return this._getBytes(1, byteOffset)[0]; + }, + + _getBitRangeData: function (bitLength, byteOffset) { + var startBit = (defined(byteOffset, this._offset) << 3) + this._bitOffset, + endBit = startBit + bitLength, + start = startBit >>> 3, + end = (endBit + 7) >>> 3, + b = this._getBytes(end - start, start, true), + wideValue = 0; + + /* jshint boss: true */ + if ((this._bitOffset = endBit & 7)) { + this._bitOffset -= 8; + } + + for (var i = 0, length = b.length; i < length; i++) { + wideValue = (wideValue << 8) | b[i]; + } + + return { + start: start, + bytes: b, + wideValue: wideValue, + }; + }, + + getSigned: function (bitLength, byteOffset) { + var shift = 32 - bitLength; + return (this.getUnsigned(bitLength, byteOffset) << shift) >> shift; + }, + + getUnsigned: function (bitLength, byteOffset) { + var value = + this._getBitRangeData(bitLength, byteOffset).wideValue >>> + -this._bitOffset; + return bitLength < 32 ? value & ~(-1 << bitLength) : value; + }, + + _setBinaryFloat: function ( + byteOffset, + value, + mantSize, + expSize, + littleEndian + ) { + var signBit = value < 0 ? 1 : 0, + exponent, + mantissa, + eMax = ~(-1 << (expSize - 1)), + eMin = 1 - eMax; + + if (value < 0) { + value = -value; + } + + if (value === 0) { + exponent = 0; + mantissa = 0; + } else if (isNaN(value)) { + exponent = 2 * eMax + 1; + mantissa = 1; + } else if (value === Infinity) { + exponent = 2 * eMax + 1; + mantissa = 0; + } else { + exponent = Math.floor(Math.log(value) / Math.LN2); + if (exponent >= eMin && exponent <= eMax) { + mantissa = Math.floor((value * pow2(-exponent) - 1) * pow2(mantSize)); + exponent += eMax; + } else { + mantissa = Math.floor(value / pow2(eMin - mantSize)); + exponent = 0; + } + } + + var b = []; + while (mantSize >= 8) { + b.push(mantissa % 256); + mantissa = Math.floor(mantissa / 256); + mantSize -= 8; + } + exponent = (exponent << mantSize) | mantissa; + expSize += mantSize; + while (expSize >= 8) { + b.push(exponent & 0xff); + exponent >>>= 8; + expSize -= 8; + } + b.push((signBit << expSize) | exponent); + + this._setBytes(byteOffset, b, littleEndian); + }, + + _setFloat32: function (byteOffset, value, littleEndian) { + this._setBinaryFloat(byteOffset, value, 23, 8, littleEndian); + }, + + _setFloat64: function (byteOffset, value, littleEndian) { + this._setBinaryFloat(byteOffset, value, 52, 11, littleEndian); + }, + + _set64: function (Type, byteOffset, value, littleEndian) { + if (!(value instanceof Type)) { + value = Type.fromNumber(value); + } + + littleEndian = defined(littleEndian, this._littleEndian); + byteOffset = defined(byteOffset, this._offset); + + var parts = littleEndian ? { lo: 0, hi: 4 } : { lo: 4, hi: 0 }; + + for (var partName in parts) { + this.setUint32( + byteOffset + parts[partName], + value[partName], + littleEndian + ); + } + + this._offset = byteOffset + 8; + }, + + setInt64: function (byteOffset, value, littleEndian) { + this._set64(Int64, byteOffset, value, littleEndian); + }, + + setUint64: function (byteOffset, value, littleEndian) { + this._set64(Uint64, byteOffset, value, littleEndian); + }, + + _setUint32: function (byteOffset, value, littleEndian) { + this._setBytes( + byteOffset, + [value & 0xff, (value >>> 8) & 0xff, (value >>> 16) & 0xff, value >>> 24], + littleEndian + ); + }, + + _setUint16: function (byteOffset, value, littleEndian) { + this._setBytes( + byteOffset, + [value & 0xff, (value >>> 8) & 0xff], + littleEndian + ); + }, + + _setUint8: function (byteOffset, value) { + this._setBytes(byteOffset, [value & 0xff]); + }, + + setUnsigned: function (byteOffset, value, bitLength) { + var data = this._getBitRangeData(bitLength, byteOffset), + wideValue = data.wideValue, + b = data.bytes; + + wideValue &= ~(~(-1 << bitLength) << -this._bitOffset); // clearing bit range before binary "or" + wideValue |= + (bitLength < 32 ? value & ~(-1 << bitLength) : value) << -this._bitOffset; // setting bits + + for (var i = b.length - 1; i >= 0; i--) { + b[i] = wideValue & 0xff; + wideValue >>>= 8; + } + + this._setBytes(data.start, b, true); + }, +}; + +var proto = jDataView.prototype; + +for (var type in dataTypes) { + (function (type) { + proto["get" + type] = function (byteOffset, littleEndian) { + return this._action(type, true, byteOffset, littleEndian); + }; + proto["set" + type] = function (byteOffset, value, littleEndian) { + this._action(type, false, byteOffset, littleEndian, value); + }; + })(type); +} + +proto._setInt32 = proto._setUint32; +proto._setInt16 = proto._setUint16; +proto._setInt8 = proto._setUint8; +proto.setSigned = proto.setUnsigned; + +for (var method in proto) { + if (method.slice(0, 3) === "set") { + (function (type) { + proto["write" + type] = function () { + Array.prototype.unshift.call(arguments, undefined); + this["set" + type].apply(this, arguments); + }; + })(method.slice(3)); + } +} + +if (typeof module !== "undefined" && typeof module.exports === "object") { + module.exports = jDataView; +} else if (typeof define === "function" && define.amd) { + define([], function () { + return jDataView; + }); +} else { + var oldGlobalThis = globalThis.jDataView; + (globalThis.jDataView = jDataView).noConflict = function () { + globalThis.jDataView = oldGlobalThis; + return this; + }; +} diff --git a/src/lib/main.js b/src/lib/main.js new file mode 100644 index 0000000..c40492a --- /dev/null +++ b/src/lib/main.js @@ -0,0 +1,64 @@ +import { jDataView } from "./jdataview"; +import { pesRead } from "./pesformat"; +import { Pattern } from "./pattern"; + +String.prototype.endsWith = function (suffix) { + return this.indexOf(suffix, this.length - suffix.length) !== -1; +}; + +function displayFileText(filename, evt, canvas) { + const view = jDataView(evt.target.result, 0, evt.size); + const pattern = new Pattern(); + filename = filename.toLowerCase(); + if (filename.endsWith("pes")) { + pesRead(view, pattern); + } + pattern.moveToPositive(); + pattern.drawShape(canvas); +} + +function handleFileReadAbort(evt) { + alert("File read aborted."); +} + +function handleFileReadError(evt) { + let message; + switch (evt.target.error.name) { + case "NotFoundError": + alert("The file could not be found at the time the read was processed."); + break; + case "SecurityError": + message = "

A file security error occured. This can be due to:

"; + message += + "
  • Accessing certain files deemed unsafe for Web applications.
  • "; + message += "
  • Performing too many read calls on file resources.
  • "; + message += + "
  • The file has changed on disk since the user selected it.
"; + alert(message); + break; + case "NotReadableError": + alert( + "The file cannot be read. This can occur if the file is open in another application." + ); + break; + case "EncodingError": + alert("The length of the data URL for the file is too long."); + break; + default: + alert("File error code " + evt.target.error.name); + } +} + +export function startFileRead(fileObject, canvas) { + const reader = new FileReader(); + + reader.onloadend = function (x) { + displayFileText.apply(null, [fileObject.name, x, canvas]); + }; + reader.abort = handleFileReadAbort; + reader.onerror = handleFileReadError; + + if (fileObject) { + reader.readAsArrayBuffer(fileObject); + } +} diff --git a/src/lib/pattern.js b/src/lib/pattern.js new file mode 100644 index 0000000..d81b7e4 --- /dev/null +++ b/src/lib/pattern.js @@ -0,0 +1,177 @@ +function Stitch(x, y, flags, color) { + this.flags = flags; + this.x = x; + this.y = y; + this.color = color; +} + +function Color(r, g, b, description) { + this.r = r; + this.g = g; + this.b = b; + this.description = description; +} + +const stitchTypes = { + normal: 0, + jump: 1, + trim: 2, + stop: 4, + end: 8, +}; + +function Pattern() { + this.colors = []; + this.stitches = []; + this.hoop = {}; + this.lastX = 0; + this.lastY = 0; + this.top = 0; + this.bottom = 0; + this.left = 0; + this.right = 0; + this.currentColorIndex = 0; +} + +Pattern.prototype.addColorRgb = function (r, g, b, description) { + this.colors[this.colors.length] = new Color(r, g, b, description); +}; + +Pattern.prototype.addColor = function (color) { + this.colors[this.colors.length] = color; +}; + +Pattern.prototype.addStitchAbs = function (x, y, flags, isAutoColorIndex) { + if ((flags & stitchTypes.end) === stitchTypes.end) { + this.calculateBoundingBox(); + this.fixColorCount(); + } + if ( + (flags & stitchTypes.stop) === stitchTypes.stop && + this.stitches.length === 0 + ) { + return; + } + if ((flags & stitchTypes.stop) === stitchTypes.stop && isAutoColorIndex) { + this.currentColorIndex += 1; + } + this.stitches[this.stitches.length] = new Stitch( + x, + y, + flags, + this.currentColorIndex + ); +}; + +Pattern.prototype.addStitchRel = function (dx, dy, flags, isAutoColorIndex) { + if (this.stitches.length !== 0) { + let nx = this.lastX + dx, + ny = this.lastY + dy; + this.lastX = nx; + this.lastY = ny; + this.addStitchAbs(nx, ny, flags, isAutoColorIndex); + } else { + this.addStitchAbs(dx, dy, flags, isAutoColorIndex); + } +}; + +Pattern.prototype.calculateBoundingBox = function () { + let i = 0, + stitchCount = this.stitches.length, + pt; + if (stitchCount === 0) { + this.bottom = 1; + this.right = 1; + return; + } + this.left = 99999; + this.top = 99999; + this.right = -99999; + this.bottom = -99999; + + for (i = 0; i < stitchCount; i += 1) { + pt = this.stitches[i]; + if (!(pt.flags & stitchTypes.trim)) { + this.left = this.left < pt.x ? this.left : pt.x; + this.top = this.top < pt.y ? this.top : pt.y; + this.right = this.right > pt.x ? this.right : pt.x; + this.bottom = this.bottom > pt.y ? this.bottom : pt.y; + } + } +}; + +Pattern.prototype.moveToPositive = function () { + let i = 0, + stitchCount = this.stitches.length; + for (i = 0; i < stitchCount; i += 1) { + this.stitches[i].x -= this.left; + this.stitches[i].y -= this.top; + } + this.right -= this.left; + this.left = 0; + this.bottom -= this.top; + this.top = 0; +}; + +Pattern.prototype.invertPatternVertical = function () { + let i = 0, + temp = -this.top, + stitchCount = this.stitches.length; + for (i = 0; i < stitchCount; i += 1) { + this.stitches[i].y = -this.stitches[i].y; + } + this.top = -this.bottom; + this.bottom = temp; +}; + +Pattern.prototype.addColorRandom = function () { + this.colors[this.colors.length] = new Color( + Math.round(Math.random() * 256), + Math.round(Math.random() * 256), + Math.round(Math.random() * 256), + "random" + ); +}; + +Pattern.prototype.fixColorCount = function () { + let maxColorIndex = 0, + stitchCount = this.stitches.length, + i; + for (i = 0; i < stitchCount; i += 1) { + maxColorIndex = Math.max(maxColorIndex, this.stitches[i].color); + } + while (this.colors.length <= maxColorIndex) { + this.addColorRandom(); + } + this.colors.splice(maxColorIndex + 1, this.colors.length - maxColorIndex - 1); +}; + +Pattern.prototype.drawShape = function (canvas) { + canvas.width = this.right; + canvas.height = this.bottom; + if (canvas.getContext) { + const ctx = canvas.getContext("2d"); + let color = this.colors[this.stitches[0].color]; + ctx.beginPath(); + ctx.strokeStyle = "rgb(" + color.r + "," + color.g + "," + color.b + ")"; + for (let i = 0; i < this.stitches.length; i++) { + const currentStitch = this.stitches[i]; + if ( + currentStitch.flags === stitchTypes.jump || + currentStitch.flags === stitchTypes.trim || + currentStitch.flags === stitchTypes.stop + ) { + ctx.stroke(); + color = this.colors[currentStitch.color]; + ctx.beginPath(); + ctx.strokeStyle = + "rgb(" + color.r + "," + color.g + "," + color.b + ")"; + ctx.moveTo(currentStitch.x, currentStitch.y); + } + ctx.lineTo(currentStitch.x, currentStitch.y); + } + ctx.stroke(); + } +}; + +export { Pattern, Color, stitchTypes }; diff --git a/src/lib/pesformat.js b/src/lib/pesformat.js new file mode 100644 index 0000000..e0b0b9a --- /dev/null +++ b/src/lib/pesformat.js @@ -0,0 +1,140 @@ +import { Color, stitchTypes } from "./pattern"; + +const namedColors = [ + new Color(0, 0, 0, "Unknown"), + new Color(14, 31, 124, "Prussian Blue"), + new Color(10, 85, 163, "Blue"), + new Color(0, 135, 119, "Teal Green"), + new Color(75, 107, 175, "Cornflower Blue"), + new Color(237, 23, 31, "Red"), + new Color(209, 92, 0, "Reddish Brown"), + new Color(145, 54, 151, "Magenta"), + new Color(228, 154, 203, "Light Lilac"), + new Color(145, 95, 172, "Lilac"), + new Color(158, 214, 125, "Mint Green"), + new Color(232, 169, 0, "Deep Gold"), + new Color(254, 186, 53, "Orange"), + new Color(255, 255, 0, "Yellow"), + new Color(112, 188, 31, "Lime Green"), + new Color(186, 152, 0, "Brass"), + new Color(168, 168, 168, "Silver"), + new Color(125, 111, 0, "Russet Brown"), + new Color(255, 255, 179, "Cream Brown"), + new Color(79, 85, 86, "Pewter"), + new Color(0, 0, 0, "Black"), + new Color(11, 61, 145, "Ultramarine"), + new Color(119, 1, 118, "Royal Purple"), + new Color(41, 49, 51, "Dark Gray"), + new Color(42, 19, 1, "Dark Brown"), + new Color(246, 74, 138, "Deep Rose"), + new Color(178, 118, 36, "Light Brown"), + new Color(252, 187, 197, "Salmon Pink"), + new Color(254, 55, 15, "Vermillion"), + new Color(240, 240, 240, "White"), + new Color(106, 28, 138, "Violet"), + new Color(168, 221, 196, "Seacrest"), + new Color(37, 132, 187, "Sky Blue"), + new Color(254, 179, 67, "Pumpkin"), + new Color(255, 243, 107, "Cream Yellow"), + new Color(208, 166, 96, "Khaki"), + new Color(209, 84, 0, "Clay Brown"), + new Color(102, 186, 73, "Leaf Green"), + new Color(19, 74, 70, "Peacock Blue"), + new Color(135, 135, 135, "Gray"), + new Color(216, 204, 198, "Warm Gray"), + new Color(67, 86, 7, "Dark Olive"), + new Color(253, 217, 222, "Flesh Pink"), + new Color(249, 147, 188, "Pink"), + new Color(0, 56, 34, "Deep Green"), + new Color(178, 175, 212, "Lavender"), + new Color(104, 106, 176, "Wisteria Violet"), + new Color(239, 227, 185, "Beige"), + new Color(247, 56, 102, "Carmine"), + new Color(181, 75, 100, "Amber Red"), + new Color(19, 43, 26, "Olive Green"), + new Color(199, 1, 86, "Dark Fuschia"), + new Color(254, 158, 50, "Tangerine"), + new Color(168, 222, 235, "Light Blue"), + new Color(0, 103, 62, "Emerald Green"), + new Color(78, 41, 144, "Purple"), + new Color(47, 126, 32, "Moss Green"), + new Color(255, 204, 204, "Flesh Pink"), + new Color(255, 217, 17, "Harvest Gold"), + new Color(9, 91, 166, "Electric Blue"), + new Color(240, 249, 112, "Lemon Yellow"), + new Color(227, 243, 91, "Fresh Green"), + new Color(255, 153, 0, "Orange"), + new Color(255, 240, 141, "Cream Yellow"), + new Color(255, 200, 200, "Applique"), +]; + +function readPecStitches(file, pattern) { + let stitchNumber = 0, + stitchType, + val1, + val2, + byteCount = file.byteLength; + while (file.tell() < byteCount) { + val1 = file.getUint8(); + val2 = file.getUint8(); + + stitchType = stitchTypes.normal; + if (val1 === 0xff && val2 === 0x00) { + pattern.addStitchRel(0, 0, stitchTypes.end, true); + break; + } + if (val1 === 0xfe && val2 === 0xb0) { + file.getInt8(); + pattern.addStitchRel(0, 0, stitchTypes.stop, true); + stitchNumber += 1; + } else { + if (val1 & 0x80) { + if (val1 & 0x20) { + stitchType = stitchTypes.trim; + } + if (val1 & 0x10) { + stitchType = stitchTypes.jump; + } + val1 = ((val1 & 0x0f) << 8) + val2; + if (val1 & 0x800) { + val1 -= 0x1000; + } + val2 = file.getUint8(); + } else if (val1 >= 0x40) { + val1 -= 0x80; + } + if (val2 & 0x80) { + if (val2 & 0x20) { + stitchType = stitchTypes.trim; + } + if (val2 & 0x10) { + stitchType = stitchTypes.jump; + } + val2 = ((val2 & 0x0f) << 8) + file.getUint8(); + if (val2 & 0x800) { + val2 -= 0x1000; + } + } else if (val2 > 0x3f) { + val2 -= 0x80; + } + pattern.addStitchRel(val1, val2, stitchType, true); + stitchNumber += 1; + } + } +} + +export function pesRead(file, pattern) { + let x, numColors, pecstart; + pecstart = file.getInt32(8, true); + file.seek(pecstart + 48); + numColors = file.getInt8() + 1; + for (x = 0; x < numColors; x += 1) { + pattern.addColor(namedColors[file.getInt8()]); + } + file.seek(pecstart + 532); + readPecStitches(file, pattern); + pattern.addStitchRel(0, 0, stitchTypes.end); +} + +export const pecReadStitches = readPecStitches; +export const pecColors = namedColors; diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..5c1f795 --- /dev/null +++ b/src/main.js @@ -0,0 +1,8 @@ +import './app.css' +import App from './App.svelte' + +const app = new App({ + target: document.getElementById('app') +}) + +export default app diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts new file mode 100644 index 0000000..4078e74 --- /dev/null +++ b/src/vite-env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..401b4d4 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import { svelte } from '@sveltejs/vite-plugin-svelte' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [svelte()] +})