diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 15e8b3b051..6369d9d98a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -35,7 +35,7 @@ jobs: run: pnpm install --frozen-lockfile - name: Build Website env: - NODE_OPTIONS: '--max_old_space_size=8192' + NODE_OPTIONS: '--max_old_space_size=12288' PUBLIC_APPWRITE_ENDPOINT: ${{ secrets.PUBLIC_APPWRITE_ENDPOINT }} PUBLIC_APPWRITE_DASHBOARD: ${{ secrets.PUBLIC_APPWRITE_DASHBOARD }} PUBLIC_APPWRITE_PROJECT_ID: ${{ secrets.PUBLIC_APPWRITE_PROJECT_ID }} diff --git a/Dockerfile b/Dockerfile index 55d207bb78..484d4145e3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -54,7 +54,7 @@ FROM base as build COPY . . RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile -RUN NODE_OPTIONS=--max_old_space_size=8192 pnpm run build +RUN NODE_OPTIONS=--max_old_space_size=12288 pnpm run build FROM base as final diff --git a/package.json b/package.json index dd7b381565..f724fefed1 100644 --- a/package.json +++ b/package.json @@ -83,6 +83,8 @@ "vite": "^5.3.1", "vite-plugin-dynamic-import": "^1.5.0", "vite-plugin-image-optimizer": "^1.1.8", - "vitest": "^1.6.0" + "vitest": "^1.6.0", + "vite-plugin-minify": "^2.0.0", + "html-minifier-terser": "^7.2.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 642c1e9e34..dd6e9dcd02 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,7 +10,7 @@ importers: dependencies: '@sentry/sveltekit': specifier: ^8.12.0 - version: 8.24.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.25.1)(@sveltejs/kit@2.5.20(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)))(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)))(encoding@0.1.13)(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)) + version: 8.24.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.25.1)(@sveltejs/kit@2.5.20(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)))(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)))(encoding@0.1.13)(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)) h3: specifier: ^1.12.0 version: 1.12.0 @@ -44,16 +44,16 @@ importers: version: 1.46.0 '@sveltejs/adapter-node': specifier: ^4.0.1 - version: 4.0.1(@sveltejs/kit@2.5.20(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)))(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8))) + version: 4.0.1(@sveltejs/kit@2.5.20(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)))(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1))) '@sveltejs/enhanced-img': specifier: ^0.1.9 version: 0.1.9(rollup@4.20.0)(svelte@4.2.18) '@sveltejs/kit': specifier: ^2.5.17 - version: 2.5.20(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)))(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)) + version: 2.5.20(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)))(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)) '@sveltejs/vite-plugin-svelte': specifier: ^3.1.1 - version: 3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)) + version: 3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)) '@tailwindcss/postcss': specifier: 4.0.0-alpha.17 version: 4.0.0-alpha.17(postcss@8.4.39) @@ -111,6 +111,9 @@ importers: highlight.js: specifier: ^11.9.0 version: 11.10.0 + html-minifier-terser: + specifier: ^7.2.0 + version: 7.2.0 markdown-it: specifier: ^14.1.0 version: 14.1.0 @@ -176,16 +179,19 @@ importers: version: 5.5.4 vite: specifier: ^5.3.1 - version: 5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8) + version: 5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1) vite-plugin-dynamic-import: specifier: ^1.5.0 version: 1.5.0 vite-plugin-image-optimizer: specifier: ^1.1.8 - version: 1.1.8(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)) + version: 1.1.8(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)) + vite-plugin-minify: + specifier: ^2.0.0 + version: 2.0.0(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)) vitest: specifier: ^1.6.0 - version: 1.6.0(@types/node@22.1.0)(jsdom@20.0.3)(lightningcss@1.25.1)(sass@1.77.8) + version: 1.6.0(@types/node@22.1.0)(jsdom@20.0.3)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1) packages: @@ -820,6 +826,9 @@ packages: resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} engines: {node: '>=6.0.0'} + '@jridgewell/source-map@0.3.6': + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} @@ -1520,6 +1529,9 @@ packages: '@types/glob@8.1.0': resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==} + '@types/html-minifier-terser@7.0.2': + resolution: {integrity: sha512-mm2HqV22l8lFQh4r2oSsOEVea+m0qqxEmwpc9kC1p/XzmjLWrReR9D/GRs8Pex2NX/imyEH9c5IU/7tMBQCHOA==} + '@types/http-errors@2.0.4': resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} @@ -1862,6 +1874,9 @@ packages: resolution: {integrity: sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==} engines: {node: '>=0.4.0'} + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} @@ -1885,6 +1900,9 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + camel-case@4.1.2: + resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} + caniuse-lite@1.0.30001650: resolution: {integrity: sha512-fgEc7hP/LB7iicdXHUI9VsBsMZmUmlVJeQP2qqQW+3lkqVhbmjEU8zp+h5stWeilX+G7uXuIUIIlWlDw9jdt8g==} @@ -1931,6 +1949,10 @@ packages: class-variance-authority@0.7.0: resolution: {integrity: sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==} + clean-css@5.3.3: + resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} + engines: {node: '>= 10.0'} + clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} @@ -1989,6 +2011,13 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} @@ -2184,6 +2213,9 @@ packages: domutils@3.1.0: resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + dotenv@16.4.5: resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} @@ -2553,6 +2585,11 @@ packages: html-escaper@3.0.3: resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} + html-minifier-terser@7.2.0: + resolution: {integrity: sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==} + engines: {node: ^14.13.1 || >=16.0.0} + hasBin: true + htmlparser2@8.0.2: resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} @@ -2905,6 +2942,9 @@ packages: lovely-logs@1.2.2: resolution: {integrity: sha512-dPvYcBok38QvXC+X8/v2BZJDA/iZfCfkRXAwp+s9rvBxY+ZWkMuhNNxukQVIUVMNutIonKpN140Vfv6LCli/wQ==} + lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -3124,6 +3164,9 @@ packages: resolution: {integrity: sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA==} os: ['!win32'] + no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + node-addon-api@3.2.1: resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} @@ -3250,6 +3293,9 @@ packages: pako@1.0.11: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + param-case@3.0.4: + resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -3272,6 +3318,9 @@ packages: parse5@7.1.2: resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + pascal-case@3.1.2: + resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -3596,6 +3645,10 @@ packages: regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + relateurl@0.2.7: + resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} + engines: {node: '>= 0.10'} + remeda@2.10.0: resolution: {integrity: sha512-2RFz0VWckq8nb0nttzToa8BB5HgLsBHokWUKYiV5C8hnsZOTO1jcx0oXKvfS5khabhS6XkngMOLebQB+pm20IQ==} @@ -3745,6 +3798,9 @@ packages: resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} @@ -3952,6 +4008,11 @@ packages: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} + terser@5.34.1: + resolution: {integrity: sha512-FsJZ7iZLd/BXkz+4xrRTGJ26o/6VTjQytUk8b8OxkwcD2I+79VPJlz7qss1+zE7h8GNIScFqXcDyJ/KqBYZFVA==} + engines: {node: '>=10'} + hasBin: true + text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} @@ -4146,6 +4207,11 @@ packages: peerDependencies: vite: '>=3' + vite-plugin-minify@2.0.0: + resolution: {integrity: sha512-xQWdXCip/CH3c5a0fftJtvpodOIZqp3gwfuSpGtik/W1YmZKe8WMTJrxvrjgrQ1NcP4EuqmiMCUaz8+If1CPMw==} + peerDependencies: + vite: ^5.4.0 + vite@5.3.5: resolution: {integrity: sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -5055,6 +5121,11 @@ snapshots: '@jridgewell/set-array@1.2.1': {} + '@jridgewell/source-map@0.3.6': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/sourcemap-codec@1.5.0': {} '@jridgewell/trace-mapping@0.3.25': @@ -5648,7 +5719,7 @@ snapshots: magic-string: 0.30.7 svelte: 4.2.18 - '@sentry/sveltekit@8.24.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.25.1)(@sveltejs/kit@2.5.20(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)))(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)))(encoding@0.1.13)(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8))': + '@sentry/sveltekit@8.24.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.25.1)(@sveltejs/kit@2.5.20(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)))(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)))(encoding@0.1.13)(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1))': dependencies: '@sentry/core': 8.24.0 '@sentry/node': 8.24.0 @@ -5657,12 +5728,12 @@ snapshots: '@sentry/types': 8.24.0 '@sentry/utils': 8.24.0 '@sentry/vite-plugin': 2.20.1(encoding@0.1.13) - '@sveltejs/kit': 2.5.20(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)))(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)) + '@sveltejs/kit': 2.5.20(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)))(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)) magic-string: 0.30.7 magicast: 0.2.8 sorcery: 0.11.0 optionalDependencies: - vite: 5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8) + vite: 5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1) transitivePeerDependencies: - '@opentelemetry/api' - '@opentelemetry/core' @@ -5697,12 +5768,12 @@ snapshots: dependencies: '@sinonjs/commons': 3.0.1 - '@sveltejs/adapter-node@4.0.1(@sveltejs/kit@2.5.20(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)))(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)))': + '@sveltejs/adapter-node@4.0.1(@sveltejs/kit@2.5.20(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)))(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)))': dependencies: '@rollup/plugin-commonjs': 25.0.8(rollup@4.20.0) '@rollup/plugin-json': 6.1.0(rollup@4.20.0) '@rollup/plugin-node-resolve': 15.2.3(rollup@4.20.0) - '@sveltejs/kit': 2.5.20(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)))(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)) + '@sveltejs/kit': 2.5.20(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)))(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)) rollup: 4.20.0 '@sveltejs/enhanced-img@0.1.9(rollup@4.20.0)(svelte@4.2.18)': @@ -5714,9 +5785,9 @@ snapshots: - rollup - svelte - '@sveltejs/kit@2.5.20(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)))(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8))': + '@sveltejs/kit@2.5.20(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)))(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)) + '@sveltejs/vite-plugin-svelte': 3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)) '@types/cookie': 0.6.0 cookie: 0.6.0 devalue: 5.0.0 @@ -5730,28 +5801,28 @@ snapshots: sirv: 2.0.4 svelte: 4.2.18 tiny-glob: 0.2.9 - vite: 5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8) + vite: 5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1) - '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)))(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8))': + '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)))(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)) + '@sveltejs/vite-plugin-svelte': 3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)) debug: 4.3.6 svelte: 4.2.18 - vite: 5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8) + vite: 5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8))': + '@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)))(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)) + '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)))(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)) debug: 4.3.6 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.11 svelte: 4.2.18 svelte-hmr: 0.16.0(svelte@4.2.18) - vite: 5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8) - vitefu: 0.2.5(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)) + vite: 5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1) + vitefu: 0.2.5(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)) transitivePeerDependencies: - supports-color @@ -5869,6 +5940,8 @@ snapshots: '@types/minimatch': 5.1.2 '@types/node': 22.1.0 + '@types/html-minifier-terser@7.0.2': {} + '@types/http-errors@2.0.4': {} '@types/istanbul-lib-coverage@2.0.6': {} @@ -6237,6 +6310,8 @@ snapshots: buffer-equal@0.0.1: {} + buffer-from@1.1.2: {} + buffer@5.7.1: dependencies: base64-js: 1.5.1 @@ -6275,6 +6350,11 @@ snapshots: callsites@3.1.0: {} + camel-case@4.1.2: + dependencies: + pascal-case: 3.1.2 + tslib: 2.6.3 + caniuse-lite@1.0.30001650: {} centra@2.7.0: @@ -6349,6 +6429,10 @@ snapshots: dependencies: clsx: 2.0.0 + clean-css@5.3.3: + dependencies: + source-map: 0.6.1 + clean-stack@2.2.0: {} cli-progress@3.12.0: @@ -6409,6 +6493,10 @@ snapshots: dependencies: delayed-stream: 1.0.0 + commander@10.0.1: {} + + commander@2.20.3: {} + commander@4.1.1: {} commander@7.2.0: {} @@ -6570,6 +6658,11 @@ snapshots: domelementtype: 2.3.0 domhandler: 5.0.3 + dot-case@3.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.6.3 + dotenv@16.4.5: {} eastasianwidth@0.2.0: {} @@ -7010,6 +7103,16 @@ snapshots: html-escaper@3.0.3: {} + html-minifier-terser@7.2.0: + dependencies: + camel-case: 4.1.2 + clean-css: 5.3.3 + commander: 10.0.1 + entities: 4.5.0 + param-case: 3.0.4 + relateurl: 0.2.7 + terser: 5.34.1 + htmlparser2@8.0.2: dependencies: domelementtype: 2.3.0 @@ -7388,6 +7491,10 @@ snapshots: lovely-logs@1.2.2: {} + lower-case@2.0.2: + dependencies: + tslib: 2.6.3 + lru-cache@10.4.3: {} lru-cache@5.1.1: @@ -7610,6 +7717,11 @@ snapshots: node-gyp-build: 4.8.1 optional: true + no-case@3.0.4: + dependencies: + lower-case: 2.0.2 + tslib: 2.6.3 + node-addon-api@3.2.1: optional: true @@ -7762,6 +7874,11 @@ snapshots: pako@1.0.11: {} + param-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.6.3 + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -7786,6 +7903,11 @@ snapshots: dependencies: entities: 4.5.0 + pascal-case@3.1.2: + dependencies: + no-case: 3.0.4 + tslib: 2.6.3 + path-exists@4.0.0: {} path-is-absolute@1.0.1: {} @@ -8021,6 +8143,8 @@ snapshots: regenerator-runtime@0.14.1: {} + relateurl@0.2.7: {} + remeda@2.10.0: dependencies: type-fest: 4.23.0 @@ -8203,6 +8327,11 @@ snapshots: source-map-js@1.2.0: {} + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + source-map@0.6.1: {} split2@1.1.1: @@ -8445,6 +8574,13 @@ snapshots: mkdirp: 1.0.4 yallist: 4.0.0 + terser@5.34.1: + dependencies: + '@jridgewell/source-map': 0.3.6 + acorn: 8.12.1 + commander: 2.20.3 + source-map-support: 0.5.21 + text-table@0.2.0: {} the-new-css-reset@1.11.2: {} @@ -8615,13 +8751,13 @@ snapshots: transitivePeerDependencies: - rollup - vite-node@1.6.0(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8): + vite-node@1.6.0(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1): dependencies: cac: 6.7.14 debug: 4.3.6 pathe: 1.1.2 picocolors: 1.0.1 - vite: 5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8) + vite: 5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1) transitivePeerDependencies: - '@types/node' - less @@ -8639,13 +8775,19 @@ snapshots: fast-glob: 3.3.2 magic-string: 0.30.11 - vite-plugin-image-optimizer@1.1.8(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)): + vite-plugin-image-optimizer@1.1.8(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)): dependencies: ansi-colors: 4.1.3 pathe: 1.1.2 - vite: 5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8) + vite: 5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1) + + vite-plugin-minify@2.0.0(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)): + dependencies: + '@types/html-minifier-terser': 7.0.2 + html-minifier-terser: 7.2.0 + vite: 5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1) - vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8): + vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1): dependencies: esbuild: 0.21.5 postcss: 8.4.41 @@ -8655,12 +8797,13 @@ snapshots: fsevents: 2.3.3 lightningcss: 1.25.1 sass: 1.77.8 + terser: 5.34.1 - vitefu@0.2.5(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)): + vitefu@0.2.5(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1)): optionalDependencies: - vite: 5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8) + vite: 5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1) - vitest@1.6.0(@types/node@22.1.0)(jsdom@20.0.3)(lightningcss@1.25.1)(sass@1.77.8): + vitest@1.6.0(@types/node@22.1.0)(jsdom@20.0.3)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1): dependencies: '@vitest/expect': 1.6.0 '@vitest/runner': 1.6.0 @@ -8679,8 +8822,8 @@ snapshots: strip-literal: 2.1.0 tinybench: 2.9.0 tinypool: 0.8.4 - vite: 5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8) - vite-node: 1.6.0(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8) + vite: 5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1) + vite-node: 1.6.0(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8)(terser@5.34.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.1.0 diff --git a/scripts/build.js b/scripts/build.js index 5141e582a0..1752b494e9 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -1,9 +1,11 @@ import { build } from 'vite'; +import { minifyHtmlPostBuild } from './html-minifier.js'; import { downloadContributors } from './download-contributor-data.js'; async function main() { await downloadContributors(); await build(); + await minifyHtmlPostBuild(); } main(); diff --git a/scripts/html-minifier.js b/scripts/html-minifier.js new file mode 100644 index 0000000000..ec461efbd8 --- /dev/null +++ b/scripts/html-minifier.js @@ -0,0 +1,88 @@ +import path from 'path'; +import fs from 'fs/promises'; +import minifier from 'html-minifier-terser'; + +const prerenderedPagesDir = 'build/prerendered'; +const htmlMinifierOptions = { + minifyJS: true, + minifyCSS: true, + useShortDoctype: true, + collapseWhitespace: true, + removeAttributeQuotes: true +}; + +async function getHtmlFiles(dir) { + let htmlFiles = []; + const files = await fs.readdir(dir, { withFileTypes: true }); + + for (const file of files) { + const filePath = path.join(dir, file.name); + if (file.isDirectory()) { + htmlFiles = htmlFiles.concat(await getHtmlFiles(filePath)); + } else if (file.isFile() && file.name.endsWith('.html')) { + htmlFiles.push(filePath); + } + } + + return htmlFiles; +} + +// Function to format sizes in bytes to KB, MB, GB, etc. +function formatSize(bytes) { + if (bytes < 1024) return `${bytes} B`; + const units = ['KB', 'MB', 'GB', 'TB']; + let value = bytes / 1024; + let unitIndex = 0; + + while (value >= 1024 && unitIndex < units.length - 1) { + value /= 1024; + unitIndex++; + } + + return `${value.toFixed(2)} ${units[unitIndex]}`; +} + +export async function minifyHtmlPostBuild() { + let minifiedCount = 0; + let totalOriginalSize = 0; + let totalMinifiedSize = 0; + + const minifyTasks = []; + + console.log('Starting html minification...'); + + try { + const htmlFiles = await getHtmlFiles(prerenderedPagesDir); + + for (const htmlPath of htmlFiles) { + minifyTasks.push( + (async () => { + try { + const html = await fs.readFile(htmlPath, 'utf-8'); + const originalSize = Buffer.byteLength(html, 'utf-8'); + totalOriginalSize += originalSize; + + const minHTML = await minifier.minify(html, htmlMinifierOptions); + const minifiedSize = Buffer.byteLength(minHTML, 'utf-8'); + totalMinifiedSize += minifiedSize; + + await fs.writeFile(htmlPath, minHTML); + + minifiedCount += 1; + } catch (error) { + console.error(`Failed to minify HTML for ${htmlPath}: ${error.message}`); + } + })() + ); + } + + await Promise.all(minifyTasks); + + console.log(`Minification complete: ${minifiedCount} files processed.`); + console.log( + `Original: ${formatSize(totalOriginalSize)}, Minified: ${formatSize(totalMinifiedSize)}` + ); + } catch (error) { + console.error(`Error processing files: ${error.message}`); + } +} diff --git a/scripts/thumbnails.js b/scripts/thumbnails.js new file mode 100644 index 0000000000..773ae8ffef --- /dev/null +++ b/scripts/thumbnails.js @@ -0,0 +1,179 @@ +import { mkdirSync, readdirSync, readFileSync } from 'fs'; +import { dirname, join } from 'path'; +import sharp from 'sharp'; +import { fileURLToPath } from 'url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +// Define the base path for static images +const srcDir = join(__dirname, '../static/images'); + +const authorDir = join(srcDir, 'avatars'); +const blogCoverDir = join(srcDir, 'blog'); +const authorDestDir = join(authorDir, 'thumbnails'); +const blogCoverDestDir = join(blogCoverDir, 'thumbnails'); + +const articlesDir = join(__dirname, '../src/routes/blog/post'); +const authorsDir = join(__dirname, '../src/routes/blog/author'); + +function isPNG(file) { + return file.endsWith('.png'); +} + +function parseFrontmatter(file, key = 'cover') { + const content = readFileSync(file, 'utf8'); + const fmRegex = /---\s*([\s\S]*?)\s*---/; + const searchForFeaturedPost = key === 'cover'; + + const featuredRegex = new RegExp(`^featured:\\s*['"]?(.+?)['"]?$`, 'm'); + + const match = content.match(fmRegex); + if (match) { + const fmContent = match[1]; + const regex = new RegExp(`^${key}:\\s*(.+)$`, 'm'); + const imageMatch = fmContent.match(regex); + if (imageMatch) { + let withFeature = {}; + withFeature.image = imageMatch[1].trim(); + + if (searchForFeaturedPost) { + const featureMatch = fmContent.match(featuredRegex); + if (featureMatch) { + withFeature.featured = featureMatch[1] === 'true'; + } else { + withFeature.featured = false; + } + } + + return withFeature; + } + } + return null; +} + +function walkDirectory(dir, list = []) { + const files = readdirSync(dir, { withFileTypes: true }); + files.forEach((file) => { + const pathToFile = join(dir, file.name); + if (file.isDirectory()) { + list = walkDirectory(pathToFile, list); + } else if (file.name === '+page.markdoc') { + list.push(pathToFile); + } + }); + + return list; +} + +function ensureDir(path) { + try { + mkdirSync(path, { recursive: true }); + } catch (err) { + if (err.code !== 'EEXIST') throw err; + } +} + +async function createThumbnails(images, destDir, options) { + const { width, height } = options; + + for (const file of images) { + let relativePath = file.substring(srcDir.length).replace(/\/blog\/|\/avatars\//, ''); + const thumbBasePath = join(destDir, relativePath); + + ensureDir(dirname(thumbBasePath)); + + const pngThumbPath = thumbBasePath.replace(/\.[^/.]+$/, '.png'); + const webpThumbPath = thumbBasePath.replace(/\.[^/.]+$/, '.webp'); + + const resizedImageBuffer = await sharp(file) + .resize({ + width, + height, + fit: sharp.fit.inside, + withoutEnlargement: true + }) + .toBuffer(); + + const sharpInstance = sharp(resizedImageBuffer); + + await Promise.all([ + sharpInstance.webp({ lossless: true }).toFile(webpThumbPath), + sharpInstance.png({ compressionLevel: 9 }).toFile(pngThumbPath) + ]); + } +} + +function getBlogCovers() { + const markdocFiles = walkDirectory(articlesDir); + return markdocFiles + .map((filePath) => { + const { featured, image: coverPath } = parseFrontmatter(filePath); + + if (coverPath && isPNG(coverPath)) { + return { + featured: featured, + coverPath: join(__dirname, '../static', coverPath) + }; + } + }) + .filter(Boolean); +} + +function getAuthorAvatars() { + const authorFiles = walkDirectory(authorsDir); + return authorFiles + .map((filePath) => { + const { image: avatarPath } = parseFrontmatter(filePath, 'avatar'); + if (avatarPath && isPNG(avatarPath)) { + return join(__dirname, '../static', avatarPath); + } + }) + .filter(Boolean); +} + +/** + * @typedef {{ width: number, height: number }} ThumbnailSize + * + * @typedef {{ + * cover: { + * normal: ThumbnailSize, + * featured: ThumbnailSize + * }, + * author: ThumbnailSize + * }} ThumbnailOptions + */ + +/** + * Preprocess thumbnails for cover and author images. + * + * @param {Object} [options={}] - Options to configure the thumbnail sizes. + * @param {{ + * cover?: { + * normal?: ThumbnailSize, + * featured?: ThumbnailSize + * }, + * author?: ThumbnailSize + * }} [options] - The optional thumbnail configuration. + */ +export async function thumbnailPreprocess(options = {}) { + const { + cover: { + normal: normalCover = { width: 320, height: 320 }, + featured: featuredCover = { width: 640, height: 640 } + } = {}, + author: authorOption = { width: 112, height: 112 } + } = options; + + const coverImages = getBlogCovers(); + const authorAvatars = getAuthorAvatars(); + + const normalCovers = coverImages.filter((img) => !img.featured).map((img) => img.coverPath); + const featuredCovers = coverImages.filter((img) => img.featured).map((img) => img.coverPath); + + await Promise.all([ + createThumbnails(authorAvatars, authorDestDir, authorOption), + createThumbnails(normalCovers, blogCoverDestDir, normalCover), + createThumbnails(featuredCovers, blogCoverDestDir, featuredCover) + ]); + + return { name: 'thumbnail-creator-preprocessor' }; +} diff --git a/src/icons/output/info.json b/src/icons/output/info.json index 6e9be45ece..fc00f8f508 100644 --- a/src/icons/output/info.json +++ b/src/icons/output/info.json @@ -1,314 +1,314 @@ { - "apple": { - "encodedCode": "\\ea01", - "prefix": "web-icon", - "className": "web-icon-apple", - "unicode": "" - }, - "appwrite": { - "encodedCode": "\\ea02", - "prefix": "web-icon", - "className": "web-icon-appwrite", - "unicode": "" - }, - "arrow-down": { - "encodedCode": "\\ea03", - "prefix": "web-icon", - "className": "web-icon-arrow-down", - "unicode": "" - }, - "arrow-ext-link": { - "encodedCode": "\\ea04", - "prefix": "web-icon", - "className": "web-icon-arrow-ext-link", - "unicode": "" - }, - "arrow-left": { - "encodedCode": "\\ea05", - "prefix": "web-icon", - "className": "web-icon-arrow-left", - "unicode": "" - }, - "arrow-right": { - "encodedCode": "\\ea06", - "prefix": "web-icon", - "className": "web-icon-arrow-right", - "unicode": "" - }, - "arrow-up": { - "encodedCode": "\\ea07", - "prefix": "web-icon", - "className": "web-icon-arrow-up", - "unicode": "" - }, - "calendar": { - "encodedCode": "\\ea08", - "prefix": "web-icon", - "className": "web-icon-calendar", - "unicode": "" - }, - "check": { - "encodedCode": "\\ea09", - "prefix": "web-icon", - "className": "web-icon-check", - "unicode": "" - }, - "chevron-down": { - "encodedCode": "\\ea0a", - "prefix": "web-icon", - "className": "web-icon-chevron-down", - "unicode": "" - }, - "chevron-left": { - "encodedCode": "\\ea0b", - "prefix": "web-icon", - "className": "web-icon-chevron-left", - "unicode": "" - }, - "chevron-right": { - "encodedCode": "\\ea0c", - "prefix": "web-icon", - "className": "web-icon-chevron-right", - "unicode": "" - }, - "chevron-up": { - "encodedCode": "\\ea0d", - "prefix": "web-icon", - "className": "web-icon-chevron-up", - "unicode": "" - }, - "close": { - "encodedCode": "\\ea0e", - "prefix": "web-icon", - "className": "web-icon-close", - "unicode": "" - }, - "command": { - "encodedCode": "\\ea0f", - "prefix": "web-icon", - "className": "web-icon-command", - "unicode": "" - }, - "copy": { - "encodedCode": "\\ea10", - "prefix": "web-icon", - "className": "web-icon-copy", - "unicode": "" - }, - "daily-dev": { - "encodedCode": "\\ea11", - "prefix": "web-icon", - "className": "web-icon-daily-dev", - "unicode": "" - }, - "dark": { - "encodedCode": "\\ea12", - "prefix": "web-icon", - "className": "web-icon-dark", - "unicode": "" - }, - "discord": { - "encodedCode": "\\ea13", - "prefix": "web-icon", - "className": "web-icon-discord", - "unicode": "" - }, - "divider-vertical": { - "encodedCode": "\\ea14", - "prefix": "web-icon", - "className": "web-icon-divider-vertical", - "unicode": "" - }, - "download": { - "encodedCode": "\\ea15", - "prefix": "web-icon", - "className": "web-icon-download", - "unicode": "" - }, - "ext-link": { - "encodedCode": "\\ea16", - "prefix": "web-icon", - "className": "web-icon-ext-link", - "unicode": "" - }, - "firebase": { - "encodedCode": "\\ea17", - "prefix": "web-icon", - "className": "web-icon-firebase", - "unicode": "" - }, - "github": { - "encodedCode": "\\ea18", - "prefix": "web-icon", - "className": "web-icon-github", - "unicode": "" - }, - "google": { - "encodedCode": "\\ea19", - "prefix": "web-icon", - "className": "web-icon-google", - "unicode": "" - }, - "hamburger-menu": { - "encodedCode": "\\ea1a", - "prefix": "web-icon", - "className": "web-icon-hamburger-menu", - "unicode": "" - }, - "light": { - "encodedCode": "\\ea1b", - "prefix": "web-icon", - "className": "web-icon-light", - "unicode": "" - }, - "linkedin": { - "encodedCode": "\\ea1c", - "prefix": "web-icon", - "className": "web-icon-linkedin", - "unicode": "" - }, - "location": { - "encodedCode": "\\ea1d", - "prefix": "web-icon", - "className": "web-icon-location", - "unicode": "" - }, - "logout-left": { - "encodedCode": "\\ea1e", - "prefix": "web-icon", - "className": "web-icon-logout-left", - "unicode": "" - }, - "logout-right": { - "encodedCode": "\\ea1f", - "prefix": "web-icon", - "className": "web-icon-logout-right", - "unicode": "" - }, - "mailgun": { - "encodedCode": "\\ea20", - "prefix": "web-icon", - "className": "web-icon-mailgun", - "unicode": "" - }, - "message": { - "encodedCode": "\\ea21", - "prefix": "web-icon", - "className": "web-icon-message", - "unicode": "" - }, - "microsoft": { - "encodedCode": "\\ea22", - "prefix": "web-icon", - "className": "web-icon-microsoft", - "unicode": "" - }, - "minus": { - "encodedCode": "\\ea23", - "prefix": "web-icon", - "className": "web-icon-minus", - "unicode": "" - }, - "nuxt": { - "encodedCode": "\\ea24", - "prefix": "web-icon", - "className": "web-icon-nuxt", - "unicode": "" - }, - "platform": { - "encodedCode": "\\ea25", - "prefix": "web-icon", - "className": "web-icon-platform", - "unicode": "" - }, - "play": { - "encodedCode": "\\ea26", - "prefix": "web-icon", - "className": "web-icon-play", - "unicode": "" - }, - "plus": { - "encodedCode": "\\ea27", - "prefix": "web-icon", - "className": "web-icon-plus", - "unicode": "" - }, - "product-hunt": { - "encodedCode": "\\ea28", - "prefix": "web-icon", - "className": "web-icon-product-hunt", - "unicode": "" - }, - "refine": { - "encodedCode": "\\ea29", - "prefix": "web-icon", - "className": "web-icon-refine", - "unicode": "" - }, - "rest": { - "encodedCode": "\\ea2a", - "prefix": "web-icon", - "className": "web-icon-rest", - "unicode": "" - }, - "search": { - "encodedCode": "\\ea2b", - "prefix": "web-icon", - "className": "web-icon-search", - "unicode": "" - }, - "sendgrid": { - "encodedCode": "\\ea2c", - "prefix": "web-icon", - "className": "web-icon-sendgrid", - "unicode": "" - }, - "star": { - "encodedCode": "\\ea2d", - "prefix": "web-icon", - "className": "web-icon-star", - "unicode": "" - }, - "system": { - "encodedCode": "\\ea2e", - "prefix": "web-icon", - "className": "web-icon-system", - "unicode": "" - }, - "textmagic": { - "encodedCode": "\\ea2f", - "prefix": "web-icon", - "className": "web-icon-textmagic", - "unicode": "" - }, - "twitter": { - "encodedCode": "\\ea30", - "prefix": "web-icon", - "className": "web-icon-twitter", - "unicode": "" - }, - "vue": { - "encodedCode": "\\ea31", - "prefix": "web-icon", - "className": "web-icon-vue", - "unicode": "" - }, - "x": { - "encodedCode": "\\ea32", - "prefix": "web-icon", - "className": "web-icon-x", - "unicode": "" - }, - "ycombinator": { - "encodedCode": "\\ea33", - "prefix": "web-icon", - "className": "web-icon-ycombinator", - "unicode": "" - }, - "youtube": { - "encodedCode": "\\ea34", - "prefix": "web-icon", - "className": "web-icon-youtube", - "unicode": "" - } + "apple": { + "encodedCode": "\\ea01", + "prefix": "web-icon", + "className": "web-icon-apple", + "unicode": "" + }, + "appwrite": { + "encodedCode": "\\ea02", + "prefix": "web-icon", + "className": "web-icon-appwrite", + "unicode": "" + }, + "arrow-down": { + "encodedCode": "\\ea03", + "prefix": "web-icon", + "className": "web-icon-arrow-down", + "unicode": "" + }, + "arrow-ext-link": { + "encodedCode": "\\ea04", + "prefix": "web-icon", + "className": "web-icon-arrow-ext-link", + "unicode": "" + }, + "arrow-left": { + "encodedCode": "\\ea05", + "prefix": "web-icon", + "className": "web-icon-arrow-left", + "unicode": "" + }, + "arrow-right": { + "encodedCode": "\\ea06", + "prefix": "web-icon", + "className": "web-icon-arrow-right", + "unicode": "" + }, + "arrow-up": { + "encodedCode": "\\ea07", + "prefix": "web-icon", + "className": "web-icon-arrow-up", + "unicode": "" + }, + "calendar": { + "encodedCode": "\\ea08", + "prefix": "web-icon", + "className": "web-icon-calendar", + "unicode": "" + }, + "check": { + "encodedCode": "\\ea09", + "prefix": "web-icon", + "className": "web-icon-check", + "unicode": "" + }, + "chevron-down": { + "encodedCode": "\\ea0a", + "prefix": "web-icon", + "className": "web-icon-chevron-down", + "unicode": "" + }, + "chevron-left": { + "encodedCode": "\\ea0b", + "prefix": "web-icon", + "className": "web-icon-chevron-left", + "unicode": "" + }, + "chevron-right": { + "encodedCode": "\\ea0c", + "prefix": "web-icon", + "className": "web-icon-chevron-right", + "unicode": "" + }, + "chevron-up": { + "encodedCode": "\\ea0d", + "prefix": "web-icon", + "className": "web-icon-chevron-up", + "unicode": "" + }, + "close": { + "encodedCode": "\\ea0e", + "prefix": "web-icon", + "className": "web-icon-close", + "unicode": "" + }, + "command": { + "encodedCode": "\\ea0f", + "prefix": "web-icon", + "className": "web-icon-command", + "unicode": "" + }, + "copy": { + "encodedCode": "\\ea10", + "prefix": "web-icon", + "className": "web-icon-copy", + "unicode": "" + }, + "daily-dev": { + "encodedCode": "\\ea11", + "prefix": "web-icon", + "className": "web-icon-daily-dev", + "unicode": "" + }, + "dark": { + "encodedCode": "\\ea12", + "prefix": "web-icon", + "className": "web-icon-dark", + "unicode": "" + }, + "discord": { + "encodedCode": "\\ea13", + "prefix": "web-icon", + "className": "web-icon-discord", + "unicode": "" + }, + "divider-vertical": { + "encodedCode": "\\ea14", + "prefix": "web-icon", + "className": "web-icon-divider-vertical", + "unicode": "" + }, + "download": { + "encodedCode": "\\ea15", + "prefix": "web-icon", + "className": "web-icon-download", + "unicode": "" + }, + "ext-link": { + "encodedCode": "\\ea16", + "prefix": "web-icon", + "className": "web-icon-ext-link", + "unicode": "" + }, + "firebase": { + "encodedCode": "\\ea17", + "prefix": "web-icon", + "className": "web-icon-firebase", + "unicode": "" + }, + "github": { + "encodedCode": "\\ea18", + "prefix": "web-icon", + "className": "web-icon-github", + "unicode": "" + }, + "google": { + "encodedCode": "\\ea19", + "prefix": "web-icon", + "className": "web-icon-google", + "unicode": "" + }, + "hamburger-menu": { + "encodedCode": "\\ea1a", + "prefix": "web-icon", + "className": "web-icon-hamburger-menu", + "unicode": "" + }, + "light": { + "encodedCode": "\\ea1b", + "prefix": "web-icon", + "className": "web-icon-light", + "unicode": "" + }, + "linkedin": { + "encodedCode": "\\ea1c", + "prefix": "web-icon", + "className": "web-icon-linkedin", + "unicode": "" + }, + "location": { + "encodedCode": "\\ea1d", + "prefix": "web-icon", + "className": "web-icon-location", + "unicode": "" + }, + "logout-left": { + "encodedCode": "\\ea1e", + "prefix": "web-icon", + "className": "web-icon-logout-left", + "unicode": "" + }, + "logout-right": { + "encodedCode": "\\ea1f", + "prefix": "web-icon", + "className": "web-icon-logout-right", + "unicode": "" + }, + "mailgun": { + "encodedCode": "\\ea20", + "prefix": "web-icon", + "className": "web-icon-mailgun", + "unicode": "" + }, + "message": { + "encodedCode": "\\ea21", + "prefix": "web-icon", + "className": "web-icon-message", + "unicode": "" + }, + "microsoft": { + "encodedCode": "\\ea22", + "prefix": "web-icon", + "className": "web-icon-microsoft", + "unicode": "" + }, + "minus": { + "encodedCode": "\\ea23", + "prefix": "web-icon", + "className": "web-icon-minus", + "unicode": "" + }, + "nuxt": { + "encodedCode": "\\ea24", + "prefix": "web-icon", + "className": "web-icon-nuxt", + "unicode": "" + }, + "platform": { + "encodedCode": "\\ea25", + "prefix": "web-icon", + "className": "web-icon-platform", + "unicode": "" + }, + "play": { + "encodedCode": "\\ea26", + "prefix": "web-icon", + "className": "web-icon-play", + "unicode": "" + }, + "plus": { + "encodedCode": "\\ea27", + "prefix": "web-icon", + "className": "web-icon-plus", + "unicode": "" + }, + "product-hunt": { + "encodedCode": "\\ea28", + "prefix": "web-icon", + "className": "web-icon-product-hunt", + "unicode": "" + }, + "refine": { + "encodedCode": "\\ea29", + "prefix": "web-icon", + "className": "web-icon-refine", + "unicode": "" + }, + "rest": { + "encodedCode": "\\ea2a", + "prefix": "web-icon", + "className": "web-icon-rest", + "unicode": "" + }, + "search": { + "encodedCode": "\\ea2b", + "prefix": "web-icon", + "className": "web-icon-search", + "unicode": "" + }, + "sendgrid": { + "encodedCode": "\\ea2c", + "prefix": "web-icon", + "className": "web-icon-sendgrid", + "unicode": "" + }, + "star": { + "encodedCode": "\\ea2d", + "prefix": "web-icon", + "className": "web-icon-star", + "unicode": "" + }, + "system": { + "encodedCode": "\\ea2e", + "prefix": "web-icon", + "className": "web-icon-system", + "unicode": "" + }, + "textmagic": { + "encodedCode": "\\ea2f", + "prefix": "web-icon", + "className": "web-icon-textmagic", + "unicode": "" + }, + "twitter": { + "encodedCode": "\\ea30", + "prefix": "web-icon", + "className": "web-icon-twitter", + "unicode": "" + }, + "vue": { + "encodedCode": "\\ea31", + "prefix": "web-icon", + "className": "web-icon-vue", + "unicode": "" + }, + "x": { + "encodedCode": "\\ea32", + "prefix": "web-icon", + "className": "web-icon-x", + "unicode": "" + }, + "ycombinator": { + "encodedCode": "\\ea33", + "prefix": "web-icon", + "className": "web-icon-ycombinator", + "unicode": "" + }, + "youtube": { + "encodedCode": "\\ea34", + "prefix": "web-icon", + "className": "web-icon-youtube", + "unicode": "" + } } diff --git a/src/icons/output/web-icon.css b/src/icons/output/web-icon.css index 22208dc214..1946420c21 100644 --- a/src/icons/output/web-icon.css +++ b/src/icons/output/web-icon.css @@ -1,15 +1,18 @@ @font-face { - font-family: "web-icon"; + font-family: 'web-icon'; font-display: swap; src: url('web-icon.eot'); /* IE9*/ - src: url('web-icon.eot#iefix') format('embedded-opentype'), /* IE6-IE8 */ - url("web-icon.woff2") format("woff2"), - url("web-icon.woff") format("woff"), - url('web-icon.ttf') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ - url('web-icon.svg#web-icon') format('svg'); /* iOS 4.1- */ + src: + url('web-icon.eot#iefix') format('embedded-opentype'), + /* IE6-IE8 */ url('web-icon.woff2') format('woff2'), + url('web-icon.woff') format('woff'), + url('web-icon.ttf') format('truetype'), + /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ url('web-icon.svg#web-icon') + format('svg'); /* iOS 4.1- */ } -[class^="web-icon-"], [class*=" web-icon-"] { +[class^='web-icon-'], +[class*=' web-icon-'] { font-family: 'web-icon' !important; font-size: 20px; font-style: normal; @@ -17,55 +20,159 @@ -moz-osx-font-smoothing: grayscale; } -.web-icon-apple:before { content: "\ea01"; } -.web-icon-appwrite:before { content: "\ea02"; } -.web-icon-arrow-down:before { content: "\ea03"; } -.web-icon-arrow-ext-link:before { content: "\ea04"; } -.web-icon-arrow-left:before { content: "\ea05"; } -.web-icon-arrow-right:before { content: "\ea06"; } -.web-icon-arrow-up:before { content: "\ea07"; } -.web-icon-calendar:before { content: "\ea08"; } -.web-icon-check:before { content: "\ea09"; } -.web-icon-chevron-down:before { content: "\ea0a"; } -.web-icon-chevron-left:before { content: "\ea0b"; } -.web-icon-chevron-right:before { content: "\ea0c"; } -.web-icon-chevron-up:before { content: "\ea0d"; } -.web-icon-close:before { content: "\ea0e"; } -.web-icon-command:before { content: "\ea0f"; } -.web-icon-copy:before { content: "\ea10"; } -.web-icon-daily-dev:before { content: "\ea11"; } -.web-icon-dark:before { content: "\ea12"; } -.web-icon-discord:before { content: "\ea13"; } -.web-icon-divider-vertical:before { content: "\ea14"; } -.web-icon-download:before { content: "\ea15"; } -.web-icon-ext-link:before { content: "\ea16"; } -.web-icon-firebase:before { content: "\ea17"; } -.web-icon-github:before { content: "\ea18"; } -.web-icon-google:before { content: "\ea19"; } -.web-icon-hamburger-menu:before { content: "\ea1a"; } -.web-icon-light:before { content: "\ea1b"; } -.web-icon-linkedin:before { content: "\ea1c"; } -.web-icon-location:before { content: "\ea1d"; } -.web-icon-logout-left:before { content: "\ea1e"; } -.web-icon-logout-right:before { content: "\ea1f"; } -.web-icon-mailgun:before { content: "\ea20"; } -.web-icon-message:before { content: "\ea21"; } -.web-icon-microsoft:before { content: "\ea22"; } -.web-icon-minus:before { content: "\ea23"; } -.web-icon-nuxt:before { content: "\ea24"; } -.web-icon-platform:before { content: "\ea25"; } -.web-icon-play:before { content: "\ea26"; } -.web-icon-plus:before { content: "\ea27"; } -.web-icon-product-hunt:before { content: "\ea28"; } -.web-icon-refine:before { content: "\ea29"; } -.web-icon-rest:before { content: "\ea2a"; } -.web-icon-search:before { content: "\ea2b"; } -.web-icon-sendgrid:before { content: "\ea2c"; } -.web-icon-star:before { content: "\ea2d"; } -.web-icon-system:before { content: "\ea2e"; } -.web-icon-textmagic:before { content: "\ea2f"; } -.web-icon-twitter:before { content: "\ea30"; } -.web-icon-vue:before { content: "\ea31"; } -.web-icon-x:before { content: "\ea32"; } -.web-icon-ycombinator:before { content: "\ea33"; } -.web-icon-youtube:before { content: "\ea34"; } +.web-icon-apple:before { + content: '\ea01'; +} +.web-icon-appwrite:before { + content: '\ea02'; +} +.web-icon-arrow-down:before { + content: '\ea03'; +} +.web-icon-arrow-ext-link:before { + content: '\ea04'; +} +.web-icon-arrow-left:before { + content: '\ea05'; +} +.web-icon-arrow-right:before { + content: '\ea06'; +} +.web-icon-arrow-up:before { + content: '\ea07'; +} +.web-icon-calendar:before { + content: '\ea08'; +} +.web-icon-check:before { + content: '\ea09'; +} +.web-icon-chevron-down:before { + content: '\ea0a'; +} +.web-icon-chevron-left:before { + content: '\ea0b'; +} +.web-icon-chevron-right:before { + content: '\ea0c'; +} +.web-icon-chevron-up:before { + content: '\ea0d'; +} +.web-icon-close:before { + content: '\ea0e'; +} +.web-icon-command:before { + content: '\ea0f'; +} +.web-icon-copy:before { + content: '\ea10'; +} +.web-icon-daily-dev:before { + content: '\ea11'; +} +.web-icon-dark:before { + content: '\ea12'; +} +.web-icon-discord:before { + content: '\ea13'; +} +.web-icon-divider-vertical:before { + content: '\ea14'; +} +.web-icon-download:before { + content: '\ea15'; +} +.web-icon-ext-link:before { + content: '\ea16'; +} +.web-icon-firebase:before { + content: '\ea17'; +} +.web-icon-github:before { + content: '\ea18'; +} +.web-icon-google:before { + content: '\ea19'; +} +.web-icon-hamburger-menu:before { + content: '\ea1a'; +} +.web-icon-light:before { + content: '\ea1b'; +} +.web-icon-linkedin:before { + content: '\ea1c'; +} +.web-icon-location:before { + content: '\ea1d'; +} +.web-icon-logout-left:before { + content: '\ea1e'; +} +.web-icon-logout-right:before { + content: '\ea1f'; +} +.web-icon-mailgun:before { + content: '\ea20'; +} +.web-icon-message:before { + content: '\ea21'; +} +.web-icon-microsoft:before { + content: '\ea22'; +} +.web-icon-minus:before { + content: '\ea23'; +} +.web-icon-nuxt:before { + content: '\ea24'; +} +.web-icon-platform:before { + content: '\ea25'; +} +.web-icon-play:before { + content: '\ea26'; +} +.web-icon-plus:before { + content: '\ea27'; +} +.web-icon-product-hunt:before { + content: '\ea28'; +} +.web-icon-refine:before { + content: '\ea29'; +} +.web-icon-rest:before { + content: '\ea2a'; +} +.web-icon-search:before { + content: '\ea2b'; +} +.web-icon-sendgrid:before { + content: '\ea2c'; +} +.web-icon-star:before { + content: '\ea2d'; +} +.web-icon-system:before { + content: '\ea2e'; +} +.web-icon-textmagic:before { + content: '\ea2f'; +} +.web-icon-twitter:before { + content: '\ea30'; +} +.web-icon-vue:before { + content: '\ea31'; +} +.web-icon-x:before { + content: '\ea32'; +} +.web-icon-ycombinator:before { + content: '\ea33'; +} +.web-icon-youtube:before { + content: '\ea34'; +} diff --git a/src/lib/UI/AuthorCover.svelte b/src/lib/UI/AuthorCover.svelte new file mode 100644 index 0000000000..88a89ea2cf --- /dev/null +++ b/src/lib/UI/AuthorCover.svelte @@ -0,0 +1,25 @@ + + + + + {author} + diff --git a/src/lib/UI/BlogPostCover.svelte b/src/lib/UI/BlogPostCover.svelte new file mode 100644 index 0000000000..28cdb7b831 --- /dev/null +++ b/src/lib/UI/BlogPostCover.svelte @@ -0,0 +1,100 @@ + + +{#if isFeatured} + + + + +{:else} +
+ + + (imageLoaded = true)} + loading="lazy" + src={isInViewport ? thumbnailSrc : null} + /> + +
+{/if} + + diff --git a/src/lib/UI/index.ts b/src/lib/UI/index.ts index ec5c08c6e9..6ac33a1e60 100644 --- a/src/lib/UI/index.ts +++ b/src/lib/UI/index.ts @@ -1,2 +1,4 @@ export { default as Tabs } from './Tabs/index.svelte'; export { default as Media } from './Media.svelte'; +export { default as AuthorCover } from './AuthorCover.svelte'; +export { default as BlogPostCover } from './BlogPostCover.svelte'; diff --git a/src/lib/animations/Products/(assets)/auth-shot.png b/src/lib/animations/Products/(assets)/auth-shot.png deleted file mode 100644 index 17a622bc94..0000000000 Binary files a/src/lib/animations/Products/(assets)/auth-shot.png and /dev/null differ diff --git a/src/lib/animations/Products/(assets)/db-shot.png b/src/lib/animations/Products/(assets)/db-shot.png deleted file mode 100644 index 1ea94076ff..0000000000 Binary files a/src/lib/animations/Products/(assets)/db-shot.png and /dev/null differ diff --git a/src/lib/animations/Products/(assets)/fn-shot.png b/src/lib/animations/Products/(assets)/fn-shot.png deleted file mode 100644 index c1c9bffc1f..0000000000 Binary files a/src/lib/animations/Products/(assets)/fn-shot.png and /dev/null differ diff --git a/src/lib/animations/Products/(assets)/messaging-shot.png b/src/lib/animations/Products/(assets)/messaging-shot.png deleted file mode 100644 index 0798ddb35a..0000000000 Binary files a/src/lib/animations/Products/(assets)/messaging-shot.png and /dev/null differ diff --git a/src/lib/animations/Products/(assets)/realtime-shot.png b/src/lib/animations/Products/(assets)/realtime-shot.png deleted file mode 100644 index 228731d3d4..0000000000 Binary files a/src/lib/animations/Products/(assets)/realtime-shot.png and /dev/null differ diff --git a/src/lib/animations/Products/(assets)/storage-shot.png b/src/lib/animations/Products/(assets)/storage-shot.png deleted file mode 100644 index d4dc0d0573..0000000000 Binary files a/src/lib/animations/Products/(assets)/storage-shot.png and /dev/null differ diff --git a/src/lib/animations/Products/Products.svelte b/src/lib/animations/Products/Products.svelte index b14146ca74..7055364a99 100644 --- a/src/lib/animations/Products/Products.svelte +++ b/src/lib/animations/Products/Products.svelte @@ -1,11 +1,4 @@ @@ -284,6 +277,7 @@ alt="" width="32" height="32" + loading="lazy" /> {copy.title} diff --git a/src/lib/animations/Products/ProductsMobile.svelte b/src/lib/animations/Products/ProductsMobile.svelte index 720eee17b0..45626dc9ee 100644 --- a/src/lib/animations/Products/ProductsMobile.svelte +++ b/src/lib/animations/Products/ProductsMobile.svelte @@ -39,7 +39,7 @@ {#if info.shot} - + {/if} @@ -51,7 +51,7 @@
- +

See your products grow

@@ -101,7 +101,7 @@ display: flex; flex-direction: column; - gap: 3rem; + gap: 1rem; .info { h3 { diff --git a/src/lib/components/Article.svelte b/src/lib/components/Article.svelte index 9c46a44d46..18726d7d32 100644 --- a/src/lib/components/Article.svelte +++ b/src/lib/components/Article.svelte @@ -1,6 +1,6 @@

  • - + {#if thumbnail} + + {:else} + + {/if}

    @@ -28,13 +33,10 @@

    - {author}

    {author}

    diff --git a/src/lib/components/LogoList.svelte b/src/lib/components/LogoList.svelte index 1ea74174d9..8ad2602030 100644 --- a/src/lib/components/LogoList.svelte +++ b/src/lib/components/LogoList.svelte @@ -89,7 +89,7 @@ > {#each logos as { src, alt, width, height }, i}
  • - +
  • {/each} diff --git a/src/lib/components/PreFooter.svelte b/src/lib/components/PreFooter.svelte index f60ab3f0bc..d3a03e5055 100644 --- a/src/lib/components/PreFooter.svelte +++ b/src/lib/components/PreFooter.svelte @@ -2,7 +2,7 @@ import { PUBLIC_APPWRITE_DASHBOARD } from '$env/static/public'; - +
    diff --git a/src/lib/components/Technologies.svelte b/src/lib/components/Technologies.svelte index 2ae92ff7d0..7e00685485 100644 --- a/src/lib/components/Technologies.svelte +++ b/src/lib/components/Technologies.svelte @@ -75,6 +75,7 @@ alt="{platform.name} quick start" width="32" height="32" + loading="lazy" /> diff --git a/src/markdoc/layouts/Author.svelte b/src/markdoc/layouts/Author.svelte index 23411d275d..29ae6dcce6 100644 --- a/src/markdoc/layouts/Author.svelte +++ b/src/markdoc/layouts/Author.svelte @@ -277,6 +277,7 @@ date={post.date} timeToRead={post.timeToRead} {avatar} + thumbnail author={name} /> {/each} @@ -284,7 +285,7 @@
    -
    +
    diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 9e744e50c3..9effa0ffe4 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -11,7 +11,6 @@ import MainFooter from '../lib/components/MainFooter.svelte'; import DeveloperCard from './DeveloperCard.svelte'; import { PUBLIC_APPWRITE_DASHBOARD } from '$env/static/public'; - import CoverImage from './dashboard.png'; import Button from '$lib/components/ui/Button.svelte'; import Hero from '$lib/components/ui/Hero.svelte'; import GradientText from '$lib/components/ui/GradientText.svelte'; @@ -89,10 +88,11 @@ class="absolute" style="top: -800px; left: 50%; translate: -50%; pointer-events:none; z-index: 10" > -
    @@ -103,7 +103,8 @@ style="top: 22rem; left: 54%; translate: calc(-50% - 900px); width: 75.9375rem;" class:web-u-hide-mobile={$isMobileNavOpen} > - + +
    - + +
    @@ -160,7 +162,7 @@
    console dashboard @@ -435,6 +437,7 @@ width="768" height="768" alt="" + loading="lazy" style="position: absolute; display: block;" />
    diff --git a/src/routes/DeveloperCard.svelte b/src/routes/DeveloperCard.svelte index 6309534a2b..2bb5b8428b 100644 --- a/src/routes/DeveloperCard.svelte +++ b/src/routes/DeveloperCard.svelte @@ -9,7 +9,7 @@
    - Avatar of {name} + Avatar of {name}
    {name}
    {tag}
    diff --git a/src/routes/blog/[[page]]/+page.svelte b/src/routes/blog/[[page]]/+page.svelte index e85528ceb5..73236998aa 100644 --- a/src/routes/blog/[[page]]/+page.svelte +++ b/src/routes/blog/[[page]]/+page.svelte @@ -1,11 +1,12 @@