From a3049369ba6aa92df4fd7d557f533809e721178a Mon Sep 17 00:00:00 2001
From: Le Minh Tri
Date: Thu, 23 Feb 2023 15:02:19 +0700
Subject: [PATCH 01/75] feat(ui): config TailwindCSS
---
astro.config.mjs | 2 +
package.json | 4 +-
pnpm-lock.yaml | 294 +++++++++++++++++++++++++++++++++++++++++++-
tailwind.config.cjs | 8 ++
4 files changed, 306 insertions(+), 2 deletions(-)
create mode 100644 tailwind.config.cjs
diff --git a/astro.config.mjs b/astro.config.mjs
index 09d43efd..5421025c 100644
--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -1,3 +1,4 @@
+import tailwind from '@astrojs/tailwind'
import { defineConfig } from 'astro/config'
import compress from 'astro-compress'
import purgecss from 'astro-purgecss'
@@ -17,6 +18,7 @@ if (baseURL.length === 0) {
export default defineConfig({
site: baseURL,
integrations: [
+ tailwind(),
purgecss(),
compress(),
]
diff --git a/package.json b/package.json
index e69c2ef6..aa3b41d9 100644
--- a/package.json
+++ b/package.json
@@ -15,9 +15,11 @@
"lint": "eslint --ext .cjs,.mjs,.ts,.astro --ignore-path .gitignore ."
},
"dependencies": {
+ "@astrojs/tailwind": "^3.0.1",
"astro": "^2.0.14",
"astro-compress": "^1.1.33",
- "astro-purgecss": "^2.0.0"
+ "astro-purgecss": "^2.0.0",
+ "tailwindcss": "^3.0.24"
},
"devDependencies": {
"@commitlint/cli": "^17.4.4",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 1aa31af6..15b88474 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1,6 +1,7 @@
lockfileVersion: 5.4
specifiers:
+ '@astrojs/tailwind': ^3.0.1
'@commitlint/cli': ^17.4.4
'@commitlint/config-conventional': ^17.4.4
'@types/node': ^18.14.0
@@ -15,12 +16,15 @@ specifiers:
eslint-plugin-astro: ^0.23.0
eslint-plugin-simple-import-sort: ^10.0.0
husky: ^8.0.3
+ tailwindcss: ^3.0.24
typescript: ^4.9.5
dependencies:
+ '@astrojs/tailwind': 3.0.1_hf2kjfio2dr6w52rh4mpociq2u
astro: 2.0.14_@types+node@18.14.0
astro-compress: 1.1.33
astro-purgecss: 2.0.0_astro@2.0.14
+ tailwindcss: 3.2.7
devDependencies:
'@commitlint/cli': 17.4.4
@@ -101,6 +105,22 @@ packages:
prismjs: 1.29.0
dev: false
+ /@astrojs/tailwind/3.0.1_hf2kjfio2dr6w52rh4mpociq2u:
+ resolution: {integrity: sha512-QSYh/xmz454j1yZU9rjw2J24PpH7j3h2ClesqMaAniOtcuL8RfP7KYCnCrk01xvjwqqO+QBpZNDD/SUhHNtFFg==}
+ peerDependencies:
+ astro: ^2.0.4
+ tailwindcss: ^3.0.24
+ dependencies:
+ '@proload/core': 0.3.3
+ astro: 2.0.14_@types+node@18.14.0
+ autoprefixer: 10.4.13_postcss@8.4.21
+ postcss: 8.4.21
+ postcss-load-config: 4.0.1_postcss@8.4.21
+ tailwindcss: 3.2.7
+ transitivePeerDependencies:
+ - ts-node
+ dev: false
+
/@astrojs/telemetry/2.0.0:
resolution: {integrity: sha512-RnWojVMIsql3GGWDP5pNWmhmBQVkCpxGNZ8yPr2cbmUqsUYGSvErhqfkLfro9j2/STi5UDmSpNgjPkQmXpgnKw==}
engines: {node: '>=16.12.0'}
@@ -859,6 +879,13 @@ packages:
tiny-glob: 0.2.9
tslib: 2.4.1
+ /@proload/core/0.3.3:
+ resolution: {integrity: sha512-7dAFWsIK84C90AMl24+N/ProHKm4iw0akcnoKjRvbfHifJZBLhaDsDus1QJmhG12lXj4e/uB/8mB/0aduCW+NQ==}
+ dependencies:
+ deepmerge: 4.3.0
+ escalade: 3.1.1
+ dev: false
+
/@trysound/sax/0.2.0:
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
engines: {node: '>=10.13.0'}
@@ -1161,11 +1188,30 @@ packages:
acorn: 8.8.1
dev: true
+ /acorn-node/1.8.2:
+ resolution: {integrity: sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==}
+ dependencies:
+ acorn: 7.4.1
+ acorn-walk: 7.2.0
+ xtend: 4.0.2
+ dev: false
+
+ /acorn-walk/7.2.0:
+ resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==}
+ engines: {node: '>=0.4.0'}
+ dev: false
+
/acorn-walk/8.2.0:
resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
engines: {node: '>=0.4.0'}
dev: true
+ /acorn/7.4.1:
+ resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+ dev: false
+
/acorn/8.8.1:
resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==}
engines: {node: '>=0.4.0'}
@@ -1228,10 +1274,22 @@ packages:
engines: {node: '>=12'}
dev: false
+ /anymatch/3.1.3:
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+ engines: {node: '>= 8'}
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.1
+ dev: false
+
/arg/4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
dev: true
+ /arg/5.0.2:
+ resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
+ dev: false
+
/argparse/1.0.10:
resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
dependencies:
@@ -1380,6 +1438,22 @@ packages:
engines: {node: '>= 4.0.0'}
dev: true
+ /autoprefixer/10.4.13_postcss@8.4.21:
+ resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==}
+ engines: {node: ^10 || ^12 || >=14}
+ hasBin: true
+ peerDependencies:
+ postcss: ^8.1.0
+ dependencies:
+ browserslist: 4.21.4
+ caniuse-lite: 1.0.30001441
+ fraction.js: 4.2.0
+ normalize-range: 0.1.2
+ picocolors: 1.0.0
+ postcss: 8.4.21
+ postcss-value-parser: 4.2.0
+ dev: false
+
/bail/2.0.2:
resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
dev: false
@@ -1390,6 +1464,11 @@ packages:
/base64-js/1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
+ /binary-extensions/2.2.0:
+ resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
+ engines: {node: '>=8'}
+ dev: false
+
/bl/4.1.0:
resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
dependencies:
@@ -1494,6 +1573,11 @@ packages:
tslib: 2.4.1
dev: false
+ /camelcase-css/2.0.1:
+ resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
+ engines: {node: '>= 6'}
+ dev: false
+
/camelcase-keys/6.2.2:
resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==}
engines: {node: '>=8'}
@@ -1557,6 +1641,21 @@ packages:
resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==}
dev: true
+ /chokidar/3.5.3:
+ resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
+ engines: {node: '>= 8.10.0'}
+ dependencies:
+ anymatch: 3.1.3
+ braces: 3.0.2
+ glob-parent: 5.1.2
+ is-binary-path: 2.1.0
+ is-glob: 4.0.3
+ normalize-path: 3.0.0
+ readdirp: 3.6.0
+ optionalDependencies:
+ fsevents: 2.3.2
+ dev: false
+
/chownr/1.1.4:
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
dev: false
@@ -1903,6 +2002,11 @@ packages:
engines: {node: '>=12.4.0'}
dev: false
+ /deepmerge/4.3.0:
+ resolution: {integrity: sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
/defaults/1.0.4:
resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==}
dependencies:
@@ -1912,6 +2016,10 @@ packages:
resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==}
engines: {node: '>=8'}
+ /defined/1.0.1:
+ resolution: {integrity: sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==}
+ dev: false
+
/dequal/2.0.3:
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
engines: {node: '>=6'}
@@ -1932,10 +2040,24 @@ packages:
engines: {node: '>=8'}
dev: false
+ /detective/5.2.1:
+ resolution: {integrity: sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==}
+ engines: {node: '>=0.8.0'}
+ hasBin: true
+ dependencies:
+ acorn-node: 1.8.2
+ defined: 1.0.1
+ minimist: 1.2.7
+ dev: false
+
/devalue/4.2.0:
resolution: {integrity: sha512-mbjoAaCL2qogBKgeFxFPOXAUsZchircF+B/79LD4sHH0+NHfYm8gZpQrskKDn5gENGt35+5OI1GUF7hLVnkPDw==}
dev: false
+ /didyoumean/1.2.2:
+ resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
+ dev: false
+
/diff/4.0.2:
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
engines: {node: '>=0.3.1'}
@@ -2438,6 +2560,10 @@ packages:
resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==}
dev: true
+ /fraction.js/4.2.0:
+ resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==}
+ dev: false
+
/fs-constants/1.0.0:
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
dev: false
@@ -2524,7 +2650,6 @@ packages:
engines: {node: '>=10.13.0'}
dependencies:
is-glob: 4.0.3
- dev: true
/glob/7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
@@ -2879,6 +3004,13 @@ packages:
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
dev: false
+ /is-binary-path/2.1.0:
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+ engines: {node: '>=8'}
+ dependencies:
+ binary-extensions: 2.2.0
+ dev: false
+
/is-buffer/2.0.5:
resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==}
engines: {node: '>=4'}
@@ -3091,6 +3223,11 @@ packages:
type-check: 0.4.0
dev: true
+ /lilconfig/2.0.6:
+ resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==}
+ engines: {node: '>=10'}
+ dev: false
+
/lines-and-columns/1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
dev: true
@@ -3776,6 +3913,16 @@ packages:
validate-npm-package-license: 3.0.4
dev: true
+ /normalize-path/3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
+ /normalize-range/0.1.2:
+ resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
/npm-run-path/4.0.1:
resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
engines: {node: '>=8'}
@@ -3796,6 +3943,11 @@ packages:
boolbase: 1.0.0
dev: false
+ /object-hash/3.0.0:
+ resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
+ engines: {node: '>= 6'}
+ dev: false
+
/once/1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
dependencies:
@@ -3982,6 +4134,11 @@ packages:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
+ /pify/2.3.0:
+ resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
/pify/4.0.1:
resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
engines: {node: '>=6'}
@@ -3994,6 +4151,72 @@ packages:
find-up: 4.1.0
dev: false
+ /postcss-import/14.1.0_postcss@8.4.21:
+ resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==}
+ engines: {node: '>=10.0.0'}
+ peerDependencies:
+ postcss: ^8.0.0
+ dependencies:
+ postcss: 8.4.21
+ postcss-value-parser: 4.2.0
+ read-cache: 1.0.0
+ resolve: 1.22.1
+ dev: false
+
+ /postcss-js/4.0.1_postcss@8.4.21:
+ resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
+ engines: {node: ^12 || ^14 || >= 16}
+ peerDependencies:
+ postcss: ^8.4.21
+ dependencies:
+ camelcase-css: 2.0.1
+ postcss: 8.4.21
+ dev: false
+
+ /postcss-load-config/3.1.4_postcss@8.4.21:
+ resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
+ engines: {node: '>= 10'}
+ peerDependencies:
+ postcss: '>=8.0.9'
+ ts-node: '>=9.0.0'
+ peerDependenciesMeta:
+ postcss:
+ optional: true
+ ts-node:
+ optional: true
+ dependencies:
+ lilconfig: 2.0.6
+ postcss: 8.4.21
+ yaml: 1.10.2
+ dev: false
+
+ /postcss-load-config/4.0.1_postcss@8.4.21:
+ resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==}
+ engines: {node: '>= 14'}
+ peerDependencies:
+ postcss: '>=8.0.9'
+ ts-node: '>=9.0.0'
+ peerDependenciesMeta:
+ postcss:
+ optional: true
+ ts-node:
+ optional: true
+ dependencies:
+ lilconfig: 2.0.6
+ postcss: 8.4.21
+ yaml: 2.2.1
+ dev: false
+
+ /postcss-nested/6.0.0_postcss@8.4.21:
+ resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==}
+ engines: {node: '>=12.0'}
+ peerDependencies:
+ postcss: ^8.2.14
+ dependencies:
+ postcss: 8.4.21
+ postcss-selector-parser: 6.0.11
+ dev: false
+
/postcss-selector-parser/6.0.11:
resolution: {integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==}
engines: {node: '>=4'}
@@ -4001,6 +4224,10 @@ packages:
cssesc: 3.0.0
util-deprecate: 1.0.2
+ /postcss-value-parser/4.2.0:
+ resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
+ dev: false
+
/postcss/8.4.20:
resolution: {integrity: sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==}
engines: {node: ^10 || ^12 || >=14}
@@ -4120,6 +4347,11 @@ packages:
engines: {node: '>=8'}
dev: true
+ /quick-lru/5.1.1:
+ resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
+ engines: {node: '>=10'}
+ dev: false
+
/rc/1.2.8:
resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
hasBin: true
@@ -4130,6 +4362,12 @@ packages:
strip-json-comments: 2.0.1
dev: false
+ /read-cache/1.0.0:
+ resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
+ dependencies:
+ pify: 2.3.0
+ dev: false
+
/read-pkg-up/7.0.1:
resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==}
engines: {node: '>=8'}
@@ -4157,6 +4395,13 @@ packages:
string_decoder: 1.3.0
util-deprecate: 1.0.2
+ /readdirp/3.6.0:
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+ engines: {node: '>=8.10.0'}
+ dependencies:
+ picomatch: 2.3.1
+ dev: false
+
/redent/3.0.0:
resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==}
engines: {node: '>=8'}
@@ -4697,6 +4942,38 @@ packages:
'@pkgr/utils': 2.3.1
tslib: 2.4.1
+ /tailwindcss/3.2.7:
+ resolution: {integrity: sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ==}
+ engines: {node: '>=12.13.0'}
+ hasBin: true
+ dependencies:
+ arg: 5.0.2
+ chokidar: 3.5.3
+ color-name: 1.1.4
+ detective: 5.2.1
+ didyoumean: 1.2.2
+ dlv: 1.1.3
+ fast-glob: 3.2.12
+ glob-parent: 6.0.2
+ is-glob: 4.0.3
+ lilconfig: 2.0.6
+ micromatch: 4.0.5
+ normalize-path: 3.0.0
+ object-hash: 3.0.0
+ picocolors: 1.0.0
+ postcss: 8.4.21
+ postcss-import: 14.1.0_postcss@8.4.21
+ postcss-js: 4.0.1_postcss@8.4.21
+ postcss-load-config: 3.1.4_postcss@8.4.21
+ postcss-nested: 6.0.0_postcss@8.4.21
+ postcss-selector-parser: 6.0.11
+ postcss-value-parser: 4.2.0
+ quick-lru: 5.1.1
+ resolve: 1.22.1
+ transitivePeerDependencies:
+ - ts-node
+ dev: false
+
/tar-fs/2.1.1:
resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==}
dependencies:
@@ -5218,6 +5495,11 @@ packages:
/wrappy/1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+ /xtend/4.0.2:
+ resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
+ engines: {node: '>=0.4'}
+ dev: false
+
/y18n/5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
@@ -5230,6 +5512,16 @@ packages:
/yallist/4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
+ /yaml/1.10.2:
+ resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
+ engines: {node: '>= 6'}
+ dev: false
+
+ /yaml/2.2.1:
+ resolution: {integrity: sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==}
+ engines: {node: '>= 14'}
+ dev: false
+
/yargs-parser/20.2.9:
resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==}
engines: {node: '>=10'}
diff --git a/tailwind.config.cjs b/tailwind.config.cjs
new file mode 100644
index 00000000..0968b45b
--- /dev/null
+++ b/tailwind.config.cjs
@@ -0,0 +1,8 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
+ theme: {
+ extend: {},
+ },
+ plugins: [],
+}
From 945811dafeff482770da4ad404a21e912a1d9766 Mon Sep 17 00:00:00 2001
From: Le Minh Tri
Date: Thu, 23 Feb 2023 16:15:13 +0700
Subject: [PATCH 02/75] feat(ui): config Tailwind Typography
---
package.json | 1 +
pnpm-lock.yaml | 56 +++++++++++++++++++++------------------------
tailwind.config.cjs | 6 ++++-
3 files changed, 32 insertions(+), 31 deletions(-)
diff --git a/package.json b/package.json
index aa3b41d9..1e197c4a 100644
--- a/package.json
+++ b/package.json
@@ -24,6 +24,7 @@
"devDependencies": {
"@commitlint/cli": "^17.4.4",
"@commitlint/config-conventional": "^17.4.4",
+ "@tailwindcss/typography": "^0.5.9",
"@types/node": "^18.14.0",
"@typescript-eslint/eslint-plugin": "^5.53.0",
"@typescript-eslint/parser": "^5.53.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 15b88474..23154a62 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -4,6 +4,7 @@ specifiers:
'@astrojs/tailwind': ^3.0.1
'@commitlint/cli': ^17.4.4
'@commitlint/config-conventional': ^17.4.4
+ '@tailwindcss/typography': ^0.5.9
'@types/node': ^18.14.0
'@typescript-eslint/eslint-plugin': ^5.53.0
'@typescript-eslint/parser': ^5.53.0
@@ -29,6 +30,7 @@ dependencies:
devDependencies:
'@commitlint/cli': 17.4.4
'@commitlint/config-conventional': 17.4.4
+ '@tailwindcss/typography': 0.5.9_tailwindcss@3.2.7
'@types/node': 18.14.0
'@typescript-eslint/eslint-plugin': 5.53.0_ny4s7qc6yg74faf3d6xty2ofzy
'@typescript-eslint/parser': 5.53.0_7kw3g6rralp5ps6mg3uyzz6azm
@@ -886,6 +888,18 @@ packages:
escalade: 3.1.1
dev: false
+ /@tailwindcss/typography/0.5.9_tailwindcss@3.2.7:
+ resolution: {integrity: sha512-t8Sg3DyynFysV9f4JDOVISGsjazNb48AeIYQwcL+Bsq5uf4RYL75C1giZ43KISjeDGBaTN3Kxh7Xj/vRSMJUUg==}
+ peerDependencies:
+ tailwindcss: '>=3.0.0 || insiders'
+ dependencies:
+ lodash.castarray: 4.4.0
+ lodash.isplainobject: 4.0.6
+ lodash.merge: 4.6.2
+ postcss-selector-parser: 6.0.10
+ tailwindcss: 3.2.7
+ dev: true
+
/@trysound/sax/0.2.0:
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
engines: {node: '>=10.13.0'}
@@ -1194,12 +1208,10 @@ packages:
acorn: 7.4.1
acorn-walk: 7.2.0
xtend: 4.0.2
- dev: false
/acorn-walk/7.2.0:
resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==}
engines: {node: '>=0.4.0'}
- dev: false
/acorn-walk/8.2.0:
resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
@@ -1210,7 +1222,6 @@ packages:
resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==}
engines: {node: '>=0.4.0'}
hasBin: true
- dev: false
/acorn/8.8.1:
resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==}
@@ -1280,7 +1291,6 @@ packages:
dependencies:
normalize-path: 3.0.0
picomatch: 2.3.1
- dev: false
/arg/4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
@@ -1288,7 +1298,6 @@ packages:
/arg/5.0.2:
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
- dev: false
/argparse/1.0.10:
resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
@@ -1467,7 +1476,6 @@ packages:
/binary-extensions/2.2.0:
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
engines: {node: '>=8'}
- dev: false
/bl/4.1.0:
resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
@@ -1576,7 +1584,6 @@ packages:
/camelcase-css/2.0.1:
resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
engines: {node: '>= 6'}
- dev: false
/camelcase-keys/6.2.2:
resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==}
@@ -1654,7 +1661,6 @@ packages:
readdirp: 3.6.0
optionalDependencies:
fsevents: 2.3.2
- dev: false
/chownr/1.1.4:
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
@@ -2018,7 +2024,6 @@ packages:
/defined/1.0.1:
resolution: {integrity: sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==}
- dev: false
/dequal/2.0.3:
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
@@ -2048,7 +2053,6 @@ packages:
acorn-node: 1.8.2
defined: 1.0.1
minimist: 1.2.7
- dev: false
/devalue/4.2.0:
resolution: {integrity: sha512-mbjoAaCL2qogBKgeFxFPOXAUsZchircF+B/79LD4sHH0+NHfYm8gZpQrskKDn5gENGt35+5OI1GUF7hLVnkPDw==}
@@ -2056,7 +2060,6 @@ packages:
/didyoumean/1.2.2:
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
- dev: false
/diff/4.0.2:
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
@@ -2077,7 +2080,6 @@ packages:
/dlv/1.1.3:
resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
- dev: false
/doctrine/3.0.0:
resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
@@ -2595,7 +2597,6 @@ packages:
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
requiresBuild: true
- dev: false
optional: true
/function-bind/1.1.1:
@@ -3009,7 +3010,6 @@ packages:
engines: {node: '>=8'}
dependencies:
binary-extensions: 2.2.0
- dev: false
/is-buffer/2.0.5:
resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==}
@@ -3226,7 +3226,6 @@ packages:
/lilconfig/2.0.6:
resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==}
engines: {node: '>=10'}
- dev: false
/lines-and-columns/1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
@@ -3258,6 +3257,10 @@ packages:
resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==}
dev: true
+ /lodash.castarray/4.4.0:
+ resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==}
+ dev: true
+
/lodash.isfunction/3.0.9:
resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==}
dev: true
@@ -3916,7 +3919,6 @@ packages:
/normalize-path/3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
- dev: false
/normalize-range/0.1.2:
resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
@@ -3946,7 +3948,6 @@ packages:
/object-hash/3.0.0:
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
engines: {node: '>= 6'}
- dev: false
/once/1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
@@ -4137,7 +4138,6 @@ packages:
/pify/2.3.0:
resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
engines: {node: '>=0.10.0'}
- dev: false
/pify/4.0.1:
resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
@@ -4161,7 +4161,6 @@ packages:
postcss-value-parser: 4.2.0
read-cache: 1.0.0
resolve: 1.22.1
- dev: false
/postcss-js/4.0.1_postcss@8.4.21:
resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
@@ -4171,7 +4170,6 @@ packages:
dependencies:
camelcase-css: 2.0.1
postcss: 8.4.21
- dev: false
/postcss-load-config/3.1.4_postcss@8.4.21:
resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
@@ -4188,7 +4186,6 @@ packages:
lilconfig: 2.0.6
postcss: 8.4.21
yaml: 1.10.2
- dev: false
/postcss-load-config/4.0.1_postcss@8.4.21:
resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==}
@@ -4215,7 +4212,14 @@ packages:
dependencies:
postcss: 8.4.21
postcss-selector-parser: 6.0.11
- dev: false
+
+ /postcss-selector-parser/6.0.10:
+ resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==}
+ engines: {node: '>=4'}
+ dependencies:
+ cssesc: 3.0.0
+ util-deprecate: 1.0.2
+ dev: true
/postcss-selector-parser/6.0.11:
resolution: {integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==}
@@ -4226,7 +4230,6 @@ packages:
/postcss-value-parser/4.2.0:
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
- dev: false
/postcss/8.4.20:
resolution: {integrity: sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==}
@@ -4243,7 +4246,6 @@ packages:
nanoid: 3.3.4
picocolors: 1.0.0
source-map-js: 1.0.2
- dev: false
/prebuild-install/7.1.1:
resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==}
@@ -4350,7 +4352,6 @@ packages:
/quick-lru/5.1.1:
resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
engines: {node: '>=10'}
- dev: false
/rc/1.2.8:
resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
@@ -4366,7 +4367,6 @@ packages:
resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
dependencies:
pify: 2.3.0
- dev: false
/read-pkg-up/7.0.1:
resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==}
@@ -4400,7 +4400,6 @@ packages:
engines: {node: '>=8.10.0'}
dependencies:
picomatch: 2.3.1
- dev: false
/redent/3.0.0:
resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==}
@@ -4972,7 +4971,6 @@ packages:
resolve: 1.22.1
transitivePeerDependencies:
- ts-node
- dev: false
/tar-fs/2.1.1:
resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==}
@@ -5498,7 +5496,6 @@ packages:
/xtend/4.0.2:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
engines: {node: '>=0.4'}
- dev: false
/y18n/5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
@@ -5515,7 +5512,6 @@ packages:
/yaml/1.10.2:
resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
engines: {node: '>= 6'}
- dev: false
/yaml/2.2.1:
resolution: {integrity: sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==}
diff --git a/tailwind.config.cjs b/tailwind.config.cjs
index 0968b45b..9e9fbcb8 100644
--- a/tailwind.config.cjs
+++ b/tailwind.config.cjs
@@ -1,8 +1,12 @@
+const typography = require('@tailwindcss/typography')
+
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
theme: {
extend: {},
},
- plugins: [],
+ plugins: [
+ typography(),
+ ],
}
From c6dbbbb0692b9521bf01ba09203e3228ac9adea9 Mon Sep 17 00:00:00 2001
From: Le Minh Tri
Date: Thu, 23 Feb 2023 22:13:34 +0700
Subject: [PATCH 03/75] feat(component): add component SEOMeta
---
src/components/SEOMeta.astro | 37 ++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
create mode 100644 src/components/SEOMeta.astro
diff --git a/src/components/SEOMeta.astro b/src/components/SEOMeta.astro
new file mode 100644
index 00000000..5a7e882c
--- /dev/null
+++ b/src/components/SEOMeta.astro
@@ -0,0 +1,37 @@
+---
+interface Props {
+ title: string
+ description: string | undefined
+ favicon: string | undefined
+ faviconMimeType: string | undefined
+ keywords: string | undefined
+ author: string | undefined
+ robots: string | undefined
+}
+
+const {
+ title,
+ description,
+ favicon,
+ faviconMimeType,
+ keywords,
+ author,
+ robots,
+} = Astro.props
+---
+
+
+
+
+
+
+
+{title}
+
+{description && }
+
+
+{keywords && }
+
+{robots && }
+
From c6ee40931ee89a1ff4eadf8b104b4254ea22ed4c Mon Sep 17 00:00:00 2001
From: Le Minh Tri
Date: Fri, 24 Feb 2023 02:58:59 +0700
Subject: [PATCH 04/75] feat: update index page UI using TailwindCSS
---
public/favicon.ico | Bin 0 -> 1150 bytes
public/favicon.svg | 13 -------
src/components/Card.astro | 46 ++----------------------
src/components/SEOMeta.astro | 12 +++----
src/configs/site.ts | 7 ++++
src/layouts/AppLayout.astro | 28 +++++++++++++++
src/layouts/Layout.astro | 40 ---------------------
src/pages/index.astro | 66 ++++++-----------------------------
8 files changed, 53 insertions(+), 159 deletions(-)
create mode 100644 public/favicon.ico
delete mode 100644 public/favicon.svg
create mode 100644 src/configs/site.ts
create mode 100644 src/layouts/AppLayout.astro
delete mode 100644 src/layouts/Layout.astro
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..f9e7a94cb19947c0d09883f353d603799cec5cd1
GIT binary patch
literal 1150
zcmd5+O-oc^6n;ywg?&uxYdkOD+NpK2BL(V|b=b~OtQa?)}7MzZ7!)VVGQ;Mj^Xd@Q(PoLBY
zNQd+O0pm91W@ilHb=;|zFCIfla$QzdD#u!`UL&H1bI*oxl1e^#ZM=p
zU*3DHneiJ7&=)<>g)!*Ta|m-vJ@J)U==>n0j`z+o$h}fX6ZNqM#=M1Gci3&9-`YIn
zQ5)p-0QAFSh}CC|F27>V5eRF9u?e2pM(DSXz^_f{yK%@+1+eoK`gxJPE<=B;K**Oq
zZ3nj5|6ITC$7-jJLwYYm7qh_6b?8Vnq`v|>MLwP+yiB&R7H2YA3!RRW*Nfycm)}k-
zT?o0&9=e%pf}FHaPco-*8jr+g7I5yZ)<3y0{tYwkYzHhyigU90X3qPWW=g34CAJd*
zYmz7Fz3S%~Vz&R5gS%kt=Dj`E#Cot|H=0If8em^
E9+2yvh5!Hn
literal 0
HcmV?d00001
diff --git a/public/favicon.svg b/public/favicon.svg
deleted file mode 100644
index 0f390629..00000000
--- a/public/favicon.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/components/Card.astro b/src/components/Card.astro
index e36b8f09..859412c8 100644
--- a/src/components/Card.astro
+++ b/src/components/Card.astro
@@ -8,9 +8,9 @@ export interface Props {
const { href, title, body } = Astro.props
---
-
+
-
+
{title}
→
@@ -19,45 +19,3 @@ const { href, title, body } = Astro.props
-
diff --git a/src/components/SEOMeta.astro b/src/components/SEOMeta.astro
index 5a7e882c..3fd181b2 100644
--- a/src/components/SEOMeta.astro
+++ b/src/components/SEOMeta.astro
@@ -1,12 +1,12 @@
---
interface Props {
title: string
- description: string | undefined
- favicon: string | undefined
- faviconMimeType: string | undefined
- keywords: string | undefined
- author: string | undefined
- robots: string | undefined
+ description?: string
+ favicon?: string
+ faviconMimeType?: string
+ keywords?: string
+ author?: string
+ robots?: string
}
const {
diff --git a/src/configs/site.ts b/src/configs/site.ts
new file mode 100644
index 00000000..81f02f80
--- /dev/null
+++ b/src/configs/site.ts
@@ -0,0 +1,7 @@
+export default {
+ title: 'LeetCode Blog',
+ description: 'Solutions for LeetCode problems - Written by ansidev',
+ author: 'ansidev',
+ favicon: '/favicon.ico',
+ faviconMimeType: 'image/ico',
+}
diff --git a/src/layouts/AppLayout.astro b/src/layouts/AppLayout.astro
new file mode 100644
index 00000000..32ee3a28
--- /dev/null
+++ b/src/layouts/AppLayout.astro
@@ -0,0 +1,28 @@
+---
+import SEOMeta from '@/components/SEOMeta.astro'
+import siteConfig from '@/configs/site'
+
+export interface Props {
+ title: string
+ description: string
+ author: string
+}
+
+const { title, author } = Astro.props
+const { favicon, faviconMimeType } = siteConfig
+---
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro
deleted file mode 100644
index 575e9caa..00000000
--- a/src/layouts/Layout.astro
+++ /dev/null
@@ -1,40 +0,0 @@
----
-export interface Props {
- title: string
-}
-
-const { title } = Astro.props
----
-
-
-
-
-
-
-
-
- {title}
-
-
-
-
-
-
diff --git a/src/pages/index.astro b/src/pages/index.astro
index c66ff95b..b1fc4987 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -1,17 +1,16 @@
---
import Card from '@/components/Card.astro'
-import Layout from '@/layouts/Layout.astro'
+import siteConfig from '@/configs/site'
+import AppLayout from '@/layouts/AppLayout.astro'
+
+const { title, description, author } = siteConfig
---
-
-
- Welcome to Astro
-
- To get started, open the directory src/pages
in your project.
-
- Code Challenge: Tweak the "Welcome to Astro" message above.
-
-
+
+
+ {title}
+ {description}
+
-
-
-
+
From 6a0ff7bdcad652ea6621a0d3ae54bb7b586153be Mon Sep 17 00:00:00 2001
From: Le Minh Tri
Date: Fri, 24 Feb 2023 11:36:57 +0700
Subject: [PATCH 05/75] fix: favicon mime type
---
src/configs/site.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/configs/site.ts b/src/configs/site.ts
index 81f02f80..0e9697ef 100644
--- a/src/configs/site.ts
+++ b/src/configs/site.ts
@@ -3,5 +3,5 @@ export default {
description: 'Solutions for LeetCode problems - Written by ansidev',
author: 'ansidev',
favicon: '/favicon.ico',
- faviconMimeType: 'image/ico',
+ faviconMimeType: 'image/x-icon',
}
From 5b93e23cfb98ea1ce297363cb2317f3bf1652f77 Mon Sep 17 00:00:00 2001
From: Le Minh Tri
Date: Fri, 24 Feb 2023 13:30:27 +0700
Subject: [PATCH 06/75] feat(content): add LeetCode solutions
---
...-substring-without-repeating-characters.md | 121 ++++++++++++
.../0008-string-to-integer-atoi.md | 180 ++++++++++++++++++
.../0053-maximum-subarray.md | 107 +++++++++++
.../leetcode-solutions/0231-power-of-two.md | 153 +++++++++++++++
.../0628-maximum-product-of-three-numbers.md | 143 ++++++++++++++
...-reach-a-position-after-exactly-k-steps.md | 120 ++++++++++++
6 files changed, 824 insertions(+)
create mode 100644 src/content/leetcode-solutions/0003-longest-substring-without-repeating-characters.md
create mode 100644 src/content/leetcode-solutions/0008-string-to-integer-atoi.md
create mode 100644 src/content/leetcode-solutions/0053-maximum-subarray.md
create mode 100644 src/content/leetcode-solutions/0231-power-of-two.md
create mode 100644 src/content/leetcode-solutions/0628-maximum-product-of-three-numbers.md
create mode 100644 src/content/leetcode-solutions/2400-number-of-ways-to-reach-a-position-after-exactly-k-steps.md
diff --git a/src/content/leetcode-solutions/0003-longest-substring-without-repeating-characters.md b/src/content/leetcode-solutions/0003-longest-substring-without-repeating-characters.md
new file mode 100644
index 00000000..c802328a
--- /dev/null
+++ b/src/content/leetcode-solutions/0003-longest-substring-without-repeating-characters.md
@@ -0,0 +1,121 @@
+---
+layout: "../layouts/Post.astro"
+title: "3. Longest Substring Without Repeating Characters"
+slug: "0003-longest-substring-without-repeating-characters"
+keywords:
+- "longest"
+- "substring"
+- "without"
+- "repeating"
+- "characters"
+author: "ansidev"
+pubDate: "2022-10-31T19:46:49+07:00"
+difficulty: "Medium"
+tags:
+- "Hash Table"
+- "String"
+- "Sliding Window"
+---
+## Problem
+
+Given a string `s`, find the length of the **longest substring** without repeating characters.
+
+**Example 1:**
+
+```
+Input: s = "abcabcbb"
+Output: 3
+Explanation: The answer is "abc", with the length of 3.
+```
+
+**Example 2:**
+
+```
+Input: s = "bbbbb"
+Output: 1
+Explanation: The answer is "b", with the length of 1.
+```
+
+**Example 3:**
+
+```
+Input: s = "pwwkew"
+Output: 3
+Explanation: The answer is "wke", with the length of 3.
+Notice that the answer must be a substring, "pwke" is a subsequence and not a substring.
+```
+
+**Constraints:**
+
+- `0 <= s.length <= 5 * 104`
+- `s` consists of English letters, digits, symbols, and spaces.
+
+## Analysis
+
+| Abbreviation | Stands for |
+| ------------ | ------------------------------------------------ |
+| `CSWRC` | `current substring without repeating characters` |
+| `LSWRC` | `longest substring without repeating characters` |
+
+- If `s` is an empty string, the LSWRC is `0`.
+- If the length of string `s` is 1, the LSWRC is `1`.
+
+## Approaches
+
+### Approach 1
+
+#### Approach
+
+- If the length of string `s` is greater than 1, because we need to determine the LSWRC, while iterating over the string, we have to check whether the character at a specific index is repeating or not. We can consider using a hashmap.
+
+ - Assume the `LSWRC` is `s[0]`.
+
+ | Initial value | Note |
+ | --------------------- | ---------------------------------------------------------------------- |
+ | `left = 0` | Left index of the LSWRC |
+ | `result = 1` | Length of the LSWRC |
+ | `lastIndex = { a=0 }` | This hashmap saves the last index of a specific character of the array |
+
+ - Start traversing the array from index `1`. For each step:
+ - Check whether the current character is repeating: `lastIndex` has the key `s[right]`.
+ - If yes, update `left = lastIndex[s[right]] + 1` if `left < lastIndex[s[right]] + 1`.
+ - Update the last index of `s[right]` to the current index.
+ - Calculate the new length of the `CSWRC`. (`right - left + 1`).
+ - Update `result` if it is less than the new length of the `CSWRC`.
+ - Finally, return `result`. It is the `LSWRC`.
+
+#### Solutions
+
+```go
+func lengthOfLongestSubstring(s string) int {
+ l := len(s)
+ if l == 0 || l == 1 {
+ return l
+ }
+
+ result, left := 1, 0
+ lastIndex := map[byte]int{}
+ lastIndex[s[0]] = 0
+ for right := 1; right < l; right++ {
+ if v, ok := lastIndex[s[right]]; ok {
+ if left < v+1 {
+ left = v + 1
+ }
+ }
+ lastIndex[s[right]] = right
+ if result < right-left+1 {
+ result = right - left + 1
+ }
+ }
+
+ return result
+}
+```
+
+#### Complexity
+
+- Time complexity: `O(n)` because we just traverse the string once.
+- Space complexity:
+ - We use four extra variables `l`, `result`, `left`, `right`, no matter what value will, they will take fixed bytes. So the space complexity is `O(1)`.
+ - The space complexity of the map `lastIndex` is `O(n)`.
+ - So the final space complexity is `O(n)`.
diff --git a/src/content/leetcode-solutions/0008-string-to-integer-atoi.md b/src/content/leetcode-solutions/0008-string-to-integer-atoi.md
new file mode 100644
index 00000000..e85c389d
--- /dev/null
+++ b/src/content/leetcode-solutions/0008-string-to-integer-atoi.md
@@ -0,0 +1,180 @@
+---
+layout: "../layouts/Post.astro"
+title: "8. String to Integer (atoi)"
+slug: "0008-string-to-integer-atoi"
+keywords:
+- "string"
+- "to"
+- "integer"
+- "atoi"
+author: "ansidev"
+pubDate: "2022-10-26T13:11:00+07:00"
+difficulty: "Medium"
+tags:
+- "String"
+---
+## Problem
+
+Implement the `myAtoi(string s)` function, which converts a string to a 32-bit signed integer (similar to C/C++'s `atoi` function).
+
+The algorithm for `myAtoi(string s)` is as follows:
+
+1. Read in and ignore any leading whitespace.
+2. Check if the next character (if not already at the end of the string) is `'-'` or `'+'`. Read this character in if it is either. This determines if the final result is negative or positive respectively. Assume the result is positive if neither is present.
+3. Read in next the characters until the next non-digit character or the end of the input is reached. The rest of the string is ignored.
+4. Convert these digits into an integer (i.e. `"123" -> 123`, `"0032" -> 32`). If no digits were read, then the integer is 0. Change the sign as necessary (from step 2).
+5. If the integer is out of the 32-bit signed integer range [-231 , 231 - 1]
, then clamp the integer so that it remains in the range. Specifically, integers less than -231
should be clamped to -231
, and integers greater than 231 -1
should be clamped to 231 -1
.
+Return the integer as the final result.
+
+**Note:**
+
+- Only the space character `' '` is considered a whitespace character.
+- **Do not ignore** any characters other than the leading whitespace or the rest of the string after the digits.
+
+**Example 1:**
+
+```
+Input: s = "42"
+Output: 42
+Explanation: The underlined characters are what is read in, the caret is the current reader position.
+Step 1: "42" (no characters read because there is no leading whitespace)
+ ^
+Step 2: "42" (no characters read because there is neither a `'-'` nor `'+'`)
+ ^
+Step 3: "42" ("42" is read in)
+ ^
+The parsed integer is 42.
+Since 42 is in the range [-2^31, 2^31 - 1], the final result is 42.
+```
+
+**Example 2:**
+
+```
+Input: s = " -42"
+Output: -42
+Explanation:
+Step 1: " -42" (leading whitespace is read and ignored)
+ ^
+Step 2: " -42" (`'-'` is read, so the result should be negative)
+ ^
+Step 3: " -42" ("42" is read in)
+ ^
+The parsed integer is -42.
+Since -42 is in the range [-2^31, 2^31 - 1], the final result is -42.
+```
+
+**Example 3:**
+
+```
+Input: s = "4193 with words"
+Output: 4193
+Explanation:
+Step 1: "4193 with words" (no characters read because there is no leading whitespace)
+ ^
+Step 2: "4193 with words" (no characters read because there is neither a `'-'` nor `'+'`)
+ ^
+Step 3: "4193 with words" ("4193" is read in; reading stops because the next character is a non-digit)
+ ^
+The parsed integer is 4193.
+Since 4193 is in the range [-2^31, 2^31 - 1], the final result is 4193.
+```
+
+**Constraints:**
+
+- `0 <= s.length <= 200`.
+- `s` consists of English letters (lower-case and upper-case), digits (`0-9`), `' '`, `'+'`, `'-'`, and `'.'`.
+
+## Analysis
+
+I don't have any special analysis since the problem is so clearly.
+
+## Approaches
+
+### Approach 1
+
+#### Approach
+
+1. Check whether the input is null (depends on programming language) or empty. If it is, return `0`.
+2. Use a pointer `i` to traverse the input string, always remember checking whether i less than length of `s`.
+ - While `s[i]` is a whitespace, keep increasing i by 1.
+ - Check whether the next character (`s[i]`) is one of `-`, `+`, or digit (`0-9`):
+ - If not, return `0`.
+ - Otherwise, check whether `s[i]` is one of `-` or `+`, save the result to a boolean variable and increase i by 1.
+ - Note that if `s[i]` is not one of `-` or `+`, this means that it is a digit, and `i` will not be increased.
+ - Check whether the current character is a sign, if it is, return `0` because it is an invalid input.
+ - Create new 64 bit float number `n` to save the result.
+ - While `s[i]` is a digit, `n = n x 10 + integer value of s[i]`, then increasing `i` by `1`.
+ - If the sign is `-`, `n = -n`.
+ - Check the range of `n`:
+ - If n < -231
, return -231
.
+ - If n > 231 -1
, return 231 -1
.
+ - Otherwise, convert n to integer and return.
+
+- Notes: `MinInt32 = -1 << 31` (-231
) and `MaxInt32 = 1<<31 - 1` (231 -1
).
+
+#### Solutions
+
+```go
+func myAtoi(s string) int {
+ l := len(s)
+ if l == 0 {
+ return 0
+ }
+
+ i := 0
+ for i < l && s[i] == ' ' {
+ i++
+ }
+
+ if i < l && s[i] != '+' &&
+ s[i] != '-' &&
+ s[i] != '0' &&
+ s[i] != '1' &&
+ s[i] != '2' &&
+ s[i] != '3' &&
+ s[i] != '4' &&
+ s[i] != '5' &&
+ s[i] != '6' &&
+ s[i] != '7' &&
+ s[i] != '8' &&
+ s[i] != '9' {
+ return 0
+ }
+
+ isNegative := false
+ if i < l && s[i] == '-' {
+ isNegative = true
+ i++
+ } else if i < l && s[i] == '+' {
+ i++
+ }
+
+ if i < l && (s[i] == '+' || s[i] == '-') {
+ return 0
+ }
+
+ var n float64 = 0
+ for i < l && s[i] >= '0' && s[i] <= '9' {
+ n = n*10 + float64(s[i]-'0')
+ i++
+ }
+
+ if isNegative {
+ n = -n
+ }
+
+ if n < math.MinInt32 {
+ return math.MinInt32
+ }
+ if n > math.MaxInt32 {
+ return math.MaxInt32
+ }
+
+ return int(n)
+}
+```
+
+#### Complexity
+
+- Time complexity: `O(n)` because we just traverse the string once.
+- Space complexity: We use three extra variable `l`, `isNegative`, `n`, no matter what value will, they will take a fixed bytes. So the space complexity is `O(1)`.
diff --git a/src/content/leetcode-solutions/0053-maximum-subarray.md b/src/content/leetcode-solutions/0053-maximum-subarray.md
new file mode 100644
index 00000000..947cd7fc
--- /dev/null
+++ b/src/content/leetcode-solutions/0053-maximum-subarray.md
@@ -0,0 +1,107 @@
+---
+layout: "../layouts/Post.astro"
+title: "53. Maximum Subarray"
+slug: "0053-maximum-subarray"
+keywords:
+- "maximum"
+- "subarray"
+- "kadane"
+author: "ansidev"
+pubDate: "2022-10-26T13:11:00+07:00"
+difficulty: "Medium"
+tags:
+- "Array"
+- "Divide and Conquer"
+- "Dynamic Programming"
+---
+## Problem
+
+Given an integer array `nums`, find the contiguous subarray (containing at least one number) which has the largest sum and return `its sum`.
+
+A `subarray` is a `contiguous` part of an array.
+
+**Example 1:**
+
+```
+Input: nums = [-2,1,-3,4,-1,2,1,-5,4]
+Output: 6
+Explanation: [4,-1,2,1] has the largest sum = 6.
+```
+
+**Example 2:**
+
+```
+Input: nums = [1]
+Output: 1
+```
+
+**Example 3:**
+
+```
+Input: nums = [5,4,-1,7,8]
+Output: 23
+```
+
+**Constraints:**
+
+- 1 <= nums.length <= 105
+- -104 <= nums[i] <= 104
+
+**Follow up:** If you have figured out the `O(n)` solution, try coding another solution using the **divide and conquer** approach, which is more subtle.
+
+## Analysis
+
+## Approaches
+
+### Approach 1
+
+#### Approach
+
+Technique: Dynamic Programming
+
+Original author: [Kadane](https://www.cmu.edu/dietrich/statistics-datascience/people/faculty/joseph-kadane.html).
+
+Assume we have `dp[i]`: maximum sum of subarray that ends at index `i`.
+
+`dp[i] = max(dp[i - 1] + nums[i], nums[i])`
+
+Initial state `dp[0] = nums[0]`.
+
+From the above formula, we just need to access its previous element at each step, so we can use 2 variables:
+
+- `currentMaxSum`: maximum sum of subarray that ends at the current index `i`.
+ - `currentMaxSum = max(currentMaxSum + nums[i], nums[i]`.
+- `globalSum`: global maximum subarray sum
+ - `globalSum = max(currentMaxSum, globalSum)`.
+
+#### Solutions
+
+```go
+func maxSubArray(nums []int) int {
+ currentMaxSum := nums[0]
+ globalSum := nums[0]
+
+ for _, x := range nums[1:] {
+ if currentMaxSum+x > x {
+ currentMaxSum += x
+ } else {
+ currentMaxSum = x
+ }
+
+ if globalSum < currentMaxSum {
+ globalSum = currentMaxSum
+ }
+ }
+
+ return globalSum
+}
+```
+
+#### Complexity
+
+- **Time Complexity**: `O(n)` because we just iterate over the array once.
+- **Space Complexity**: `O(1)`. We just use 2 integer variables for extra spaces.
+
+## References
+
+- https://en.wikipedia.org/wiki/Maximum_subarray_problem
diff --git a/src/content/leetcode-solutions/0231-power-of-two.md b/src/content/leetcode-solutions/0231-power-of-two.md
new file mode 100644
index 00000000..789584a3
--- /dev/null
+++ b/src/content/leetcode-solutions/0231-power-of-two.md
@@ -0,0 +1,153 @@
+---
+layout: "../layouts/Post.astro"
+title: "231. Power of Two"
+slug: "0231-power-of-two"
+keywords:
+- "power of two"
+author: "ansidev"
+pubDate: "2022-10-27T15:23:12+07:00"
+difficulty: "Easy"
+tags:
+- "Math"
+- "Bit Manipulation"
+- "Recursion"
+---
+## Problem
+
+Given an integer `n`, return `true` *if it is a power of two. Otherwise, return* `false`.
+
+An integer `n` is a power of two, if there exists an integer `x` such that n == 2x
.
+
+**Example 1:**
+
+```
+Input: n = 1
+Output: true
+Explanation: 20 = 1
+```
+**Example 2:**
+
+```
+Input: n = 16
+Output: true
+Explanation: 24 = 16
+```
+**Example 3:**
+
+```
+Input: n = 3
+Output: false
+```
+
+**Constraints:**
+
+- -231 <= n <= 231 - 1
.
+
+**Follow up:** Could you solve it without loops/recursion?
+
+## Analysis
+
+1. If `n` is a power of two:
+
+
+n = 2i
(`i ≥ 0`)
+ ≥ 20 = 1
+
+
+`=>` **If `n < 0`, `n` is not a power of two**.
+
+2. If `n` is a power of two:
+
+The binary form of every 2i
(`i` is a non-negative number):
+
+
+20 10
= 110
= 12
+
+21 10
= 210
= 102
+
+22 10
= 410
= 1002
+
+23 10
= 810
= 10002
+
+...
+
+2i 10
= 100...002
(only one 1-digit at the first position and followed by total `i` 0-digit numbers)
+ |__i__|
+
+
+2.1. If `i = 0`:
+
+n = 20 = 1 > 0
+n & (n-1) = 1 & 0 = 0
+
+
+
+2.2. If `i > 0`:
+
+The binary form of every 2i - 1
:
+
+
+21 10 - 1
= 110
= 012
+
+22 10 - 1
= 310
= 0112
+
+23 10 - 1
= 710
= 01112
+
+...
+
+2i 10 - 1
= 011...112
(total `i` 1-digit numbers)
+ |__i__|
+
+
+For `i > 0`, we have:
+
+
+n - 1 = 2i 10 - 1
≥ 0
+n & (n-1) = 2i 10
& 2i 10 - 1
= 100...002
& 011...112
= 0
+ |__i__| |__i__|
+
+
+```
+If n is a power of two: n & (n-1) = 0.
+```
+
+3. If `n` is not an power of two, we have:
+
+ n10
= [0....0][1....1][0....0]2
(i ≥ 0, j ≥ 2, k ≥ 1)
+ |__i__| |__j__| |__k__|
+
+ (n-1)10
= [0....0][1....1]0[1....1]2
+ |__i__| |_j-1_| |__k__|
+
+x = n10 & (n-1)10
= [0....0][1.....][0....0]2
+ |__i__| |_j-1_| |_k+1_|
+
+
+- `j ≥ 2` => `j-1 ≥ 1`. So `x` has at least one 1-digit number => `x > 0`.
+
+```
+If n is not a power of two: n & (n-1) > 0.
+```
+
+```
+As result, n is a power of two if and only if n > 0 and n & (n-1) = 0.
+```
+## Approaches
+
+### Approach 1
+
+#### Approach
+
+- `n` is a power of two if and only if `n > 0` and `n & (n-1) = 0`.
+
+#### Solutions
+
+```go
+func isPowerOfTwo(n int) bool {
+ return n > 0 && n&(n-1) == 0
+}
+```
+
+#### Complexity
+
+- **Time Complexity**: `O(1)`.
diff --git a/src/content/leetcode-solutions/0628-maximum-product-of-three-numbers.md b/src/content/leetcode-solutions/0628-maximum-product-of-three-numbers.md
new file mode 100644
index 00000000..79cd737f
--- /dev/null
+++ b/src/content/leetcode-solutions/0628-maximum-product-of-three-numbers.md
@@ -0,0 +1,143 @@
+---
+layout: "../layouts/Post.astro"
+title: "628. Maximum Product of Three Numbers"
+slug: "0628-maximum-product-of-three-numbers"
+keywords:
+- "maximum"
+- "product"
+- "of"
+- "three"
+- "numbers"
+author: "ansidev"
+pubDate: "2022-11-18T08:58:46+07:00"
+difficulty: "Easy"
+tags:
+- "Array"
+- "Math"
+- "Sorting"
+---
+## Problem
+
+Given an integer array `nums`, *find three numbers whose product is maximum and return the maximum product*.
+
+**Example 1:**
+
+```
+Input: nums = [1,2,3]
+Output: 6
+```
+
+**Example 2:**
+
+```
+Input: nums = [1,2,3,4]
+Output: 24
+```
+
+**Example 3:**
+
+```
+Input: nums = [-1,-2,-3]
+Output: -6
+ ```
+
+**Constraints:**
+
+- `3 <= nums.length <= 104`.
+- `-1000 <= nums[i] <= 1000`.
+
+## Analysis
+
+If length of `nums` is 3, maximum product is `nums[0] x nums[1] x nums[2]`.
+
+## Approaches
+
+### Approach 1
+
+```
+Notes:
+- l: length of nums.
+- nums[i:j]: sub array of nums from index i to j (includes nums[i], nums[j]).
+```
+#### Approach
+
+- If length of `nums` is 3, maximum product is `nums[0] x nums[1] x nums[2]`.
+- If length of `nums` is greater than 3:
+ - Step 1: Sort the input array (ascending).
+ - For the sorted array, there are following possible cases:
+ - Case 1: All element are positive numbers.
+ - `maxProduct = nums[l-3] x nums[l-2] x nums[l-1]`.
+ - Case 2: All element are negative numbers.
+ - Product of two random elements will be a positive number.
+ - Product of three random elements will be a negative number.
+ - If `n1 > 0`, `n2 < n3 < 0`: `n1 x n2 < n1 x n3 < 0`.
+ - If `m1 < 0`, `0 < m2 < n3`: `m1 x m3 < m1 x m2 < 0`.
+ - So to find the maximum product of three numbers in this case, we need to find two negative numbers `a`, `b` that `a x b` has max value (note that `a x b > 0`), then find the third number which is the maximum value of remaining ones.
+ - `nums[0]` & `nums[1]` are two smallest negative numbers. So their product will be the maximum product of two numbers. `nums[l-1]` is the maximum one of [`nums[2]`, `nums[3]`,..., `nums[l-1]`].
+ - Finally, the maximum product of three numbers in this case is 👉 `nums[0] x nums[1] x nums[l-1]`.
+ - Other cases.
+ - `nums` has at least 4 elements.
+ - If `nums` contains zero:
+ - If `nums[0] = 0`, all remaining elements are positive numbers (similar to case 1)
+ - 👉 `maxProduct = nums[l-3] x nums[l-2] x nums[l-1]`.
+ - If `nums[l-1] = 0`, all remaining elements are negative numbers (similar to case 2)
+ - `maxProduct` of three numbers of sub array `nums[0:l-2]` is a negative number, it less than product of `nums[l-1]` (`= 0`) and two random numbers of sub array `nums[0:l-2]`. So in this case, we can pick three numbers `nums[l-3]`, `nums[l-2]`, `nums[l-1]`.
+ - 👉 `maxProduct = nums[l-3] x nums[l-2] x nums[l-1] = 0`.
+ - If `nums[i] = 0` (`0 < i < l-1`), because `nums` has at least 4 elements, so there are possible cases:
+ - `nums` has at least there positive numbers, similar to case 1.
+ - `nums` has two positive numbers:
+ - If `l = 4`:
+ - `nums` = [`nums[0]`, `0`, `num[2]`, `nums[3]`].
+ - `nums[0] x nums[2] x nums[3] < 0 x num[2] x nums[3] = 0`.
+ - 👉 `maxProduct` must contains zero so `maxProduct = 0 = nums[l-3] x nums[l-2] x nums[l-1]`
+ - If `l > 4`:
+ - `nums` = [`nums[0]`, `nums[1]`, ..., `nums[l-4]` ,`0`, `num[l-2]`, `nums[l-1]`].
+ - If one of three numbers of `maxProduct` is zero, `maxProduct = 0`.
+ - Otherwise, if two of three numbers of `maxProduct` is `num[l-2]`, `nums[l-1]`, `maxProduct < 0`.
+ - Otherwise, two of three numbers of `maxProduct` is negative numbers, max product of two negative numbers of sub array `nums[0:l-4]` is `nums[0] x nums[1] > 0`.
+ - `maxProduct = nums[0] x nums[1] x nums[l-1] > 0`
+ - 👉 `maxProduct = nums[0] x nums[1] x nums[l-1] > 0`
+ - 👉 `maxProduct = nums[0] x nums[1] x nums[l-1]`
+ - `nums` has one positive numbers:
+ - `nums` = [`nums[0]`, `nums[1]`, ..., `nums[l-3]` ,`0`, `nums[l-1]`].
+ - We have cases:
+ - `maxProduct` contains zero: `0 x nums[i] x nums[j] = 0`
+ - `maxProduct` does not contain zero:
+ - `nums[i] x nums[j] x nums[k] < 0` (`i < j < k < 0`)
+ - `nums[i] x nums[j] x nums[l-1] > 0` (`i < j < 0`)
+ - So `maxProduct` is product of two negative numbers and one positive number (`nums[l-1]`)
+ - 👉 `maxProduct = max(nums[j] x num[j]) x nums[l-1] = nums[0] x nums[1] x nums[l-1]`.
+ - The maximum product of three numbers in every cases (`l > 3`) is one of two:
+ - `nums[0] x nums[1] x nums[l-1]`
+ - `nums[l-3] x nums[l-2] x nums[l-1]`
+ - Conclusion, 👉 `maxProduct = max(nums[0] x nums[1] x nums[l-1], nums[l-3] x nums[l-2] x nums[l-1])`.
+
+#### Solutions
+
+```go
+import "sort"
+
+func maximumProduct(nums []int) int {
+ l := len(nums)
+
+ if l == 3 {
+ return nums[0] * nums[1] * nums[2]
+ }
+
+ sort.Ints(nums)
+
+ return max(nums[0]*nums[1]*nums[l-1], nums[l-3]*nums[l-2]*nums[l-1])
+}
+
+func max(x int, y int) int {
+ if x > y {
+ return x
+ }
+
+ return y
+}
+```
+
+#### Complexity
+
+- **Time Complexity**: Time complexity of the sort algorithm.
diff --git a/src/content/leetcode-solutions/2400-number-of-ways-to-reach-a-position-after-exactly-k-steps.md b/src/content/leetcode-solutions/2400-number-of-ways-to-reach-a-position-after-exactly-k-steps.md
new file mode 100644
index 00000000..f57b4743
--- /dev/null
+++ b/src/content/leetcode-solutions/2400-number-of-ways-to-reach-a-position-after-exactly-k-steps.md
@@ -0,0 +1,120 @@
+---
+layout: "../layouts/Post.astro"
+title: "2400. Number of Ways to Reach a Position After Exactly k Steps"
+slug: "2400-number-of-ways-to-reach-a-position-after-exactly-k-steps"
+keywords:
+- "number"
+- "of"
+- "ways"
+- "to"
+- "reach"
+- "a"
+- "position"
+- "after"
+- "exactly"
+- "k"
+- "steps"
+author: "ansidev"
+pubDate: "2022-10-24T23:49:00+07:00"
+difficulty: "Medium"
+tags:
+- "Math"
+- "Dynamic Programming"
+- "Combinatorics"
+---
+## Problem
+
+You are given two **positive** integers `startPos` and `endPos`. Initially, you are standing at position startPos on an **infinite** number line. With one step, you can move either one position to the left, or one position to the right.
+
+Given a positive integer `k`, return the number of **different** ways to reach the position `endPos` starting from `startPos`, such that you perform **exactly** `k` steps. Since the answer may be very large, return it **modulo** 109 + 7
.
+
+Two ways are considered different if the order of the steps made is not exactly the same.
+
+**Note** that the number line includes negative integers.
+
+**Example 1:**
+
+```
+Input: startPos = 1, endPos = 2, k = 3
+Output: 3
+Explanation: We can reach position 2 from 1 in exactly 3 steps in three ways:
+- 1 -> 2 -> 3 -> 2.
+- 1 -> 2 -> 1 -> 2.
+- 1 -> 0 -> 1 -> 2.
+It can be proven that no other way is possible, so we return 3.
+```
+**Example 2:**
+
+```
+Input: startPos = 2, endPos = 5, k = 10
+Output: 0
+Explanation: It is impossible to reach position 5 from position 2 in exactly 10 steps.
+```
+
+**Constraints:**
+
+- `1 <= startPos, endPos, k <= 1000`
+
+## Analysis
+
+Assuming `d` is the **distance** between `startPos` and `endPos` => `d = abs(startPos - endPos)`.
+
+- `1 <= startPos <= 1000`
+- `-1000 <= -endPos <= -1`
+
+=> `-999 <= startPos - endPos <= 999`
+
+=> `0 <= d = abs(startPos - endPos) <= 999`
+
+For `k` is the **numbers of steps** and `d` is the **distance** between `startPos` and `endPos`, the number of ways is:
+- `dfs(k, d) = dfs(k-1, abs(d-1)) + dfs(k-1, d+1)`.
+
+For k steps, the maximum distance is k.
+- **d > k**: `dfs(k, d) = 0`.
+- **d = k**: `dfs(k, d) = dfs(k, k) = 1`.
+- **d = 0**: `dfs(k, 0) = dfs(k-1, 1) + dfs(k-1, 1) = 2 x dfs(k-1, 1)`.
+
+
+Example values:
+- `dfs(0,0) = 1`.
+- `dfs(1, 0) = 2 x dfs(0, 1) = 0`.
+- `dfs(1, 1) = 1`.
+- `dfs(2, 0) = 2 x dfs(1, 1) = 2 x 1 = 2`.
+- `dfs(2, 1) = dfs(1, 0) + dfs(1, 2) = 0 + 0 = 0`.
+- `dfs(2, 2) = 1`.
+
+## Approaches
+
+### Approach 1
+
+#### Approach
+
+- From the above analysis, we can use the bottom-up approach to calculate the next values of the `dfs` function from each prior values. Then, we can get the number of ways.
+
+#### Solutions
+
+```go
+func numberOfWays(startPos int, endPos int, k int) int {
+ const mod = 1e9 + 7
+ dp := [1001][1001]int{}
+ for i := 1; i <= 1000; i++ {
+ dp[i][i] = 1
+ for j := 0; j < i; j++ {
+ dp[i][j] = (dp[i-1][abs(j-1)] + dp[i-1][j+1]) % mod
+ }
+ }
+
+ return dp[k][abs(startPos-endPos)]
+}
+
+func abs(x int) int {
+ if x >= 0 {
+ return x
+ }
+
+ return -x
+}
+```
+
+## References
+- dfs: [[deep-first-search|Deep First Search]]
From 39ec3736614459cbb2c9dbcfdeb4773a08a3a9fa Mon Sep 17 00:00:00 2001
From: Le Minh Tri
Date: Fri, 24 Feb 2023 13:27:33 +0700
Subject: [PATCH 07/75] feat(content): add content config
---
.gitignore | 3 +++
src/content/config.ts | 16 ++++++++++++++++
src/env.d.ts | 2 ++
3 files changed, 21 insertions(+)
create mode 100644 src/content/config.ts
diff --git a/.gitignore b/.gitignore
index 08879b96..2eac41de 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,6 @@ pnpm-debug.log*
# VSCode Workspace
astro-basic-template.code-workspace
+
+# Astro directories
+.astro
diff --git a/src/content/config.ts b/src/content/config.ts
new file mode 100644
index 00000000..71663c22
--- /dev/null
+++ b/src/content/config.ts
@@ -0,0 +1,16 @@
+import { defineCollection, z } from 'astro:content'
+
+const leetcodeSolutionCollection = defineCollection({
+ schema: z.object({
+ title: z.string(),
+ keywords: z.array(z.string()),
+ author: z.string(),
+ pubDate: z.string(),
+ difficulty: z.string(),
+ tags: z.array(z.string()),
+ }),
+})
+
+export const collections = {
+ 'leetcode-solutions': leetcodeSolutionCollection,
+}
diff --git a/src/env.d.ts b/src/env.d.ts
index f964fe0c..6811d7c2 100644
--- a/src/env.d.ts
+++ b/src/env.d.ts
@@ -1 +1,3 @@
+// eslint-disable-next-line @typescript-eslint/triple-slash-reference
+///
///
From 3f81bcec054c6d04031951c10f3e303ad175a4f2 Mon Sep 17 00:00:00 2001
From: Le Minh Tri
Date: Fri, 24 Feb 2023 15:18:57 +0700
Subject: [PATCH 08/75] feat(component): add component Icon
---
src/components/Icon.astro | 45 +++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
create mode 100644 src/components/Icon.astro
diff --git a/src/components/Icon.astro b/src/components/Icon.astro
new file mode 100644
index 00000000..7eb44d7f
--- /dev/null
+++ b/src/components/Icon.astro
@@ -0,0 +1,45 @@
+---
+import bi from '@iconify-json/bi/icons.json'
+import type { HTMLAttributes } from 'astro/types'
+import _get from 'lodash.get'
+
+export interface Props extends HTMLAttributes<'svg'> {
+ size?: number
+}
+
+const { size = 16, ...props } = Astro.props
+
+const getIcon = (icon: string) => {
+ if (typeof icon !== 'string' || icon.length === 0) {
+ return ''
+ }
+
+ const s = icon.split(':')
+
+ if (s.length < 2) {
+ return ''
+ }
+
+ const preset = s[0]
+ const iconName = s[1]
+
+ if (preset !== 'bi') {
+ return ''
+ }
+
+ return _get(bi.icons, `${iconName}.body`)
+}
+
+const svg = getIcon(props.name || '')
+---
+
+
From 3ba04a43894a23b75f7cdd300ac55e5cf64738c0 Mon Sep 17 00:00:00 2001
From: Le Minh Tri
Date: Fri, 24 Feb 2023 15:20:49 +0700
Subject: [PATCH 09/75] build(dep): add package lodash.get
---
package.json | 2 ++
pnpm-lock.yaml | 18 ++++++++++++++++++
2 files changed, 20 insertions(+)
diff --git a/package.json b/package.json
index 1e197c4a..0087398c 100644
--- a/package.json
+++ b/package.json
@@ -25,6 +25,7 @@
"@commitlint/cli": "^17.4.4",
"@commitlint/config-conventional": "^17.4.4",
"@tailwindcss/typography": "^0.5.9",
+ "@types/lodash.get": "^4.4.7",
"@types/node": "^18.14.0",
"@typescript-eslint/eslint-plugin": "^5.53.0",
"@typescript-eslint/parser": "^5.53.0",
@@ -34,6 +35,7 @@
"eslint-plugin-astro": "^0.23.0",
"eslint-plugin-simple-import-sort": "^10.0.0",
"husky": "^8.0.3",
+ "lodash.get": "^4.4.2",
"typescript": "^4.9.5"
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 23154a62..dcbb092c 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -5,6 +5,7 @@ specifiers:
'@commitlint/cli': ^17.4.4
'@commitlint/config-conventional': ^17.4.4
'@tailwindcss/typography': ^0.5.9
+ '@types/lodash.get': ^4.4.7
'@types/node': ^18.14.0
'@typescript-eslint/eslint-plugin': ^5.53.0
'@typescript-eslint/parser': ^5.53.0
@@ -17,6 +18,7 @@ specifiers:
eslint-plugin-astro: ^0.23.0
eslint-plugin-simple-import-sort: ^10.0.0
husky: ^8.0.3
+ lodash.get: ^4.4.2
tailwindcss: ^3.0.24
typescript: ^4.9.5
@@ -31,6 +33,7 @@ devDependencies:
'@commitlint/cli': 17.4.4
'@commitlint/config-conventional': 17.4.4
'@tailwindcss/typography': 0.5.9_tailwindcss@3.2.7
+ '@types/lodash.get': 4.4.7
'@types/node': 18.14.0
'@typescript-eslint/eslint-plugin': 5.53.0_ny4s7qc6yg74faf3d6xty2ofzy
'@typescript-eslint/parser': 5.53.0_7kw3g6rralp5ps6mg3uyzz6azm
@@ -40,6 +43,7 @@ devDependencies:
eslint-plugin-astro: 0.23.0_eslint@8.34.0
eslint-plugin-simple-import-sort: 10.0.0_eslint@8.34.0
husky: 8.0.3
+ lodash.get: 4.4.2
typescript: 4.9.5
packages:
@@ -984,6 +988,16 @@ packages:
resolution: {integrity: sha512-sqm9g7mHlPY/43fcSNrCYfOeX9zkTTK+euO5E6+CVijSMm5tTjkVdwdqRkY3ljjIAf8679vps5jKUoJBCLsMDA==}
dev: false
+ /@types/lodash.get/4.4.7:
+ resolution: {integrity: sha512-af34Mj+KdDeuzsJBxc/XeTtOx0SZHZNLd+hdrn+PcKGQs0EG2TJTzQAOTCZTgDJCArahlCzLWSy8c2w59JRz7Q==}
+ dependencies:
+ '@types/lodash': 4.14.191
+ dev: true
+
+ /@types/lodash/4.14.191:
+ resolution: {integrity: sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==}
+ dev: true
+
/@types/mdast/3.0.10:
resolution: {integrity: sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==}
dependencies:
@@ -3261,6 +3275,10 @@ packages:
resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==}
dev: true
+ /lodash.get/4.4.2:
+ resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
+ dev: true
+
/lodash.isfunction/3.0.9:
resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==}
dev: true
From 1576b66bdd28b77a44fc27bf1592ccb4e379db25 Mon Sep 17 00:00:00 2001
From: Le Minh Tri
Date: Fri, 24 Feb 2023 15:23:39 +0700
Subject: [PATCH 10/75] build(dep): add package @iconify-json/bi
---
package.json | 1 +
pnpm-lock.yaml | 12 ++++++++++++
2 files changed, 13 insertions(+)
diff --git a/package.json b/package.json
index 0087398c..be3f420c 100644
--- a/package.json
+++ b/package.json
@@ -24,6 +24,7 @@
"devDependencies": {
"@commitlint/cli": "^17.4.4",
"@commitlint/config-conventional": "^17.4.4",
+ "@iconify-json/bi": "^1.1.15",
"@tailwindcss/typography": "^0.5.9",
"@types/lodash.get": "^4.4.7",
"@types/node": "^18.14.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index dcbb092c..2edb9b2e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -4,6 +4,7 @@ specifiers:
'@astrojs/tailwind': ^3.0.1
'@commitlint/cli': ^17.4.4
'@commitlint/config-conventional': ^17.4.4
+ '@iconify-json/bi': ^1.1.15
'@tailwindcss/typography': ^0.5.9
'@types/lodash.get': ^4.4.7
'@types/node': ^18.14.0
@@ -32,6 +33,7 @@ dependencies:
devDependencies:
'@commitlint/cli': 17.4.4
'@commitlint/config-conventional': 17.4.4
+ '@iconify-json/bi': 1.1.15
'@tailwindcss/typography': 0.5.9_tailwindcss@3.2.7
'@types/lodash.get': 4.4.7
'@types/node': 18.14.0
@@ -802,6 +804,16 @@ packages:
resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
dev: true
+ /@iconify-json/bi/1.1.15:
+ resolution: {integrity: sha512-NsbDeTVIYwgPLyAT0UgzuaCl79V65Z+M319BjbdEwdnbDGuaYgmAMBJUIWrnBEVoEg7rtouAuvaZRb3nIYIRcA==}
+ dependencies:
+ '@iconify/types': 2.0.0
+ dev: true
+
+ /@iconify/types/2.0.0:
+ resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
+ dev: true
+
/@jridgewell/gen-mapping/0.1.1:
resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==}
engines: {node: '>=6.0.0'}
From 9138d224ccdc89c6351de7a712f988045c45c7ed Mon Sep 17 00:00:00 2001
From: Le Minh Tri
Date: Fri, 24 Feb 2023 15:35:13 +0700
Subject: [PATCH 11/75] build(dep): add package tailwindcss-themer
---
package.json | 1 +
pnpm-lock.yaml | 22 ++++++++++++++++++----
2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/package.json b/package.json
index be3f420c..2f953206 100644
--- a/package.json
+++ b/package.json
@@ -37,6 +37,7 @@
"eslint-plugin-simple-import-sort": "^10.0.0",
"husky": "^8.0.3",
"lodash.get": "^4.4.2",
+ "tailwindcss-themer": "^3.0.1",
"typescript": "^4.9.5"
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 2edb9b2e..03dce9e8 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -21,6 +21,7 @@ specifiers:
husky: ^8.0.3
lodash.get: ^4.4.2
tailwindcss: ^3.0.24
+ tailwindcss-themer: ^3.0.1
typescript: ^4.9.5
dependencies:
@@ -46,6 +47,7 @@ devDependencies:
eslint-plugin-simple-import-sort: 10.0.0_eslint@8.34.0
husky: 8.0.3
lodash.get: 4.4.2
+ tailwindcss-themer: 3.0.1_tailwindcss@3.2.7
typescript: 4.9.5
packages:
@@ -1767,7 +1769,6 @@ packages:
dependencies:
color-name: 1.1.4
simple-swizzle: 0.2.2
- dev: false
/color/4.2.3:
resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
@@ -1775,7 +1776,6 @@ packages:
dependencies:
color-convert: 2.0.1
color-string: 1.9.1
- dev: false
/comma-separated-tokens/2.0.3:
resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
@@ -3029,7 +3029,6 @@ packages:
/is-arrayish/0.3.2:
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
- dev: false
/is-binary-path/2.1.0:
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
@@ -3227,6 +3226,10 @@ packages:
engines: {'0': node >= 0.2.0}
dev: true
+ /just-unique/4.2.0:
+ resolution: {integrity: sha512-cxQGGUiit6CGUpuuiezY8N4m1wgF4o7127rXEXDFcxeDUFfdV7gSkwA26Fe2wWBiNQq2SZOgN4gSmMxB/StA8Q==}
+ dev: true
+
/kind-of/6.0.3:
resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
engines: {node: '>=0.10.0'}
@@ -4756,7 +4759,6 @@ packages:
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
dependencies:
is-arrayish: 0.3.2
- dev: false
/sisteransi/1.0.5:
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
@@ -4971,6 +4973,18 @@ packages:
'@pkgr/utils': 2.3.1
tslib: 2.4.1
+ /tailwindcss-themer/3.0.1_tailwindcss@3.2.7:
+ resolution: {integrity: sha512-fYbrcm9/WrLepfFg51PcbfQuEBv0jFeMYlU/emCuvTt6NOvzks9Dlp2Ji+EqM6K7KHA6KpZ2NJWbZLmewpHNwA==}
+ peerDependencies:
+ tailwindcss: ^3.1.0
+ dependencies:
+ color: 4.2.3
+ just-unique: 4.2.0
+ lodash.merge: 4.6.2
+ lodash.mergewith: 4.6.2
+ tailwindcss: 3.2.7
+ dev: true
+
/tailwindcss/3.2.7:
resolution: {integrity: sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ==}
engines: {node: '>=12.13.0'}
From 32641ff0da07bf9aafc599075239eade33cf86ca Mon Sep 17 00:00:00 2001
From: Le Minh Tri
Date: Fri, 24 Feb 2023 11:34:20 +0700
Subject: [PATCH 12/75] feat(theme): add theme config
---
tailwind.config.cjs | 3 +++
theme.config.cjs | 57 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 60 insertions(+)
create mode 100644 theme.config.cjs
diff --git a/tailwind.config.cjs b/tailwind.config.cjs
index 9e9fbcb8..8b4f0c9c 100644
--- a/tailwind.config.cjs
+++ b/tailwind.config.cjs
@@ -1,3 +1,5 @@
+const tailwindCssTheme = require('tailwindcss-themer')
+const themeConfig = require('./theme.config.cjs')
const typography = require('@tailwindcss/typography')
/** @type {import('tailwindcss').Config} */
@@ -7,6 +9,7 @@ module.exports = {
extend: {},
},
plugins: [
+ tailwindCssTheme(themeConfig),
typography(),
],
}
diff --git a/theme.config.cjs b/theme.config.cjs
new file mode 100644
index 00000000..946fc068
--- /dev/null
+++ b/theme.config.cjs
@@ -0,0 +1,57 @@
+const colors = require('tailwindcss/colors')
+
+const themeColors = {
+ light: {
+ secondary: colors.zinc['900'],
+ tertiary: colors.zinc['50'],
+ },
+ dark: {
+ secondary: colors.zinc['100'],
+ tertiary: colors.zinc['900'],
+ },
+}
+
+const darkTheme = ({ primary, secondary, tertiary }) => {
+ return {
+ primary: primary,
+ secondary: secondary,
+ tertiary: tertiary,
+ }
+}
+
+const lightTheme = ({ primary, secondary, tertiary }) => {
+ return {
+ primary: primary,
+ secondary: secondary,
+ tertiary: tertiary,
+ }
+}
+
+const siteTheme = ({ primary, secondary, tertiary }, isDark = true) =>
+ isDark
+ ? darkTheme({ primary, secondary, tertiary })
+ : lightTheme(darkTheme({ primary, secondary, tertiary }))
+
+module.exports = {
+ defaultTheme: {
+ extend: {
+ colors: siteTheme({
+ primary: '#ffa116',
+ secondary: themeColors.dark['secondary'],
+ tertiary: themeColors.dark['tertiary'],
+ }, true)
+ }
+ },
+ themes: [
+ {
+ name: 'leetcode-light',
+ extend: {
+ colors: siteTheme({
+ primary: '#ffa116',
+ secondary: themeColors.light['secondary'],
+ tertiary: themeColors.light['tertiary'],
+ }, false)
+ }
+ }
+ ]
+}
From 8fc54f9baee083580e8ee33b5dd3820d779a4025 Mon Sep 17 00:00:00 2001
From: Le Minh Tri
Date: Fri, 24 Feb 2023 15:49:14 +0700
Subject: [PATCH 13/75] feat(config): add author's avatar
---
public/ansidev.png | Bin 0 -> 1117 bytes
src/configs/site.ts | 1 +
2 files changed, 1 insertion(+)
create mode 100644 public/ansidev.png
diff --git a/public/ansidev.png b/public/ansidev.png
new file mode 100644
index 0000000000000000000000000000000000000000..b22cfb9410a38061c945cabb4c7a47cf330c3755
GIT binary patch
literal 1117
zcmV-j1fu(iP)GXlX!R3U>9>R+T#^IZcdY=FcFXRX)*{ET9R-o<8
zB;I{a0FK;b99~68&;Xr*W2FpVya8sV0rMvq?UX(}$AzcwGRmqLQ_=~Q9~sXZ
zTv&xUB;gYEtWd6O1S%V2e=$u{22cv=$fUEmJP?2}h-H8t6K``BT?!inAQfAx_QA*|r->712%bTK-#h%k-fIlM9%$FMTJLkVoN@iBnc_+>VMhTu3$Xb+P<+w)
z67DVl4rLg#9=ySLQs4cAzMnwh8Dq?x5rq8l#@|a{GVaw_@4J100kBgCN**%W{r2;{
zYYF^>YHEfW2dXP$q8-UpPf}QO#=7dO`ff+m0R4)NpfiGc^54D`lsOQ}
z9B6kZ!a*mjsWYJag>;gtRV0EHdvMkf?Mp1SF4aC=TRDGOoEiKj6U4HSpl
zs)see>O7-;w206r5xDfAYa6ehMVL0yyghq(aC_+#f@gra-1)u;F
j2|xiT00p2(06L@J#%M5quhO5B00000NkvXXu0mjfvS#hX
literal 0
HcmV?d00001
diff --git a/src/configs/site.ts b/src/configs/site.ts
index 0e9697ef..3e85b573 100644
--- a/src/configs/site.ts
+++ b/src/configs/site.ts
@@ -2,6 +2,7 @@ export default {
title: 'LeetCode Blog',
description: 'Solutions for LeetCode problems - Written by ansidev',
author: 'ansidev',
+ authorAvatar: '/ansidev.png',
favicon: '/favicon.ico',
faviconMimeType: 'image/x-icon',
}
From d8789c16bbb7c46d4d74d90dc125c701e8a1d8e3 Mon Sep 17 00:00:00 2001
From: Le Minh Tri
Date: Fri, 24 Feb 2023 16:01:20 +0700
Subject: [PATCH 14/75] build(dep): add package sass
---
package.json | 1 +
pnpm-lock.yaml | 31 +++++++++++++++++++++++--------
2 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/package.json b/package.json
index 2f953206..326f19ef 100644
--- a/package.json
+++ b/package.json
@@ -37,6 +37,7 @@
"eslint-plugin-simple-import-sort": "^10.0.0",
"husky": "^8.0.3",
"lodash.get": "^4.4.2",
+ "sass": "^1.58.3",
"tailwindcss-themer": "^3.0.1",
"typescript": "^4.9.5"
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 03dce9e8..ba7f41e9 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -20,13 +20,14 @@ specifiers:
eslint-plugin-simple-import-sort: ^10.0.0
husky: ^8.0.3
lodash.get: ^4.4.2
+ sass: ^1.58.3
tailwindcss: ^3.0.24
tailwindcss-themer: ^3.0.1
typescript: ^4.9.5
dependencies:
'@astrojs/tailwind': 3.0.1_hf2kjfio2dr6w52rh4mpociq2u
- astro: 2.0.14_@types+node@18.14.0
+ astro: 2.0.14_hlkwzk2izwsolfmdrejei4vrty
astro-compress: 1.1.33
astro-purgecss: 2.0.0_astro@2.0.14
tailwindcss: 3.2.7
@@ -47,6 +48,7 @@ devDependencies:
eslint-plugin-simple-import-sort: 10.0.0_eslint@8.34.0
husky: 8.0.3
lodash.get: 4.4.2
+ sass: 1.58.3
tailwindcss-themer: 3.0.1_tailwindcss@3.2.7
typescript: 4.9.5
@@ -91,7 +93,7 @@ packages:
astro: ^2.0.2
dependencies:
'@astrojs/prism': 2.0.0
- astro: 2.0.14_@types+node@18.14.0
+ astro: 2.0.14_hlkwzk2izwsolfmdrejei4vrty
github-slugger: 1.5.0
import-meta-resolve: 2.2.0
rehype-raw: 6.1.1
@@ -122,7 +124,7 @@ packages:
tailwindcss: ^3.0.24
dependencies:
'@proload/core': 0.3.3
- astro: 2.0.14_@types+node@18.14.0
+ astro: 2.0.14_hlkwzk2izwsolfmdrejei4vrty
autoprefixer: 10.4.13_postcss@8.4.21
postcss: 8.4.21
postcss-load-config: 4.0.1_postcss@8.4.21
@@ -1389,11 +1391,11 @@ packages:
peerDependencies:
astro: ^2.0.0
dependencies:
- astro: 2.0.14_@types+node@18.14.0
+ astro: 2.0.14_hlkwzk2izwsolfmdrejei4vrty
purgecss: 5.0.0
dev: false
- /astro/2.0.14_@types+node@18.14.0:
+ /astro/2.0.14_hlkwzk2izwsolfmdrejei4vrty:
resolution: {integrity: sha512-BiXnHyK3rj5Uz45V5p9jRi0xtJc/zxhCxnXYAekHHF1bVvvoa3aXMwl0GZ3Bc0mxP6vPLmbRcjNKdqfyZn1B3Q==}
engines: {node: '>=16.12.0', npm: '>=6.14.0'}
hasBin: true
@@ -1446,7 +1448,7 @@ packages:
typescript: 4.9.5
unist-util-visit: 4.1.1
vfile: 5.3.6
- vite: 4.1.2_@types+node@18.14.0
+ vite: 4.1.2_hlkwzk2izwsolfmdrejei4vrty
vitefu: 0.2.4_vite@4.1.2
yargs-parser: 21.1.1
zod: 3.20.2
@@ -2964,6 +2966,9 @@ packages:
engines: {node: '>= 4'}
dev: true
+ /immutable/4.2.4:
+ resolution: {integrity: sha512-WDxL3Hheb1JkRN3sQkyujNlL/xRjAo3rJtaU5xeufUauG66JdMr32bLj4gF+vWl84DIA3Zxw7tiAjneYzRRw+w==}
+
/import-fresh/3.3.0:
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
engines: {node: '>=6'}
@@ -4678,6 +4683,15 @@ packages:
suf-log: 2.5.3
dev: false
+ /sass/1.58.3:
+ resolution: {integrity: sha512-Q7RaEtYf6BflYrQ+buPudKR26/lH+10EmO9bBqbmPh/KeLqv8bjpTNqxe71ocONqXq+jYiCbpPUmQMS+JJPk4A==}
+ engines: {node: '>=12.0.0'}
+ hasBin: true
+ dependencies:
+ chokidar: 3.5.3
+ immutable: 4.2.4
+ source-map-js: 1.0.2
+
/section-matter/1.0.0:
resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==}
engines: {node: '>=4'}
@@ -5362,7 +5376,7 @@ packages:
vfile-message: 3.1.3
dev: false
- /vite/4.1.2_@types+node@18.14.0:
+ /vite/4.1.2_hlkwzk2izwsolfmdrejei4vrty:
resolution: {integrity: sha512-MWDb9Rfy3DI8omDQySbMK93nQqStwbsQWejXRY2EBzEWKmLAXWb1mkI9Yw2IJrc+oCvPCI1Os5xSSIBYY6DEAw==}
engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true
@@ -5392,6 +5406,7 @@ packages:
postcss: 8.4.21
resolve: 1.22.1
rollup: 3.14.0
+ sass: 1.58.3
optionalDependencies:
fsevents: 2.3.2
dev: false
@@ -5404,7 +5419,7 @@ packages:
vite:
optional: true
dependencies:
- vite: 4.1.2_@types+node@18.14.0
+ vite: 4.1.2_hlkwzk2izwsolfmdrejei4vrty
dev: false
/vscode-css-languageservice/6.2.1:
From a12192e0356124f07748d2bb3dc6530a2a49d98b Mon Sep 17 00:00:00 2001
From: Le Minh Tri
Date: Fri, 24 Feb 2023 16:24:55 +0700
Subject: [PATCH 15/75] feat(theme): add theme colors
---
theme.config.cjs | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/theme.config.cjs b/theme.config.cjs
index 946fc068..8ea6b653 100644
--- a/theme.config.cjs
+++ b/theme.config.cjs
@@ -1,6 +1,11 @@
const colors = require('tailwindcss/colors')
const themeColors = {
+ leetcode: {
+ easy: '#00af9b',
+ medium: '#ffb800',
+ hard: '#ff2d55',
+ },
light: {
secondary: colors.zinc['900'],
tertiary: colors.zinc['50'],
@@ -12,18 +17,50 @@ const themeColors = {
}
const darkTheme = ({ primary, secondary, tertiary }) => {
+ const baseColors = {
+ fill: primary,
+ text: secondary,
+ 'text-inverted': tertiary,
+ link: colors.blue['500'],
+ 'link-hover': colors.pink['500'],
+ }
+
return {
primary: primary,
secondary: secondary,
tertiary: tertiary,
+ site: {
+ 'bg': '#1a1a1a',
+ 'header-bg': '#282828',
+ 'header-border': colors.zinc['600'],
+ 'title': baseColors.text,
+ 'header-text': baseColors.text,
+ 'header-text-hover': baseColors.fill,
+ },
}
}
const lightTheme = ({ primary, secondary, tertiary }) => {
+ const baseColors = {
+ fill: primary,
+ text: secondary,
+ 'text-inverted': tertiary,
+ link: colors.blue['500'],
+ 'link-hover': colors.pink['500'],
+ }
+
return {
primary: primary,
secondary: secondary,
tertiary: tertiary,
+ site: {
+ 'bg': colors.white,
+ 'header-bg': primary,
+ 'header-border': primary,
+ 'title': baseColors['text-inverted'],
+ 'header-text': baseColors['text-inverted'],
+ 'header-text-hover': colors.gray['300'],
+ },
}
}
From 2df0a343aa02450f22a2a502e8ca2e4ff530adca Mon Sep 17 00:00:00 2001
From: Le Minh Tri
Date: Fri, 24 Feb 2023 16:27:05 +0700
Subject: [PATCH 16/75] feat(component): add component AppHeader
---
src/components/AppHeader.astro | 67 ++++++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+)
create mode 100644 src/components/AppHeader.astro
diff --git a/src/components/AppHeader.astro b/src/components/AppHeader.astro
new file mode 100644
index 00000000..07a3a014
--- /dev/null
+++ b/src/components/AppHeader.astro
@@ -0,0 +1,67 @@
+---
+import type { HTMLAttributes } from 'astro/types'
+
+import siteConfig from '@/configs/site'
+
+import Icon from './Icon.astro'
+
+export interface Props extends HTMLAttributes<'svg'> {}
+
+const { ...props } = Astro.props
+const { title, description, authorAvatar } = siteConfig
+---
+
+
+
+
From 502690c537988131b0470ea7e9c319efa3daca96 Mon Sep 17 00:00:00 2001
From: Le Minh Tri
Date: Fri, 24 Feb 2023 16:33:28 +0700
Subject: [PATCH 17/75] chore(ui): update the default layout and homepage
---
src/layouts/AppLayout.astro | 10 ++++++++--
src/pages/index.astro | 11 +++++++----
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/src/layouts/AppLayout.astro b/src/layouts/AppLayout.astro
index 32ee3a28..2244f0d4 100644
--- a/src/layouts/AppLayout.astro
+++ b/src/layouts/AppLayout.astro
@@ -1,4 +1,5 @@
---
+import AppHeader from '@/components/AppHeader.astro'
import SEOMeta from '@/components/SEOMeta.astro'
import siteConfig from '@/configs/site'
@@ -6,10 +7,13 @@ export interface Props {
title: string
description: string
author: string
+ headerCssClasses?: string
}
-const { title, author } = Astro.props
+const { title, description = '', author, headerCssClasses = '' } = Astro.props
const { favicon, faviconMimeType } = siteConfig
+const pageDescription =
+ description.length > 0 ? description : `${title} - ${siteConfig.description}`
---
@@ -17,12 +21,14 @@ const { favicon, faviconMimeType } = siteConfig
-
+
+
diff --git a/src/pages/index.astro b/src/pages/index.astro
index b1fc4987..71e18a39 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -6,10 +6,13 @@ import AppLayout from '@/layouts/AppLayout.astro'
const { title, description, author } = siteConfig
---
-
-
- {title}
- {description}
+
+