+ {" "}
+ Coffee taste always matters the most. With PHI, it will always be
+ perfect. Phi means the golden ratio. If you brew your coffee with
+ the golden ratio, it will always taste good. In the Phi section,
+ there are three boxes that the barista on shift should fill. These
+ are the main elements for adjusting the daily coffee recipe:
+
+ {" "}
+ Your barista enters the daily recipe, which will be recorded in your
+ database. You can view your adjustment chart see what’s happening in
+ your bar, and check the quality of your coffee serving in your store.
+
+ {" "}
+ Coffee taste always matters the most. With PHI, it will always be
+ perfect. Phi means the golden ratio. If you brew your coffee with
+ the golden ratio, it will always taste good. In the Phi section,
+ there are three boxes that the barista on shift should fill. These
+ are the main elements for adjusting the daily coffee recipe:
+
+ {" "}
+ Your barista enters the daily recipe, which will be recorded in your
+ database. You can view your adjustment chart see what’s happening in
+ your bar, and check the quality of your coffee serving in your store.
+
+
+ );
+};
+
+export default SectionWrapper(Phi, "Phi");
diff --git a/components/landingComponents/StepProduct.jsx b/components/landingComponents/StepProduct.jsx
new file mode 100644
index 0000000..cb5b772
--- /dev/null
+++ b/components/landingComponents/StepProduct.jsx
@@ -0,0 +1,868 @@
+"use clients";
+import React, { useEffect, useState } from "react";
+import { motion } from "framer-motion";
+
+import { SectionWrapper } from "src/hoc";
+import { fadeIn, textVariant } from "src/utils/motion";
+import { styles } from "src/style";
+import { stepProducts } from "src/constans";
+import Image from "next/image";
+import phi from "@img/adjustw.png";
+import app from "../../src/assets/app.png";
+import Avatar from "boring-avatars";
+
+const StepProduct = ({}) => {
+ const [activeIndex, setActiveIndex] = useState(1);
+
+ return (
+
+
+
+
+ Be Part of Our Stress Test and try us as an early adapter
+
+
+
+
+
+
+ Subscribe
+
+
+
+
+
+ {services.map((service, index) => (
+
+ ))}
+
+
+ );
+};
+
+export default SectionWrapper(StressTest, "StressTest");
diff --git a/datacalender.js b/datacalender.js
index 1237d23..19c351f 100644
--- a/datacalender.js
+++ b/datacalender.js
@@ -1,3 +1,5 @@
+import ActivityCard from "@comp/TaskPage/ActivityCard/page";
+
export const PersianM = (month) => {
switch (month) {
case (month = "1"):
@@ -398,3 +400,27 @@ export const holidays = {
},
],
};
+
+export const activityFake = {
+ amount: "0",
+ amountType: " 0",
+ description: "Closing the accounts ",
+ doneAt: "0001-01-01T00:00:00",
+ hasDisposed: false,
+ id: "8c3b04cb-a4dc-471b-baa3-a0ce773301fa",
+ isDisposable: false,
+ isDone: false,
+ performanceDescription: "",
+ scheduleType: 0,
+ setFor: "2024-09-04T06:00:00",
+ shiftPlanId: "dfb74c6e-5c27-4c4b-866f-ae66f7320331",
+ shiftTitle: "morning shift",
+ status: 0,
+ title: "Cleaning the southern walls of the hall b",
+ type: 0,
+ unDoneReason: "",
+ userFirstName: "hossein",
+ userFullName: "hossein masoomi pour",
+ userId: "27b63e2b-8b36-41a0-b0e1-270a51184f15",
+ userLastName: "masoomi pour",
+};
diff --git a/package-lock.json b/package-lock.json
index 7f09b4f..0bd0a87 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -38,7 +38,8 @@
"react-vertical-timeline-component": "^3.6.0",
"simple-react-validator": "^1.6.2",
"swiper": "^10.2.0",
- "tailwindcss": "3.3.3"
+ "tailwindcss": "3.3.3",
+ "tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"css-loader": "^6.8.1",
@@ -2458,26 +2459,6 @@
"resolved": "https://registry.npmjs.org/@types/draco3d/-/draco3d-1.4.9.tgz",
"integrity": "sha512-4MMUjMQb4yA5fJ4osXx+QxGHt0/ZSy4spT6jL1HM7Tn8OJEC35siqdnpOo+HxPhYjqEFumKfGVF9hJfdyKBIBA=="
},
- "node_modules/@types/eslint": {
- "version": "8.56.5",
- "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.5.tgz",
- "integrity": "sha512-u5/YPJHo1tvkSF2CE0USEkxon82Z5DBy2xR+qfyYNszpX9qcs4sT6uq2kBbj4BXY1+DBGDPnrhMZV3pKWGNukw==",
- "dev": true,
- "dependencies": {
- "@types/estree": "*",
- "@types/json-schema": "*"
- }
- },
- "node_modules/@types/eslint-scope": {
- "version": "3.7.7",
- "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
- "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
- "dev": true,
- "dependencies": {
- "@types/eslint": "*",
- "@types/estree": "*"
- }
- },
"node_modules/@types/estree": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
@@ -2580,9 +2561,9 @@
}
},
"node_modules/@webassemblyjs/ast": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
- "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz",
+ "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==",
"dev": true,
"dependencies": {
"@webassemblyjs/helper-numbers": "1.11.6",
@@ -2602,9 +2583,9 @@
"dev": true
},
"node_modules/@webassemblyjs/helper-buffer": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
- "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz",
+ "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==",
"dev": true
},
"node_modules/@webassemblyjs/helper-numbers": {
@@ -2625,15 +2606,15 @@
"dev": true
},
"node_modules/@webassemblyjs/helper-wasm-section": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
- "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz",
+ "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==",
"dev": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
- "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/ast": "1.12.1",
+ "@webassemblyjs/helper-buffer": "1.12.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
- "@webassemblyjs/wasm-gen": "1.11.6"
+ "@webassemblyjs/wasm-gen": "1.12.1"
}
},
"node_modules/@webassemblyjs/ieee754": {
@@ -2661,28 +2642,28 @@
"dev": true
},
"node_modules/@webassemblyjs/wasm-edit": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
- "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz",
+ "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==",
"dev": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
- "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/ast": "1.12.1",
+ "@webassemblyjs/helper-buffer": "1.12.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
- "@webassemblyjs/helper-wasm-section": "1.11.6",
- "@webassemblyjs/wasm-gen": "1.11.6",
- "@webassemblyjs/wasm-opt": "1.11.6",
- "@webassemblyjs/wasm-parser": "1.11.6",
- "@webassemblyjs/wast-printer": "1.11.6"
+ "@webassemblyjs/helper-wasm-section": "1.12.1",
+ "@webassemblyjs/wasm-gen": "1.12.1",
+ "@webassemblyjs/wasm-opt": "1.12.1",
+ "@webassemblyjs/wasm-parser": "1.12.1",
+ "@webassemblyjs/wast-printer": "1.12.1"
}
},
"node_modules/@webassemblyjs/wasm-gen": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
- "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz",
+ "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==",
"dev": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/ast": "1.12.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
"@webassemblyjs/ieee754": "1.11.6",
"@webassemblyjs/leb128": "1.11.6",
@@ -2690,24 +2671,24 @@
}
},
"node_modules/@webassemblyjs/wasm-opt": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
- "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz",
+ "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==",
"dev": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
- "@webassemblyjs/helper-buffer": "1.11.6",
- "@webassemblyjs/wasm-gen": "1.11.6",
- "@webassemblyjs/wasm-parser": "1.11.6"
+ "@webassemblyjs/ast": "1.12.1",
+ "@webassemblyjs/helper-buffer": "1.12.1",
+ "@webassemblyjs/wasm-gen": "1.12.1",
+ "@webassemblyjs/wasm-parser": "1.12.1"
}
},
"node_modules/@webassemblyjs/wasm-parser": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
- "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz",
+ "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==",
"dev": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/ast": "1.12.1",
"@webassemblyjs/helper-api-error": "1.11.6",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
"@webassemblyjs/ieee754": "1.11.6",
@@ -2716,12 +2697,12 @@
}
},
"node_modules/@webassemblyjs/wast-printer": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
- "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz",
+ "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==",
"dev": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/ast": "1.12.1",
"@xtuc/long": "4.2.2"
}
},
@@ -2748,40 +2729,30 @@
"node": ">=0.4.0"
}
},
- "node_modules/acorn-import-assertions": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
- "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
+ "node_modules/acorn-import-attributes": {
+ "version": "1.9.5",
+ "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz",
+ "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==",
"dev": true,
"peerDependencies": {
"acorn": "^8"
}
},
"node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "dev": true,
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
- "node_modules/ajv-keywords": {
- "version": "3.5.2",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
- "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
- "dev": true,
- "peerDependencies": {
- "ajv": "^6.9.1"
- }
- },
"node_modules/ansi-escapes": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
@@ -3732,9 +3703,9 @@
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"node_modules/enhanced-resolve": {
- "version": "5.15.1",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.1.tgz",
- "integrity": "sha512-3d3JRbwsCLJsYgvb6NuWEG44jjPSOMuS73L/6+7BZuoKm3W+qXnSoIYVHi8dG7Qcg4inAY4jbzkZ7MnskePeDg==",
+ "version": "5.17.1",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
+ "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==",
"dev": true,
"dependencies": {
"graceful-fs": "^4.2.4",
@@ -3998,6 +3969,11 @@
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
},
+ "node_modules/fast-uri": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz",
+ "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw=="
+ },
"node_modules/fastq": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
@@ -4183,19 +4159,6 @@
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "hasInstallScript": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@@ -5005,10 +4968,9 @@
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
},
"node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
},
"node_modules/json5": {
"version": "2.2.3",
@@ -6409,6 +6371,37 @@
"url": "https://opencollective.com/webpack"
}
},
+ "node_modules/schema-utils/node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/schema-utils/node_modules/ajv-keywords": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+ "dev": true,
+ "peerDependencies": {
+ "ajv": "^6.9.1"
+ }
+ },
+ "node_modules/schema-utils/node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
"node_modules/semver": {
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
@@ -6856,6 +6849,14 @@
"node": ">=14.0.0"
}
},
+ "node_modules/tailwindcss-animate": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz",
+ "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==",
+ "peerDependencies": {
+ "tailwindcss": ">=3.0.0 || insiders"
+ }
+ },
"node_modules/tapable": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
@@ -7320,6 +7321,7 @@
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
"dependencies": {
"punycode": "^2.1.0"
}
@@ -7425,26 +7427,25 @@
"integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="
},
"node_modules/webpack": {
- "version": "5.90.3",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz",
- "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==",
+ "version": "5.94.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz",
+ "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==",
"dev": true,
"dependencies": {
- "@types/eslint-scope": "^3.7.3",
"@types/estree": "^1.0.5",
- "@webassemblyjs/ast": "^1.11.5",
- "@webassemblyjs/wasm-edit": "^1.11.5",
- "@webassemblyjs/wasm-parser": "^1.11.5",
+ "@webassemblyjs/ast": "^1.12.1",
+ "@webassemblyjs/wasm-edit": "^1.12.1",
+ "@webassemblyjs/wasm-parser": "^1.12.1",
"acorn": "^8.7.1",
- "acorn-import-assertions": "^1.9.0",
+ "acorn-import-attributes": "^1.9.5",
"browserslist": "^4.21.10",
"chrome-trace-event": "^1.0.2",
- "enhanced-resolve": "^5.15.0",
+ "enhanced-resolve": "^5.17.1",
"es-module-lexer": "^1.2.1",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
"glob-to-regexp": "^0.4.1",
- "graceful-fs": "^4.2.9",
+ "graceful-fs": "^4.2.11",
"json-parse-even-better-errors": "^2.3.1",
"loader-runner": "^4.2.0",
"mime-types": "^2.1.27",
@@ -7452,7 +7453,7 @@
"schema-utils": "^3.2.0",
"tapable": "^2.1.1",
"terser-webpack-plugin": "^5.3.10",
- "watchpack": "^2.4.0",
+ "watchpack": "^2.4.1",
"webpack-sources": "^3.2.3"
},
"bin": {
@@ -7480,6 +7481,19 @@
"node": ">=10.13.0"
}
},
+ "node_modules/webpack/node_modules/watchpack": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz",
+ "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==",
+ "dev": true,
+ "dependencies": {
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.1.2"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
"node_modules/whatwg-url": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
@@ -7601,21 +7615,6 @@
"node": ">=16.0.0"
}
},
- "node_modules/workbox-build/node_modules/ajv": {
- "version": "8.13.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz",
- "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==",
- "dependencies": {
- "fast-deep-equal": "^3.1.3",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2",
- "uri-js": "^4.4.1"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
"node_modules/workbox-build/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -7644,11 +7643,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/workbox-build/node_modules/json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
- },
"node_modules/workbox-build/node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
diff --git a/package.json b/package.json
index 32daf12..f354f46 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"version": "0.2.7",
"private": true,
"scripts": {
- "dev": "next dev -p 8080",
+ "dev": "next dev -p 8000",
"build": "next build",
"start": "next start",
"lint": "next lint"
@@ -39,7 +39,8 @@
"react-vertical-timeline-component": "^3.6.0",
"simple-react-validator": "^1.6.2",
"swiper": "^10.2.0",
- "tailwindcss": "3.3.3"
+ "tailwindcss": "3.3.3",
+ "tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"css-loader": "^6.8.1",
diff --git a/public/fallback-ce627215c0e4a9af.js b/public/fallback-ce627215c0e4a9af.js
new file mode 100644
index 0000000..f02f9ce
--- /dev/null
+++ b/public/fallback-ce627215c0e4a9af.js
@@ -0,0 +1 @@
+self.fallback=async e=>{let{destination:a,url:n}=e,o={document:"/offline",image:!1,audio:!1,video:!1,font:!1}[a];return o?caches.match(o,{ignoreSearch:!0}):Response.error()};
\ No newline at end of file
diff --git a/public/fallback-development.js b/public/fallback-development.js
deleted file mode 100644
index 9610be1..0000000
--- a/public/fallback-development.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * ATTENTION: An "eval-source-map" devtool has been used.
- * This devtool is neither made for production nor for readable output files.
- * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
- * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
- * or disable the default devtool with "devtool: false".
- * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
- */
-/******/ (function() { // webpackBootstrap
-/******/ "use strict";
-/******/ var __webpack_modules__ = ({
-
-/***/ "./node_modules/@ducanh2912/next-pwa/dist/fallback.js":
-/*!************************************************************!*\
- !*** ./node_modules/@ducanh2912/next-pwa/dist/fallback.js ***!
- \************************************************************/
-/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
-
-eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\nself.fallback = async (_)=>{\n let { destination: e, url: A } = _, s = {\n document: \"/offline\",\n image: false,\n audio: false,\n video: false,\n font: false\n }[e];\n return s ? caches.match(s, {\n ignoreSearch: !0\n }) : \"\" === e && false && 0 ? 0 : Response.error();\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvQGR1Y2FuaDI5MTIvbmV4dC1wd2EvZGlzdC9mYWxsYmFjay5qcyIsIm1hcHBpbmdzIjoiO0FBQUE7QUFDQSxVQUFVLHlCQUF5QjtBQUNuQyxrQkFBa0IsVUFBcUM7QUFDdkQsZUFBZSxLQUFrQztBQUNqRCxlQUFlLEtBQWtDO0FBQ2pELGVBQWUsS0FBa0M7QUFDakQsY0FBYyxLQUFpQztBQUMvQyxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUssZ0JBQWdCLEtBQWlDLElBQUksQ0FBd0MsR0FBRyxDQUUvRjtBQUNOIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vX05fRS8uL25vZGVfbW9kdWxlcy9AZHVjYW5oMjkxMi9uZXh0LXB3YS9kaXN0L2ZhbGxiYWNrLmpzP2NlNGIiXSwic291cmNlc0NvbnRlbnQiOlsic2VsZi5mYWxsYmFjayA9IGFzeW5jIChfKT0+e1xuICAgIGxldCB7IGRlc3RpbmF0aW9uOiBlLCB1cmw6IEEgfSA9IF8sIHMgPSB7XG4gICAgICAgIGRvY3VtZW50OiBwcm9jZXNzLmVudi5fX1BXQV9GQUxMQkFDS19ET0NVTUVOVF9fLFxuICAgICAgICBpbWFnZTogcHJvY2Vzcy5lbnYuX19QV0FfRkFMTEJBQ0tfSU1BR0VfXyxcbiAgICAgICAgYXVkaW86IHByb2Nlc3MuZW52Ll9fUFdBX0ZBTExCQUNLX0FVRElPX18sXG4gICAgICAgIHZpZGVvOiBwcm9jZXNzLmVudi5fX1BXQV9GQUxMQkFDS19WSURFT19fLFxuICAgICAgICBmb250OiBwcm9jZXNzLmVudi5fX1BXQV9GQUxMQkFDS19GT05UX19cbiAgICB9W2VdO1xuICAgIHJldHVybiBzID8gY2FjaGVzLm1hdGNoKHMsIHtcbiAgICAgICAgaWdub3JlU2VhcmNoOiAhMFxuICAgIH0pIDogXCJcIiA9PT0gZSAmJiBwcm9jZXNzLmVudi5fX1BXQV9GQUxMQkFDS19EQVRBX18gJiYgQS5tYXRjaCgvXFwvX25leHRcXC9kYXRhXFwvLitcXC8uK1xcLmpzb24kL2kpID8gY2FjaGVzLm1hdGNoKHByb2Nlc3MuZW52Ll9fUFdBX0ZBTExCQUNLX0RBVEFfXywge1xuICAgICAgICBpZ25vcmVTZWFyY2g6ICEwXG4gICAgfSkgOiBSZXNwb25zZS5lcnJvcigpO1xufTsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/@ducanh2912/next-pwa/dist/fallback.js\n"));
-
-/***/ })
-
-/******/ });
-/************************************************************************/
-/******/ // The require scope
-/******/ var __webpack_require__ = {};
-/******/
-/************************************************************************/
-/******/ /* webpack/runtime/make namespace object */
-/******/ !function() {
-/******/ // define __esModule on exports
-/******/ __webpack_require__.r = function(exports) {
-/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
-/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
-/******/ }
-/******/ Object.defineProperty(exports, '__esModule', { value: true });
-/******/ };
-/******/ }();
-/******/
-/******/ /* webpack/runtime/trusted types policy */
-/******/ !function() {
-/******/ var policy;
-/******/ __webpack_require__.tt = function() {
-/******/ // Create Trusted Type policy if Trusted Types are available and the policy doesn't exist yet.
-/******/ if (policy === undefined) {
-/******/ policy = {
-/******/ createScript: function(script) { return script; }
-/******/ };
-/******/ if (typeof trustedTypes !== "undefined" && trustedTypes.createPolicy) {
-/******/ policy = trustedTypes.createPolicy("nextjs#bundler", policy);
-/******/ }
-/******/ }
-/******/ return policy;
-/******/ };
-/******/ }();
-/******/
-/******/ /* webpack/runtime/trusted types script */
-/******/ !function() {
-/******/ __webpack_require__.ts = function(script) { return __webpack_require__.tt().createScript(script); };
-/******/ }();
-/******/
-/******/ /* webpack/runtime/react refresh */
-/******/ !function() {
-/******/ if (__webpack_require__.i) {
-/******/ __webpack_require__.i.push(function(options) {
-/******/ var originalFactory = options.factory;
-/******/ options.factory = function(moduleObject, moduleExports, webpackRequire) {
-/******/ var hasRefresh = typeof self !== "undefined" && !!self.$RefreshInterceptModuleExecution$;
-/******/ var cleanup = hasRefresh ? self.$RefreshInterceptModuleExecution$(moduleObject.id) : function() {};
-/******/ try {
-/******/ originalFactory.call(this, moduleObject, moduleExports, webpackRequire);
-/******/ } finally {
-/******/ cleanup();
-/******/ }
-/******/ }
-/******/ })
-/******/ }
-/******/ }();
-/******/
-/******/ /* webpack/runtime/compat */
-/******/
-/******/
-/******/ // noop fns to prevent runtime errors during initialization
-/******/ if (typeof self !== "undefined") {
-/******/ self.$RefreshReg$ = function () {};
-/******/ self.$RefreshSig$ = function () {
-/******/ return function (type) {
-/******/ return type;
-/******/ };
-/******/ };
-/******/ }
-/******/
-/************************************************************************/
-/******/
-/******/ // startup
-/******/ // Load entry module and return exports
-/******/ // This entry module can't be inlined because the eval-source-map devtool is used.
-/******/ var __webpack_exports__ = {};
-/******/ __webpack_modules__["./node_modules/@ducanh2912/next-pwa/dist/fallback.js"](0, __webpack_exports__, __webpack_require__);
-/******/
-/******/ })()
-;
\ No newline at end of file
diff --git a/public/images/Vector1.png b/public/images/Vector1.png
new file mode 100644
index 0000000..7ab2a58
Binary files /dev/null and b/public/images/Vector1.png differ
diff --git a/public/images/adjustw.png b/public/images/adjustw.png
new file mode 100644
index 0000000..7f2f35f
Binary files /dev/null and b/public/images/adjustw.png differ
diff --git a/public/images/logo/lam.png b/public/images/logo/lam.png
new file mode 100644
index 0000000..f77d25b
Binary files /dev/null and b/public/images/logo/lam.png differ
diff --git a/public/images/logo/ros.png b/public/images/logo/ros.png
new file mode 100644
index 0000000..651ee2a
Binary files /dev/null and b/public/images/logo/ros.png differ
diff --git a/public/images/logo/tuk.png b/public/images/logo/tuk.png
new file mode 100644
index 0000000..2b1b902
Binary files /dev/null and b/public/images/logo/tuk.png differ
diff --git a/public/images/logo/vee.png b/public/images/logo/vee.png
new file mode 100644
index 0000000..6ab25b5
Binary files /dev/null and b/public/images/logo/vee.png differ
diff --git a/public/images/logo/woo.png b/public/images/logo/woo.png
new file mode 100644
index 0000000..b04336e
Binary files /dev/null and b/public/images/logo/woo.png differ
diff --git a/public/images/phi1t.png b/public/images/phi1t.png
new file mode 100644
index 0000000..b681d97
Binary files /dev/null and b/public/images/phi1t.png differ
diff --git a/public/images/test.gif b/public/images/test.gif
new file mode 100644
index 0000000..1fa095d
Binary files /dev/null and b/public/images/test.gif differ
diff --git a/public/sw.js b/public/sw.js
index 6d6df48..8d806a2 100644
--- a/public/sw.js
+++ b/public/sw.js
@@ -1,115 +1 @@
-/**
- * Copyright 2018 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// If the loader is already loaded, just stop.
-if (!self.define) {
- let registry = {};
-
- // Used for `eval` and `importScripts` where we can't get script URL by other means.
- // In both cases, it's safe to use a global var because those functions are synchronous.
- let nextDefineUri;
-
- const singleRequire = (uri, parentUri) => {
- uri = new URL(uri + ".js", parentUri).href;
- return registry[uri] || (
-
- new Promise(resolve => {
- if ("document" in self) {
- const script = document.createElement("script");
- script.src = uri;
- script.onload = resolve;
- document.head.appendChild(script);
- } else {
- nextDefineUri = uri;
- importScripts(uri);
- resolve();
- }
- })
-
- .then(() => {
- let promise = registry[uri];
- if (!promise) {
- throw new Error(`Module ${uri} didn’t register its module`);
- }
- return promise;
- })
- );
- };
-
- self.define = (depsNames, factory) => {
- const uri = nextDefineUri || ("document" in self ? document.currentScript.src : "") || location.href;
- if (registry[uri]) {
- // Module is already loading or loaded.
- return;
- }
- let exports = {};
- const require = depUri => singleRequire(depUri, uri);
- const specialDeps = {
- module: { uri },
- exports,
- require
- };
- registry[uri] = Promise.all(depsNames.map(
- depName => specialDeps[depName] || require(depName)
- )).then(deps => {
- factory(...deps);
- return exports;
- });
- };
-}
-define(['./workbox-1e54d6fe'], (function (workbox) { 'use strict';
-
- importScripts("/fallback-development.js");
- self.skipWaiting();
- workbox.clientsClaim();
-
- /**
- * The precacheAndRoute() method efficiently caches and responds to
- * requests for URLs in the manifest.
- * See https://goo.gl/S9QRab
- */
- workbox.precacheAndRoute([{
- "url": "/offline",
- "revision": "development"
- }], {
- "ignoreURLParametersMatching": [/^utm_/, /^fbclid$/, /ts/]
- });
- workbox.cleanupOutdatedCaches();
- workbox.registerRoute("/", new workbox.NetworkFirst({
- "cacheName": "start-url",
- plugins: [{
- cacheWillUpdate: async ({
- response: e
- }) => e && "opaqueredirect" === e.type ? new Response(e.body, {
- status: 200,
- statusText: "OK",
- headers: e.headers
- }) : e
- }, {
- handlerDidError: async ({
- request: e
- }) => "undefined" != typeof self ? self.fallback(e) : Response.error()
- }]
- }), 'GET');
- workbox.registerRoute(/.*/i, new workbox.NetworkOnly({
- "cacheName": "dev",
- plugins: [{
- handlerDidError: async ({
- request: e
- }) => "undefined" != typeof self ? self.fallback(e) : Response.error()
- }]
- }), 'GET');
- self.__WB_DISABLE_DEV_LOGS = true;
-
-}));
-//# sourceMappingURL=sw.js.map
+if(!self.define){let e,a={};const s=(s,c)=>(s=new URL(s+".js",c).href,a[s]||new Promise((a=>{if("document"in self){const e=document.createElement("script");e.src=s,e.onload=a,document.head.appendChild(e)}else e=s,importScripts(s),a()})).then((()=>{let e=a[s];if(!e)throw new Error(`Module ${s} didn’t register its module`);return e})));self.define=(c,i)=>{const n=e||("document"in self?document.currentScript.src:"")||location.href;if(a[n])return;let t={};const f=e=>s(e,n),r={module:{uri:n},exports:t,require:f};a[n]=Promise.all(c.map((e=>r[e]||f(e)))).then((e=>(i(...e),t)))}}define(["./workbox-c06b064f"],(function(e){"use strict";importScripts("/fallback-ce627215c0e4a9af.js"),self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"/_next/static/HocLuybuPOLcUC6NGe9sI/_buildManifest.js",revision:"66a650a40453999ca40002ee32e3481e"},{url:"/_next/static/HocLuybuPOLcUC6NGe9sI/_ssgManifest.js",revision:"b6652df95db52feb4daf4eca35380933"},{url:"/_next/static/chunks/135-fbe9e1bd4358248a.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/13b76428-56ef92d027d6786a.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/148-76a3e61f8b509e85.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/235-44d31a43a4a9f007.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/245-7a31a50c90ece09f.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/313-2ca7f36ac98d1f42.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/361-1eadcd47b00762f2.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/375-b9d52f23ead03da9.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/396-d24fc3578f46fc4e.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/478-18c8f2345006432f.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/525-4c1f9a0f7eae889b.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/568-fd836c769a6919a6.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/747-1e11f0325e4f5aa5.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/778-315d8ff4db0336f1.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/807-9065b9e93d5afb07.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/874-3409183e9254cad1.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/889-db564906afe704f4.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/906-47764d1840e263ce.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/92-41d871ab515da13f.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/986-62db81ee10936871.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/app/about-us/page-7acd3145d93381bc.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/app/add-buy/page-f2c872005a0397bc.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/app/app/acount/page-f83ba430764f1ea1.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/app/app/coffee-brew/page-b5f5e7bb4c561fa1.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/app/app/employees/page-abb35b7c2cf5b86b.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/app/app/home/page-435b85b59b5f64cc.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/app/app/login/page-f4896bdf871fdd06.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/app/app/news/page-9e4a8508082ecfec.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/app/app/shifts/complete-shift/page-cd28ad634fcfd257.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/app/app/shifts/manage-shift/page-83bf971f64f5349f.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/app/app/shifts/page-5b77d58a9800268f.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/app/app/tasks/add-task/page-d7ff93922fa8a331.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/app/app/tasks/page-5ff180539e8c08eb.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/app/layout-8e4596961d262d2e.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/app/page-927da11e5cd02a0b.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/app/pricing/page-79265f7f6948f655.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/ca377847-c7b13a2d3dbd7978.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/fd9d1056-76aadce26f555392.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/framework-89837f5784be6e42.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/main-5485f73f6f712ade.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/main-app-463a5ceba39d13c0.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/pages/_app-52924524f99094ab.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/pages/_error-c92d5c4bb2b49926.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js",revision:"79330112775102f91e1010318bae2bd3"},{url:"/_next/static/chunks/webpack-6ab4177fbe0089ba.js",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/_next/static/css/2d0b62e6e148789e.css",revision:"2d0b62e6e148789e"},{url:"/_next/static/css/34c26eb5be187d8a.css",revision:"34c26eb5be187d8a"},{url:"/_next/static/css/7ed86a6f2ce35613.css",revision:"7ed86a6f2ce35613"},{url:"/_next/static/css/afd026d3c415d315.css",revision:"afd026d3c415d315"},{url:"/_next/static/media/26a46d62cd723877-s.woff2",revision:"befd9c0fdfa3d8a645d5f95717ed6420"},{url:"/_next/static/media/55c55f0601d81cf3-s.woff2",revision:"43828e14271c77b87e3ed582dbff9f74"},{url:"/_next/static/media/581909926a08bbc8-s.woff2",revision:"f0b86e7c24f455280b8df606b89af891"},{url:"/_next/static/media/6d93bde91c0c2823-s.woff2",revision:"621a07228c8ccbfd647918f1021b4868"},{url:"/_next/static/media/97e0cb1ae144a2a9-s.woff2",revision:"e360c61c5bd8d90639fd4503c829c2dc"},{url:"/_next/static/media/Vector1.8129c6ce.png",revision:"17a7084f16c85847f17977f594679ced"},{url:"/_next/static/media/a34f9d1faa5f3315-s.p.woff2",revision:"d4fe31e6a2aebc06b8d6e558c9141119"},{url:"/_next/static/media/adjust.8a4e8d0e.png",revision:"5211a7519534ca172844a42bce17465a"},{url:"/_next/static/media/adjustw.750c874c.png",revision:"cdde1aad7bebb72f4badb0789f7e6e27"},{url:"/_next/static/media/app.542d2db5.png",revision:"5cf2e6ff5ef3237a6f9ad369cc92dc76"},{url:"/_next/static/media/backend.8008d8ae.png",revision:"b6f97a0bb77c12636d32a57efacd1d10"},{url:"/_next/static/media/bg.64a109c7.png",revision:"64a109c7"},{url:"/_next/static/media/carrent.f51c1ee5.png",revision:"de7775e7e769abcd0478a0f32554addf"},{url:"/_next/static/media/close.64934c3b.svg",revision:"333c66a5dff1d7cc3968f6e7af4c5b2c"},{url:"/_next/static/media/creator.69ea3236.png",revision:"2fb53dc768e9f2b21e8eba0b31c50f1d"},{url:"/_next/static/media/css.a39d8948.png",revision:"562320553594c7fc047b9d0cf55233ab"},{url:"/_next/static/media/df0a9ae256c0569c-s.woff2",revision:"d54db44de5ccb18886ece2fda72bdfe0"},{url:"/_next/static/media/docker.888df998.png",revision:"48daa53dc2e75aa18777f55eb610c4f1"},{url:"/_next/static/media/figma.522534b7.png",revision:"897539713a3105b6ee3b797851459130"},{url:"/_next/static/media/git.3337db5a.png",revision:"91e38c1fb4b2410c06d56542d09086d0"},{url:"/_next/static/media/github.665bfffe.png",revision:"69b7e397e348747e802b90e5eb0bfbd4"},{url:"/_next/static/media/html.5faed4ed.png",revision:"ff5aca29bd447b791c743ad0075e5aa3"},{url:"/_next/static/media/ig.1b04410f.png",revision:"ad3e83bda02be12d20e80665a2d35d0d"},{url:"/_next/static/media/javascript.80891722.png",revision:"c1f39577de277de6ff5f654e996f1028"},{url:"/_next/static/media/jobit.2df3aeaa.png",revision:"261dcd8d434a22a8ce067dcfe77160b8"},{url:"/_next/static/media/lam.a61d06b3.png",revision:"31d23d6bb5b90b53b6b6c3b03d7cc598"},{url:"/_next/static/media/loading.5d5a7205.gif",revision:"bac61c8d9306edae5b74e399d1485ad3"},{url:"/_next/static/media/logo.82328059.svg",revision:"2c844ef471eafcba8331c476cfef883b"},{url:"/_next/static/media/logo.9568c8e7.png",revision:"9cde4940e517fbafd74784802b462e5b"},{url:"/_next/static/media/logo2.26701545.png",revision:"a876896a85faad3f81a50af5ac1392f9"},{url:"/_next/static/media/logo2.8d20420d.png",revision:"97bc09c6257714ce55faa41bc2da88b5"},{url:"/_next/static/media/menu.3fc6164d.svg",revision:"d4926d3f2dc6c41bdcb19909d4ae93c8"},{url:"/_next/static/media/meta.3b282ee4.png",revision:"c39c206e11ef45ddc19167e6c167e1d8"},{url:"/_next/static/media/mobile.6333563d.png",revision:"9537758db1d756949a924fcd4404895f"},{url:"/_next/static/media/mongodb.004a26cb.png",revision:"1fb83876d8f00b2f67374b05838d09d2"},{url:"/_next/static/media/nodejs.fbe4a5b0.png",revision:"9e79e8c3cdcccfc06c9840883f15b2c1"},{url:"/_next/static/media/notif.1e9f8243.png",revision:"bd85e30b2bf85bc83b9189b47bbac828"},{url:"/_next/static/media/phi1.ba638ea9.png",revision:"1116ff7c816453d26ea5fe9ae84169d1"},{url:"/_next/static/media/phi2.8f52adc1.png",revision:"72f098a8c6fd79ff2300e47467237f0d"},{url:"/_next/static/media/phi3.00f9ce61.png",revision:"a80bc58f24f702839feb34b5043679d8"},{url:"/_next/static/media/reactjs.38edcd3f.png",revision:"f70556624353bdc24ec1e69a2d979630"},{url:"/_next/static/media/redux.fd412f4b.png",revision:"31f3e54c7d49efed1b6a03edc4476ba2"},{url:"/_next/static/media/ros.990a7841.png",revision:"145618df97c1ecb76a6ef3d349248e0c"},{url:"/_next/static/media/setting.752bec9e.png",revision:"8a4a4a0bc0dc99c74dfb06ab82183f1c"},{url:"/_next/static/media/shopify.c8963632.png",revision:"7d0c465185ea1aa651737aedf2e889f9"},{url:"/_next/static/media/starbucks.ca9c1564.png",revision:"739125c98702ba3575a572618abc82f6"},{url:"/_next/static/media/tailwind.cd1d4bac.png",revision:"c73f9afce409c73a75bb36ce9da84a94"},{url:"/_next/static/media/tesla.cd57c981.png",revision:"00f12a1675ac2554f83449c254abfc66"},{url:"/_next/static/media/threejs.fe404a12.svg",revision:"d75c09a5a967d4425a175b6bfe5ca4e5"},{url:"/_next/static/media/tuk.a8268338.png",revision:"e209dfe18a1e168cd56f8cf85ca4a800"},{url:"/_next/static/media/tuk.e4f3e0e2.png",revision:"f0ef8c133b136488c44fbee1c27aba25"},{url:"/_next/static/media/typescript.ccdf44e2.png",revision:"6a41ab01fd39f8bae6bad97ef7109cf9"},{url:"/_next/static/media/vee.321f6ec3.png",revision:"752e6df9e64b8554669ecbc95bb0cde4"},{url:"/_next/static/media/web.a0fb760b.png",revision:"f59df0f5b55cde9fc8e02c3dfe1e3540"},{url:"/_next/static/media/woo.abc77e01.png",revision:"e40cf597740cf29d2cab57b3720a4c26"},{url:"/android-chrome-192x192.png",revision:"5a2b679c2087c606306393171e90e5e3"},{url:"/android-chrome-512x512.png",revision:"70e7c2793f6a0cc9cf2e15bf618938d0"},{url:"/apple-touch-icon.png",revision:"73ac676e78dc2f3a4ca9fb7f6d7ab8a2"},{url:"/browserconfig.xml",revision:"a493ba0aa0b8ec8068d786d7248bb92c"},{url:"/fallback-ce627215c0e4a9af.js",revision:"a5281aa1504c5d6bcd7ba1097870376a"},{url:"/favicon-16x16.png",revision:"b59e99894c6ece0c4acf1bd30a61f293"},{url:"/favicon-32x32.png",revision:"722bded6887acd0241f8e05917a4b180"},{url:"/favicon.ico",revision:"9292c7c8eef1860fa5093b1ce664c11c"},{url:"/fonts/woff/KalamehWeb-Black.woff",revision:"76927eb3c8978995345660385aff7ec4"},{url:"/fonts/woff/KalamehWeb-Bold.woff",revision:"962a46f356f93fe9a4aadc4dd2ed0eec"},{url:"/fonts/woff/KalamehWeb-ExtraBold.woff",revision:"2bc26bafe58675b967b6679f0c988702"},{url:"/fonts/woff/KalamehWeb-ExtraLight.woff",revision:"2c34c6b56cf5d5f28b855a26e12c7903"},{url:"/fonts/woff/KalamehWeb-Light.woff",revision:"bcf5ef6b7b982e0ab7290e6c2cda510b"},{url:"/fonts/woff/KalamehWeb-Medium.woff",revision:"f10476fa00c806a8862f8d28510e0d61"},{url:"/fonts/woff/KalamehWeb-Regular.woff",revision:"7aa63793827e31b8e41fda71f8072de6"},{url:"/fonts/woff/KalamehWeb-SemiBold.woff",revision:"494ba66e4eaa329a55c61419b2054fcf"},{url:"/fonts/woff/KalamehWeb-Thin.woff",revision:"bd4a8af2c70bebc7ec5342da46b27cdc"},{url:"/fonts/woff2/KalamehWeb-Black.woff2",revision:"64befedcea62edb8d51adf7b6c9e0cf9"},{url:"/fonts/woff2/KalamehWeb-Bold.woff2",revision:"341e8d81a6ad98239138dfe2f29c7e3d"},{url:"/fonts/woff2/KalamehWeb-ExtraBold.woff2",revision:"a3d26b194c12792fe056884bb54be360"},{url:"/fonts/woff2/KalamehWeb-ExtraLight.woff2",revision:"3d0141c1e3552bdc2cb5ce9d2d49c573"},{url:"/fonts/woff2/KalamehWeb-Light.woff2",revision:"a7aaf4d231f0df6371846801379cb489"},{url:"/fonts/woff2/KalamehWeb-Medium.woff2",revision:"847e07561576a0465bc688345bfef035"},{url:"/fonts/woff2/KalamehWeb-Regular.woff2",revision:"14520e3d88672cebe595a4dd4e8d1e68"},{url:"/fonts/woff2/KalamehWeb-SemiBold.woff2",revision:"25c8a9f46296bf3edb1e9c9b24a98ad5"},{url:"/fonts/woff2/KalamehWeb-Thin.woff2",revision:"416a93f37781ddfc7bc91f75d0f0a9f5"},{url:"/images/Vector1.png",revision:"17a7084f16c85847f17977f594679ced"},{url:"/images/adjust.png",revision:"5211a7519534ca172844a42bce17465a"},{url:"/images/adjustw.png",revision:"cdde1aad7bebb72f4badb0789f7e6e27"},{url:"/images/bg.png",revision:"d59230ecd8a56fd3d09d20a5f367cfbf"},{url:"/images/cloud1.png",revision:"36648f073e8cce0a55e579fd550e5d84"},{url:"/images/cloud2.png",revision:"972cec38053ef477ffad876d5fcd423c"},{url:"/images/cloud3.png",revision:"9815b2f8a56546d759ff529c2ed0df13"},{url:"/images/core.png",revision:"aa45ef82e9a55762a3a4c70fa2e703fa"},{url:"/images/extract.png",revision:"300f35767658e1c01700daf62ebad59f"},{url:"/images/ig.png",revision:"ad3e83bda02be12d20e80665a2d35d0d"},{url:"/images/loading.gif",revision:"bac61c8d9306edae5b74e399d1485ad3"},{url:"/images/logo-t.png",revision:"d5ca78535960c4937278993900a53423"},{url:"/images/logo.png",revision:"9cde4940e517fbafd74784802b462e5b"},{url:"/images/logo/lam.png",revision:"31d23d6bb5b90b53b6b6c3b03d7cc598"},{url:"/images/logo/ros.png",revision:"145618df97c1ecb76a6ef3d349248e0c"},{url:"/images/logo/tuk.png",revision:"f0ef8c133b136488c44fbee1c27aba25"},{url:"/images/logo/vee.png",revision:"752e6df9e64b8554669ecbc95bb0cde4"},{url:"/images/logo/woo.png",revision:"e40cf597740cf29d2cab57b3720a4c26"},{url:"/images/logo2.png",revision:"97bc09c6257714ce55faa41bc2da88b5"},{url:"/images/notif.png",revision:"bd85e30b2bf85bc83b9189b47bbac828"},{url:"/images/person.png",revision:"686018c95d96501c6f78256e85c6fed3"},{url:"/images/phi1t.png",revision:"c45c717d505a6a26c87ee68a8b47e5b6"},{url:"/images/scales.png",revision:"9878c309208f0879891bec07e1d728b2"},{url:"/images/setting.png",revision:"8a4a4a0bc0dc99c74dfb06ab82183f1c"},{url:"/images/smile.gif",revision:"82896dd0e700e257a4d6a0002663a806"},{url:"/images/task.png",revision:"d7b1ada9aacebb1c1b32b4a17976a39e"},{url:"/images/test.gif",revision:"d3869163799f9c6055a3a6c96ace08ee"},{url:"/images/timer.png",revision:"c3122960ecb8cada6c9f5970fc85e750"},{url:"/images/tuk.png",revision:"e209dfe18a1e168cd56f8cf85ca4a800"},{url:"/manifest.json",revision:"8c6744a64965df82f708eb8d04bc1b22"},{url:"/mstile-150x150.png",revision:"078e558a0511af65e96a21bfe3dad74c"},{url:"/offline",revision:"HocLuybuPOLcUC6NGe9sI"},{url:"/safari-pinned-tab.svg",revision:"d7f01631a8bb713216ac118b4fd19730"},{url:"/site.webmanifest",revision:"ff21f16e80257e0b9256bd0eee876b87"},{url:"/swe-worker-5c72df51bb1f6ee0.js",revision:"5a47d90db13bb1309b25bdf7b363570e"}],{ignoreURLParametersMatching:[/^utm_/,/^fbclid$/]}),e.cleanupOutdatedCaches(),e.registerRoute("/",new e.NetworkFirst({cacheName:"start-url",plugins:[{cacheWillUpdate:async({response:e})=>e&&"opaqueredirect"===e.type?new Response(e.body,{status:200,statusText:"OK",headers:e.headers}):e},{handlerDidError:async({request:e})=>"undefined"!=typeof self?self.fallback(e):Response.error()}]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:gstatic)\.com\/.*/i,new e.CacheFirst({cacheName:"google-fonts-webfonts",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:31536e3}),{handlerDidError:async({request:e})=>"undefined"!=typeof self?self.fallback(e):Response.error()}]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:googleapis)\.com\/.*/i,new e.StaleWhileRevalidate({cacheName:"google-fonts-stylesheets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800}),{handlerDidError:async({request:e})=>"undefined"!=typeof self?self.fallback(e):Response.error()}]}),"GET"),e.registerRoute(/\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,new e.StaleWhileRevalidate({cacheName:"static-font-assets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800}),{handlerDidError:async({request:e})=>"undefined"!=typeof self?self.fallback(e):Response.error()}]}),"GET"),e.registerRoute(/\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,new e.StaleWhileRevalidate({cacheName:"static-image-assets",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:2592e3}),{handlerDidError:async({request:e})=>"undefined"!=typeof self?self.fallback(e):Response.error()}]}),"GET"),e.registerRoute(/\/_next\/static.+\.js$/i,new e.CacheFirst({cacheName:"next-static-js-assets",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400}),{handlerDidError:async({request:e})=>"undefined"!=typeof self?self.fallback(e):Response.error()}]}),"GET"),e.registerRoute(/\/_next\/image\?url=.+$/i,new e.StaleWhileRevalidate({cacheName:"next-image",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400}),{handlerDidError:async({request:e})=>"undefined"!=typeof self?self.fallback(e):Response.error()}]}),"GET"),e.registerRoute(/\.(?:mp3|wav|ogg)$/i,new e.CacheFirst({cacheName:"static-audio-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400}),{handlerDidError:async({request:e})=>"undefined"!=typeof self?self.fallback(e):Response.error()}]}),"GET"),e.registerRoute(/\.(?:mp4|webm)$/i,new e.CacheFirst({cacheName:"static-video-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400}),{handlerDidError:async({request:e})=>"undefined"!=typeof self?self.fallback(e):Response.error()}]}),"GET"),e.registerRoute(/\.(?:js)$/i,new e.StaleWhileRevalidate({cacheName:"static-js-assets",plugins:[new e.ExpirationPlugin({maxEntries:48,maxAgeSeconds:86400}),{handlerDidError:async({request:e})=>"undefined"!=typeof self?self.fallback(e):Response.error()}]}),"GET"),e.registerRoute(/\.(?:css|less)$/i,new e.StaleWhileRevalidate({cacheName:"static-style-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400}),{handlerDidError:async({request:e})=>"undefined"!=typeof self?self.fallback(e):Response.error()}]}),"GET"),e.registerRoute(/\/_next\/data\/.+\/.+\.json$/i,new e.StaleWhileRevalidate({cacheName:"next-data",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400}),{handlerDidError:async({request:e})=>"undefined"!=typeof self?self.fallback(e):Response.error()}]}),"GET"),e.registerRoute(/\.(?:json|xml|csv)$/i,new e.NetworkFirst({cacheName:"static-data-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400}),{handlerDidError:async({request:e})=>"undefined"!=typeof self?self.fallback(e):Response.error()}]}),"GET"),e.registerRoute((({sameOrigin:e,url:{pathname:a}})=>!(!e||a.startsWith("/api/auth/callback")||!a.startsWith("/api/"))),new e.NetworkFirst({cacheName:"apis",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:16,maxAgeSeconds:86400}),{handlerDidError:async({request:e})=>"undefined"!=typeof self?self.fallback(e):Response.error()}]}),"GET"),e.registerRoute((({request:e,url:{pathname:a},sameOrigin:s})=>"1"===e.headers.get("RSC")&&"1"===e.headers.get("Next-Router-Prefetch")&&s&&!a.startsWith("/api/")),new e.NetworkFirst({cacheName:"pages-rsc-prefetch",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400}),{handlerDidError:async({request:e})=>"undefined"!=typeof self?self.fallback(e):Response.error()}]}),"GET"),e.registerRoute((({request:e,url:{pathname:a},sameOrigin:s})=>"1"===e.headers.get("RSC")&&s&&!a.startsWith("/api/")),new e.NetworkFirst({cacheName:"pages-rsc",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400}),{handlerDidError:async({request:e})=>"undefined"!=typeof self?self.fallback(e):Response.error()}]}),"GET"),e.registerRoute((({url:{pathname:e},sameOrigin:a})=>a&&!e.startsWith("/api/")),new e.NetworkFirst({cacheName:"pages",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400}),{handlerDidError:async({request:e})=>"undefined"!=typeof self?self.fallback(e):Response.error()}]}),"GET"),e.registerRoute((({sameOrigin:e})=>!e),new e.NetworkFirst({cacheName:"cross-origin",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:3600}),{handlerDidError:async({request:e})=>"undefined"!=typeof self?self.fallback(e):Response.error()}]}),"GET"),self.__WB_DISABLE_DEV_LOGS=!0}));
diff --git a/public/sw.js.map b/public/sw.js.map
deleted file mode 100644
index b6dccf4..0000000
--- a/public/sw.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"sw.js","sources":["C:/Users/jp/AppData/Local/Temp/680d688e80e3705a94c77be1b6647b9a/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from 'Y:/projects/brizco/node_modules/workbox-routing/registerRoute.mjs';\nimport {NetworkFirst as workbox_strategies_NetworkFirst} from 'Y:/projects/brizco/node_modules/workbox-strategies/NetworkFirst.mjs';\nimport {NetworkOnly as workbox_strategies_NetworkOnly} from 'Y:/projects/brizco/node_modules/workbox-strategies/NetworkOnly.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from 'Y:/projects/brizco/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from 'Y:/projects/brizco/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {cleanupOutdatedCaches as workbox_precaching_cleanupOutdatedCaches} from 'Y:/projects/brizco/node_modules/workbox-precaching/cleanupOutdatedCaches.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\nimportScripts(\n \"/fallback-development.js\"\n);\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"/offline\",\n \"revision\": \"development\"\n }\n], {\n \"ignoreURLParametersMatching\": [/^utm_/, /^fbclid$/, /ts/]\n});\nworkbox_precaching_cleanupOutdatedCaches();\n\n\n\nworkbox_routing_registerRoute(\"/\", new workbox_strategies_NetworkFirst({ \"cacheName\":\"start-url\", plugins: [{ cacheWillUpdate: async ({ response: e })=>e && \"opaqueredirect\" === e.type ? new Response(e.body, { status: 200, statusText: \"OK\", headers: e.headers }) : e }, { handlerDidError: async ({ request: e })=>\"undefined\" != typeof self ? self.fallback(e) : Response.error() }] }), 'GET');\nworkbox_routing_registerRoute(/.*/i, new workbox_strategies_NetworkOnly({ \"cacheName\":\"dev\", plugins: [{ handlerDidError: async ({ request: e })=>\"undefined\" != typeof self ? self.fallback(e) : Response.error() }] }), 'GET');\n\n\n\n\nself.__WB_DISABLE_DEV_LOGS = true;"],"names":["importScripts","self","skipWaiting","workbox_core_clientsClaim","workbox_precaching_precacheAndRoute","workbox_precaching_cleanupOutdatedCaches","workbox_routing_registerRoute","workbox_strategies_NetworkFirst","plugins","cacheWillUpdate","response","e","type","Response","body","status","statusText","headers","handlerDidError","request","fallback","error","workbox_strategies_NetworkOnly","__WB_DISABLE_DEV_LOGS"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkBAA,CAAa,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CACX,CACF,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAC,CAAA;EAQDC,CAAI,CAAA,CAAA,CAAA,CAACC,CAAW,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAE,CAAA;AAElBC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAyB,EAAE,CAAA;;AAG3B,CAAA,CAAA,CAAA,CAAA,CAAA;AACA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;AACA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;AACA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;AACA,CAAA,CAAA,CAAA,CAAA,CAAA;AACAC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAmC,CAAC,CAClC,CAAA;EACE,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAK,EAAE,CAAU,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;EACjB,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAU,EAAE,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;AACd,CAAA,CAAA,CAAC,CACF,CAAE,CAAA,CAAA;EACD,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAA6B,EAAE,CAAC,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAO,EAAE,CAAU,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAE,IAAI,CAAA;AAC3D,CAAA,CAAA,CAAC,CAAC,CAAA;AACFC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAwC,EAAE,CAAA;AAI1CC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAA6B,CAAC,CAAA,CAAA,CAAG,CAAE,CAAA,CAAA,CAAA,CAAA,CAAIC,oBAA+B,CAAC,CAAA;EAAE,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAW,EAAC,CAAW,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;EAAEC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAO,EAAE,CAAC,CAAA;GAAEC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAe,EAAE,CAAO,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;EAAEC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAQ,EAAEC,CAAAA;AAAE,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAC,CAAGA,CAAAA,CAAAA,CAAAA,CAAAA,CAAC,CAAI,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAgB,KAAKA,CAAC,CAACC,CAAI,CAAA,CAAA,CAAA,CAAA,CAAA,CAAG,IAAIC,CAAQ,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAACF,CAAC,CAACG,IAAI,CAAE,CAAA,CAAA;EAAEC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAM,EAAE,CAAG,CAAA,CAAA,CAAA;EAAEC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAU,EAAE,CAAI,CAAA,CAAA,CAAA,CAAA;QAAEC,CAAO,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAEN,CAAC,CAACM,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA;EAAQ,CAAC,CAAA,CAAA,CAAA,CAAA,CAAC,GAAGN,CAAAA;AAAE,CAAA,CAAA,CAAA,CAAA,CAAC,CAAE,CAAA,CAAA;GAAEO,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAe,EAAE,CAAO,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;EAAEC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAO,EAAER,CAAAA;AAAE,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAC,KAAG,CAAW,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAI,CAAOV,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAI,GAAGA,CAAI,CAAA,CAAA,CAAA,CAACmB,CAAQ,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAACT,CAAC,CAAC,CAAA,CAAA,CAAGE,CAAQ,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAACQ,KAAK,CAAC,CAAA;KAAG,CAAA;AAAE,CAAA,CAAA,CAAC,CAAC,CAAA,CAAE,CAAK,CAAA,CAAA,CAAA,CAAA,CAAC,CAAA;AACvYf,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAA6B,CAAC,CAAA,CAAA,CAAA,CAAA,CAAK,CAAE,CAAA,CAAA,CAAA,CAAA,CAAIgB,mBAA8B,CAAC,CAAA;EAAE,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAW,EAAC,CAAK,CAAA,CAAA,CAAA,CAAA,CAAA;EAAEd,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAO,EAAE,CAAC,CAAA;GAAEU,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAe,EAAE,CAAO,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;EAAEC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAO,EAAER,CAAAA;AAAE,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAC,KAAG,CAAW,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAI,CAAOV,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAI,GAAGA,CAAI,CAAA,CAAA,CAAA,CAACmB,CAAQ,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAACT,CAAC,CAAC,CAAA,CAAA,CAAGE,CAAQ,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAACQ,KAAK,CAAC,CAAA;KAAG,CAAA;AAAE,CAAA,CAAA,CAAC,CAAC,CAAA,CAAE,CAAK,CAAA,CAAA,CAAA,CAAA,CAAC,CAAA;EAKhOpB,CAAI,CAAA,CAAA,CAAA,CAACsB,CAAqB,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAG,CAAI,CAAA,CAAA,CAAA,CAAA;;"}
\ No newline at end of file
diff --git a/public/swe-worker-5c72df51bb1f6ee0.js b/public/swe-worker-5c72df51bb1f6ee0.js
new file mode 100644
index 0000000..36e6e59
--- /dev/null
+++ b/public/swe-worker-5c72df51bb1f6ee0.js
@@ -0,0 +1 @@
+self.onmessage=async e=>{switch(e.data.type){case"__START_URL_CACHE__":{let t=e.data.url,a=await fetch(t);if(!a.redirected)return(await caches.open("start-url")).put(t,a);return Promise.resolve()}case"__FRONTEND_NAV_CACHE__":{let t=e.data.url,a=await caches.open("pages");if(await a.match(t,{ignoreSearch:!0}))return;let s=await fetch(t);if(!s.ok)return;if(a.put(t,s.clone()),e.data.shouldCacheAggressively&&s.headers.get("Content-Type")?.includes("text/html"))try{let e=await s.text(),t=[],a=await caches.open("static-style-assets"),r=await caches.open("next-static-js-assets"),c=await caches.open("static-js-assets");for(let[s,r]of e.matchAll(//g))/rel=['"]stylesheet['"]/.test(s)&&t.push(a.match(r).then(e=>e?Promise.resolve():a.add(r)));for(let[,a]of e.matchAll(//g)){let e=/\/_next\/static.+\.js$/i.test(a)?r:c;t.push(e.match(a).then(t=>t?Promise.resolve():e.add(a)))}return await Promise.all(t)}catch{}return Promise.resolve()}default:return Promise.resolve()}};
\ No newline at end of file
diff --git a/public/swe-worker-development.js b/public/swe-worker-development.js
deleted file mode 100644
index d8ae94f..0000000
--- a/public/swe-worker-development.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * ATTENTION: An "eval-source-map" devtool has been used.
- * This devtool is neither made for production nor for readable output files.
- * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
- * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
- * or disable the default devtool with "devtool: false".
- * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
- */
-/******/ (function() { // webpackBootstrap
-/******/ "use strict";
-/******/ var __webpack_modules__ = ({
-
-/***/ "./node_modules/@ducanh2912/next-pwa/dist/sw-entry-worker.js":
-/*!*******************************************************************!*\
- !*** ./node_modules/@ducanh2912/next-pwa/dist/sw-entry-worker.js ***!
- \*******************************************************************/
-/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
-
-eval(__webpack_require__.ts("__webpack_require__.r(__webpack_exports__);\nself.onmessage = async (e)=>{\n switch(e.data.type){\n case \"__START_URL_CACHE__\":\n {\n let t = e.data.url, a = await fetch(t);\n if (!a.redirected) return (await caches.open(\"start-url\")).put(t, a);\n return Promise.resolve();\n }\n case \"__FRONTEND_NAV_CACHE__\":\n {\n let t = e.data.url, a = await caches.open(\"pages\");\n if (await a.match(t, {\n ignoreSearch: !0\n })) return;\n let s = await fetch(t);\n if (!s.ok) return;\n if (a.put(t, s.clone()), e.data.shouldCacheAggressively && s.headers.get(\"Content-Type\")?.includes(\"text/html\")) try {\n let e = await s.text(), t = [], a = await caches.open(\"static-style-assets\"), r = await caches.open(\"next-static-js-assets\"), c = await caches.open(\"static-js-assets\");\n for (let [s, r] of e.matchAll(//g))/rel=['\"]stylesheet['\"]/.test(s) && t.push(a.match(r).then((e)=>e ? Promise.resolve() : a.add(r)));\n for (let [, a] of e.matchAll(//g)){\n let e = /\\/_next\\/static.+\\.js$/i.test(a) ? r : c;\n t.push(e.match(a).then((t)=>t ? Promise.resolve() : e.add(a)));\n }\n return await Promise.all(t);\n } catch {}\n return Promise.resolve();\n }\n default:\n return Promise.resolve();\n }\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvQGR1Y2FuaDI5MTIvbmV4dC1wd2EvZGlzdC9zdy1lbnRyeS13b3JrZXIuanMiLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL19OX0UvLi9ub2RlX21vZHVsZXMvQGR1Y2FuaDI5MTIvbmV4dC1wd2EvZGlzdC9zdy1lbnRyeS13b3JrZXIuanM/NmM4NCJdLCJzb3VyY2VzQ29udGVudCI6WyJzZWxmLm9ubWVzc2FnZSA9IGFzeW5jIChlKT0+e1xuICAgIHN3aXRjaChlLmRhdGEudHlwZSl7XG4gICAgICAgIGNhc2UgXCJfX1NUQVJUX1VSTF9DQUNIRV9fXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbGV0IHQgPSBlLmRhdGEudXJsLCBhID0gYXdhaXQgZmV0Y2godCk7XG4gICAgICAgICAgICAgICAgaWYgKCFhLnJlZGlyZWN0ZWQpIHJldHVybiAoYXdhaXQgY2FjaGVzLm9wZW4oXCJzdGFydC11cmxcIikpLnB1dCh0LCBhKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJfX0ZST05URU5EX05BVl9DQUNIRV9fXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbGV0IHQgPSBlLmRhdGEudXJsLCBhID0gYXdhaXQgY2FjaGVzLm9wZW4oXCJwYWdlc1wiKTtcbiAgICAgICAgICAgICAgICBpZiAoYXdhaXQgYS5tYXRjaCh0LCB7XG4gICAgICAgICAgICAgICAgICAgIGlnbm9yZVNlYXJjaDogITBcbiAgICAgICAgICAgICAgICB9KSkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIGxldCBzID0gYXdhaXQgZmV0Y2godCk7XG4gICAgICAgICAgICAgICAgaWYgKCFzLm9rKSByZXR1cm47XG4gICAgICAgICAgICAgICAgaWYgKGEucHV0KHQsIHMuY2xvbmUoKSksIGUuZGF0YS5zaG91bGRDYWNoZUFnZ3Jlc3NpdmVseSAmJiBzLmhlYWRlcnMuZ2V0KFwiQ29udGVudC1UeXBlXCIpPy5pbmNsdWRlcyhcInRleHQvaHRtbFwiKSkgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGUgPSBhd2FpdCBzLnRleHQoKSwgdCA9IFtdLCBhID0gYXdhaXQgY2FjaGVzLm9wZW4oXCJzdGF0aWMtc3R5bGUtYXNzZXRzXCIpLCByID0gYXdhaXQgY2FjaGVzLm9wZW4oXCJuZXh0LXN0YXRpYy1qcy1hc3NldHNcIiksIGMgPSBhd2FpdCBjYWNoZXMub3BlbihcInN0YXRpYy1qcy1hc3NldHNcIik7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IFtzLCByXSBvZiBlLm1hdGNoQWxsKC88bGluay4qP2hyZWY9WydcIl0oLio/KVsnXCJdLio/Pi9nKSkvcmVsPVsnXCJdc3R5bGVzaGVldFsnXCJdLy50ZXN0KHMpICYmIHQucHVzaChhLm1hdGNoKHIpLnRoZW4oKGUpPT5lID8gUHJvbWlzZS5yZXNvbHZlKCkgOiBhLmFkZChyKSkpO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBbLCBhXSBvZiBlLm1hdGNoQWxsKC88c2NyaXB0Lio/c3JjPVsnXCJdKC4qPylbJ1wiXS4qPz4vZykpe1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGUgPSAvXFwvX25leHRcXC9zdGF0aWMuK1xcLmpzJC9pLnRlc3QoYSkgPyByIDogYztcbiAgICAgICAgICAgICAgICAgICAgICAgIHQucHVzaChlLm1hdGNoKGEpLnRoZW4oKHQpPT50ID8gUHJvbWlzZS5yZXNvbHZlKCkgOiBlLmFkZChhKSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhd2FpdCBQcm9taXNlLmFsbCh0KTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoICB7fVxuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG59OyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/@ducanh2912/next-pwa/dist/sw-entry-worker.js\n"));
-
-/***/ })
-
-/******/ });
-/************************************************************************/
-/******/ // The require scope
-/******/ var __webpack_require__ = {};
-/******/
-/************************************************************************/
-/******/ /* webpack/runtime/make namespace object */
-/******/ !function() {
-/******/ // define __esModule on exports
-/******/ __webpack_require__.r = function(exports) {
-/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
-/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
-/******/ }
-/******/ Object.defineProperty(exports, '__esModule', { value: true });
-/******/ };
-/******/ }();
-/******/
-/******/ /* webpack/runtime/trusted types policy */
-/******/ !function() {
-/******/ var policy;
-/******/ __webpack_require__.tt = function() {
-/******/ // Create Trusted Type policy if Trusted Types are available and the policy doesn't exist yet.
-/******/ if (policy === undefined) {
-/******/ policy = {
-/******/ createScript: function(script) { return script; }
-/******/ };
-/******/ if (typeof trustedTypes !== "undefined" && trustedTypes.createPolicy) {
-/******/ policy = trustedTypes.createPolicy("nextjs#bundler", policy);
-/******/ }
-/******/ }
-/******/ return policy;
-/******/ };
-/******/ }();
-/******/
-/******/ /* webpack/runtime/trusted types script */
-/******/ !function() {
-/******/ __webpack_require__.ts = function(script) { return __webpack_require__.tt().createScript(script); };
-/******/ }();
-/******/
-/******/ /* webpack/runtime/react refresh */
-/******/ !function() {
-/******/ if (__webpack_require__.i) {
-/******/ __webpack_require__.i.push(function(options) {
-/******/ var originalFactory = options.factory;
-/******/ options.factory = function(moduleObject, moduleExports, webpackRequire) {
-/******/ var hasRefresh = typeof self !== "undefined" && !!self.$RefreshInterceptModuleExecution$;
-/******/ var cleanup = hasRefresh ? self.$RefreshInterceptModuleExecution$(moduleObject.id) : function() {};
-/******/ try {
-/******/ originalFactory.call(this, moduleObject, moduleExports, webpackRequire);
-/******/ } finally {
-/******/ cleanup();
-/******/ }
-/******/ }
-/******/ })
-/******/ }
-/******/ }();
-/******/
-/******/ /* webpack/runtime/compat */
-/******/
-/******/
-/******/ // noop fns to prevent runtime errors during initialization
-/******/ if (typeof self !== "undefined") {
-/******/ self.$RefreshReg$ = function () {};
-/******/ self.$RefreshSig$ = function () {
-/******/ return function (type) {
-/******/ return type;
-/******/ };
-/******/ };
-/******/ }
-/******/
-/************************************************************************/
-/******/
-/******/ // startup
-/******/ // Load entry module and return exports
-/******/ // This entry module can't be inlined because the eval-source-map devtool is used.
-/******/ var __webpack_exports__ = {};
-/******/ __webpack_modules__["./node_modules/@ducanh2912/next-pwa/dist/sw-entry-worker.js"](0, __webpack_exports__, __webpack_require__);
-/******/
-/******/ })()
-;
\ No newline at end of file
diff --git a/public/workbox-1e54d6fe.js b/public/workbox-1e54d6fe.js
deleted file mode 100644
index 876a7ee..0000000
--- a/public/workbox-1e54d6fe.js
+++ /dev/null
@@ -1,3593 +0,0 @@
-define(['exports'], (function (exports) { 'use strict';
-
- // @ts-ignore
- try {
- self['workbox:core:7.0.0'] && _();
- } catch (e) {}
-
- /*
- Copyright 2019 Google LLC
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- const logger = (() => {
- // Don't overwrite this value if it's already set.
- // See https://github.com/GoogleChrome/workbox/pull/2284#issuecomment-560470923
- if (!('__WB_DISABLE_DEV_LOGS' in globalThis)) {
- self.__WB_DISABLE_DEV_LOGS = false;
- }
- let inGroup = false;
- const methodToColorMap = {
- debug: `#7f8c8d`,
- log: `#2ecc71`,
- warn: `#f39c12`,
- error: `#c0392b`,
- groupCollapsed: `#3498db`,
- groupEnd: null // No colored prefix on groupEnd
- };
- const print = function (method, args) {
- if (self.__WB_DISABLE_DEV_LOGS) {
- return;
- }
- if (method === 'groupCollapsed') {
- // Safari doesn't print all console.groupCollapsed() arguments:
- // https://bugs.webkit.org/show_bug.cgi?id=182754
- if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {
- console[method](...args);
- return;
- }
- }
- const styles = [`background: ${methodToColorMap[method]}`, `border-radius: 0.5em`, `color: white`, `font-weight: bold`, `padding: 2px 0.5em`];
- // When in a group, the workbox prefix is not displayed.
- const logPrefix = inGroup ? [] : ['%cworkbox', styles.join(';')];
- console[method](...logPrefix, ...args);
- if (method === 'groupCollapsed') {
- inGroup = true;
- }
- if (method === 'groupEnd') {
- inGroup = false;
- }
- };
- // eslint-disable-next-line @typescript-eslint/ban-types
- const api = {};
- const loggerMethods = Object.keys(methodToColorMap);
- for (const key of loggerMethods) {
- const method = key;
- api[method] = (...args) => {
- print(method, args);
- };
- }
- return api;
- })();
-
- /*
- Copyright 2018 Google LLC
-
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- const messages$1 = {
- 'invalid-value': ({
- paramName,
- validValueDescription,
- value
- }) => {
- if (!paramName || !validValueDescription) {
- throw new Error(`Unexpected input to 'invalid-value' error.`);
- }
- return `The '${paramName}' parameter was given a value with an ` + `unexpected value. ${validValueDescription} Received a value of ` + `${JSON.stringify(value)}.`;
- },
- 'not-an-array': ({
- moduleName,
- className,
- funcName,
- paramName
- }) => {
- if (!moduleName || !className || !funcName || !paramName) {
- throw new Error(`Unexpected input to 'not-an-array' error.`);
- }
- return `The parameter '${paramName}' passed into ` + `'${moduleName}.${className}.${funcName}()' must be an array.`;
- },
- 'incorrect-type': ({
- expectedType,
- paramName,
- moduleName,
- className,
- funcName
- }) => {
- if (!expectedType || !paramName || !moduleName || !funcName) {
- throw new Error(`Unexpected input to 'incorrect-type' error.`);
- }
- const classNameStr = className ? `${className}.` : '';
- return `The parameter '${paramName}' passed into ` + `'${moduleName}.${classNameStr}` + `${funcName}()' must be of type ${expectedType}.`;
- },
- 'incorrect-class': ({
- expectedClassName,
- paramName,
- moduleName,
- className,
- funcName,
- isReturnValueProblem
- }) => {
- if (!expectedClassName || !moduleName || !funcName) {
- throw new Error(`Unexpected input to 'incorrect-class' error.`);
- }
- const classNameStr = className ? `${className}.` : '';
- if (isReturnValueProblem) {
- return `The return value from ` + `'${moduleName}.${classNameStr}${funcName}()' ` + `must be an instance of class ${expectedClassName}.`;
- }
- return `The parameter '${paramName}' passed into ` + `'${moduleName}.${classNameStr}${funcName}()' ` + `must be an instance of class ${expectedClassName}.`;
- },
- 'missing-a-method': ({
- expectedMethod,
- paramName,
- moduleName,
- className,
- funcName
- }) => {
- if (!expectedMethod || !paramName || !moduleName || !className || !funcName) {
- throw new Error(`Unexpected input to 'missing-a-method' error.`);
- }
- return `${moduleName}.${className}.${funcName}() expected the ` + `'${paramName}' parameter to expose a '${expectedMethod}' method.`;
- },
- 'add-to-cache-list-unexpected-type': ({
- entry
- }) => {
- return `An unexpected entry was passed to ` + `'workbox-precaching.PrecacheController.addToCacheList()' The entry ` + `'${JSON.stringify(entry)}' isn't supported. You must supply an array of ` + `strings with one or more characters, objects with a url property or ` + `Request objects.`;
- },
- 'add-to-cache-list-conflicting-entries': ({
- firstEntry,
- secondEntry
- }) => {
- if (!firstEntry || !secondEntry) {
- throw new Error(`Unexpected input to ` + `'add-to-cache-list-duplicate-entries' error.`);
- }
- return `Two of the entries passed to ` + `'workbox-precaching.PrecacheController.addToCacheList()' had the URL ` + `${firstEntry} but different revision details. Workbox is ` + `unable to cache and version the asset correctly. Please remove one ` + `of the entries.`;
- },
- 'plugin-error-request-will-fetch': ({
- thrownErrorMessage
- }) => {
- if (!thrownErrorMessage) {
- throw new Error(`Unexpected input to ` + `'plugin-error-request-will-fetch', error.`);
- }
- return `An error was thrown by a plugins 'requestWillFetch()' method. ` + `The thrown error message was: '${thrownErrorMessage}'.`;
- },
- 'invalid-cache-name': ({
- cacheNameId,
- value
- }) => {
- if (!cacheNameId) {
- throw new Error(`Expected a 'cacheNameId' for error 'invalid-cache-name'`);
- }
- return `You must provide a name containing at least one character for ` + `setCacheDetails({${cacheNameId}: '...'}). Received a value of ` + `'${JSON.stringify(value)}'`;
- },
- 'unregister-route-but-not-found-with-method': ({
- method
- }) => {
- if (!method) {
- throw new Error(`Unexpected input to ` + `'unregister-route-but-not-found-with-method' error.`);
- }
- return `The route you're trying to unregister was not previously ` + `registered for the method type '${method}'.`;
- },
- 'unregister-route-route-not-registered': () => {
- return `The route you're trying to unregister was not previously ` + `registered.`;
- },
- 'queue-replay-failed': ({
- name
- }) => {
- return `Replaying the background sync queue '${name}' failed.`;
- },
- 'duplicate-queue-name': ({
- name
- }) => {
- return `The Queue name '${name}' is already being used. ` + `All instances of backgroundSync.Queue must be given unique names.`;
- },
- 'expired-test-without-max-age': ({
- methodName,
- paramName
- }) => {
- return `The '${methodName}()' method can only be used when the ` + `'${paramName}' is used in the constructor.`;
- },
- 'unsupported-route-type': ({
- moduleName,
- className,
- funcName,
- paramName
- }) => {
- return `The supplied '${paramName}' parameter was an unsupported type. ` + `Please check the docs for ${moduleName}.${className}.${funcName} for ` + `valid input types.`;
- },
- 'not-array-of-class': ({
- value,
- expectedClass,
- moduleName,
- className,
- funcName,
- paramName
- }) => {
- return `The supplied '${paramName}' parameter must be an array of ` + `'${expectedClass}' objects. Received '${JSON.stringify(value)},'. ` + `Please check the call to ${moduleName}.${className}.${funcName}() ` + `to fix the issue.`;
- },
- 'max-entries-or-age-required': ({
- moduleName,
- className,
- funcName
- }) => {
- return `You must define either config.maxEntries or config.maxAgeSeconds` + `in ${moduleName}.${className}.${funcName}`;
- },
- 'statuses-or-headers-required': ({
- moduleName,
- className,
- funcName
- }) => {
- return `You must define either config.statuses or config.headers` + `in ${moduleName}.${className}.${funcName}`;
- },
- 'invalid-string': ({
- moduleName,
- funcName,
- paramName
- }) => {
- if (!paramName || !moduleName || !funcName) {
- throw new Error(`Unexpected input to 'invalid-string' error.`);
- }
- return `When using strings, the '${paramName}' parameter must start with ` + `'http' (for cross-origin matches) or '/' (for same-origin matches). ` + `Please see the docs for ${moduleName}.${funcName}() for ` + `more info.`;
- },
- 'channel-name-required': () => {
- return `You must provide a channelName to construct a ` + `BroadcastCacheUpdate instance.`;
- },
- 'invalid-responses-are-same-args': () => {
- return `The arguments passed into responsesAreSame() appear to be ` + `invalid. Please ensure valid Responses are used.`;
- },
- 'expire-custom-caches-only': () => {
- return `You must provide a 'cacheName' property when using the ` + `expiration plugin with a runtime caching strategy.`;
- },
- 'unit-must-be-bytes': ({
- normalizedRangeHeader
- }) => {
- if (!normalizedRangeHeader) {
- throw new Error(`Unexpected input to 'unit-must-be-bytes' error.`);
- }
- return `The 'unit' portion of the Range header must be set to 'bytes'. ` + `The Range header provided was "${normalizedRangeHeader}"`;
- },
- 'single-range-only': ({
- normalizedRangeHeader
- }) => {
- if (!normalizedRangeHeader) {
- throw new Error(`Unexpected input to 'single-range-only' error.`);
- }
- return `Multiple ranges are not supported. Please use a single start ` + `value, and optional end value. The Range header provided was ` + `"${normalizedRangeHeader}"`;
- },
- 'invalid-range-values': ({
- normalizedRangeHeader
- }) => {
- if (!normalizedRangeHeader) {
- throw new Error(`Unexpected input to 'invalid-range-values' error.`);
- }
- return `The Range header is missing both start and end values. At least ` + `one of those values is needed. The Range header provided was ` + `"${normalizedRangeHeader}"`;
- },
- 'no-range-header': () => {
- return `No Range header was found in the Request provided.`;
- },
- 'range-not-satisfiable': ({
- size,
- start,
- end
- }) => {
- return `The start (${start}) and end (${end}) values in the Range are ` + `not satisfiable by the cached response, which is ${size} bytes.`;
- },
- 'attempt-to-cache-non-get-request': ({
- url,
- method
- }) => {
- return `Unable to cache '${url}' because it is a '${method}' request and ` + `only 'GET' requests can be cached.`;
- },
- 'cache-put-with-no-response': ({
- url
- }) => {
- return `There was an attempt to cache '${url}' but the response was not ` + `defined.`;
- },
- 'no-response': ({
- url,
- error
- }) => {
- let message = `The strategy could not generate a response for '${url}'.`;
- if (error) {
- message += ` The underlying error is ${error}.`;
- }
- return message;
- },
- 'bad-precaching-response': ({
- url,
- status
- }) => {
- return `The precaching request for '${url}' failed` + (status ? ` with an HTTP status of ${status}.` : `.`);
- },
- 'non-precached-url': ({
- url
- }) => {
- return `createHandlerBoundToURL('${url}') was called, but that URL is ` + `not precached. Please pass in a URL that is precached instead.`;
- },
- 'add-to-cache-list-conflicting-integrities': ({
- url
- }) => {
- return `Two of the entries passed to ` + `'workbox-precaching.PrecacheController.addToCacheList()' had the URL ` + `${url} with different integrity values. Please remove one of them.`;
- },
- 'missing-precache-entry': ({
- cacheName,
- url
- }) => {
- return `Unable to find a precached response in ${cacheName} for ${url}.`;
- },
- 'cross-origin-copy-response': ({
- origin
- }) => {
- return `workbox-core.copyResponse() can only be used with same-origin ` + `responses. It was passed a response with origin ${origin}.`;
- },
- 'opaque-streams-source': ({
- type
- }) => {
- const message = `One of the workbox-streams sources resulted in an ` + `'${type}' response.`;
- if (type === 'opaqueredirect') {
- return `${message} Please do not use a navigation request that results ` + `in a redirect as a source.`;
- }
- return `${message} Please ensure your sources are CORS-enabled.`;
- }
- };
-
- /*
- Copyright 2018 Google LLC
-
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- const generatorFunction = (code, details = {}) => {
- const message = messages$1[code];
- if (!message) {
- throw new Error(`Unable to find message for code '${code}'.`);
- }
- return message(details);
- };
- const messageGenerator = generatorFunction;
-
- /*
- Copyright 2018 Google LLC
-
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- /**
- * Workbox errors should be thrown with this class.
- * This allows use to ensure the type easily in tests,
- * helps developers identify errors from workbox
- * easily and allows use to optimise error
- * messages correctly.
- *
- * @private
- */
- class WorkboxError extends Error {
- /**
- *
- * @param {string} errorCode The error code that
- * identifies this particular error.
- * @param {Object=} details Any relevant arguments
- * that will help developers identify issues should
- * be added as a key on the context object.
- */
- constructor(errorCode, details) {
- const message = messageGenerator(errorCode, details);
- super(message);
- this.name = errorCode;
- this.details = details;
- }
- }
-
- /*
- Copyright 2018 Google LLC
-
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- /*
- * This method throws if the supplied value is not an array.
- * The destructed values are required to produce a meaningful error for users.
- * The destructed and restructured object is so it's clear what is
- * needed.
- */
- const isArray = (value, details) => {
- if (!Array.isArray(value)) {
- throw new WorkboxError('not-an-array', details);
- }
- };
- const hasMethod = (object, expectedMethod, details) => {
- const type = typeof object[expectedMethod];
- if (type !== 'function') {
- details['expectedMethod'] = expectedMethod;
- throw new WorkboxError('missing-a-method', details);
- }
- };
- const isType = (object, expectedType, details) => {
- if (typeof object !== expectedType) {
- details['expectedType'] = expectedType;
- throw new WorkboxError('incorrect-type', details);
- }
- };
- const isInstance = (object,
- // Need the general type to do the check later.
- // eslint-disable-next-line @typescript-eslint/ban-types
- expectedClass, details) => {
- if (!(object instanceof expectedClass)) {
- details['expectedClassName'] = expectedClass.name;
- throw new WorkboxError('incorrect-class', details);
- }
- };
- const isOneOf = (value, validValues, details) => {
- if (!validValues.includes(value)) {
- details['validValueDescription'] = `Valid values are ${JSON.stringify(validValues)}.`;
- throw new WorkboxError('invalid-value', details);
- }
- };
- const isArrayOfClass = (value,
- // Need general type to do check later.
- expectedClass,
- // eslint-disable-line
- details) => {
- const error = new WorkboxError('not-array-of-class', details);
- if (!Array.isArray(value)) {
- throw error;
- }
- for (const item of value) {
- if (!(item instanceof expectedClass)) {
- throw error;
- }
- }
- };
- const finalAssertExports = {
- hasMethod,
- isArray,
- isInstance,
- isOneOf,
- isType,
- isArrayOfClass
- };
-
- // @ts-ignore
- try {
- self['workbox:routing:7.0.0'] && _();
- } catch (e) {}
-
- /*
- Copyright 2018 Google LLC
-
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- /**
- * The default HTTP method, 'GET', used when there's no specific method
- * configured for a route.
- *
- * @type {string}
- *
- * @private
- */
- const defaultMethod = 'GET';
- /**
- * The list of valid HTTP methods associated with requests that could be routed.
- *
- * @type {Array}
- *
- * @private
- */
- const validMethods = ['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT'];
-
- /*
- Copyright 2018 Google LLC
-
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- /**
- * @param {function()|Object} handler Either a function, or an object with a
- * 'handle' method.
- * @return {Object} An object with a handle method.
- *
- * @private
- */
- const normalizeHandler = handler => {
- if (handler && typeof handler === 'object') {
- {
- finalAssertExports.hasMethod(handler, 'handle', {
- moduleName: 'workbox-routing',
- className: 'Route',
- funcName: 'constructor',
- paramName: 'handler'
- });
- }
- return handler;
- } else {
- {
- finalAssertExports.isType(handler, 'function', {
- moduleName: 'workbox-routing',
- className: 'Route',
- funcName: 'constructor',
- paramName: 'handler'
- });
- }
- return {
- handle: handler
- };
- }
- };
-
- /*
- Copyright 2018 Google LLC
-
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- /**
- * A `Route` consists of a pair of callback functions, "match" and "handler".
- * The "match" callback determine if a route should be used to "handle" a
- * request by returning a non-falsy value if it can. The "handler" callback
- * is called when there is a match and should return a Promise that resolves
- * to a `Response`.
- *
- * @memberof workbox-routing
- */
- class Route {
- /**
- * Constructor for Route class.
- *
- * @param {workbox-routing~matchCallback} match
- * A callback function that determines whether the route matches a given
- * `fetch` event by returning a non-falsy value.
- * @param {workbox-routing~handlerCallback} handler A callback
- * function that returns a Promise resolving to a Response.
- * @param {string} [method='GET'] The HTTP method to match the Route
- * against.
- */
- constructor(match, handler, method = defaultMethod) {
- {
- finalAssertExports.isType(match, 'function', {
- moduleName: 'workbox-routing',
- className: 'Route',
- funcName: 'constructor',
- paramName: 'match'
- });
- if (method) {
- finalAssertExports.isOneOf(method, validMethods, {
- paramName: 'method'
- });
- }
- }
- // These values are referenced directly by Router so cannot be
- // altered by minificaton.
- this.handler = normalizeHandler(handler);
- this.match = match;
- this.method = method;
- }
- /**
- *
- * @param {workbox-routing-handlerCallback} handler A callback
- * function that returns a Promise resolving to a Response
- */
- setCatchHandler(handler) {
- this.catchHandler = normalizeHandler(handler);
- }
- }
-
- /*
- Copyright 2018 Google LLC
-
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- /**
- * RegExpRoute makes it easy to create a regular expression based
- * {@link workbox-routing.Route}.
- *
- * For same-origin requests the RegExp only needs to match part of the URL. For
- * requests against third-party servers, you must define a RegExp that matches
- * the start of the URL.
- *
- * @memberof workbox-routing
- * @extends workbox-routing.Route
- */
- class RegExpRoute extends Route {
- /**
- * If the regular expression contains
- * [capture groups]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references},
- * the captured values will be passed to the
- * {@link workbox-routing~handlerCallback} `params`
- * argument.
- *
- * @param {RegExp} regExp The regular expression to match against URLs.
- * @param {workbox-routing~handlerCallback} handler A callback
- * function that returns a Promise resulting in a Response.
- * @param {string} [method='GET'] The HTTP method to match the Route
- * against.
- */
- constructor(regExp, handler, method) {
- {
- finalAssertExports.isInstance(regExp, RegExp, {
- moduleName: 'workbox-routing',
- className: 'RegExpRoute',
- funcName: 'constructor',
- paramName: 'pattern'
- });
- }
- const match = ({
- url
- }) => {
- const result = regExp.exec(url.href);
- // Return immediately if there's no match.
- if (!result) {
- return;
- }
- // Require that the match start at the first character in the URL string
- // if it's a cross-origin request.
- // See https://github.com/GoogleChrome/workbox/issues/281 for the context
- // behind this behavior.
- if (url.origin !== location.origin && result.index !== 0) {
- {
- logger.debug(`The regular expression '${regExp.toString()}' only partially matched ` + `against the cross-origin URL '${url.toString()}'. RegExpRoute's will only ` + `handle cross-origin requests if they match the entire URL.`);
- }
- return;
- }
- // If the route matches, but there aren't any capture groups defined, then
- // this will return [], which is truthy and therefore sufficient to
- // indicate a match.
- // If there are capture groups, then it will return their values.
- return result.slice(1);
- };
- super(match, handler, method);
- }
- }
-
- /*
- Copyright 2018 Google LLC
-
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- const getFriendlyURL = url => {
- const urlObj = new URL(String(url), location.href);
- // See https://github.com/GoogleChrome/workbox/issues/2323
- // We want to include everything, except for the origin if it's same-origin.
- return urlObj.href.replace(new RegExp(`^${location.origin}`), '');
- };
-
- /*
- Copyright 2018 Google LLC
-
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- /**
- * The Router can be used to process a `FetchEvent` using one or more
- * {@link workbox-routing.Route}, responding with a `Response` if
- * a matching route exists.
- *
- * If no route matches a given a request, the Router will use a "default"
- * handler if one is defined.
- *
- * Should the matching Route throw an error, the Router will use a "catch"
- * handler if one is defined to gracefully deal with issues and respond with a
- * Request.
- *
- * If a request matches multiple routes, the **earliest** registered route will
- * be used to respond to the request.
- *
- * @memberof workbox-routing
- */
- class Router {
- /**
- * Initializes a new Router.
- */
- constructor() {
- this._routes = new Map();
- this._defaultHandlerMap = new Map();
- }
- /**
- * @return {Map>} routes A `Map` of HTTP
- * method name ('GET', etc.) to an array of all the corresponding `Route`
- * instances that are registered.
- */
- get routes() {
- return this._routes;
- }
- /**
- * Adds a fetch event listener to respond to events when a route matches
- * the event's request.
- */
- addFetchListener() {
- // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705
- self.addEventListener('fetch', event => {
- const {
- request
- } = event;
- const responsePromise = this.handleRequest({
- request,
- event
- });
- if (responsePromise) {
- event.respondWith(responsePromise);
- }
- });
- }
- /**
- * Adds a message event listener for URLs to cache from the window.
- * This is useful to cache resources loaded on the page prior to when the
- * service worker started controlling it.
- *
- * The format of the message data sent from the window should be as follows.
- * Where the `urlsToCache` array may consist of URL strings or an array of
- * URL string + `requestInit` object (the same as you'd pass to `fetch()`).
- *
- * ```
- * {
- * type: 'CACHE_URLS',
- * payload: {
- * urlsToCache: [
- * './script1.js',
- * './script2.js',
- * ['./script3.js', {mode: 'no-cors'}],
- * ],
- * },
- * }
- * ```
- */
- addCacheListener() {
- // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705
- self.addEventListener('message', event => {
- // event.data is type 'any'
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
- if (event.data && event.data.type === 'CACHE_URLS') {
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
- const {
- payload
- } = event.data;
- {
- logger.debug(`Caching URLs from the window`, payload.urlsToCache);
- }
- const requestPromises = Promise.all(payload.urlsToCache.map(entry => {
- if (typeof entry === 'string') {
- entry = [entry];
- }
- const request = new Request(...entry);
- return this.handleRequest({
- request,
- event
- });
- // TODO(philipwalton): TypeScript errors without this typecast for
- // some reason (probably a bug). The real type here should work but
- // doesn't: `Array | undefined>`.
- })); // TypeScript
- event.waitUntil(requestPromises);
- // If a MessageChannel was used, reply to the message on success.
- if (event.ports && event.ports[0]) {
- void requestPromises.then(() => event.ports[0].postMessage(true));
- }
- }
- });
- }
- /**
- * Apply the routing rules to a FetchEvent object to get a Response from an
- * appropriate Route's handler.
- *
- * @param {Object} options
- * @param {Request} options.request The request to handle.
- * @param {ExtendableEvent} options.event The event that triggered the
- * request.
- * @return {Promise|undefined} A promise is returned if a
- * registered route can handle the request. If there is no matching
- * route and there's no `defaultHandler`, `undefined` is returned.
- */
- handleRequest({
- request,
- event
- }) {
- {
- finalAssertExports.isInstance(request, Request, {
- moduleName: 'workbox-routing',
- className: 'Router',
- funcName: 'handleRequest',
- paramName: 'options.request'
- });
- }
- const url = new URL(request.url, location.href);
- if (!url.protocol.startsWith('http')) {
- {
- logger.debug(`Workbox Router only supports URLs that start with 'http'.`);
- }
- return;
- }
- const sameOrigin = url.origin === location.origin;
- const {
- params,
- route
- } = this.findMatchingRoute({
- event,
- request,
- sameOrigin,
- url
- });
- let handler = route && route.handler;
- const debugMessages = [];
- {
- if (handler) {
- debugMessages.push([`Found a route to handle this request:`, route]);
- if (params) {
- debugMessages.push([`Passing the following params to the route's handler:`, params]);
- }
- }
- }
- // If we don't have a handler because there was no matching route, then
- // fall back to defaultHandler if that's defined.
- const method = request.method;
- if (!handler && this._defaultHandlerMap.has(method)) {
- {
- debugMessages.push(`Failed to find a matching route. Falling ` + `back to the default handler for ${method}.`);
- }
- handler = this._defaultHandlerMap.get(method);
- }
- if (!handler) {
- {
- // No handler so Workbox will do nothing. If logs is set of debug
- // i.e. verbose, we should print out this information.
- logger.debug(`No route found for: ${getFriendlyURL(url)}`);
- }
- return;
- }
- {
- // We have a handler, meaning Workbox is going to handle the route.
- // print the routing details to the console.
- logger.groupCollapsed(`Router is responding to: ${getFriendlyURL(url)}`);
- debugMessages.forEach(msg => {
- if (Array.isArray(msg)) {
- logger.log(...msg);
- } else {
- logger.log(msg);
- }
- });
- logger.groupEnd();
- }
- // Wrap in try and catch in case the handle method throws a synchronous
- // error. It should still callback to the catch handler.
- let responsePromise;
- try {
- responsePromise = handler.handle({
- url,
- request,
- event,
- params
- });
- } catch (err) {
- responsePromise = Promise.reject(err);
- }
- // Get route's catch handler, if it exists
- const catchHandler = route && route.catchHandler;
- if (responsePromise instanceof Promise && (this._catchHandler || catchHandler)) {
- responsePromise = responsePromise.catch(async err => {
- // If there's a route catch handler, process that first
- if (catchHandler) {
- {
- // Still include URL here as it will be async from the console group
- // and may not make sense without the URL
- logger.groupCollapsed(`Error thrown when responding to: ` + ` ${getFriendlyURL(url)}. Falling back to route's Catch Handler.`);
- logger.error(`Error thrown by:`, route);
- logger.error(err);
- logger.groupEnd();
- }
- try {
- return await catchHandler.handle({
- url,
- request,
- event,
- params
- });
- } catch (catchErr) {
- if (catchErr instanceof Error) {
- err = catchErr;
- }
- }
- }
- if (this._catchHandler) {
- {
- // Still include URL here as it will be async from the console group
- // and may not make sense without the URL
- logger.groupCollapsed(`Error thrown when responding to: ` + ` ${getFriendlyURL(url)}. Falling back to global Catch Handler.`);
- logger.error(`Error thrown by:`, route);
- logger.error(err);
- logger.groupEnd();
- }
- return this._catchHandler.handle({
- url,
- request,
- event
- });
- }
- throw err;
- });
- }
- return responsePromise;
- }
- /**
- * Checks a request and URL (and optionally an event) against the list of
- * registered routes, and if there's a match, returns the corresponding
- * route along with any params generated by the match.
- *
- * @param {Object} options
- * @param {URL} options.url
- * @param {boolean} options.sameOrigin The result of comparing `url.origin`
- * against the current origin.
- * @param {Request} options.request The request to match.
- * @param {Event} options.event The corresponding event.
- * @return {Object} An object with `route` and `params` properties.
- * They are populated if a matching route was found or `undefined`
- * otherwise.
- */
- findMatchingRoute({
- url,
- sameOrigin,
- request,
- event
- }) {
- const routes = this._routes.get(request.method) || [];
- for (const route of routes) {
- let params;
- // route.match returns type any, not possible to change right now.
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
- const matchResult = route.match({
- url,
- sameOrigin,
- request,
- event
- });
- if (matchResult) {
- {
- // Warn developers that using an async matchCallback is almost always
- // not the right thing to do.
- if (matchResult instanceof Promise) {
- logger.warn(`While routing ${getFriendlyURL(url)}, an async ` + `matchCallback function was used. Please convert the ` + `following route to use a synchronous matchCallback function:`, route);
- }
- }
- // See https://github.com/GoogleChrome/workbox/issues/2079
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
- params = matchResult;
- if (Array.isArray(params) && params.length === 0) {
- // Instead of passing an empty array in as params, use undefined.
- params = undefined;
- } else if (matchResult.constructor === Object &&
- // eslint-disable-line
- Object.keys(matchResult).length === 0) {
- // Instead of passing an empty object in as params, use undefined.
- params = undefined;
- } else if (typeof matchResult === 'boolean') {
- // For the boolean value true (rather than just something truth-y),
- // don't set params.
- // See https://github.com/GoogleChrome/workbox/pull/2134#issuecomment-513924353
- params = undefined;
- }
- // Return early if have a match.
- return {
- route,
- params
- };
- }
- }
- // If no match was found above, return and empty object.
- return {};
- }
- /**
- * Define a default `handler` that's called when no routes explicitly
- * match the incoming request.
- *
- * Each HTTP method ('GET', 'POST', etc.) gets its own default handler.
- *
- * Without a default handler, unmatched requests will go against the
- * network as if there were no service worker present.
- *
- * @param {workbox-routing~handlerCallback} handler A callback
- * function that returns a Promise resulting in a Response.
- * @param {string} [method='GET'] The HTTP method to associate with this
- * default handler. Each method has its own default.
- */
- setDefaultHandler(handler, method = defaultMethod) {
- this._defaultHandlerMap.set(method, normalizeHandler(handler));
- }
- /**
- * If a Route throws an error while handling a request, this `handler`
- * will be called and given a chance to provide a response.
- *
- * @param {workbox-routing~handlerCallback} handler A callback
- * function that returns a Promise resulting in a Response.
- */
- setCatchHandler(handler) {
- this._catchHandler = normalizeHandler(handler);
- }
- /**
- * Registers a route with the router.
- *
- * @param {workbox-routing.Route} route The route to register.
- */
- registerRoute(route) {
- {
- finalAssertExports.isType(route, 'object', {
- moduleName: 'workbox-routing',
- className: 'Router',
- funcName: 'registerRoute',
- paramName: 'route'
- });
- finalAssertExports.hasMethod(route, 'match', {
- moduleName: 'workbox-routing',
- className: 'Router',
- funcName: 'registerRoute',
- paramName: 'route'
- });
- finalAssertExports.isType(route.handler, 'object', {
- moduleName: 'workbox-routing',
- className: 'Router',
- funcName: 'registerRoute',
- paramName: 'route'
- });
- finalAssertExports.hasMethod(route.handler, 'handle', {
- moduleName: 'workbox-routing',
- className: 'Router',
- funcName: 'registerRoute',
- paramName: 'route.handler'
- });
- finalAssertExports.isType(route.method, 'string', {
- moduleName: 'workbox-routing',
- className: 'Router',
- funcName: 'registerRoute',
- paramName: 'route.method'
- });
- }
- if (!this._routes.has(route.method)) {
- this._routes.set(route.method, []);
- }
- // Give precedence to all of the earlier routes by adding this additional
- // route to the end of the array.
- this._routes.get(route.method).push(route);
- }
- /**
- * Unregisters a route with the router.
- *
- * @param {workbox-routing.Route} route The route to unregister.
- */
- unregisterRoute(route) {
- if (!this._routes.has(route.method)) {
- throw new WorkboxError('unregister-route-but-not-found-with-method', {
- method: route.method
- });
- }
- const routeIndex = this._routes.get(route.method).indexOf(route);
- if (routeIndex > -1) {
- this._routes.get(route.method).splice(routeIndex, 1);
- } else {
- throw new WorkboxError('unregister-route-route-not-registered');
- }
- }
- }
-
- /*
- Copyright 2019 Google LLC
-
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- let defaultRouter;
- /**
- * Creates a new, singleton Router instance if one does not exist. If one
- * does already exist, that instance is returned.
- *
- * @private
- * @return {Router}
- */
- const getOrCreateDefaultRouter = () => {
- if (!defaultRouter) {
- defaultRouter = new Router();
- // The helpers that use the default Router assume these listeners exist.
- defaultRouter.addFetchListener();
- defaultRouter.addCacheListener();
- }
- return defaultRouter;
- };
-
- /*
- Copyright 2019 Google LLC
-
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- /**
- * Easily register a RegExp, string, or function with a caching
- * strategy to a singleton Router instance.
- *
- * This method will generate a Route for you if needed and
- * call {@link workbox-routing.Router#registerRoute}.
- *
- * @param {RegExp|string|workbox-routing.Route~matchCallback|workbox-routing.Route} capture
- * If the capture param is a `Route`, all other arguments will be ignored.
- * @param {workbox-routing~handlerCallback} [handler] A callback
- * function that returns a Promise resulting in a Response. This parameter
- * is required if `capture` is not a `Route` object.
- * @param {string} [method='GET'] The HTTP method to match the Route
- * against.
- * @return {workbox-routing.Route} The generated `Route`.
- *
- * @memberof workbox-routing
- */
- function registerRoute(capture, handler, method) {
- let route;
- if (typeof capture === 'string') {
- const captureUrl = new URL(capture, location.href);
- {
- if (!(capture.startsWith('/') || capture.startsWith('http'))) {
- throw new WorkboxError('invalid-string', {
- moduleName: 'workbox-routing',
- funcName: 'registerRoute',
- paramName: 'capture'
- });
- }
- // We want to check if Express-style wildcards are in the pathname only.
- // TODO: Remove this log message in v4.
- const valueToCheck = capture.startsWith('http') ? captureUrl.pathname : capture;
- // See https://github.com/pillarjs/path-to-regexp#parameters
- const wildcards = '[*:?+]';
- if (new RegExp(`${wildcards}`).exec(valueToCheck)) {
- logger.debug(`The '$capture' parameter contains an Express-style wildcard ` + `character (${wildcards}). Strings are now always interpreted as ` + `exact matches; use a RegExp for partial or wildcard matches.`);
- }
- }
- const matchCallback = ({
- url
- }) => {
- {
- if (url.pathname === captureUrl.pathname && url.origin !== captureUrl.origin) {
- logger.debug(`${capture} only partially matches the cross-origin URL ` + `${url.toString()}. This route will only handle cross-origin requests ` + `if they match the entire URL.`);
- }
- }
- return url.href === captureUrl.href;
- };
- // If `capture` is a string then `handler` and `method` must be present.
- route = new Route(matchCallback, handler, method);
- } else if (capture instanceof RegExp) {
- // If `capture` is a `RegExp` then `handler` and `method` must be present.
- route = new RegExpRoute(capture, handler, method);
- } else if (typeof capture === 'function') {
- // If `capture` is a function then `handler` and `method` must be present.
- route = new Route(capture, handler, method);
- } else if (capture instanceof Route) {
- route = capture;
- } else {
- throw new WorkboxError('unsupported-route-type', {
- moduleName: 'workbox-routing',
- funcName: 'registerRoute',
- paramName: 'capture'
- });
- }
- const defaultRouter = getOrCreateDefaultRouter();
- defaultRouter.registerRoute(route);
- return route;
- }
-
- // @ts-ignore
- try {
- self['workbox:strategies:7.0.0'] && _();
- } catch (e) {}
-
- /*
- Copyright 2018 Google LLC
-
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- const cacheOkAndOpaquePlugin = {
- /**
- * Returns a valid response (to allow caching) if the status is 200 (OK) or
- * 0 (opaque).
- *
- * @param {Object} options
- * @param {Response} options.response
- * @return {Response|null}
- *
- * @private
- */
- cacheWillUpdate: async ({
- response
- }) => {
- if (response.status === 200 || response.status === 0) {
- return response;
- }
- return null;
- }
- };
-
- /*
- Copyright 2018 Google LLC
-
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- const _cacheNameDetails = {
- googleAnalytics: 'googleAnalytics',
- precache: 'precache-v2',
- prefix: 'workbox',
- runtime: 'runtime',
- suffix: typeof registration !== 'undefined' ? registration.scope : ''
- };
- const _createCacheName = cacheName => {
- return [_cacheNameDetails.prefix, cacheName, _cacheNameDetails.suffix].filter(value => value && value.length > 0).join('-');
- };
- const eachCacheNameDetail = fn => {
- for (const key of Object.keys(_cacheNameDetails)) {
- fn(key);
- }
- };
- const cacheNames = {
- updateDetails: details => {
- eachCacheNameDetail(key => {
- if (typeof details[key] === 'string') {
- _cacheNameDetails[key] = details[key];
- }
- });
- },
- getGoogleAnalyticsName: userCacheName => {
- return userCacheName || _createCacheName(_cacheNameDetails.googleAnalytics);
- },
- getPrecacheName: userCacheName => {
- return userCacheName || _createCacheName(_cacheNameDetails.precache);
- },
- getPrefix: () => {
- return _cacheNameDetails.prefix;
- },
- getRuntimeName: userCacheName => {
- return userCacheName || _createCacheName(_cacheNameDetails.runtime);
- },
- getSuffix: () => {
- return _cacheNameDetails.suffix;
- }
- };
-
- /*
- Copyright 2020 Google LLC
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- function stripParams(fullURL, ignoreParams) {
- const strippedURL = new URL(fullURL);
- for (const param of ignoreParams) {
- strippedURL.searchParams.delete(param);
- }
- return strippedURL.href;
- }
- /**
- * Matches an item in the cache, ignoring specific URL params. This is similar
- * to the `ignoreSearch` option, but it allows you to ignore just specific
- * params (while continuing to match on the others).
- *
- * @private
- * @param {Cache} cache
- * @param {Request} request
- * @param {Object} matchOptions
- * @param {Array} ignoreParams
- * @return {Promise}
- */
- async function cacheMatchIgnoreParams(cache, request, ignoreParams, matchOptions) {
- const strippedRequestURL = stripParams(request.url, ignoreParams);
- // If the request doesn't include any ignored params, match as normal.
- if (request.url === strippedRequestURL) {
- return cache.match(request, matchOptions);
- }
- // Otherwise, match by comparing keys
- const keysOptions = Object.assign(Object.assign({}, matchOptions), {
- ignoreSearch: true
- });
- const cacheKeys = await cache.keys(request, keysOptions);
- for (const cacheKey of cacheKeys) {
- const strippedCacheKeyURL = stripParams(cacheKey.url, ignoreParams);
- if (strippedRequestURL === strippedCacheKeyURL) {
- return cache.match(cacheKey, matchOptions);
- }
- }
- return;
- }
-
- /*
- Copyright 2018 Google LLC
-
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- /**
- * The Deferred class composes Promises in a way that allows for them to be
- * resolved or rejected from outside the constructor. In most cases promises
- * should be used directly, but Deferreds can be necessary when the logic to
- * resolve a promise must be separate.
- *
- * @private
- */
- class Deferred {
- /**
- * Creates a promise and exposes its resolve and reject functions as methods.
- */
- constructor() {
- this.promise = new Promise((resolve, reject) => {
- this.resolve = resolve;
- this.reject = reject;
- });
- }
- }
-
- /*
- Copyright 2018 Google LLC
-
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- // Callbacks to be executed whenever there's a quota error.
- // Can't change Function type right now.
- // eslint-disable-next-line @typescript-eslint/ban-types
- const quotaErrorCallbacks = new Set();
-
- /*
- Copyright 2018 Google LLC
-
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- /**
- * Runs all of the callback functions, one at a time sequentially, in the order
- * in which they were registered.
- *
- * @memberof workbox-core
- * @private
- */
- async function executeQuotaErrorCallbacks() {
- {
- logger.log(`About to run ${quotaErrorCallbacks.size} ` + `callbacks to clean up caches.`);
- }
- for (const callback of quotaErrorCallbacks) {
- await callback();
- {
- logger.log(callback, 'is complete.');
- }
- }
- {
- logger.log('Finished running callbacks.');
- }
- }
-
- /*
- Copyright 2019 Google LLC
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- /**
- * Returns a promise that resolves and the passed number of milliseconds.
- * This utility is an async/await-friendly version of `setTimeout`.
- *
- * @param {number} ms
- * @return {Promise}
- * @private
- */
- function timeout(ms) {
- return new Promise(resolve => setTimeout(resolve, ms));
- }
-
- /*
- Copyright 2020 Google LLC
-
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- function toRequest(input) {
- return typeof input === 'string' ? new Request(input) : input;
- }
- /**
- * A class created every time a Strategy instance instance calls
- * {@link workbox-strategies.Strategy~handle} or
- * {@link workbox-strategies.Strategy~handleAll} that wraps all fetch and
- * cache actions around plugin callbacks and keeps track of when the strategy
- * is "done" (i.e. all added `event.waitUntil()` promises have resolved).
- *
- * @memberof workbox-strategies
- */
- class StrategyHandler {
- /**
- * Creates a new instance associated with the passed strategy and event
- * that's handling the request.
- *
- * The constructor also initializes the state that will be passed to each of
- * the plugins handling this request.
- *
- * @param {workbox-strategies.Strategy} strategy
- * @param {Object} options
- * @param {Request|string} options.request A request to run this strategy for.
- * @param {ExtendableEvent} options.event The event associated with the
- * request.
- * @param {URL} [options.url]
- * @param {*} [options.params] The return value from the
- * {@link workbox-routing~matchCallback} (if applicable).
- */
- constructor(strategy, options) {
- this._cacheKeys = {};
- /**
- * The request the strategy is performing (passed to the strategy's
- * `handle()` or `handleAll()` method).
- * @name request
- * @instance
- * @type {Request}
- * @memberof workbox-strategies.StrategyHandler
- */
- /**
- * The event associated with this request.
- * @name event
- * @instance
- * @type {ExtendableEvent}
- * @memberof workbox-strategies.StrategyHandler
- */
- /**
- * A `URL` instance of `request.url` (if passed to the strategy's
- * `handle()` or `handleAll()` method).
- * Note: the `url` param will be present if the strategy was invoked
- * from a workbox `Route` object.
- * @name url
- * @instance
- * @type {URL|undefined}
- * @memberof workbox-strategies.StrategyHandler
- */
- /**
- * A `param` value (if passed to the strategy's
- * `handle()` or `handleAll()` method).
- * Note: the `param` param will be present if the strategy was invoked
- * from a workbox `Route` object and the
- * {@link workbox-routing~matchCallback} returned
- * a truthy value (it will be that value).
- * @name params
- * @instance
- * @type {*|undefined}
- * @memberof workbox-strategies.StrategyHandler
- */
- {
- finalAssertExports.isInstance(options.event, ExtendableEvent, {
- moduleName: 'workbox-strategies',
- className: 'StrategyHandler',
- funcName: 'constructor',
- paramName: 'options.event'
- });
- }
- Object.assign(this, options);
- this.event = options.event;
- this._strategy = strategy;
- this._handlerDeferred = new Deferred();
- this._extendLifetimePromises = [];
- // Copy the plugins list (since it's mutable on the strategy),
- // so any mutations don't affect this handler instance.
- this._plugins = [...strategy.plugins];
- this._pluginStateMap = new Map();
- for (const plugin of this._plugins) {
- this._pluginStateMap.set(plugin, {});
- }
- this.event.waitUntil(this._handlerDeferred.promise);
- }
- /**
- * Fetches a given request (and invokes any applicable plugin callback
- * methods) using the `fetchOptions` (for non-navigation requests) and
- * `plugins` defined on the `Strategy` object.
- *
- * The following plugin lifecycle methods are invoked when using this method:
- * - `requestWillFetch()`
- * - `fetchDidSucceed()`
- * - `fetchDidFail()`
- *
- * @param {Request|string} input The URL or request to fetch.
- * @return {Promise}
- */
- async fetch(input) {
- const {
- event
- } = this;
- let request = toRequest(input);
- if (request.mode === 'navigate' && event instanceof FetchEvent && event.preloadResponse) {
- const possiblePreloadResponse = await event.preloadResponse;
- if (possiblePreloadResponse) {
- {
- logger.log(`Using a preloaded navigation response for ` + `'${getFriendlyURL(request.url)}'`);
- }
- return possiblePreloadResponse;
- }
- }
- // If there is a fetchDidFail plugin, we need to save a clone of the
- // original request before it's either modified by a requestWillFetch
- // plugin or before the original request's body is consumed via fetch().
- const originalRequest = this.hasCallback('fetchDidFail') ? request.clone() : null;
- try {
- for (const cb of this.iterateCallbacks('requestWillFetch')) {
- request = await cb({
- request: request.clone(),
- event
- });
- }
- } catch (err) {
- if (err instanceof Error) {
- throw new WorkboxError('plugin-error-request-will-fetch', {
- thrownErrorMessage: err.message
- });
- }
- }
- // The request can be altered by plugins with `requestWillFetch` making
- // the original request (most likely from a `fetch` event) different
- // from the Request we make. Pass both to `fetchDidFail` to aid debugging.
- const pluginFilteredRequest = request.clone();
- try {
- let fetchResponse;
- // See https://github.com/GoogleChrome/workbox/issues/1796
- fetchResponse = await fetch(request, request.mode === 'navigate' ? undefined : this._strategy.fetchOptions);
- if ("development" !== 'production') {
- logger.debug(`Network request for ` + `'${getFriendlyURL(request.url)}' returned a response with ` + `status '${fetchResponse.status}'.`);
- }
- for (const callback of this.iterateCallbacks('fetchDidSucceed')) {
- fetchResponse = await callback({
- event,
- request: pluginFilteredRequest,
- response: fetchResponse
- });
- }
- return fetchResponse;
- } catch (error) {
- {
- logger.log(`Network request for ` + `'${getFriendlyURL(request.url)}' threw an error.`, error);
- }
- // `originalRequest` will only exist if a `fetchDidFail` callback
- // is being used (see above).
- if (originalRequest) {
- await this.runCallbacks('fetchDidFail', {
- error: error,
- event,
- originalRequest: originalRequest.clone(),
- request: pluginFilteredRequest.clone()
- });
- }
- throw error;
- }
- }
- /**
- * Calls `this.fetch()` and (in the background) runs `this.cachePut()` on
- * the response generated by `this.fetch()`.
- *
- * The call to `this.cachePut()` automatically invokes `this.waitUntil()`,
- * so you do not have to manually call `waitUntil()` on the event.
- *
- * @param {Request|string} input The request or URL to fetch and cache.
- * @return {Promise}
- */
- async fetchAndCachePut(input) {
- const response = await this.fetch(input);
- const responseClone = response.clone();
- void this.waitUntil(this.cachePut(input, responseClone));
- return response;
- }
- /**
- * Matches a request from the cache (and invokes any applicable plugin
- * callback methods) using the `cacheName`, `matchOptions`, and `plugins`
- * defined on the strategy object.
- *
- * The following plugin lifecycle methods are invoked when using this method:
- * - cacheKeyWillByUsed()
- * - cachedResponseWillByUsed()
- *
- * @param {Request|string} key The Request or URL to use as the cache key.
- * @return {Promise} A matching response, if found.
- */
- async cacheMatch(key) {
- const request = toRequest(key);
- let cachedResponse;
- const {
- cacheName,
- matchOptions
- } = this._strategy;
- const effectiveRequest = await this.getCacheKey(request, 'read');
- const multiMatchOptions = Object.assign(Object.assign({}, matchOptions), {
- cacheName
- });
- cachedResponse = await caches.match(effectiveRequest, multiMatchOptions);
- {
- if (cachedResponse) {
- logger.debug(`Found a cached response in '${cacheName}'.`);
- } else {
- logger.debug(`No cached response found in '${cacheName}'.`);
- }
- }
- for (const callback of this.iterateCallbacks('cachedResponseWillBeUsed')) {
- cachedResponse = (await callback({
- cacheName,
- matchOptions,
- cachedResponse,
- request: effectiveRequest,
- event: this.event
- })) || undefined;
- }
- return cachedResponse;
- }
- /**
- * Puts a request/response pair in the cache (and invokes any applicable
- * plugin callback methods) using the `cacheName` and `plugins` defined on
- * the strategy object.
- *
- * The following plugin lifecycle methods are invoked when using this method:
- * - cacheKeyWillByUsed()
- * - cacheWillUpdate()
- * - cacheDidUpdate()
- *
- * @param {Request|string} key The request or URL to use as the cache key.
- * @param {Response} response The response to cache.
- * @return {Promise} `false` if a cacheWillUpdate caused the response
- * not be cached, and `true` otherwise.
- */
- async cachePut(key, response) {
- const request = toRequest(key);
- // Run in the next task to avoid blocking other cache reads.
- // https://github.com/w3c/ServiceWorker/issues/1397
- await timeout(0);
- const effectiveRequest = await this.getCacheKey(request, 'write');
- {
- if (effectiveRequest.method && effectiveRequest.method !== 'GET') {
- throw new WorkboxError('attempt-to-cache-non-get-request', {
- url: getFriendlyURL(effectiveRequest.url),
- method: effectiveRequest.method
- });
- }
- // See https://github.com/GoogleChrome/workbox/issues/2818
- const vary = response.headers.get('Vary');
- if (vary) {
- logger.debug(`The response for ${getFriendlyURL(effectiveRequest.url)} ` + `has a 'Vary: ${vary}' header. ` + `Consider setting the {ignoreVary: true} option on your strategy ` + `to ensure cache matching and deletion works as expected.`);
- }
- }
- if (!response) {
- {
- logger.error(`Cannot cache non-existent response for ` + `'${getFriendlyURL(effectiveRequest.url)}'.`);
- }
- throw new WorkboxError('cache-put-with-no-response', {
- url: getFriendlyURL(effectiveRequest.url)
- });
- }
- const responseToCache = await this._ensureResponseSafeToCache(response);
- if (!responseToCache) {
- {
- logger.debug(`Response '${getFriendlyURL(effectiveRequest.url)}' ` + `will not be cached.`, responseToCache);
- }
- return false;
- }
- const {
- cacheName,
- matchOptions
- } = this._strategy;
- const cache = await self.caches.open(cacheName);
- const hasCacheUpdateCallback = this.hasCallback('cacheDidUpdate');
- const oldResponse = hasCacheUpdateCallback ? await cacheMatchIgnoreParams(
- // TODO(philipwalton): the `__WB_REVISION__` param is a precaching
- // feature. Consider into ways to only add this behavior if using
- // precaching.
- cache, effectiveRequest.clone(), ['__WB_REVISION__'], matchOptions) : null;
- {
- logger.debug(`Updating the '${cacheName}' cache with a new Response ` + `for ${getFriendlyURL(effectiveRequest.url)}.`);
- }
- try {
- await cache.put(effectiveRequest, hasCacheUpdateCallback ? responseToCache.clone() : responseToCache);
- } catch (error) {
- if (error instanceof Error) {
- // See https://developer.mozilla.org/en-US/docs/Web/API/DOMException#exception-QuotaExceededError
- if (error.name === 'QuotaExceededError') {
- await executeQuotaErrorCallbacks();
- }
- throw error;
- }
- }
- for (const callback of this.iterateCallbacks('cacheDidUpdate')) {
- await callback({
- cacheName,
- oldResponse,
- newResponse: responseToCache.clone(),
- request: effectiveRequest,
- event: this.event
- });
- }
- return true;
- }
- /**
- * Checks the list of plugins for the `cacheKeyWillBeUsed` callback, and
- * executes any of those callbacks found in sequence. The final `Request`
- * object returned by the last plugin is treated as the cache key for cache
- * reads and/or writes. If no `cacheKeyWillBeUsed` plugin callbacks have
- * been registered, the passed request is returned unmodified
- *
- * @param {Request} request
- * @param {string} mode
- * @return {Promise}
- */
- async getCacheKey(request, mode) {
- const key = `${request.url} | ${mode}`;
- if (!this._cacheKeys[key]) {
- let effectiveRequest = request;
- for (const callback of this.iterateCallbacks('cacheKeyWillBeUsed')) {
- effectiveRequest = toRequest(await callback({
- mode,
- request: effectiveRequest,
- event: this.event,
- // params has a type any can't change right now.
- params: this.params // eslint-disable-line
- }));
- }
- this._cacheKeys[key] = effectiveRequest;
- }
- return this._cacheKeys[key];
- }
- /**
- * Returns true if the strategy has at least one plugin with the given
- * callback.
- *
- * @param {string} name The name of the callback to check for.
- * @return {boolean}
- */
- hasCallback(name) {
- for (const plugin of this._strategy.plugins) {
- if (name in plugin) {
- return true;
- }
- }
- return false;
- }
- /**
- * Runs all plugin callbacks matching the given name, in order, passing the
- * given param object (merged ith the current plugin state) as the only
- * argument.
- *
- * Note: since this method runs all plugins, it's not suitable for cases
- * where the return value of a callback needs to be applied prior to calling
- * the next callback. See
- * {@link workbox-strategies.StrategyHandler#iterateCallbacks}
- * below for how to handle that case.
- *
- * @param {string} name The name of the callback to run within each plugin.
- * @param {Object} param The object to pass as the first (and only) param
- * when executing each callback. This object will be merged with the
- * current plugin state prior to callback execution.
- */
- async runCallbacks(name, param) {
- for (const callback of this.iterateCallbacks(name)) {
- // TODO(philipwalton): not sure why `any` is needed. It seems like
- // this should work with `as WorkboxPluginCallbackParam[C]`.
- await callback(param);
- }
- }
- /**
- * Accepts a callback and returns an iterable of matching plugin callbacks,
- * where each callback is wrapped with the current handler state (i.e. when
- * you call each callback, whatever object parameter you pass it will
- * be merged with the plugin's current state).
- *
- * @param {string} name The name fo the callback to run
- * @return {Array}
- */
- *iterateCallbacks(name) {
- for (const plugin of this._strategy.plugins) {
- if (typeof plugin[name] === 'function') {
- const state = this._pluginStateMap.get(plugin);
- const statefulCallback = param => {
- const statefulParam = Object.assign(Object.assign({}, param), {
- state
- });
- // TODO(philipwalton): not sure why `any` is needed. It seems like
- // this should work with `as WorkboxPluginCallbackParam[C]`.
- return plugin[name](statefulParam);
- };
- yield statefulCallback;
- }
- }
- }
- /**
- * Adds a promise to the
- * [extend lifetime promises]{@link https://w3c.github.io/ServiceWorker/#extendableevent-extend-lifetime-promises}
- * of the event event associated with the request being handled (usually a
- * `FetchEvent`).
- *
- * Note: you can await
- * {@link workbox-strategies.StrategyHandler~doneWaiting}
- * to know when all added promises have settled.
- *
- * @param {Promise} promise A promise to add to the extend lifetime promises
- * of the event that triggered the request.
- */
- waitUntil(promise) {
- this._extendLifetimePromises.push(promise);
- return promise;
- }
- /**
- * Returns a promise that resolves once all promises passed to
- * {@link workbox-strategies.StrategyHandler~waitUntil}
- * have settled.
- *
- * Note: any work done after `doneWaiting()` settles should be manually
- * passed to an event's `waitUntil()` method (not this handler's
- * `waitUntil()` method), otherwise the service worker thread my be killed
- * prior to your work completing.
- */
- async doneWaiting() {
- let promise;
- while (promise = this._extendLifetimePromises.shift()) {
- await promise;
- }
- }
- /**
- * Stops running the strategy and immediately resolves any pending
- * `waitUntil()` promises.
- */
- destroy() {
- this._handlerDeferred.resolve(null);
- }
- /**
- * This method will call cacheWillUpdate on the available plugins (or use
- * status === 200) to determine if the Response is safe and valid to cache.
- *
- * @param {Request} options.request
- * @param {Response} options.response
- * @return {Promise}
- *
- * @private
- */
- async _ensureResponseSafeToCache(response) {
- let responseToCache = response;
- let pluginsUsed = false;
- for (const callback of this.iterateCallbacks('cacheWillUpdate')) {
- responseToCache = (await callback({
- request: this.request,
- response: responseToCache,
- event: this.event
- })) || undefined;
- pluginsUsed = true;
- if (!responseToCache) {
- break;
- }
- }
- if (!pluginsUsed) {
- if (responseToCache && responseToCache.status !== 200) {
- responseToCache = undefined;
- }
- {
- if (responseToCache) {
- if (responseToCache.status !== 200) {
- if (responseToCache.status === 0) {
- logger.warn(`The response for '${this.request.url}' ` + `is an opaque response. The caching strategy that you're ` + `using will not cache opaque responses by default.`);
- } else {
- logger.debug(`The response for '${this.request.url}' ` + `returned a status code of '${response.status}' and won't ` + `be cached as a result.`);
- }
- }
- }
- }
- }
- return responseToCache;
- }
- }
-
- /*
- Copyright 2020 Google LLC
-
- Use of this source code is governed by an MIT-style
- license that can be found in the LICENSE file or at
- https://opensource.org/licenses/MIT.
- */
- /**
- * An abstract base class that all other strategy classes must extend from:
- *
- * @memberof workbox-strategies
- */
- class Strategy {
- /**
- * Creates a new instance of the strategy and sets all documented option
- * properties as public instance properties.
- *
- * Note: if a custom strategy class extends the base Strategy class and does
- * not need more than these properties, it does not need to define its own
- * constructor.
- *
- * @param {Object} [options]
- * @param {string} [options.cacheName] Cache name to store and retrieve
- * requests. Defaults to the cache names provided by
- * {@link workbox-core.cacheNames}.
- * @param {Array
-
+ {/* */}
+
-
+ {/* */}
+
+
diff --git a/src/assets/app.png b/src/assets/app.png
new file mode 100644
index 0000000..17e3672
Binary files /dev/null and b/src/assets/app.png differ
diff --git a/src/assets/phi1.png b/src/assets/phi1.png
new file mode 100644
index 0000000..2d89d41
Binary files /dev/null and b/src/assets/phi1.png differ
diff --git a/src/assets/phi2.png b/src/assets/phi2.png
new file mode 100644
index 0000000..e4c1c11
Binary files /dev/null and b/src/assets/phi2.png differ
diff --git a/src/assets/phi3.png b/src/assets/phi3.png
new file mode 100644
index 0000000..0f1e178
Binary files /dev/null and b/src/assets/phi3.png differ
diff --git a/src/constans/index.js b/src/constans/index.js
index 8d0da5e..62f5eb9 100644
--- a/src/constans/index.js
+++ b/src/constans/index.js
@@ -7,16 +7,16 @@ export const navLinks = [
{
id: "product",
title: "product",
+ go: false,
+ },
+ {
+ id: "pricing",
+ title: "pricing",
go: true,
},
{
- id: "Pricing",
- title: "Pricing",
- go: true,
- },
- {
- id: "contact-us",
- title: "contact us",
+ id: "about-us",
+ title: "about us",
go: true,
},
];
@@ -38,52 +38,34 @@ const services = [
const experiences = [
{
- title: "setup routine Modes",
- date: "step 1",
+ title: "Insert tasks and assign",
+ date: "Insert tasks ",
+ points: ["Insert tasks and assign them to positions in the store"],
+ },
+ {
+ title: "Create a clear shift plan",
+ date: "clear shift plan ",
points: [
- "Begin your journey with Briz by customizing Collection Routines to suit your unique business needs. Whether it's for the bustling holiday season, a reflective Ramadan, or your standard daily operations, simply activate the desired mode. Save various modes to maintain a recorded task list for each routine, ensuring a streamlined and efficient approach to every aspect of your business.",
+ "Create a clear shift plan for each week and assign a supervisor to each shift.",
],
},
{
- title: "setup each section",
- date: "step 2",
+ title: "activity assigned to a specific person",
+ date: "specific ",
points: [
- "Continue shaping your unique coffee shop experience by defining each distinct area within your establishment with Briz. Set up sections like the bar, kitchen, and seating area in our system. This process not only helps in organizing physical spaces but also assists in assigning tasks, managing resources, and streamlining operations for each specific zone.",
+ "After shift planning, each task becomes an activity assigned to a specific person.",
],
},
{
- title: "setup stuff positions",
- date: "step 3",
- points: [
- "Define roles such as Barista, Waiter, Cashier, and more within our system to clarify responsibilities and streamline workflow. This organization allows you to manage schedules, assign tasks, and track performance more effectively. Empower your staff with clear definitions and watch as your service flourishes with precision and care.",
- ],
+ title: "real time ",
+ date: "Track in system",
+ points: ["Track the operation routine in the system in real time."],
},
{
- title: "define staff ",
- date: "step 4",
+ title: "confirms completion",
+ date: "completion ",
points: [
- "Define your team in the app by entering each staff member's name, contact number, and specific access levels.",
- ],
- },
- {
- title: "setup shift forms",
- date: "step 5",
- points: [
- "establish and manage shift patterns to ensure your coffee shop operates smoothly around the clock. Whether it's the early birds in the morning shift, the rush-hour warriors of the afternoon, or the night owls keeping the evening vibe alive, our system allows you to customize and control shift timings. Define morning, afternoon, and night shifts, or any other custom intervals that fit your unique business rhythm. By organizing and adapting shift schedules, you'll maintain a consistent, quality service any time of day, all while keeping your team well-rested and ready to excel.",
- ],
- },
- {
- title: "insert tasks ",
- date: "step 6",
- points: [
- "Progress further with Briz by inserting and customizing tasks that keep your coffee shop humming. Whether they are daily grind duties, weekly deep cleans, or special event preparations, our system allows you to define tasks as daily, weekly, or on a custom schedule. Assign these tasks to positions rather than individuals, such as assigning cleaning duties to the closing Barista or inventory checks to the morning Manager. This method ensures that responsibilities are clear and consistent, regardless of personnel changes. Once you've planned your shifts for each week, each staff member assigned to a position will automatically inherit the tasks associated with it, ensuring a smooth operation and an evenly distributed workload.",
- ],
- },
- {
- title: "Weekly Shift Planning",
- date: "step 7",
- points: [
- "Each week, take the time to strategically assign staff to their specific positions for each day, considering their strengths, preferences, and the needs of your coffee shop. As you place each staff member in their role, they are automatically assigned the tasks linked to their position for that shift.",
+ "After closing the shift, your supervisor checks all the tasks, confirms completion, and rates the staff.",
],
},
];
@@ -91,22 +73,55 @@ const experiences = [
const testimonials = [
{
testimonial:
- "Comprehensive Oversight: A Panoramic View for Owners and Supervisors",
- title: "holistic view ",
+ " This refers to the precise amount of ground coffee used for each brew. Adjusting the BCG ensures consistency in the flavor profile and strength of the coffee, playing a key role in achieving the perfect cup.",
+ title: "Basic Coffee Gram (BCG) ",
},
{
testimonial:
- "Strategic Shift Scheduling: Mastering the Art of Staff Allocation",
- title: "Weekly Shift Planning",
+ "This measures the final weight of the extracted coffee after brewing. OEG helps monitor the efficiency of the brewing process and determines the yield of the coffee, crucial for maintaining the desired taste and texture.",
+ title: "Output Extract Grammage (OEG)",
},
{
- testimonial: "Performance Insights: Supervisor-Driven Staff Ratings",
- title: "rating by supervisor",
- },
- {
- testimonial: "Validation Excellence: Supervisor Task Confirmation",
- title: "verify by supervisor ",
+ testimonial:
+ "This is the total time taken to brew the coffee from start to finish. The ET influences the balance of flavors in the coffee, as shorter times can result in under-extracted coffee while longer times may lead to over-extraction, both impacting the final taste.",
+ title: " Extraction Time (ET)",
},
];
-export { services, experiences, testimonials };
+const stepProducts = [
+ {
+ des: "You can fully customize and define your operation system. In the first step, set up your routines. Each system can have different settings for specific times of the year.",
+ title: "setup your routine ",
+ img: "1",
+ },
+ {
+ des: "Define your sections to gain better insights into your operations. You can create unlimited sections.",
+ title: "setup your sections",
+ img: "2",
+ },
+ {
+ des: "Positions play a crucial role in our platform. Tasks are assigned to positions, so please add and manage them carefully",
+ title: " setup your positions",
+ img: "3",
+ },
+
+ {
+ des: "You need to set up your staff information. They will log in when they enter your complex.",
+ title: " setup staff information",
+ img: "4",
+ },
+
+ {
+ des: "You need to establish your shift logic, defining start and end times for each day of the week.",
+ title: " setup your shifts logic",
+ img: "5",
+ },
+
+ {
+ des: "Set up all your tasks at this stage, assigning them to shifts and positions. Ensure their reproducibility in three modes: daily tasks, weekly tasks on specific days, and monthly tasks on particular days.",
+ title: "insert all of your tasks",
+ img: "6",
+ },
+];
+
+export { services, experiences, testimonials, stepProducts };
diff --git a/style/globals.css b/style/globals.css
index c99a9b4..fa17a95 100644
--- a/style/globals.css
+++ b/style/globals.css
@@ -539,3 +539,7 @@ body {
transparent
);
}
+
+.vertical-timeline.vertical-timeline--two-columns:before {
+ opacity: 0.1; /* Set the opacity to 0.5 */
+}