├── .github ├── FUNDING.yml └── workflows │ └── pages.yml ├── .gitignore ├── .npmrc ├── LICENSE ├── README.md ├── package-lock.json ├── package.json ├── screenshot.png ├── src ├── app.html ├── components │ └── editor │ │ ├── index.svelte │ │ └── theme.js ├── examples.js ├── routes │ ├── +layout.js │ └── +page.svelte └── service-worker.js ├── static └── favicon.png ├── svelte.config.js └── vite.config.js /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | open_collective: css-doodle 2 | -------------------------------------------------------------------------------- /.github/workflows/pages.yml: -------------------------------------------------------------------------------- 1 | # Simple workflow for deploying static content to GitHub Pages 2 | name: Deploy GitHub Pages 3 | 4 | on: 5 | # Runs on pushes targeting the default branch 6 | push: 7 | branches: ["main"] 8 | 9 | # Allows you to run this workflow manually from the Actions tab 10 | workflow_dispatch: 11 | 12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 13 | permissions: 14 | contents: read 15 | pages: write 16 | id-token: write 17 | 18 | jobs: 19 | # Single deploy job since we're just deploying 20 | deploy: 21 | environment: 22 | name: github-pages 23 | url: ${{ steps.deployment.outputs.page_url }} 24 | 25 | runs-on: ubuntu-latest 26 | 27 | strategy: 28 | matrix: 29 | os: [ubuntu-latest] 30 | node-version: [23.x] 31 | 32 | steps: 33 | - name: Checkout 34 | uses: actions/checkout@v4 35 | - name: Setup Pages 36 | uses: actions/configure-pages@v4 37 | - name: Use Node.js ${{ matrix.node-version }} 38 | uses: actions/setup-node@v2 39 | with: 40 | node-version: ${{ matrix.node-version }} 41 | - run: yarn install 42 | - run: yarn build 43 | - name: Upload artifact 44 | uses: actions/upload-pages-artifact@v3 45 | with: 46 | # Upload entire repository 47 | path: './build' 48 | - name: Deploy to GitHub Pages 49 | id: deployment 50 | uses: actions/deploy-pages@v4 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /.svelte-kit 4 | /package 5 | /build 6 | .env 7 | .env.* 8 | !.env.example 9 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Yuan Chuan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SVG Playground 2 | 3 | https://css-doodle.com/svg 4 | 5 | 6 | screenshot 7 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svg", 3 | "version": "0.0.1", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "svg", 9 | "version": "0.0.1", 10 | "dependencies": { 11 | "@codemirror/lang-css": "^6.0.0", 12 | "codemirror": "^6.0.1", 13 | "css-doodle": "0.40.2" 14 | }, 15 | "devDependencies": { 16 | "@sveltejs/adapter-static": "2.0.1", 17 | "@sveltejs/kit": "^1.22.4", 18 | "svelte": "3.57.0", 19 | "vite": "^4.4.8" 20 | }, 21 | "engines": { 22 | "node": ">= 18.0.0" 23 | } 24 | }, 25 | "node_modules/@codemirror/autocomplete": { 26 | "version": "6.17.0", 27 | "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.17.0.tgz", 28 | "integrity": "sha512-fdfj6e6ZxZf8yrkMHUSJJir7OJkHkZKaOZGzLWIYp2PZ3jd+d+UjG8zVPqJF6d3bKxkhvXTPan/UZ1t7Bqm0gA==", 29 | "dependencies": { 30 | "@codemirror/language": "^6.0.0", 31 | "@codemirror/state": "^6.0.0", 32 | "@codemirror/view": "^6.17.0", 33 | "@lezer/common": "^1.0.0" 34 | }, 35 | "peerDependencies": { 36 | "@codemirror/language": "^6.0.0", 37 | "@codemirror/state": "^6.0.0", 38 | "@codemirror/view": "^6.0.0", 39 | "@lezer/common": "^1.0.0" 40 | } 41 | }, 42 | "node_modules/@codemirror/commands": { 43 | "version": "6.6.0", 44 | "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.6.0.tgz", 45 | "integrity": "sha512-qnY+b7j1UNcTS31Eenuc/5YJB6gQOzkUoNmJQc0rznwqSRpeaWWpjkWy2C/MPTcePpsKJEM26hXrOXl1+nceXg==", 46 | "dependencies": { 47 | "@codemirror/language": "^6.0.0", 48 | "@codemirror/state": "^6.4.0", 49 | "@codemirror/view": "^6.27.0", 50 | "@lezer/common": "^1.1.0" 51 | } 52 | }, 53 | "node_modules/@codemirror/lang-css": { 54 | "version": "6.2.1", 55 | "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.2.1.tgz", 56 | "integrity": "sha512-/UNWDNV5Viwi/1lpr/dIXJNWiwDxpw13I4pTUAsNxZdg6E0mI2kTQb0P2iHczg1Tu+H4EBgJR+hYhKiHKko7qg==", 57 | "dependencies": { 58 | "@codemirror/autocomplete": "^6.0.0", 59 | "@codemirror/language": "^6.0.0", 60 | "@codemirror/state": "^6.0.0", 61 | "@lezer/common": "^1.0.2", 62 | "@lezer/css": "^1.0.0" 63 | } 64 | }, 65 | "node_modules/@codemirror/language": { 66 | "version": "6.10.2", 67 | "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.2.tgz", 68 | "integrity": "sha512-kgbTYTo0Au6dCSc/TFy7fK3fpJmgHDv1sG1KNQKJXVi+xBTEeBPY/M30YXiU6mMXeH+YIDLsbrT4ZwNRdtF+SA==", 69 | "dependencies": { 70 | "@codemirror/state": "^6.0.0", 71 | "@codemirror/view": "^6.23.0", 72 | "@lezer/common": "^1.1.0", 73 | "@lezer/highlight": "^1.0.0", 74 | "@lezer/lr": "^1.0.0", 75 | "style-mod": "^4.0.0" 76 | } 77 | }, 78 | "node_modules/@codemirror/lint": { 79 | "version": "6.8.1", 80 | "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.1.tgz", 81 | "integrity": "sha512-IZ0Y7S4/bpaunwggW2jYqwLuHj0QtESf5xcROewY6+lDNwZ/NzvR4t+vpYgg9m7V8UXLPYqG+lu3DF470E5Oxg==", 82 | "dependencies": { 83 | "@codemirror/state": "^6.0.0", 84 | "@codemirror/view": "^6.0.0", 85 | "crelt": "^1.0.5" 86 | } 87 | }, 88 | "node_modules/@codemirror/search": { 89 | "version": "6.5.6", 90 | "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.6.tgz", 91 | "integrity": "sha512-rpMgcsh7o0GuCDUXKPvww+muLA1pDJaFrpq/CCHtpQJYz8xopu4D1hPcKRoDD0YlF8gZaqTNIRa4VRBWyhyy7Q==", 92 | "dependencies": { 93 | "@codemirror/state": "^6.0.0", 94 | "@codemirror/view": "^6.0.0", 95 | "crelt": "^1.0.5" 96 | } 97 | }, 98 | "node_modules/@codemirror/state": { 99 | "version": "6.4.1", 100 | "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz", 101 | "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==" 102 | }, 103 | "node_modules/@codemirror/view": { 104 | "version": "6.29.0", 105 | "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.29.0.tgz", 106 | "integrity": "sha512-ED4ims4fkf7eOA+HYLVP8VVg3NMllt1FPm9PEJBfYFnidKlRITBaua38u68L1F60eNtw2YNcDN5jsIzhKZwWQA==", 107 | "dependencies": { 108 | "@codemirror/state": "^6.4.0", 109 | "style-mod": "^4.1.0", 110 | "w3c-keyname": "^2.2.4" 111 | } 112 | }, 113 | "node_modules/@esbuild/android-arm": { 114 | "version": "0.18.20", 115 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", 116 | "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", 117 | "cpu": [ 118 | "arm" 119 | ], 120 | "dev": true, 121 | "optional": true, 122 | "os": [ 123 | "android" 124 | ], 125 | "engines": { 126 | "node": ">=12" 127 | } 128 | }, 129 | "node_modules/@esbuild/android-arm64": { 130 | "version": "0.18.20", 131 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", 132 | "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", 133 | "cpu": [ 134 | "arm64" 135 | ], 136 | "dev": true, 137 | "optional": true, 138 | "os": [ 139 | "android" 140 | ], 141 | "engines": { 142 | "node": ">=12" 143 | } 144 | }, 145 | "node_modules/@esbuild/android-x64": { 146 | "version": "0.18.20", 147 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", 148 | "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", 149 | "cpu": [ 150 | "x64" 151 | ], 152 | "dev": true, 153 | "optional": true, 154 | "os": [ 155 | "android" 156 | ], 157 | "engines": { 158 | "node": ">=12" 159 | } 160 | }, 161 | "node_modules/@esbuild/darwin-arm64": { 162 | "version": "0.18.20", 163 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", 164 | "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", 165 | "cpu": [ 166 | "arm64" 167 | ], 168 | "dev": true, 169 | "optional": true, 170 | "os": [ 171 | "darwin" 172 | ], 173 | "engines": { 174 | "node": ">=12" 175 | } 176 | }, 177 | "node_modules/@esbuild/darwin-x64": { 178 | "version": "0.18.20", 179 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", 180 | "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", 181 | "cpu": [ 182 | "x64" 183 | ], 184 | "dev": true, 185 | "optional": true, 186 | "os": [ 187 | "darwin" 188 | ], 189 | "engines": { 190 | "node": ">=12" 191 | } 192 | }, 193 | "node_modules/@esbuild/freebsd-arm64": { 194 | "version": "0.18.20", 195 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", 196 | "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", 197 | "cpu": [ 198 | "arm64" 199 | ], 200 | "dev": true, 201 | "optional": true, 202 | "os": [ 203 | "freebsd" 204 | ], 205 | "engines": { 206 | "node": ">=12" 207 | } 208 | }, 209 | "node_modules/@esbuild/freebsd-x64": { 210 | "version": "0.18.20", 211 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", 212 | "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", 213 | "cpu": [ 214 | "x64" 215 | ], 216 | "dev": true, 217 | "optional": true, 218 | "os": [ 219 | "freebsd" 220 | ], 221 | "engines": { 222 | "node": ">=12" 223 | } 224 | }, 225 | "node_modules/@esbuild/linux-arm": { 226 | "version": "0.18.20", 227 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", 228 | "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", 229 | "cpu": [ 230 | "arm" 231 | ], 232 | "dev": true, 233 | "optional": true, 234 | "os": [ 235 | "linux" 236 | ], 237 | "engines": { 238 | "node": ">=12" 239 | } 240 | }, 241 | "node_modules/@esbuild/linux-arm64": { 242 | "version": "0.18.20", 243 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", 244 | "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", 245 | "cpu": [ 246 | "arm64" 247 | ], 248 | "dev": true, 249 | "optional": true, 250 | "os": [ 251 | "linux" 252 | ], 253 | "engines": { 254 | "node": ">=12" 255 | } 256 | }, 257 | "node_modules/@esbuild/linux-ia32": { 258 | "version": "0.18.20", 259 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", 260 | "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", 261 | "cpu": [ 262 | "ia32" 263 | ], 264 | "dev": true, 265 | "optional": true, 266 | "os": [ 267 | "linux" 268 | ], 269 | "engines": { 270 | "node": ">=12" 271 | } 272 | }, 273 | "node_modules/@esbuild/linux-loong64": { 274 | "version": "0.18.20", 275 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", 276 | "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", 277 | "cpu": [ 278 | "loong64" 279 | ], 280 | "dev": true, 281 | "optional": true, 282 | "os": [ 283 | "linux" 284 | ], 285 | "engines": { 286 | "node": ">=12" 287 | } 288 | }, 289 | "node_modules/@esbuild/linux-mips64el": { 290 | "version": "0.18.20", 291 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", 292 | "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", 293 | "cpu": [ 294 | "mips64el" 295 | ], 296 | "dev": true, 297 | "optional": true, 298 | "os": [ 299 | "linux" 300 | ], 301 | "engines": { 302 | "node": ">=12" 303 | } 304 | }, 305 | "node_modules/@esbuild/linux-ppc64": { 306 | "version": "0.18.20", 307 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", 308 | "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", 309 | "cpu": [ 310 | "ppc64" 311 | ], 312 | "dev": true, 313 | "optional": true, 314 | "os": [ 315 | "linux" 316 | ], 317 | "engines": { 318 | "node": ">=12" 319 | } 320 | }, 321 | "node_modules/@esbuild/linux-riscv64": { 322 | "version": "0.18.20", 323 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", 324 | "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", 325 | "cpu": [ 326 | "riscv64" 327 | ], 328 | "dev": true, 329 | "optional": true, 330 | "os": [ 331 | "linux" 332 | ], 333 | "engines": { 334 | "node": ">=12" 335 | } 336 | }, 337 | "node_modules/@esbuild/linux-s390x": { 338 | "version": "0.18.20", 339 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", 340 | "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", 341 | "cpu": [ 342 | "s390x" 343 | ], 344 | "dev": true, 345 | "optional": true, 346 | "os": [ 347 | "linux" 348 | ], 349 | "engines": { 350 | "node": ">=12" 351 | } 352 | }, 353 | "node_modules/@esbuild/linux-x64": { 354 | "version": "0.18.20", 355 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", 356 | "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", 357 | "cpu": [ 358 | "x64" 359 | ], 360 | "dev": true, 361 | "optional": true, 362 | "os": [ 363 | "linux" 364 | ], 365 | "engines": { 366 | "node": ">=12" 367 | } 368 | }, 369 | "node_modules/@esbuild/netbsd-x64": { 370 | "version": "0.18.20", 371 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", 372 | "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", 373 | "cpu": [ 374 | "x64" 375 | ], 376 | "dev": true, 377 | "optional": true, 378 | "os": [ 379 | "netbsd" 380 | ], 381 | "engines": { 382 | "node": ">=12" 383 | } 384 | }, 385 | "node_modules/@esbuild/openbsd-x64": { 386 | "version": "0.18.20", 387 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", 388 | "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", 389 | "cpu": [ 390 | "x64" 391 | ], 392 | "dev": true, 393 | "optional": true, 394 | "os": [ 395 | "openbsd" 396 | ], 397 | "engines": { 398 | "node": ">=12" 399 | } 400 | }, 401 | "node_modules/@esbuild/sunos-x64": { 402 | "version": "0.18.20", 403 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", 404 | "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", 405 | "cpu": [ 406 | "x64" 407 | ], 408 | "dev": true, 409 | "optional": true, 410 | "os": [ 411 | "sunos" 412 | ], 413 | "engines": { 414 | "node": ">=12" 415 | } 416 | }, 417 | "node_modules/@esbuild/win32-arm64": { 418 | "version": "0.18.20", 419 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", 420 | "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", 421 | "cpu": [ 422 | "arm64" 423 | ], 424 | "dev": true, 425 | "optional": true, 426 | "os": [ 427 | "win32" 428 | ], 429 | "engines": { 430 | "node": ">=12" 431 | } 432 | }, 433 | "node_modules/@esbuild/win32-ia32": { 434 | "version": "0.18.20", 435 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", 436 | "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", 437 | "cpu": [ 438 | "ia32" 439 | ], 440 | "dev": true, 441 | "optional": true, 442 | "os": [ 443 | "win32" 444 | ], 445 | "engines": { 446 | "node": ">=12" 447 | } 448 | }, 449 | "node_modules/@esbuild/win32-x64": { 450 | "version": "0.18.20", 451 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", 452 | "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", 453 | "cpu": [ 454 | "x64" 455 | ], 456 | "dev": true, 457 | "optional": true, 458 | "os": [ 459 | "win32" 460 | ], 461 | "engines": { 462 | "node": ">=12" 463 | } 464 | }, 465 | "node_modules/@fastify/busboy": { 466 | "version": "2.1.1", 467 | "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", 468 | "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", 469 | "dev": true, 470 | "engines": { 471 | "node": ">=14" 472 | } 473 | }, 474 | "node_modules/@jridgewell/sourcemap-codec": { 475 | "version": "1.5.0", 476 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", 477 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", 478 | "dev": true 479 | }, 480 | "node_modules/@lezer/common": { 481 | "version": "1.2.1", 482 | "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz", 483 | "integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ==" 484 | }, 485 | "node_modules/@lezer/css": { 486 | "version": "1.1.8", 487 | "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.1.8.tgz", 488 | "integrity": "sha512-7JhxupKuMBaWQKjQoLtzhGj83DdnZY9MckEOG5+/iLKNK2ZJqKc6hf6uc0HjwCX7Qlok44jBNqZhHKDhEhZYLA==", 489 | "dependencies": { 490 | "@lezer/common": "^1.2.0", 491 | "@lezer/highlight": "^1.0.0", 492 | "@lezer/lr": "^1.0.0" 493 | } 494 | }, 495 | "node_modules/@lezer/highlight": { 496 | "version": "1.2.0", 497 | "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz", 498 | "integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==", 499 | "dependencies": { 500 | "@lezer/common": "^1.0.0" 501 | } 502 | }, 503 | "node_modules/@lezer/lr": { 504 | "version": "1.4.2", 505 | "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz", 506 | "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==", 507 | "dependencies": { 508 | "@lezer/common": "^1.0.0" 509 | } 510 | }, 511 | "node_modules/@polka/url": { 512 | "version": "1.0.0-next.25", 513 | "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz", 514 | "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==", 515 | "dev": true 516 | }, 517 | "node_modules/@sveltejs/adapter-static": { 518 | "version": "2.0.1", 519 | "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-2.0.1.tgz", 520 | "integrity": "sha512-o5/q3YwD/ErxYCFlK1v3ydvldyNKk1lh3oeyxn4mhz+Pkbx/uuxhzmbOpytTlp5aVqNHDVsb04xadUzOFCDDzw==", 521 | "dev": true, 522 | "peerDependencies": { 523 | "@sveltejs/kit": "^1.5.0" 524 | } 525 | }, 526 | "node_modules/@sveltejs/kit": { 527 | "version": "1.30.4", 528 | "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.30.4.tgz", 529 | "integrity": "sha512-JSQIQT6XvdchCRQEm7BABxPC56WP5RYVONAi+09S8tmzeP43fBsRlr95bFmsTQM2RHBldfgQk+jgdnsKI75daA==", 530 | "dev": true, 531 | "hasInstallScript": true, 532 | "dependencies": { 533 | "@sveltejs/vite-plugin-svelte": "^2.5.0", 534 | "@types/cookie": "^0.5.1", 535 | "cookie": "^0.5.0", 536 | "devalue": "^4.3.1", 537 | "esm-env": "^1.0.0", 538 | "kleur": "^4.1.5", 539 | "magic-string": "^0.30.0", 540 | "mrmime": "^1.0.1", 541 | "sade": "^1.8.1", 542 | "set-cookie-parser": "^2.6.0", 543 | "sirv": "^2.0.2", 544 | "tiny-glob": "^0.2.9", 545 | "undici": "^5.28.3" 546 | }, 547 | "bin": { 548 | "svelte-kit": "svelte-kit.js" 549 | }, 550 | "engines": { 551 | "node": "^16.14 || >=18" 552 | }, 553 | "peerDependencies": { 554 | "svelte": "^3.54.0 || ^4.0.0-next.0 || ^5.0.0-next.0", 555 | "vite": "^4.0.0" 556 | } 557 | }, 558 | "node_modules/@sveltejs/vite-plugin-svelte": { 559 | "version": "2.5.3", 560 | "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-2.5.3.tgz", 561 | "integrity": "sha512-erhNtXxE5/6xGZz/M9eXsmI7Pxa6MS7jyTy06zN3Ck++ldrppOnOlJwHHTsMC7DHDQdgUp4NAc4cDNQ9eGdB/w==", 562 | "dev": true, 563 | "dependencies": { 564 | "@sveltejs/vite-plugin-svelte-inspector": "^1.0.4", 565 | "debug": "^4.3.4", 566 | "deepmerge": "^4.3.1", 567 | "kleur": "^4.1.5", 568 | "magic-string": "^0.30.3", 569 | "svelte-hmr": "^0.15.3", 570 | "vitefu": "^0.2.4" 571 | }, 572 | "engines": { 573 | "node": "^14.18.0 || >= 16" 574 | }, 575 | "peerDependencies": { 576 | "svelte": "^3.54.0 || ^4.0.0 || ^5.0.0-next.0", 577 | "vite": "^4.0.0" 578 | } 579 | }, 580 | "node_modules/@sveltejs/vite-plugin-svelte-inspector": { 581 | "version": "1.0.4", 582 | "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-1.0.4.tgz", 583 | "integrity": "sha512-zjiuZ3yydBtwpF3bj0kQNV0YXe+iKE545QGZVTaylW3eAzFr+pJ/cwK8lZEaRp4JtaJXhD5DyWAV4AxLh6DgaQ==", 584 | "dev": true, 585 | "dependencies": { 586 | "debug": "^4.3.4" 587 | }, 588 | "engines": { 589 | "node": "^14.18.0 || >= 16" 590 | }, 591 | "peerDependencies": { 592 | "@sveltejs/vite-plugin-svelte": "^2.2.0", 593 | "svelte": "^3.54.0 || ^4.0.0", 594 | "vite": "^4.0.0" 595 | } 596 | }, 597 | "node_modules/@types/cookie": { 598 | "version": "0.5.4", 599 | "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.5.4.tgz", 600 | "integrity": "sha512-7z/eR6O859gyWIAjuvBWFzNURmf2oPBmJlfVWkwehU5nzIyjwBsTh7WMmEEV4JFnHuQ3ex4oyTvfKzcyJVDBNA==", 601 | "dev": true 602 | }, 603 | "node_modules/codemirror": { 604 | "version": "6.0.1", 605 | "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz", 606 | "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==", 607 | "dependencies": { 608 | "@codemirror/autocomplete": "^6.0.0", 609 | "@codemirror/commands": "^6.0.0", 610 | "@codemirror/language": "^6.0.0", 611 | "@codemirror/lint": "^6.0.0", 612 | "@codemirror/search": "^6.0.0", 613 | "@codemirror/state": "^6.0.0", 614 | "@codemirror/view": "^6.0.0" 615 | } 616 | }, 617 | "node_modules/cookie": { 618 | "version": "0.5.0", 619 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 620 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", 621 | "dev": true, 622 | "engines": { 623 | "node": ">= 0.6" 624 | } 625 | }, 626 | "node_modules/crelt": { 627 | "version": "1.0.6", 628 | "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", 629 | "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==" 630 | }, 631 | "node_modules/css-doodle": { 632 | "version": "0.40.2", 633 | "resolved": "https://registry.npmjs.org/css-doodle/-/css-doodle-0.40.2.tgz", 634 | "integrity": "sha512-DRM8EvOLRLYYxvDBdM855XHwEEvI9nxc2zKs5gQWiscSstoTYWd1sHIm5X3VJXjYBFAq3lytl60UDHlgWexMbQ==", 635 | "license": "MIT", 636 | "funding": { 637 | "type": "opencollective", 638 | "url": "https://opencollective.com/css-doodle" 639 | } 640 | }, 641 | "node_modules/debug": { 642 | "version": "4.3.6", 643 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", 644 | "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", 645 | "dev": true, 646 | "dependencies": { 647 | "ms": "2.1.2" 648 | }, 649 | "engines": { 650 | "node": ">=6.0" 651 | }, 652 | "peerDependenciesMeta": { 653 | "supports-color": { 654 | "optional": true 655 | } 656 | } 657 | }, 658 | "node_modules/deepmerge": { 659 | "version": "4.3.1", 660 | "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", 661 | "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", 662 | "dev": true, 663 | "engines": { 664 | "node": ">=0.10.0" 665 | } 666 | }, 667 | "node_modules/devalue": { 668 | "version": "4.3.3", 669 | "resolved": "https://registry.npmjs.org/devalue/-/devalue-4.3.3.tgz", 670 | "integrity": "sha512-UH8EL6H2ifcY8TbD2QsxwCC/pr5xSwPvv85LrLXVihmHVC3T3YqTCIwnR5ak0yO1KYqlxrPVOA/JVZJYPy2ATg==", 671 | "dev": true 672 | }, 673 | "node_modules/esbuild": { 674 | "version": "0.18.20", 675 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", 676 | "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", 677 | "dev": true, 678 | "hasInstallScript": true, 679 | "bin": { 680 | "esbuild": "bin/esbuild" 681 | }, 682 | "engines": { 683 | "node": ">=12" 684 | }, 685 | "optionalDependencies": { 686 | "@esbuild/android-arm": "0.18.20", 687 | "@esbuild/android-arm64": "0.18.20", 688 | "@esbuild/android-x64": "0.18.20", 689 | "@esbuild/darwin-arm64": "0.18.20", 690 | "@esbuild/darwin-x64": "0.18.20", 691 | "@esbuild/freebsd-arm64": "0.18.20", 692 | "@esbuild/freebsd-x64": "0.18.20", 693 | "@esbuild/linux-arm": "0.18.20", 694 | "@esbuild/linux-arm64": "0.18.20", 695 | "@esbuild/linux-ia32": "0.18.20", 696 | "@esbuild/linux-loong64": "0.18.20", 697 | "@esbuild/linux-mips64el": "0.18.20", 698 | "@esbuild/linux-ppc64": "0.18.20", 699 | "@esbuild/linux-riscv64": "0.18.20", 700 | "@esbuild/linux-s390x": "0.18.20", 701 | "@esbuild/linux-x64": "0.18.20", 702 | "@esbuild/netbsd-x64": "0.18.20", 703 | "@esbuild/openbsd-x64": "0.18.20", 704 | "@esbuild/sunos-x64": "0.18.20", 705 | "@esbuild/win32-arm64": "0.18.20", 706 | "@esbuild/win32-ia32": "0.18.20", 707 | "@esbuild/win32-x64": "0.18.20" 708 | } 709 | }, 710 | "node_modules/esm-env": { 711 | "version": "1.0.0", 712 | "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.0.0.tgz", 713 | "integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==", 714 | "dev": true 715 | }, 716 | "node_modules/fsevents": { 717 | "version": "2.3.3", 718 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 719 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 720 | "dev": true, 721 | "hasInstallScript": true, 722 | "optional": true, 723 | "os": [ 724 | "darwin" 725 | ], 726 | "engines": { 727 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 728 | } 729 | }, 730 | "node_modules/globalyzer": { 731 | "version": "0.1.0", 732 | "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", 733 | "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", 734 | "dev": true 735 | }, 736 | "node_modules/globrex": { 737 | "version": "0.1.2", 738 | "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", 739 | "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", 740 | "dev": true 741 | }, 742 | "node_modules/kleur": { 743 | "version": "4.1.5", 744 | "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", 745 | "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", 746 | "dev": true, 747 | "engines": { 748 | "node": ">=6" 749 | } 750 | }, 751 | "node_modules/magic-string": { 752 | "version": "0.30.10", 753 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", 754 | "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", 755 | "dev": true, 756 | "dependencies": { 757 | "@jridgewell/sourcemap-codec": "^1.4.15" 758 | } 759 | }, 760 | "node_modules/mri": { 761 | "version": "1.2.0", 762 | "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", 763 | "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", 764 | "dev": true, 765 | "engines": { 766 | "node": ">=4" 767 | } 768 | }, 769 | "node_modules/mrmime": { 770 | "version": "1.0.1", 771 | "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", 772 | "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", 773 | "dev": true, 774 | "engines": { 775 | "node": ">=10" 776 | } 777 | }, 778 | "node_modules/ms": { 779 | "version": "2.1.2", 780 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 781 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 782 | "dev": true 783 | }, 784 | "node_modules/nanoid": { 785 | "version": "3.3.7", 786 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", 787 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", 788 | "dev": true, 789 | "funding": [ 790 | { 791 | "type": "github", 792 | "url": "https://github.com/sponsors/ai" 793 | } 794 | ], 795 | "bin": { 796 | "nanoid": "bin/nanoid.cjs" 797 | }, 798 | "engines": { 799 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 800 | } 801 | }, 802 | "node_modules/picocolors": { 803 | "version": "1.0.1", 804 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", 805 | "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", 806 | "dev": true 807 | }, 808 | "node_modules/postcss": { 809 | "version": "8.4.40", 810 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.40.tgz", 811 | "integrity": "sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==", 812 | "dev": true, 813 | "funding": [ 814 | { 815 | "type": "opencollective", 816 | "url": "https://opencollective.com/postcss/" 817 | }, 818 | { 819 | "type": "tidelift", 820 | "url": "https://tidelift.com/funding/github/npm/postcss" 821 | }, 822 | { 823 | "type": "github", 824 | "url": "https://github.com/sponsors/ai" 825 | } 826 | ], 827 | "dependencies": { 828 | "nanoid": "^3.3.7", 829 | "picocolors": "^1.0.1", 830 | "source-map-js": "^1.2.0" 831 | }, 832 | "engines": { 833 | "node": "^10 || ^12 || >=14" 834 | } 835 | }, 836 | "node_modules/rollup": { 837 | "version": "3.29.4", 838 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", 839 | "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", 840 | "dev": true, 841 | "bin": { 842 | "rollup": "dist/bin/rollup" 843 | }, 844 | "engines": { 845 | "node": ">=14.18.0", 846 | "npm": ">=8.0.0" 847 | }, 848 | "optionalDependencies": { 849 | "fsevents": "~2.3.2" 850 | } 851 | }, 852 | "node_modules/sade": { 853 | "version": "1.8.1", 854 | "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", 855 | "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", 856 | "dev": true, 857 | "dependencies": { 858 | "mri": "^1.1.0" 859 | }, 860 | "engines": { 861 | "node": ">=6" 862 | } 863 | }, 864 | "node_modules/set-cookie-parser": { 865 | "version": "2.6.0", 866 | "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", 867 | "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==", 868 | "dev": true 869 | }, 870 | "node_modules/sirv": { 871 | "version": "2.0.4", 872 | "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", 873 | "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", 874 | "dev": true, 875 | "dependencies": { 876 | "@polka/url": "^1.0.0-next.24", 877 | "mrmime": "^2.0.0", 878 | "totalist": "^3.0.0" 879 | }, 880 | "engines": { 881 | "node": ">= 10" 882 | } 883 | }, 884 | "node_modules/sirv/node_modules/mrmime": { 885 | "version": "2.0.0", 886 | "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", 887 | "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", 888 | "dev": true, 889 | "engines": { 890 | "node": ">=10" 891 | } 892 | }, 893 | "node_modules/source-map-js": { 894 | "version": "1.2.0", 895 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", 896 | "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", 897 | "dev": true, 898 | "engines": { 899 | "node": ">=0.10.0" 900 | } 901 | }, 902 | "node_modules/style-mod": { 903 | "version": "4.1.2", 904 | "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz", 905 | "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==" 906 | }, 907 | "node_modules/svelte": { 908 | "version": "3.57.0", 909 | "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.57.0.tgz", 910 | "integrity": "sha512-WMXEvF+RtAaclw0t3bPDTUe19pplMlfyKDsixbHQYgCWi9+O9VN0kXU1OppzrB9gPAvz4NALuoca2LfW2bOjTQ==", 911 | "dev": true, 912 | "engines": { 913 | "node": ">= 8" 914 | } 915 | }, 916 | "node_modules/svelte-hmr": { 917 | "version": "0.15.3", 918 | "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.3.tgz", 919 | "integrity": "sha512-41snaPswvSf8TJUhlkoJBekRrABDXDMdpNpT2tfHIv4JuhgvHqLMhEPGtaQn0BmbNSTkuz2Ed20DF2eHw0SmBQ==", 920 | "dev": true, 921 | "engines": { 922 | "node": "^12.20 || ^14.13.1 || >= 16" 923 | }, 924 | "peerDependencies": { 925 | "svelte": "^3.19.0 || ^4.0.0" 926 | } 927 | }, 928 | "node_modules/tiny-glob": { 929 | "version": "0.2.9", 930 | "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", 931 | "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", 932 | "dev": true, 933 | "dependencies": { 934 | "globalyzer": "0.1.0", 935 | "globrex": "^0.1.2" 936 | } 937 | }, 938 | "node_modules/totalist": { 939 | "version": "3.0.1", 940 | "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", 941 | "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", 942 | "dev": true, 943 | "engines": { 944 | "node": ">=6" 945 | } 946 | }, 947 | "node_modules/undici": { 948 | "version": "5.28.4", 949 | "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", 950 | "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", 951 | "dev": true, 952 | "dependencies": { 953 | "@fastify/busboy": "^2.0.0" 954 | }, 955 | "engines": { 956 | "node": ">=14.0" 957 | } 958 | }, 959 | "node_modules/vite": { 960 | "version": "4.5.3", 961 | "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", 962 | "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==", 963 | "dev": true, 964 | "dependencies": { 965 | "esbuild": "^0.18.10", 966 | "postcss": "^8.4.27", 967 | "rollup": "^3.27.1" 968 | }, 969 | "bin": { 970 | "vite": "bin/vite.js" 971 | }, 972 | "engines": { 973 | "node": "^14.18.0 || >=16.0.0" 974 | }, 975 | "funding": { 976 | "url": "https://github.com/vitejs/vite?sponsor=1" 977 | }, 978 | "optionalDependencies": { 979 | "fsevents": "~2.3.2" 980 | }, 981 | "peerDependencies": { 982 | "@types/node": ">= 14", 983 | "less": "*", 984 | "lightningcss": "^1.21.0", 985 | "sass": "*", 986 | "stylus": "*", 987 | "sugarss": "*", 988 | "terser": "^5.4.0" 989 | }, 990 | "peerDependenciesMeta": { 991 | "@types/node": { 992 | "optional": true 993 | }, 994 | "less": { 995 | "optional": true 996 | }, 997 | "lightningcss": { 998 | "optional": true 999 | }, 1000 | "sass": { 1001 | "optional": true 1002 | }, 1003 | "stylus": { 1004 | "optional": true 1005 | }, 1006 | "sugarss": { 1007 | "optional": true 1008 | }, 1009 | "terser": { 1010 | "optional": true 1011 | } 1012 | } 1013 | }, 1014 | "node_modules/vitefu": { 1015 | "version": "0.2.5", 1016 | "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", 1017 | "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", 1018 | "dev": true, 1019 | "peerDependencies": { 1020 | "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" 1021 | }, 1022 | "peerDependenciesMeta": { 1023 | "vite": { 1024 | "optional": true 1025 | } 1026 | } 1027 | }, 1028 | "node_modules/w3c-keyname": { 1029 | "version": "2.2.8", 1030 | "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", 1031 | "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==" 1032 | } 1033 | } 1034 | } 1035 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svg", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "dev": "vite dev", 7 | "build": "vite build", 8 | "preview": "vite preview" 9 | }, 10 | "devDependencies": { 11 | "@sveltejs/adapter-static": "2.0.1", 12 | "@sveltejs/kit": "^1.22.4", 13 | "svelte": "3.57.0", 14 | "vite": "^4.4.8" 15 | }, 16 | "type": "module", 17 | "dependencies": { 18 | "@codemirror/lang-css": "^6.0.0", 19 | "codemirror": "^6.0.1", 20 | "css-doodle": "0.40.2" 21 | }, 22 | "engines": { 23 | "node": ">= 18.0.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/css-doodle/svg/e5ac1c3851a0933bb9ce7f295cc145c6e948db54/screenshot.png -------------------------------------------------------------------------------- /src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | SVG playground 8 | %sveltekit.head% 9 | 21 | 22 | 23 |
24 | %sveltekit.body% 25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /src/components/editor/index.svelte: -------------------------------------------------------------------------------- 1 |
2 | 3 | 60 | 61 | 78 | -------------------------------------------------------------------------------- /src/components/editor/theme.js: -------------------------------------------------------------------------------- 1 | import {EditorView} from '@codemirror/view'; 2 | 3 | const white = '#D5F1FF'; 4 | const dark = '#1b2e37'; 5 | 6 | export default EditorView.theme({ 7 | "&": { 8 | color: white, 9 | backgroundColor: dark, 10 | }, 11 | ".ͼi": { 12 | color: '#11b0ff', 13 | }, 14 | ".ͼd": { 15 | color: '#e9e91e', 16 | }, 17 | ".ͼc": { 18 | color: '#8d7cff', 19 | }, 20 | ".ͼb": { 21 | color: '#eb5eff', 22 | }, 23 | ".ͼm": { 24 | color: '#66787f', 25 | }, 26 | ".ͼj": { 27 | color: '#8d7cff', 28 | }, 29 | "&.cm-focused .cm-cursor": { 30 | borderLeftColor: "yellow" 31 | }, 32 | "&.cm-focused .cm-selectionBackground, ::selection": { 33 | backgroundColor: '#233b49', 34 | }, 35 | ".cm-selectionBackground": { 36 | backgroundColor: '#242D4A', 37 | }, 38 | ".cm-gutters": { 39 | backgroundColor: "#1B2D37", 40 | color: "#D5F1FF33", 41 | border: "none" 42 | }, 43 | ".cm-activeLine": { 44 | backgroundColor: '#233b49', 45 | }, 46 | ".cm-activeLineGutter": { 47 | color: white, 48 | backgroundColor: '#233b49', 49 | } 50 | }, {dark: true}); 51 | 52 | -------------------------------------------------------------------------------- /src/examples.js: -------------------------------------------------------------------------------- 1 | export default { 2 | grid: read(` 3 | svg { 4 | viewBox: .5 .5 10 10; 5 | stroke: #1B2D37; 6 | stroke-width: .04; 7 | 8 | circle*10x10 { 9 | fill: @p(yellow, blueviolet, deeppink); 10 | cx, cy: @nx, @ny; 11 | r: @r(.05, .48); 12 | style animation: scale @r(2s) reverse; 13 | } 14 | 15 | style { 16 | @keyframes scale { 17 | to { r: 0 } 18 | } 19 | } 20 | } 21 | `), 22 | 23 | basic: read(` 24 | svg { 25 | viewBox: 0 0 10 10; 26 | stroke: #000; 27 | stroke-width: .1; 28 | circle { 29 | fill: deepskyblue; 30 | cx: 4; 31 | cy: 4; 32 | r: 3 33 | } 34 | rect { 35 | width: 1; 36 | height: 1; 37 | fill: yellow; 38 | transform: translate(8.5 7.8) rotate(45); 39 | } 40 | rect { 41 | width: 10; 42 | height: 10; 43 | fill: none; 44 | } 45 | } 46 | `), 47 | 48 | snowflake: read(` 49 | svg { 50 | viewBox: -50 -50 100 100; 51 | stroke-linecap: round; 52 | stroke: #000; 53 | 54 | path*6 { 55 | transform: rotate(@n(*60)); 56 | d: M 0 0 0 44 57 | @M2x3(M 0 @ny(* -9) 58 | L @pn(±9) $(-10*@ny - 5.8)); 59 | } 60 | } 61 | `), 62 | 63 | wavy: read(` 64 | svg { 65 | viewBox: -58 -57 114 114; 66 | stroke-width: .15; 67 | stroke: #1B2D37; 68 | fill: #D5F1FF; 69 | circle*720 { 70 | r: $(sin(π/@N*@n)*10); 71 | cx, cy: @Plot( 72 | r: 40+sin(4t)*5+sin(12t)*5 73 | ); 74 | } 75 | } 76 | `), 77 | 78 | flower: read(` 79 | svg { 80 | viewBox: 0 0 10 10.1; 81 | stroke: #000; 82 | stroke-width: .1; 83 | stroke-dasharray: 100; 84 | stroke-linecap: round; 85 | 86 | path*3 { 87 | style animation: move @r(2s, 4s) reverse; 88 | fill: none; 89 | d: @pn(M 5 10 Q 5 5 8 1, 90 | M 5 10 Q 4 5 2 4, 91 | M 5 10 Q 6 6 8 4); 92 | } 93 | circle*3 { 94 | style animation: scale @r(1s, 2s) reverse; 95 | fill: @pn(yellow, blueviolet, deeppink); 96 | cx, cy: @pn(8 1, 2 4, 8 4); 97 | r: @r(.2, .5); 98 | } 99 | 100 | style { 101 | @keyframes move { 102 | to { stroke-dashoffset: 100 } 103 | } 104 | @keyframes scale { 105 | to { r: 0 } 106 | } 107 | } 108 | } 109 | `), 110 | 111 | star: read(` 112 | svg { 113 | viewBox: -50 -50 100 100; 114 | polygon { 115 | stroke: #000; 116 | points: @m10.@Plot( 117 | r: seq(20, 40); 118 | rotate: 18; 119 | ); 120 | fill: defs linearGradient { 121 | gradientTransform: rotate(30); 122 | stop { offset: 50%; stop-color: deeppink } 123 | stop { offset: 100%; stop-color: yellow } 124 | } 125 | } 126 | } 127 | `), 128 | 129 | '99 bottles of beer': read(` 130 | svg { 131 | viewBox: 0 0 16 $(99*5); 132 | overflow: visible; 133 | style max-height: inherit; 134 | foreignObject { 135 | width, height: 100%; 136 | font-size: 1; 137 | style line-height: 1; 138 | p*99-1 { 139 | content: \` 140 | @n bottles of beer on the wall,
141 | @n bottles of beer.
142 | Take one down and pass it around,
143 | @n(-1) bottles of beer on the wall. 144 | \`; 145 | } 146 | } 147 | } 148 | `), 149 | 150 | 'window pattern': read(` 151 | svg { 152 | viewBox: 0 0 200 200 padding 20; 153 | fill: none; 154 | stroke: #1B2D37; 155 | stroke-width: 3; 156 | stroke-linecap: square; 157 | 158 | path { 159 | d: 160 | M 0 0 h 200 v 200 h -200 z 161 | M 100 5 162 | @p(@p(@p(h-43 v5 h-10 v-5 h-10 v16 h-32 v10 h10 v-26 h-10) 163 | @flip.invert.reverse.p) 164 | @flipv.invert.p) 165 | @flip.p; 166 | } 167 | } 168 | `), 169 | 170 | lines: read(` 171 | svg { 172 | viewBox: 0 0 100 100; 173 | 174 | /* background */ 175 | rect { 176 | fill: #0ce5f2; 177 | width, height: 100%; 178 | } 179 | 180 | g { 181 | fill: none; 182 | 183 | /* lines */ 184 | path*200 { 185 | stroke: @p(#ff4ea5, yellow, @m5(#fff)); 186 | stroke-width: @r.5; 187 | stroke-dasharray: @r(5, 60) @r5; 188 | d: M 50 120 189 | Q @Plot(r: 20; move: 20 80) 190 | @Plot(r: 125; move: 80 60); 191 | } 192 | 193 | filter: defs filter { 194 | feTurbulence { 195 | type: fractalNoise; 196 | baseFrequency: .03; 197 | seed: @r1000; 198 | } 199 | feDisplacementMap { 200 | in: SourceGraphic; 201 | scale: 20; 202 | } 203 | } 204 | 205 | /* fix for Safari */ 206 | mask: defs mask { 207 | rect { 208 | width, height: 100%; 209 | fill: #fff; 210 | } 211 | } 212 | } 213 | } 214 | `), 215 | 216 | 'hyperbolic circles': read(` 217 | svg { 218 | viewBox: -5 -5 10 10; 219 | g { 220 | stroke: #1B2D37; 221 | stroke-width: .04; 222 | 223 | circle { 224 | r: 5; 225 | fill: #f9f8eb; 226 | } 227 | circle*4 { 228 | r: 5; 229 | cx, cy: @Plot(r: 7.07; rotate: 45); 230 | fill: #76b39d; 231 | } 232 | circle*8 { 233 | cx, cy: @Plot(r: 5.5; rotate: $(45/2)); 234 | r: $(5/2.39); 235 | fill: #05004e; 236 | } 237 | circle*16 { 238 | r: 1.01; 239 | cx, cy: @Plot(r: 5.2; rotate: $(45/4)); 240 | fill: #fd5f00; 241 | } 242 | circle*32 { 243 | r: $(5/9.6); 244 | cx, cy: @Plot(r: 5.2; rotate: $(45/8)); 245 | fill: #f9f8eb; 246 | } 247 | circle*64 { 248 | r: $(5/21); 249 | cx, cy: @Plot(r: 5.08; rotate: $(45/16)); 250 | fill: #76b39d; 251 | } 252 | 253 | /* masking and border */ 254 | mask: defs mask { circle { r: 5; fill: #fff }} 255 | circle { r: 4.98; fill: none} 256 | } 257 | } 258 | `), 259 | 260 | 'patterns': read(` 261 | svg { 262 | viewBox: 0 0 1 1; 263 | defs mask#circle { 264 | circle { 265 | r: 4.9; 266 | fill: #fff; 267 | } 268 | } 269 | rect*2 { 270 | x, y: @pn(0, .049); 271 | width, height: @pn(1, .9); 272 | fill: defs pattern { 273 | width, height: @pn(.1, .1114); 274 | viewBox: -5 -5 10 10; 275 | g { 276 | circle*4 { 277 | r: 4.9; 278 | cx, cy: @Plot(r: 7.07; rotate: 45); 279 | fill: #11A8E3; 280 | } 281 | circle { 282 | r: 1.2; 283 | fill: @pn(#D01C3B, #E0D31C); 284 | } 285 | mask: url(#circle); 286 | } 287 | } 288 | } 289 | } 290 | `), 291 | 292 | '10 PRINT': read(` 293 | svg { 294 | viewBox: 0 0 16 16 padding .2; 295 | stroke: #1B2D37; 296 | stroke-width: .4; 297 | stroke-linecap: round; 298 | 299 | line*16x16 { 300 | draw: @r(1s); 301 | x1, y1, x2, y2: @p( 302 | @nx(-1) @ny(-1) @nx @ny, 303 | @nx @ny(-1) @nx(-1) @ny, 304 | @nx @ny(-1) @nx @ny 305 | ); 306 | } 307 | } 308 | `), 309 | 310 | 'weave': read(` 311 | svg { 312 | viewBox: 0 0 1 1; 313 | preserveAspectRatio: xMidYMid slice; 314 | rect { 315 | width, height: 100%; 316 | fill: defs pattern { 317 | viewBox: 0 0 14 14; 318 | patternTransform: rotate(45); 319 | width, height: 12%; 320 | path { 321 | fill: none; 322 | stroke-linecap: square; 323 | stroke: #1b2d37; 324 | stroke-width: 1; 325 | draw: 3s; 326 | d: M 4 5 327 | @p(@p(h -1 v -2 h 3 v 4 h -5 v -6 h 6) 328 | @flipv.reverse.p) 329 | M 4 9 @flipv.p 330 | } 331 | } 332 | } 333 | } 334 | `), 335 | 336 | 'polyline': read(` 337 | svg { 338 | viewBox: -50 -50 100 100; 339 | stroke: #1B2D37; 340 | fill: none; 341 | 342 | polyline { 343 | draw: 1s; 344 | points: @m61.@Plot( 345 | turn: 20.1; 346 | r: t;; 347 | ); 348 | } 349 | 350 | rect { 351 | stroke-width: 2; 352 | width, height: 98; 353 | x, y: -49; 354 | } 355 | } 356 | `), 357 | 358 | 'blob circles': read(` 359 | svg { 360 | --color: #f5f0e1, #ff6e40; 361 | --color2: #1e3d59, #ffc13b, #ffcce7; 362 | 363 | viewBox: 0 0 1 1; 364 | preserveAspectRatio: xMidYMid slice; 365 | 366 | rect { 367 | width, height: 100%; 368 | fill: defs pattern { 369 | viewBox: 0 0 8 8; 370 | patternTransform: rotate(-45); 371 | width, height: 25%; 372 | rect*4 { 373 | fill: @pn(--color); 374 | x, y: 0 @pn(0, 2, 6, 4); 375 | width, height: 8 2; 376 | } 377 | circle*4 { 378 | r: 1.25; 379 | cx, cy: @pn(2 2, 6 2, 6 6, 2 6); 380 | fill: @pnr(--color); 381 | stroke-width: 1.5; 382 | stroke: defs radialgradient { 383 | stop {offset: .99; stop-color: @pnr(--color2) } 384 | stop {offset: 0; stop-color: @pn(--color) } 385 | } 386 | } 387 | } 388 | } 389 | } 390 | `), 391 | 392 | 'codepen logo': read(` 393 | svg { 394 | viewBox: -5 -5 10 11.5; 395 | 396 | fill: none; 397 | stroke: #000; 398 | stroke-width: .6; 399 | stroke-linejoin: round; 400 | 401 | --a: @m4.Plot(r: 2; scale: @sqrt2 1); 402 | --b: @m4.Plot(r: 2; scale: @sqrt2 1; move: 0 2); 403 | 404 | path { 405 | d: M @p((--a)) z 406 | M @p((--b)) z 407 | @M4(M @pn(--a) @pn(--b)) 408 | } 409 | } 410 | `), 411 | 412 | 'fibonacci spiral': read(` 413 | svg { 414 | viewBox: -50 -50 100 100; 415 | circle*300 { 416 | fill: hsl($(120-90*@sin.n), 80%, 50%); 417 | r: @sqrt(@n/60); 418 | cx: $(@n*.618^4 * cos(2π*@n*.618)); 419 | cy: $(@n*.618^4 * sin(2π*@n*.618)); 420 | } 421 | } 422 | `), 423 | 424 | 'planet': read(` 425 | svg { 426 | --color-a: pink; 427 | --color-b: #322EA2; 428 | 429 | viewBox: -5 -5 10 10; 430 | g { 431 | mask: defs mask { 432 | circle { 433 | r: 3; 434 | fill: #fff; 435 | } 436 | } 437 | circle { 438 | r: 3; 439 | fill: @p(--color-a); 440 | } 441 | g { 442 | filter: defs filter { 443 | feTurbulence { 444 | type: fractalNoise; 445 | baseFrequency: 100; 446 | } 447 | feDisplacementMap { 448 | in: SourceGraphic; 449 | scale: 3; 450 | } 451 | } 452 | circle { 453 | cx, cy: 4; 454 | r: 6; 455 | fill: @p(--color-b); 456 | filter: defs filter { 457 | feGaussianBlur { 458 | stdDeviation: .7; 459 | } 460 | } 461 | } 462 | } 463 | } 464 | 465 | g { 466 | transform: rotate(-20); 467 | circle*50 { 468 | r: @r(.1); 469 | fill: @p(--color-a, --color-b); 470 | cx, cy: @Plot( 471 | turn: .774; 472 | scale: 3 1.3; 473 | rotate: 227; 474 | move: 0 .6; 475 | r: 1.5; 476 | ) 477 | } 478 | } 479 | 480 | g { 481 | mask: defs mask { 482 | circle { 483 | r: .85; 484 | cx, cy:2; 485 | fill: #fff; 486 | } 487 | } 488 | circle { 489 | r: 8; 490 | fill: @p(--color-b); 491 | } 492 | g { 493 | filter: defs filter { 494 | feTurbulence { 495 | type: fractalNoise; 496 | baseFrequency: 100; 497 | } 498 | feDisplacementMap { 499 | in: SourceGraphic; 500 | scale: 1; 501 | } 502 | } 503 | circle { 504 | cx, cy: 1; 505 | r: 1.5; 506 | fill: @p(--color-a); 507 | filter: defs filter { 508 | feGaussianBlur { 509 | stdDeviation: .2; 510 | } 511 | } 512 | } 513 | } 514 | } 515 | } 516 | `), 517 | 518 | 'zigzag': read(` 519 | svg { 520 | viewBox: 0 0 10 10 p 2; 521 | path { 522 | stroke: #000; 523 | stroke-linecap: round; 524 | stroke-linejoin: round; 525 | stroke-width: .4; 526 | fill: none; 527 | draw: 3s; 528 | d: M 0 0 529 | @M10.pn(0 @n @n 0, @n 0 0 @n) 530 | @M10.pn(@n @N @N @n, @N @n @n @N); 531 | } 532 | } 533 | `), 534 | 535 | 'arc shape': read(` 536 | svg { 537 | viewBox: -50 -50 100 100 p 40; 538 | fill: none; 539 | 540 | --color: blue; 541 | 542 | --a: π/180 * -80 - π/2; 543 | --b: π/180 * -45 - π/2; 544 | --arc: $(50 * cos(a)) $(50 * sin(a)) 545 | A 50 50 0 0 1 546 | $(50 * cos(b)) $(50 * sin(b)); 547 | 548 | circle { 549 | r: 50; 550 | stroke-width: .5; 551 | stroke: @p(--color); 552 | } 553 | 554 | g { 555 | stroke-width: 6; 556 | stroke-linecap: round; 557 | stroke-linejoin: round; 558 | path { 559 | stroke: color-mix(in srgb, @p(--color) 40%, #fff); 560 | fill: color-mix(in srgb, @p(--color) 40%, #fff); 561 | d: M 0 0 @p(--arc) z 562 | } 563 | path { 564 | stroke: @p(--color); 565 | d: M @p(--arc); 566 | } 567 | } 568 | } 569 | `), 570 | 571 | 'loop': read(` 572 | svg { 573 | viewBox: 0 0 24 24 p 4; 574 | stroke-linecap: square; 575 | stroke: blue; 576 | fill: none; 577 | path*0-3 { 578 | d: @M0-3( 579 | M @p.$(12 - 6/4*@n) 12 @p 6 580 | A @p.$(6 - 6/4*@n) @p 0 1 0 6 @lp3 581 | ); 582 | transform: 583 | translate(@pn(0 0, 24 0, 24 24, 0 24)) 584 | rotate(@n(*90)); 585 | } 586 | } 587 | `), 588 | 589 | 'openai logo': read(` 590 | svg { 591 | viewBox: -50 -50 100 100 p 20; 592 | stroke-linecap: round; 593 | stroke: blue; 594 | fill: none; 595 | 596 | --x: 14 * cos(π/6) * -1; 597 | --y: 14 * sin(π/6); 598 | 599 | g*6 { 600 | transform: rotate(@n(*60)); 601 | path { 602 | stroke-width: 4.2; 603 | d: M $(x - 1) $y $(x - 1) $(-3.4y) 604 | } 605 | path { 606 | stroke-width: 6; 607 | d: M $x $(-3.4y) $(-x) $(-5.4y) 608 | A 22 22 0 0 1 $(-3.1x) $(-1.4y); 609 | } 610 | } 611 | } 612 | `), 613 | 614 | 'drawing ring': read(` 615 | svg { 616 | viewBox: -50 -50 100 100; 617 | path { 618 | stroke: #1B2D37; 619 | fill: none; 620 | d: M 0 0 T 0 @m120.n(*@pn(@m4(.2), @m4(-.2))) 24; 621 | draw: 10s; 622 | } 623 | } 624 | `), 625 | 626 | 'icons': read(` 627 | /* Icons from https://fonts.google.com/knowledge */ 628 | 629 | svg { 630 | viewBox: 0 0 120 20 p 1; 631 | 632 | stroke: #000; 633 | stroke-width: .5; 634 | fill: none; 635 | 636 | /* outlines */ 637 | g rect*5 { 638 | width, height: 20; 639 | x, y: @n(*25, -25) 0; 640 | stroke-dasharray: .5; 641 | stroke-width: .2; 642 | } 643 | 644 | g { 645 | path { 646 | d: M 12 20 A 6 6 0 1 1 12 0 z 647 | M 18 16 A 6 6 0 0 1 18 4 z; 648 | } 649 | } 650 | 651 | g { 652 | transform: translate(25, 0); 653 | circle*2x2 { 654 | r, cx, cy: 5 @nx(*10, -5) @ny(*10, -5); 655 | } 656 | } 657 | 658 | g { 659 | transform: translate(50, 0); 660 | stroke-miterlimit: 1; 661 | path { 662 | d: M 0 0 0 10 0 20 10 20 663 | 0 10 0 0 20 20 10 20; 664 | } 665 | } 666 | 667 | g { 668 | transform: translate(75, 0); 669 | line { 670 | x1, y1, x2, y2: 10 0 10 20; 671 | } 672 | circle*2 { 673 | r, cx, cy: @n(*5) 10 10; 674 | } 675 | } 676 | 677 | g { 678 | transform: translate(100, 0); 679 | path { 680 | d: M 0 20 A 20 20 0 0 1 20 0 L 20 20 z 681 | M 8.5 20 A 11.5 11.5 0 0 1 20 8.5; 682 | } 683 | } 684 | } 685 | `), 686 | 687 | 'css logo': read(` 688 | svg { 689 | viewbox: 0 0 10 10; 690 | 691 | title { 692 | content: "CSS LOGO"; 693 | } 694 | 695 | /* background */ 696 | path { 697 | fill: rebeccapurple; 698 | d: M 0 0 8.4 0 Q 10 0 10 1.6 699 | L 10 8.4 Q 10 10 8.4 10 700 | L 1.6 10 Q 0 10 0 8.4 701 | } 702 | 703 | g { 704 | stroke: #fff; 705 | stroke-width: .75; 706 | fill: none; 707 | 708 | /* C */ 709 | path { 710 | d: M 4.25 6.5 711 | c 0 -1 -1.25 -1 -1.25 0 712 | l 0 1.5 713 | c 0 1 1.25 1 1.25 0 714 | } 715 | 716 | /* SS */ 717 | path*2 { 718 | d: M @pn(8.75, 6.5) 6.5 719 | c 0 -1 -1.25 -1 -1.25 0 720 | s 1.25 .5 1.25 1.5 721 | c 0 1 -1.25 1 -1.25 0 722 | } 723 | } 724 | } 725 | `), 726 | 727 | 'servo logo': read(` 728 | svg { 729 | viewBox: -50 -50 100 100 p 12; 730 | 731 | --r: 50; 732 | --x: -2.4; 733 | --d: .618r; 734 | --y: 1.618x; 735 | 736 | path*5 { 737 | transform-origin: $x $y; 738 | transform: translate($(-1x) $(-1y)) rotate(@n(*72)); 739 | fill: @pn.Mirror(#1292e8,#009d9a,#42be65); 740 | d: M 0 $d 0 $r 741 | A $r $r 0 0 0 $(r*cos(π/10)) $(r*sin(π/10)) 742 | L $(d*sin(π/2.5)) $(d*cos(π/2.5)); 743 | } 744 | } 745 | `) 746 | 747 | } 748 | 749 | function read(input) { 750 | let temp = input.replace(/^\n+/g, ''); 751 | let len = temp.length - temp.replace(/^\s+/g, '').length; 752 | let result = input.split('\n').map(n => ( 753 | n.replace(new RegExp(`^\\s{${len}}`, 'g'), '') 754 | )); 755 | return result.join('\n').trim(); 756 | } 757 | -------------------------------------------------------------------------------- /src/routes/+layout.js: -------------------------------------------------------------------------------- 1 | export const prerender = true; 2 | export const trailingSlash = 'always'; 3 | -------------------------------------------------------------------------------- /src/routes/+page.svelte: -------------------------------------------------------------------------------- 1 |
2 |
3 |
    4 | {#each exampleNames as name} 5 |
  • {name}
  • 6 | {/each} 7 |
8 |
9 | 10 |
11 |
12 |

13 | 14 | New Syntax To Write SVG 15 | 16 |

17 | 32 |
33 |
34 | 35 |
36 |
37 | {#if isNull(codeFromQuery) && mounted} 38 | 39 | {/if} 40 |
41 |
42 | 43 |
44 |
45 | 46 | 47 |
48 |
49 | {#if tab === 'graph'} 50 | {@html svgCode} 51 | {:else} 52 |
{svgCode}
53 | {/if} 54 |
55 |
56 |
57 | 58 | 197 | 198 | 466 | -------------------------------------------------------------------------------- /src/service-worker.js: -------------------------------------------------------------------------------- 1 | import { build, files, version } from '$service-worker'; 2 | 3 | const ASSETS = `cache${version}`; 4 | 5 | // `build` is an array of all the files generated by the bundler, 6 | // `files` is an array of everything in the `static` directory 7 | const to_cache = build.concat(files); 8 | const staticAssets = new Set(to_cache); 9 | 10 | self.addEventListener('install', event => { 11 | event.waitUntil( 12 | caches 13 | .open(ASSETS) 14 | .then(cache => cache.addAll(to_cache)) 15 | .then(() => { 16 | self.skipWaiting(); 17 | }) 18 | ); 19 | }); 20 | 21 | self.addEventListener('activate', event => { 22 | event.waitUntil( 23 | caches.keys().then(async keys => { 24 | // delete old caches 25 | for (const key of keys) { 26 | if (key !== ASSETS) await caches.delete(key); 27 | } 28 | 29 | self.clients.claim(); 30 | }) 31 | ); 32 | }); 33 | 34 | 35 | /** 36 | * Fetch the asset from the network and store it in the cache. 37 | * Fall back to the cache if the user is offline. 38 | */ 39 | async function fetchAndCache(request) { 40 | const cache = await caches.open(`offline${version}`) 41 | 42 | try { 43 | const response = await fetch(request); 44 | cache.put(request, response.clone()); 45 | return response; 46 | } catch (err) { 47 | const response = await cache.match(request); 48 | if (response) return response; 49 | 50 | throw err; 51 | } 52 | } 53 | 54 | self.addEventListener('fetch', event => { 55 | if (event.request.method !== 'GET' || event.request.headers.has('range')) return; 56 | 57 | const url = new URL(event.request.url); 58 | 59 | // don't try to handle e.g. data: URIs 60 | const isHttp = url.protocol.startsWith('http'); 61 | const isDevServerRequest = url.hostname === self.location.hostname && url.port !== self.location.port; 62 | const isStaticAsset = url.host === self.location.host && staticAssets.has(url.pathname); 63 | const skipBecauseUncached = event.request.cache === 'only-if-cached' && !isStaticAsset; 64 | 65 | if (isHttp && !isDevServerRequest && !skipBecauseUncached) { 66 | event.respondWith( 67 | (async () => { 68 | // always serve static files and bundler-generated assets from cache. 69 | // if your application has other URLs with data that will never change, 70 | // set this variable to true for them and they will only be fetched once. 71 | const cachedAsset = (isStaticAsset) && await caches.match(event.request); 72 | 73 | // for pages, you might want to serve a build `service-worker-index.html` file, 74 | // which Sapper has generated for you. It's not right for every 75 | // app, but if it's right for yours then uncomment this section 76 | /* 77 | if (!cachedAsset && url.origin === self.origin && routes.find(route => route.pattern.test(url.pathname))) { 78 | return caches.match('/service-worker-index.html'); 79 | } 80 | */ 81 | return cachedAsset || fetchAndCache(event.request); 82 | })() 83 | ); 84 | } 85 | }); 86 | -------------------------------------------------------------------------------- /static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/css-doodle/svg/e5ac1c3851a0933bb9ce7f295cc145c6e948db54/static/favicon.png -------------------------------------------------------------------------------- /svelte.config.js: -------------------------------------------------------------------------------- 1 | import adapter from '@sveltejs/adapter-static'; 2 | 3 | /** @type {import('@sveltejs/kit').Config} */ 4 | const config = { 5 | kit: { 6 | adapter: adapter(), 7 | serviceWorker: { 8 | register: true, 9 | }, 10 | paths: { 11 | base: '/svg', 12 | }, 13 | } 14 | }; 15 | 16 | export default config; 17 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { sveltekit } from '@sveltejs/kit/vite'; 2 | 3 | const config = { 4 | plugins: [ 5 | sveltekit() 6 | ] 7 | }; 8 | 9 | export default config; 10 | --------------------------------------------------------------------------------