diff --git a/package-lock.json b/package-lock.json
index 9244c2b..23a046b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -35,6 +35,7 @@
"react": "^18.3.1",
"react-country-flag": "^3.1.0",
"react-dom": "^18.3.1",
+ "react-flagpack": "^2.0.6",
"react-markdown": "^10.1.0",
"react-responsive": "^10.0.1",
"react-router-dom": "*",
@@ -16505,6 +16506,18 @@
"node": ">= 4.0.0"
}
},
+ "node_modules/meow": {
+ "version": "13.2.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz",
+ "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/merge-descriptors": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
@@ -20641,6 +20654,49 @@
"integrity": "sha512-SN/U6Ytxf1QGkw/9ve5Y+NxBbZM6Ht95tuXNMKs8EJyFa/Vy/+Co3stop3KBHARfn/giv+Lj1uUnTfOJ3moFEQ==",
"license": "MIT"
},
+ "node_modules/react-flagpack": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/react-flagpack/-/react-flagpack-2.0.6.tgz",
+ "integrity": "sha512-ZLRC6u/d6AVTpMcFKZf2aSYPDmesPEzU084I99sU/Bcg32Jux6acE2bfHQnW2P/HYfSzx9YWwiNjJKxiW8OTGQ==",
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^5.3.0",
+ "fs-extra": "^11.2.0",
+ "meow": "^13.2.0"
+ },
+ "bin": {
+ "react-flagpack": "cli/flagpack.js"
+ },
+ "peerDependencies": {
+ "react": "^16.8.* || ^17.* || ^18.*"
+ }
+ },
+ "node_modules/react-flagpack/node_modules/chalk": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
+ "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/react-flagpack/node_modules/fs-extra": {
+ "version": "11.3.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
+ "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
diff --git a/package.json b/package.json
index 5f94f7c..8b2ccec 100644
--- a/package.json
+++ b/package.json
@@ -30,6 +30,7 @@
"react": "^18.3.1",
"react-country-flag": "^3.1.0",
"react-dom": "^18.3.1",
+ "react-flagpack": "^2.0.6",
"react-markdown": "^10.1.0",
"react-responsive": "^10.0.1",
"react-router-dom": "*",
diff --git a/public/flags/l/AD.svg b/public/flags/l/AD.svg
new file mode 100644
index 0000000..22ec262
--- /dev/null
+++ b/public/flags/l/AD.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/l/AE.svg b/public/flags/l/AE.svg
new file mode 100644
index 0000000..18a6ff6
--- /dev/null
+++ b/public/flags/l/AE.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/AF.svg b/public/flags/l/AF.svg
new file mode 100644
index 0000000..a7696b0
--- /dev/null
+++ b/public/flags/l/AF.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/l/AG.svg b/public/flags/l/AG.svg
new file mode 100644
index 0000000..5adc73a
--- /dev/null
+++ b/public/flags/l/AG.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/l/AI.svg b/public/flags/l/AI.svg
new file mode 100644
index 0000000..dd91a58
--- /dev/null
+++ b/public/flags/l/AI.svg
@@ -0,0 +1,37 @@
+
diff --git a/public/flags/l/AL.svg b/public/flags/l/AL.svg
new file mode 100644
index 0000000..7095b2e
--- /dev/null
+++ b/public/flags/l/AL.svg
@@ -0,0 +1,12 @@
+
diff --git a/public/flags/l/AM.svg b/public/flags/l/AM.svg
new file mode 100644
index 0000000..9e24ada
--- /dev/null
+++ b/public/flags/l/AM.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/AO.svg b/public/flags/l/AO.svg
new file mode 100644
index 0000000..dae7969
--- /dev/null
+++ b/public/flags/l/AO.svg
@@ -0,0 +1,43 @@
+
diff --git a/public/flags/l/AQ.svg b/public/flags/l/AQ.svg
new file mode 100644
index 0000000..57f2d88
--- /dev/null
+++ b/public/flags/l/AQ.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/AR.svg b/public/flags/l/AR.svg
new file mode 100644
index 0000000..a6b3f6a
--- /dev/null
+++ b/public/flags/l/AR.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/l/AS.svg b/public/flags/l/AS.svg
new file mode 100644
index 0000000..29480cd
--- /dev/null
+++ b/public/flags/l/AS.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/l/AT.svg b/public/flags/l/AT.svg
new file mode 100644
index 0000000..6e0f152
--- /dev/null
+++ b/public/flags/l/AT.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/AU.svg b/public/flags/l/AU.svg
new file mode 100644
index 0000000..03582e0
--- /dev/null
+++ b/public/flags/l/AU.svg
@@ -0,0 +1,34 @@
+
diff --git a/public/flags/l/AW.svg b/public/flags/l/AW.svg
new file mode 100644
index 0000000..296f849
--- /dev/null
+++ b/public/flags/l/AW.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/AX.svg b/public/flags/l/AX.svg
new file mode 100644
index 0000000..564e1d6
--- /dev/null
+++ b/public/flags/l/AX.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/AZ.svg b/public/flags/l/AZ.svg
new file mode 100644
index 0000000..df3365b
--- /dev/null
+++ b/public/flags/l/AZ.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/l/BA.svg b/public/flags/l/BA.svg
new file mode 100644
index 0000000..0ecbb81
--- /dev/null
+++ b/public/flags/l/BA.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/BB.svg b/public/flags/l/BB.svg
new file mode 100644
index 0000000..eeb17cd
--- /dev/null
+++ b/public/flags/l/BB.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/BD.svg b/public/flags/l/BD.svg
new file mode 100644
index 0000000..f2d458e
--- /dev/null
+++ b/public/flags/l/BD.svg
@@ -0,0 +1,12 @@
+
diff --git a/public/flags/l/BE.svg b/public/flags/l/BE.svg
new file mode 100644
index 0000000..a22f0f1
--- /dev/null
+++ b/public/flags/l/BE.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/BF.svg b/public/flags/l/BF.svg
new file mode 100644
index 0000000..f71b590
--- /dev/null
+++ b/public/flags/l/BF.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/BG.svg b/public/flags/l/BG.svg
new file mode 100644
index 0000000..ce54fba
--- /dev/null
+++ b/public/flags/l/BG.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/BH.svg b/public/flags/l/BH.svg
new file mode 100644
index 0000000..1f039f1
--- /dev/null
+++ b/public/flags/l/BH.svg
@@ -0,0 +1,12 @@
+
diff --git a/public/flags/l/BI.svg b/public/flags/l/BI.svg
new file mode 100644
index 0000000..2d5f382
--- /dev/null
+++ b/public/flags/l/BI.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/l/BJ.svg b/public/flags/l/BJ.svg
new file mode 100644
index 0000000..ca235f1
--- /dev/null
+++ b/public/flags/l/BJ.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/BL.svg b/public/flags/l/BL.svg
new file mode 100644
index 0000000..e8e6be8
--- /dev/null
+++ b/public/flags/l/BL.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/BM.svg b/public/flags/l/BM.svg
new file mode 100644
index 0000000..bd069b7
--- /dev/null
+++ b/public/flags/l/BM.svg
@@ -0,0 +1,47 @@
+
diff --git a/public/flags/l/BN.svg b/public/flags/l/BN.svg
new file mode 100644
index 0000000..8b3a85c
--- /dev/null
+++ b/public/flags/l/BN.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/l/BO.svg b/public/flags/l/BO.svg
new file mode 100644
index 0000000..62b5cc7
--- /dev/null
+++ b/public/flags/l/BO.svg
@@ -0,0 +1,56 @@
+
diff --git a/public/flags/l/BQ-BO.svg b/public/flags/l/BQ-BO.svg
new file mode 100644
index 0000000..0ac99e9
--- /dev/null
+++ b/public/flags/l/BQ-BO.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/l/BQ-SA.svg b/public/flags/l/BQ-SA.svg
new file mode 100644
index 0000000..4487a5f
--- /dev/null
+++ b/public/flags/l/BQ-SA.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/l/BQ-SE.svg b/public/flags/l/BQ-SE.svg
new file mode 100644
index 0000000..b34d1b4
--- /dev/null
+++ b/public/flags/l/BQ-SE.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/l/BR.svg b/public/flags/l/BR.svg
new file mode 100644
index 0000000..fcb6f6e
--- /dev/null
+++ b/public/flags/l/BR.svg
@@ -0,0 +1,48 @@
+
diff --git a/public/flags/l/BS.svg b/public/flags/l/BS.svg
new file mode 100644
index 0000000..8fcfdd7
--- /dev/null
+++ b/public/flags/l/BS.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/BT.svg b/public/flags/l/BT.svg
new file mode 100644
index 0000000..94e491b
--- /dev/null
+++ b/public/flags/l/BT.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/l/BV.svg b/public/flags/l/BV.svg
new file mode 100644
index 0000000..03fcea6
--- /dev/null
+++ b/public/flags/l/BV.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/BW.svg b/public/flags/l/BW.svg
new file mode 100644
index 0000000..5821696
--- /dev/null
+++ b/public/flags/l/BW.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/BY.svg b/public/flags/l/BY.svg
new file mode 100644
index 0000000..1fb07bd
--- /dev/null
+++ b/public/flags/l/BY.svg
@@ -0,0 +1,40 @@
+
diff --git a/public/flags/l/BZ.svg b/public/flags/l/BZ.svg
new file mode 100644
index 0000000..ec8f63f
--- /dev/null
+++ b/public/flags/l/BZ.svg
@@ -0,0 +1,60 @@
+
diff --git a/public/flags/l/CA.svg b/public/flags/l/CA.svg
new file mode 100644
index 0000000..24c8965
--- /dev/null
+++ b/public/flags/l/CA.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/CC.svg b/public/flags/l/CC.svg
new file mode 100644
index 0000000..4134470
--- /dev/null
+++ b/public/flags/l/CC.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/l/CD.svg b/public/flags/l/CD.svg
new file mode 100644
index 0000000..cdefc98
--- /dev/null
+++ b/public/flags/l/CD.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/CF.svg b/public/flags/l/CF.svg
new file mode 100644
index 0000000..f3eb2b7
--- /dev/null
+++ b/public/flags/l/CF.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/l/CG.svg b/public/flags/l/CG.svg
new file mode 100644
index 0000000..7603133
--- /dev/null
+++ b/public/flags/l/CG.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/CH.svg b/public/flags/l/CH.svg
new file mode 100644
index 0000000..f90db30
--- /dev/null
+++ b/public/flags/l/CH.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/CI.svg b/public/flags/l/CI.svg
new file mode 100644
index 0000000..6487267
--- /dev/null
+++ b/public/flags/l/CI.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/CK.svg b/public/flags/l/CK.svg
new file mode 100644
index 0000000..1c6c2bd
--- /dev/null
+++ b/public/flags/l/CK.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/l/CL.svg b/public/flags/l/CL.svg
new file mode 100644
index 0000000..0f68440
--- /dev/null
+++ b/public/flags/l/CL.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/CM.svg b/public/flags/l/CM.svg
new file mode 100644
index 0000000..9a0e633
--- /dev/null
+++ b/public/flags/l/CM.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/CN.svg b/public/flags/l/CN.svg
new file mode 100644
index 0000000..8e52ffe
--- /dev/null
+++ b/public/flags/l/CN.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/l/CO.svg b/public/flags/l/CO.svg
new file mode 100644
index 0000000..c000ab8
--- /dev/null
+++ b/public/flags/l/CO.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/CR.svg b/public/flags/l/CR.svg
new file mode 100644
index 0000000..1fcfc1d
--- /dev/null
+++ b/public/flags/l/CR.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/CU.svg b/public/flags/l/CU.svg
new file mode 100644
index 0000000..32a211e
--- /dev/null
+++ b/public/flags/l/CU.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/l/CV.svg b/public/flags/l/CV.svg
new file mode 100644
index 0000000..e3b810a
--- /dev/null
+++ b/public/flags/l/CV.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/l/CW.svg b/public/flags/l/CW.svg
new file mode 100644
index 0000000..10b377b
--- /dev/null
+++ b/public/flags/l/CW.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/l/CX.svg b/public/flags/l/CX.svg
new file mode 100644
index 0000000..3f540c7
--- /dev/null
+++ b/public/flags/l/CX.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/l/CY.svg b/public/flags/l/CY.svg
new file mode 100644
index 0000000..4a5259b
--- /dev/null
+++ b/public/flags/l/CY.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/CZ.svg b/public/flags/l/CZ.svg
new file mode 100644
index 0000000..abdbc6d
--- /dev/null
+++ b/public/flags/l/CZ.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/l/DE.svg b/public/flags/l/DE.svg
new file mode 100644
index 0000000..7fa97e7
--- /dev/null
+++ b/public/flags/l/DE.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/DJ.svg b/public/flags/l/DJ.svg
new file mode 100644
index 0000000..82f0a58
--- /dev/null
+++ b/public/flags/l/DJ.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/l/DK.svg b/public/flags/l/DK.svg
new file mode 100644
index 0000000..a608dd5
--- /dev/null
+++ b/public/flags/l/DK.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/DM.svg b/public/flags/l/DM.svg
new file mode 100644
index 0000000..c1db5fc
--- /dev/null
+++ b/public/flags/l/DM.svg
@@ -0,0 +1,30 @@
+
diff --git a/public/flags/l/DO.svg b/public/flags/l/DO.svg
new file mode 100644
index 0000000..ac43321
--- /dev/null
+++ b/public/flags/l/DO.svg
@@ -0,0 +1,41 @@
+
diff --git a/public/flags/l/DZ.svg b/public/flags/l/DZ.svg
new file mode 100644
index 0000000..a3e1237
--- /dev/null
+++ b/public/flags/l/DZ.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/EC.svg b/public/flags/l/EC.svg
new file mode 100644
index 0000000..d84a678
--- /dev/null
+++ b/public/flags/l/EC.svg
@@ -0,0 +1,49 @@
+
diff --git a/public/flags/l/EE.svg b/public/flags/l/EE.svg
new file mode 100644
index 0000000..da9c344
--- /dev/null
+++ b/public/flags/l/EE.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/EG.svg b/public/flags/l/EG.svg
new file mode 100644
index 0000000..ec6b006
--- /dev/null
+++ b/public/flags/l/EG.svg
@@ -0,0 +1,31 @@
+
diff --git a/public/flags/l/EH.svg b/public/flags/l/EH.svg
new file mode 100644
index 0000000..499a22c
--- /dev/null
+++ b/public/flags/l/EH.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/l/ER.svg b/public/flags/l/ER.svg
new file mode 100644
index 0000000..b9d0a24
--- /dev/null
+++ b/public/flags/l/ER.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/ES.svg b/public/flags/l/ES.svg
new file mode 100644
index 0000000..371c859
--- /dev/null
+++ b/public/flags/l/ES.svg
@@ -0,0 +1,79 @@
+
diff --git a/public/flags/l/ET.svg b/public/flags/l/ET.svg
new file mode 100644
index 0000000..92706ad
--- /dev/null
+++ b/public/flags/l/ET.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/l/FI.svg b/public/flags/l/FI.svg
new file mode 100644
index 0000000..579667e
--- /dev/null
+++ b/public/flags/l/FI.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/FJ.svg b/public/flags/l/FJ.svg
new file mode 100644
index 0000000..6b1a14e
--- /dev/null
+++ b/public/flags/l/FJ.svg
@@ -0,0 +1,61 @@
+
diff --git a/public/flags/l/FK.svg b/public/flags/l/FK.svg
new file mode 100644
index 0000000..a10cbbe
--- /dev/null
+++ b/public/flags/l/FK.svg
@@ -0,0 +1,31 @@
+
diff --git a/public/flags/l/FM.svg b/public/flags/l/FM.svg
new file mode 100644
index 0000000..af026d4
--- /dev/null
+++ b/public/flags/l/FM.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/l/FO.svg b/public/flags/l/FO.svg
new file mode 100644
index 0000000..25005c6
--- /dev/null
+++ b/public/flags/l/FO.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/FR.svg b/public/flags/l/FR.svg
new file mode 100644
index 0000000..ad57343
--- /dev/null
+++ b/public/flags/l/FR.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/GA.svg b/public/flags/l/GA.svg
new file mode 100644
index 0000000..bc4d944
--- /dev/null
+++ b/public/flags/l/GA.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/GB-NIR.svg b/public/flags/l/GB-NIR.svg
new file mode 100644
index 0000000..1375cb6
--- /dev/null
+++ b/public/flags/l/GB-NIR.svg
@@ -0,0 +1,25 @@
+
diff --git a/public/flags/l/GB-SCT.svg b/public/flags/l/GB-SCT.svg
new file mode 100644
index 0000000..4a08561
--- /dev/null
+++ b/public/flags/l/GB-SCT.svg
@@ -0,0 +1,11 @@
+
diff --git a/public/flags/l/GB-UKM.svg b/public/flags/l/GB-UKM.svg
new file mode 100644
index 0000000..22e1ec3
--- /dev/null
+++ b/public/flags/l/GB-UKM.svg
@@ -0,0 +1,25 @@
+
diff --git a/public/flags/l/GB-WLS.svg b/public/flags/l/GB-WLS.svg
new file mode 100644
index 0000000..744080f
--- /dev/null
+++ b/public/flags/l/GB-WLS.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/l/GB.svg b/public/flags/l/GB.svg
new file mode 100644
index 0000000..c19795b
--- /dev/null
+++ b/public/flags/l/GB.svg
@@ -0,0 +1,12 @@
+
diff --git a/public/flags/l/GD.svg b/public/flags/l/GD.svg
new file mode 100644
index 0000000..78c4233
--- /dev/null
+++ b/public/flags/l/GD.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/l/GE.svg b/public/flags/l/GE.svg
new file mode 100644
index 0000000..965d6b4
--- /dev/null
+++ b/public/flags/l/GE.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/l/GF.svg b/public/flags/l/GF.svg
new file mode 100644
index 0000000..8048540
--- /dev/null
+++ b/public/flags/l/GF.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/GG.svg b/public/flags/l/GG.svg
new file mode 100644
index 0000000..ccd1132
--- /dev/null
+++ b/public/flags/l/GG.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/GH.svg b/public/flags/l/GH.svg
new file mode 100644
index 0000000..cf2bcd2
--- /dev/null
+++ b/public/flags/l/GH.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/GI.svg b/public/flags/l/GI.svg
new file mode 100644
index 0000000..dcf1847
--- /dev/null
+++ b/public/flags/l/GI.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/l/GL.svg b/public/flags/l/GL.svg
new file mode 100644
index 0000000..2ceca6f
--- /dev/null
+++ b/public/flags/l/GL.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/l/GM.svg b/public/flags/l/GM.svg
new file mode 100644
index 0000000..9f9ec53
--- /dev/null
+++ b/public/flags/l/GM.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/GN.svg b/public/flags/l/GN.svg
new file mode 100644
index 0000000..9582410
--- /dev/null
+++ b/public/flags/l/GN.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/GP.svg b/public/flags/l/GP.svg
new file mode 100644
index 0000000..fdb621e
--- /dev/null
+++ b/public/flags/l/GP.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/GQ.svg b/public/flags/l/GQ.svg
new file mode 100644
index 0000000..1255e5c
--- /dev/null
+++ b/public/flags/l/GQ.svg
@@ -0,0 +1,34 @@
+
diff --git a/public/flags/l/GR.svg b/public/flags/l/GR.svg
new file mode 100644
index 0000000..a963b02
--- /dev/null
+++ b/public/flags/l/GR.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/l/GS.svg b/public/flags/l/GS.svg
new file mode 100644
index 0000000..ee7721c
--- /dev/null
+++ b/public/flags/l/GS.svg
@@ -0,0 +1,66 @@
+
diff --git a/public/flags/l/GT.svg b/public/flags/l/GT.svg
new file mode 100644
index 0000000..5002456
--- /dev/null
+++ b/public/flags/l/GT.svg
@@ -0,0 +1,26 @@
+
diff --git a/public/flags/l/GU.svg b/public/flags/l/GU.svg
new file mode 100644
index 0000000..4c9c77f
--- /dev/null
+++ b/public/flags/l/GU.svg
@@ -0,0 +1,35 @@
+
diff --git a/public/flags/l/GW.svg b/public/flags/l/GW.svg
new file mode 100644
index 0000000..929767f
--- /dev/null
+++ b/public/flags/l/GW.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/GY.svg b/public/flags/l/GY.svg
new file mode 100644
index 0000000..3e843ff
--- /dev/null
+++ b/public/flags/l/GY.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/HK.svg b/public/flags/l/HK.svg
new file mode 100644
index 0000000..74bf2b8
--- /dev/null
+++ b/public/flags/l/HK.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/l/HM.svg b/public/flags/l/HM.svg
new file mode 100644
index 0000000..be1bfeb
--- /dev/null
+++ b/public/flags/l/HM.svg
@@ -0,0 +1,34 @@
+
diff --git a/public/flags/l/HN.svg b/public/flags/l/HN.svg
new file mode 100644
index 0000000..7680674
--- /dev/null
+++ b/public/flags/l/HN.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/l/HR.svg b/public/flags/l/HR.svg
new file mode 100644
index 0000000..4a0487e
--- /dev/null
+++ b/public/flags/l/HR.svg
@@ -0,0 +1,60 @@
+
diff --git a/public/flags/l/HT.svg b/public/flags/l/HT.svg
new file mode 100644
index 0000000..a3aa906
--- /dev/null
+++ b/public/flags/l/HT.svg
@@ -0,0 +1,47 @@
+
diff --git a/public/flags/l/HU.svg b/public/flags/l/HU.svg
new file mode 100644
index 0000000..1a49f11
--- /dev/null
+++ b/public/flags/l/HU.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/ID.svg b/public/flags/l/ID.svg
new file mode 100644
index 0000000..605dc1e
--- /dev/null
+++ b/public/flags/l/ID.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/IE.svg b/public/flags/l/IE.svg
new file mode 100644
index 0000000..3181d70
--- /dev/null
+++ b/public/flags/l/IE.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/IL.svg b/public/flags/l/IL.svg
new file mode 100644
index 0000000..9cdcddb
--- /dev/null
+++ b/public/flags/l/IL.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/l/IM.svg b/public/flags/l/IM.svg
new file mode 100644
index 0000000..0e5be82
--- /dev/null
+++ b/public/flags/l/IM.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/l/IN.svg b/public/flags/l/IN.svg
new file mode 100644
index 0000000..9117cb0
--- /dev/null
+++ b/public/flags/l/IN.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/l/IO.svg b/public/flags/l/IO.svg
new file mode 100644
index 0000000..3158c90
--- /dev/null
+++ b/public/flags/l/IO.svg
@@ -0,0 +1,43 @@
+
diff --git a/public/flags/l/IQ.svg b/public/flags/l/IQ.svg
new file mode 100644
index 0000000..3342931
--- /dev/null
+++ b/public/flags/l/IQ.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/l/IR.svg b/public/flags/l/IR.svg
new file mode 100644
index 0000000..4449f3c
--- /dev/null
+++ b/public/flags/l/IR.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/l/IS.svg b/public/flags/l/IS.svg
new file mode 100644
index 0000000..357c89d
--- /dev/null
+++ b/public/flags/l/IS.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/IT.svg b/public/flags/l/IT.svg
new file mode 100644
index 0000000..ee42480
--- /dev/null
+++ b/public/flags/l/IT.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/JE.svg b/public/flags/l/JE.svg
new file mode 100644
index 0000000..dcea67b
--- /dev/null
+++ b/public/flags/l/JE.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/JM.svg b/public/flags/l/JM.svg
new file mode 100644
index 0000000..840814e
--- /dev/null
+++ b/public/flags/l/JM.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/JO.svg b/public/flags/l/JO.svg
new file mode 100644
index 0000000..83f9482
--- /dev/null
+++ b/public/flags/l/JO.svg
@@ -0,0 +1,25 @@
+
diff --git a/public/flags/l/JP.svg b/public/flags/l/JP.svg
new file mode 100644
index 0000000..18127d2
--- /dev/null
+++ b/public/flags/l/JP.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/KE.svg b/public/flags/l/KE.svg
new file mode 100644
index 0000000..7e40e61
--- /dev/null
+++ b/public/flags/l/KE.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/l/KG.svg b/public/flags/l/KG.svg
new file mode 100644
index 0000000..97f7f1b
--- /dev/null
+++ b/public/flags/l/KG.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/KH.svg b/public/flags/l/KH.svg
new file mode 100644
index 0000000..9b56c33
--- /dev/null
+++ b/public/flags/l/KH.svg
@@ -0,0 +1,97 @@
+
diff --git a/public/flags/l/KI.svg b/public/flags/l/KI.svg
new file mode 100644
index 0000000..b265f20
--- /dev/null
+++ b/public/flags/l/KI.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/l/KM.svg b/public/flags/l/KM.svg
new file mode 100644
index 0000000..e44bcc9
--- /dev/null
+++ b/public/flags/l/KM.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/l/KN.svg b/public/flags/l/KN.svg
new file mode 100644
index 0000000..3ff1747
--- /dev/null
+++ b/public/flags/l/KN.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/l/KP.svg b/public/flags/l/KP.svg
new file mode 100644
index 0000000..a153ed9
--- /dev/null
+++ b/public/flags/l/KP.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/l/KR.svg b/public/flags/l/KR.svg
new file mode 100644
index 0000000..a6932a4
--- /dev/null
+++ b/public/flags/l/KR.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/l/KW.svg b/public/flags/l/KW.svg
new file mode 100644
index 0000000..523c6b3
--- /dev/null
+++ b/public/flags/l/KW.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/l/KY.svg b/public/flags/l/KY.svg
new file mode 100644
index 0000000..4886430
--- /dev/null
+++ b/public/flags/l/KY.svg
@@ -0,0 +1,60 @@
+
diff --git a/public/flags/l/KZ.svg b/public/flags/l/KZ.svg
new file mode 100644
index 0000000..84179f8
--- /dev/null
+++ b/public/flags/l/KZ.svg
@@ -0,0 +1,32 @@
+
diff --git a/public/flags/l/LA.svg b/public/flags/l/LA.svg
new file mode 100644
index 0000000..bd64118
--- /dev/null
+++ b/public/flags/l/LA.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/LB.svg b/public/flags/l/LB.svg
new file mode 100644
index 0000000..3ac6809
--- /dev/null
+++ b/public/flags/l/LB.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/LC.svg b/public/flags/l/LC.svg
new file mode 100644
index 0000000..ba3be1d
--- /dev/null
+++ b/public/flags/l/LC.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/LI.svg b/public/flags/l/LI.svg
new file mode 100644
index 0000000..cb3ed38
--- /dev/null
+++ b/public/flags/l/LI.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/l/LK.svg b/public/flags/l/LK.svg
new file mode 100644
index 0000000..b821f45
--- /dev/null
+++ b/public/flags/l/LK.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/LR.svg b/public/flags/l/LR.svg
new file mode 100644
index 0000000..ab2c4bb
--- /dev/null
+++ b/public/flags/l/LR.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/LS.svg b/public/flags/l/LS.svg
new file mode 100644
index 0000000..ae04d1c
--- /dev/null
+++ b/public/flags/l/LS.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/LT.svg b/public/flags/l/LT.svg
new file mode 100644
index 0000000..c32ea7b
--- /dev/null
+++ b/public/flags/l/LT.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/LU.svg b/public/flags/l/LU.svg
new file mode 100644
index 0000000..d8518c1
--- /dev/null
+++ b/public/flags/l/LU.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/LV.svg b/public/flags/l/LV.svg
new file mode 100644
index 0000000..97cdca8
--- /dev/null
+++ b/public/flags/l/LV.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/LY.svg b/public/flags/l/LY.svg
new file mode 100644
index 0000000..c09db62
--- /dev/null
+++ b/public/flags/l/LY.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/MA.svg b/public/flags/l/MA.svg
new file mode 100644
index 0000000..f272b71
--- /dev/null
+++ b/public/flags/l/MA.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/MC.svg b/public/flags/l/MC.svg
new file mode 100644
index 0000000..aa1ac3d
--- /dev/null
+++ b/public/flags/l/MC.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/MD.svg b/public/flags/l/MD.svg
new file mode 100644
index 0000000..1667106
--- /dev/null
+++ b/public/flags/l/MD.svg
@@ -0,0 +1,33 @@
+
diff --git a/public/flags/l/ME.svg b/public/flags/l/ME.svg
new file mode 100644
index 0000000..d033806
--- /dev/null
+++ b/public/flags/l/ME.svg
@@ -0,0 +1,34 @@
+
diff --git a/public/flags/l/MF.svg b/public/flags/l/MF.svg
new file mode 100644
index 0000000..85f237f
--- /dev/null
+++ b/public/flags/l/MF.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/MG.svg b/public/flags/l/MG.svg
new file mode 100644
index 0000000..f2c7236
--- /dev/null
+++ b/public/flags/l/MG.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/MH.svg b/public/flags/l/MH.svg
new file mode 100644
index 0000000..94bb49e
--- /dev/null
+++ b/public/flags/l/MH.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/l/MK.svg b/public/flags/l/MK.svg
new file mode 100644
index 0000000..e19b52a
--- /dev/null
+++ b/public/flags/l/MK.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/ML.svg b/public/flags/l/ML.svg
new file mode 100644
index 0000000..0fae42a
--- /dev/null
+++ b/public/flags/l/ML.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/MM.svg b/public/flags/l/MM.svg
new file mode 100644
index 0000000..129109c
--- /dev/null
+++ b/public/flags/l/MM.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/MN.svg b/public/flags/l/MN.svg
new file mode 100644
index 0000000..0f1c879
--- /dev/null
+++ b/public/flags/l/MN.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/MO.svg b/public/flags/l/MO.svg
new file mode 100644
index 0000000..cc61c1d
--- /dev/null
+++ b/public/flags/l/MO.svg
@@ -0,0 +1,30 @@
+
diff --git a/public/flags/l/MP.svg b/public/flags/l/MP.svg
new file mode 100644
index 0000000..32d4b18
--- /dev/null
+++ b/public/flags/l/MP.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/l/MQ.svg b/public/flags/l/MQ.svg
new file mode 100644
index 0000000..87776b3
--- /dev/null
+++ b/public/flags/l/MQ.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/MR.svg b/public/flags/l/MR.svg
new file mode 100644
index 0000000..32c6f2c
--- /dev/null
+++ b/public/flags/l/MR.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/l/MS.svg b/public/flags/l/MS.svg
new file mode 100644
index 0000000..4ca1d75
--- /dev/null
+++ b/public/flags/l/MS.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/l/MT.svg b/public/flags/l/MT.svg
new file mode 100644
index 0000000..3229789
--- /dev/null
+++ b/public/flags/l/MT.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/MU.svg b/public/flags/l/MU.svg
new file mode 100644
index 0000000..016a5e5
--- /dev/null
+++ b/public/flags/l/MU.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/l/MV.svg b/public/flags/l/MV.svg
new file mode 100644
index 0000000..2c99a4f
--- /dev/null
+++ b/public/flags/l/MV.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/l/MW.svg b/public/flags/l/MW.svg
new file mode 100644
index 0000000..56b6aa0
--- /dev/null
+++ b/public/flags/l/MW.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/l/MX.svg b/public/flags/l/MX.svg
new file mode 100644
index 0000000..716a24b
--- /dev/null
+++ b/public/flags/l/MX.svg
@@ -0,0 +1,22 @@
+
diff --git a/public/flags/l/MY.svg b/public/flags/l/MY.svg
new file mode 100644
index 0000000..29e2e69
--- /dev/null
+++ b/public/flags/l/MY.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/l/MZ.svg b/public/flags/l/MZ.svg
new file mode 100644
index 0000000..77917e9
--- /dev/null
+++ b/public/flags/l/MZ.svg
@@ -0,0 +1,31 @@
+
diff --git a/public/flags/l/NA.svg b/public/flags/l/NA.svg
new file mode 100644
index 0000000..729be88
--- /dev/null
+++ b/public/flags/l/NA.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/l/NC.svg b/public/flags/l/NC.svg
new file mode 100644
index 0000000..1a92319
--- /dev/null
+++ b/public/flags/l/NC.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/NE.svg b/public/flags/l/NE.svg
new file mode 100644
index 0000000..8f47e8f
--- /dev/null
+++ b/public/flags/l/NE.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/l/NF.svg b/public/flags/l/NF.svg
new file mode 100644
index 0000000..ad1d9f2
--- /dev/null
+++ b/public/flags/l/NF.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/NG.svg b/public/flags/l/NG.svg
new file mode 100644
index 0000000..b2f4b52
--- /dev/null
+++ b/public/flags/l/NG.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/NI.svg b/public/flags/l/NI.svg
new file mode 100644
index 0000000..012c9fb
--- /dev/null
+++ b/public/flags/l/NI.svg
@@ -0,0 +1,31 @@
+
diff --git a/public/flags/l/NL.svg b/public/flags/l/NL.svg
new file mode 100644
index 0000000..89b8e1c
--- /dev/null
+++ b/public/flags/l/NL.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/NO.svg b/public/flags/l/NO.svg
new file mode 100644
index 0000000..c239f29
--- /dev/null
+++ b/public/flags/l/NO.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/NP.svg b/public/flags/l/NP.svg
new file mode 100644
index 0000000..bbf7c90
--- /dev/null
+++ b/public/flags/l/NP.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/l/NR.svg b/public/flags/l/NR.svg
new file mode 100644
index 0000000..904f431
--- /dev/null
+++ b/public/flags/l/NR.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/NU.svg b/public/flags/l/NU.svg
new file mode 100644
index 0000000..d7afcf0
--- /dev/null
+++ b/public/flags/l/NU.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/l/NZ.svg b/public/flags/l/NZ.svg
new file mode 100644
index 0000000..9fbdebc
--- /dev/null
+++ b/public/flags/l/NZ.svg
@@ -0,0 +1,30 @@
+
diff --git a/public/flags/l/OM.svg b/public/flags/l/OM.svg
new file mode 100644
index 0000000..bdc03dc
--- /dev/null
+++ b/public/flags/l/OM.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/l/PA.svg b/public/flags/l/PA.svg
new file mode 100644
index 0000000..8d22ddc
--- /dev/null
+++ b/public/flags/l/PA.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/l/PE.svg b/public/flags/l/PE.svg
new file mode 100644
index 0000000..5bfe6a1
--- /dev/null
+++ b/public/flags/l/PE.svg
@@ -0,0 +1,45 @@
+
diff --git a/public/flags/l/PF.svg b/public/flags/l/PF.svg
new file mode 100644
index 0000000..b3c2681
--- /dev/null
+++ b/public/flags/l/PF.svg
@@ -0,0 +1,42 @@
+
diff --git a/public/flags/l/PG.svg b/public/flags/l/PG.svg
new file mode 100644
index 0000000..b053485
--- /dev/null
+++ b/public/flags/l/PG.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/PH.svg b/public/flags/l/PH.svg
new file mode 100644
index 0000000..eeec523
--- /dev/null
+++ b/public/flags/l/PH.svg
@@ -0,0 +1,28 @@
+
diff --git a/public/flags/l/PK.svg b/public/flags/l/PK.svg
new file mode 100644
index 0000000..8f19c3b
--- /dev/null
+++ b/public/flags/l/PK.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/PL.svg b/public/flags/l/PL.svg
new file mode 100644
index 0000000..8f2ebf4
--- /dev/null
+++ b/public/flags/l/PL.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/PM.svg b/public/flags/l/PM.svg
new file mode 100644
index 0000000..6911162
--- /dev/null
+++ b/public/flags/l/PM.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/PN.svg b/public/flags/l/PN.svg
new file mode 100644
index 0000000..8dc1c1a
--- /dev/null
+++ b/public/flags/l/PN.svg
@@ -0,0 +1,57 @@
+
diff --git a/public/flags/l/PR.svg b/public/flags/l/PR.svg
new file mode 100644
index 0000000..b189a8c
--- /dev/null
+++ b/public/flags/l/PR.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/l/PS.svg b/public/flags/l/PS.svg
new file mode 100644
index 0000000..1d0ee1c
--- /dev/null
+++ b/public/flags/l/PS.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/PT.svg b/public/flags/l/PT.svg
new file mode 100644
index 0000000..e4c3d1f
--- /dev/null
+++ b/public/flags/l/PT.svg
@@ -0,0 +1,121 @@
+
diff --git a/public/flags/l/PW.svg b/public/flags/l/PW.svg
new file mode 100644
index 0000000..172f8f6
--- /dev/null
+++ b/public/flags/l/PW.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/PY.svg b/public/flags/l/PY.svg
new file mode 100644
index 0000000..e58276d
--- /dev/null
+++ b/public/flags/l/PY.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/l/QA.svg b/public/flags/l/QA.svg
new file mode 100644
index 0000000..c81ad8b
--- /dev/null
+++ b/public/flags/l/QA.svg
@@ -0,0 +1,12 @@
+
diff --git a/public/flags/l/RE.svg b/public/flags/l/RE.svg
new file mode 100644
index 0000000..6424614
--- /dev/null
+++ b/public/flags/l/RE.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/RO.svg b/public/flags/l/RO.svg
new file mode 100644
index 0000000..17e15b0
--- /dev/null
+++ b/public/flags/l/RO.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/RS.svg b/public/flags/l/RS.svg
new file mode 100644
index 0000000..c9ce390
--- /dev/null
+++ b/public/flags/l/RS.svg
@@ -0,0 +1,34 @@
+
diff --git a/public/flags/l/RU.svg b/public/flags/l/RU.svg
new file mode 100644
index 0000000..0dceb5a
--- /dev/null
+++ b/public/flags/l/RU.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/RW.svg b/public/flags/l/RW.svg
new file mode 100644
index 0000000..f02e3e8
--- /dev/null
+++ b/public/flags/l/RW.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/l/SA.svg b/public/flags/l/SA.svg
new file mode 100644
index 0000000..f37c89b
--- /dev/null
+++ b/public/flags/l/SA.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/l/SB.svg b/public/flags/l/SB.svg
new file mode 100644
index 0000000..a54c4f1
--- /dev/null
+++ b/public/flags/l/SB.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/l/SC.svg b/public/flags/l/SC.svg
new file mode 100644
index 0000000..fa37ed8
--- /dev/null
+++ b/public/flags/l/SC.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/l/SD.svg b/public/flags/l/SD.svg
new file mode 100644
index 0000000..2f7d3cf
--- /dev/null
+++ b/public/flags/l/SD.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/SE.svg b/public/flags/l/SE.svg
new file mode 100644
index 0000000..0aeb247
--- /dev/null
+++ b/public/flags/l/SE.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/SG.svg b/public/flags/l/SG.svg
new file mode 100644
index 0000000..8fe8174
--- /dev/null
+++ b/public/flags/l/SG.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/SH.svg b/public/flags/l/SH.svg
new file mode 100644
index 0000000..c22d7a5
--- /dev/null
+++ b/public/flags/l/SH.svg
@@ -0,0 +1,28 @@
+
diff --git a/public/flags/l/SI.svg b/public/flags/l/SI.svg
new file mode 100644
index 0000000..1e7e519
--- /dev/null
+++ b/public/flags/l/SI.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/l/SJ.svg b/public/flags/l/SJ.svg
new file mode 100644
index 0000000..4745e9f
--- /dev/null
+++ b/public/flags/l/SJ.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/SK.svg b/public/flags/l/SK.svg
new file mode 100644
index 0000000..3728166
--- /dev/null
+++ b/public/flags/l/SK.svg
@@ -0,0 +1,26 @@
+
diff --git a/public/flags/l/SL.svg b/public/flags/l/SL.svg
new file mode 100644
index 0000000..c538e39
--- /dev/null
+++ b/public/flags/l/SL.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/SM.svg b/public/flags/l/SM.svg
new file mode 100644
index 0000000..bf6e0ef
--- /dev/null
+++ b/public/flags/l/SM.svg
@@ -0,0 +1,42 @@
+
diff --git a/public/flags/l/SN.svg b/public/flags/l/SN.svg
new file mode 100644
index 0000000..8ac150d
--- /dev/null
+++ b/public/flags/l/SN.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/SO.svg b/public/flags/l/SO.svg
new file mode 100644
index 0000000..678d5cd
--- /dev/null
+++ b/public/flags/l/SO.svg
@@ -0,0 +1,12 @@
+
diff --git a/public/flags/l/SR.svg b/public/flags/l/SR.svg
new file mode 100644
index 0000000..b326c82
--- /dev/null
+++ b/public/flags/l/SR.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/SS.svg b/public/flags/l/SS.svg
new file mode 100644
index 0000000..99bb04d
--- /dev/null
+++ b/public/flags/l/SS.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/l/ST.svg b/public/flags/l/ST.svg
new file mode 100644
index 0000000..5c2d46d
--- /dev/null
+++ b/public/flags/l/ST.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/l/SV.svg b/public/flags/l/SV.svg
new file mode 100644
index 0000000..5139ff1
--- /dev/null
+++ b/public/flags/l/SV.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/l/SX.svg b/public/flags/l/SX.svg
new file mode 100644
index 0000000..50df181
--- /dev/null
+++ b/public/flags/l/SX.svg
@@ -0,0 +1,35 @@
+
diff --git a/public/flags/l/SY.svg b/public/flags/l/SY.svg
new file mode 100644
index 0000000..83b9c2f
--- /dev/null
+++ b/public/flags/l/SY.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/l/SZ.svg b/public/flags/l/SZ.svg
new file mode 100644
index 0000000..59e0944
--- /dev/null
+++ b/public/flags/l/SZ.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/l/TC.svg b/public/flags/l/TC.svg
new file mode 100644
index 0000000..ba990b2
--- /dev/null
+++ b/public/flags/l/TC.svg
@@ -0,0 +1,28 @@
+
diff --git a/public/flags/l/TD.svg b/public/flags/l/TD.svg
new file mode 100644
index 0000000..a65e003
--- /dev/null
+++ b/public/flags/l/TD.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/TF.svg b/public/flags/l/TF.svg
new file mode 100644
index 0000000..403631a
--- /dev/null
+++ b/public/flags/l/TF.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/l/TG.svg b/public/flags/l/TG.svg
new file mode 100644
index 0000000..5d7c7ce
--- /dev/null
+++ b/public/flags/l/TG.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/l/TH.svg b/public/flags/l/TH.svg
new file mode 100644
index 0000000..d222cd8
--- /dev/null
+++ b/public/flags/l/TH.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/TJ.svg b/public/flags/l/TJ.svg
new file mode 100644
index 0000000..0ecb62a
--- /dev/null
+++ b/public/flags/l/TJ.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/l/TK.svg b/public/flags/l/TK.svg
new file mode 100644
index 0000000..20461c0
--- /dev/null
+++ b/public/flags/l/TK.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/l/TL.svg b/public/flags/l/TL.svg
new file mode 100644
index 0000000..e1fdc4e
--- /dev/null
+++ b/public/flags/l/TL.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/TM.svg b/public/flags/l/TM.svg
new file mode 100644
index 0000000..2d5ec3f
--- /dev/null
+++ b/public/flags/l/TM.svg
@@ -0,0 +1,75 @@
+
diff --git a/public/flags/l/TN.svg b/public/flags/l/TN.svg
new file mode 100644
index 0000000..101c2be
--- /dev/null
+++ b/public/flags/l/TN.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/TO.svg b/public/flags/l/TO.svg
new file mode 100644
index 0000000..1d471c8
--- /dev/null
+++ b/public/flags/l/TO.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/TR.svg b/public/flags/l/TR.svg
new file mode 100644
index 0000000..e100c94
--- /dev/null
+++ b/public/flags/l/TR.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/TT.svg b/public/flags/l/TT.svg
new file mode 100644
index 0000000..d15172c
--- /dev/null
+++ b/public/flags/l/TT.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/TV.svg b/public/flags/l/TV.svg
new file mode 100644
index 0000000..435f799
--- /dev/null
+++ b/public/flags/l/TV.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/l/TW.svg b/public/flags/l/TW.svg
new file mode 100644
index 0000000..88a0df2
--- /dev/null
+++ b/public/flags/l/TW.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/TZ.svg b/public/flags/l/TZ.svg
new file mode 100644
index 0000000..fa1374f
--- /dev/null
+++ b/public/flags/l/TZ.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/UA.svg b/public/flags/l/UA.svg
new file mode 100644
index 0000000..aca2885
--- /dev/null
+++ b/public/flags/l/UA.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/l/UG.svg b/public/flags/l/UG.svg
new file mode 100644
index 0000000..6121a3b
--- /dev/null
+++ b/public/flags/l/UG.svg
@@ -0,0 +1,28 @@
+
diff --git a/public/flags/l/UM.svg b/public/flags/l/UM.svg
new file mode 100644
index 0000000..0e7ce16
--- /dev/null
+++ b/public/flags/l/UM.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/l/US.svg b/public/flags/l/US.svg
new file mode 100644
index 0000000..1c1fa9f
--- /dev/null
+++ b/public/flags/l/US.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/l/UY.svg b/public/flags/l/UY.svg
new file mode 100644
index 0000000..2f6ad55
--- /dev/null
+++ b/public/flags/l/UY.svg
@@ -0,0 +1,32 @@
+
diff --git a/public/flags/l/UZ.svg b/public/flags/l/UZ.svg
new file mode 100644
index 0000000..d2a876a
--- /dev/null
+++ b/public/flags/l/UZ.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/VA.svg b/public/flags/l/VA.svg
new file mode 100644
index 0000000..74c8d04
--- /dev/null
+++ b/public/flags/l/VA.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/l/VC.svg b/public/flags/l/VC.svg
new file mode 100644
index 0000000..90d1cbf
--- /dev/null
+++ b/public/flags/l/VC.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/l/VE.svg b/public/flags/l/VE.svg
new file mode 100644
index 0000000..84beecc
--- /dev/null
+++ b/public/flags/l/VE.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/l/VG.svg b/public/flags/l/VG.svg
new file mode 100644
index 0000000..20f9919
--- /dev/null
+++ b/public/flags/l/VG.svg
@@ -0,0 +1,28 @@
+
diff --git a/public/flags/l/VI.svg b/public/flags/l/VI.svg
new file mode 100644
index 0000000..bb889f3
--- /dev/null
+++ b/public/flags/l/VI.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/l/VN.svg b/public/flags/l/VN.svg
new file mode 100644
index 0000000..b007320
--- /dev/null
+++ b/public/flags/l/VN.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/VU.svg b/public/flags/l/VU.svg
new file mode 100644
index 0000000..38d9611
--- /dev/null
+++ b/public/flags/l/VU.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/l/WF.svg b/public/flags/l/WF.svg
new file mode 100644
index 0000000..69f8a1b
--- /dev/null
+++ b/public/flags/l/WF.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/l/WS.svg b/public/flags/l/WS.svg
new file mode 100644
index 0000000..69e8e8d
--- /dev/null
+++ b/public/flags/l/WS.svg
@@ -0,0 +1,22 @@
+
diff --git a/public/flags/l/YE.svg b/public/flags/l/YE.svg
new file mode 100644
index 0000000..81f2ac9
--- /dev/null
+++ b/public/flags/l/YE.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/l/YT.svg b/public/flags/l/YT.svg
new file mode 100644
index 0000000..08e88f6
--- /dev/null
+++ b/public/flags/l/YT.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/l/ZA.svg b/public/flags/l/ZA.svg
new file mode 100644
index 0000000..f893769
--- /dev/null
+++ b/public/flags/l/ZA.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/l/ZM.svg b/public/flags/l/ZM.svg
new file mode 100644
index 0000000..790483f
--- /dev/null
+++ b/public/flags/l/ZM.svg
@@ -0,0 +1,22 @@
+
diff --git a/public/flags/l/ZW.svg b/public/flags/l/ZW.svg
new file mode 100644
index 0000000..5f109ad
--- /dev/null
+++ b/public/flags/l/ZW.svg
@@ -0,0 +1,28 @@
+
diff --git a/public/flags/m/AD.svg b/public/flags/m/AD.svg
new file mode 100644
index 0000000..0f226c8
--- /dev/null
+++ b/public/flags/m/AD.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/m/AE.svg b/public/flags/m/AE.svg
new file mode 100644
index 0000000..e24b8db
--- /dev/null
+++ b/public/flags/m/AE.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/AF.svg b/public/flags/m/AF.svg
new file mode 100644
index 0000000..6546ac9
--- /dev/null
+++ b/public/flags/m/AF.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/m/AG.svg b/public/flags/m/AG.svg
new file mode 100644
index 0000000..f13e9e2
--- /dev/null
+++ b/public/flags/m/AG.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/m/AI.svg b/public/flags/m/AI.svg
new file mode 100644
index 0000000..b77c1ec
--- /dev/null
+++ b/public/flags/m/AI.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/m/AL.svg b/public/flags/m/AL.svg
new file mode 100644
index 0000000..8168980
--- /dev/null
+++ b/public/flags/m/AL.svg
@@ -0,0 +1,12 @@
+
diff --git a/public/flags/m/AM.svg b/public/flags/m/AM.svg
new file mode 100644
index 0000000..90f1f8f
--- /dev/null
+++ b/public/flags/m/AM.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/AO.svg b/public/flags/m/AO.svg
new file mode 100644
index 0000000..0d01265
--- /dev/null
+++ b/public/flags/m/AO.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/m/AQ.svg b/public/flags/m/AQ.svg
new file mode 100644
index 0000000..8944055
--- /dev/null
+++ b/public/flags/m/AQ.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/m/AR.svg b/public/flags/m/AR.svg
new file mode 100644
index 0000000..98ed0e9
--- /dev/null
+++ b/public/flags/m/AR.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/m/AS.svg b/public/flags/m/AS.svg
new file mode 100644
index 0000000..fd1967e
--- /dev/null
+++ b/public/flags/m/AS.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/AT.svg b/public/flags/m/AT.svg
new file mode 100644
index 0000000..f2bb062
--- /dev/null
+++ b/public/flags/m/AT.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/AU.svg b/public/flags/m/AU.svg
new file mode 100644
index 0000000..e1a1d7c
--- /dev/null
+++ b/public/flags/m/AU.svg
@@ -0,0 +1,34 @@
+
diff --git a/public/flags/m/AW.svg b/public/flags/m/AW.svg
new file mode 100644
index 0000000..615b4ff
--- /dev/null
+++ b/public/flags/m/AW.svg
@@ -0,0 +1,30 @@
+
diff --git a/public/flags/m/AX.svg b/public/flags/m/AX.svg
new file mode 100644
index 0000000..92484aa
--- /dev/null
+++ b/public/flags/m/AX.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/AZ.svg b/public/flags/m/AZ.svg
new file mode 100644
index 0000000..a89bc8a
--- /dev/null
+++ b/public/flags/m/AZ.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/m/BA.svg b/public/flags/m/BA.svg
new file mode 100644
index 0000000..855270f
--- /dev/null
+++ b/public/flags/m/BA.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/BB.svg b/public/flags/m/BB.svg
new file mode 100644
index 0000000..fbd61dc
--- /dev/null
+++ b/public/flags/m/BB.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/BD.svg b/public/flags/m/BD.svg
new file mode 100644
index 0000000..5134152
--- /dev/null
+++ b/public/flags/m/BD.svg
@@ -0,0 +1,12 @@
+
diff --git a/public/flags/m/BE.svg b/public/flags/m/BE.svg
new file mode 100644
index 0000000..d5c4585
--- /dev/null
+++ b/public/flags/m/BE.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/BF.svg b/public/flags/m/BF.svg
new file mode 100644
index 0000000..af32645
--- /dev/null
+++ b/public/flags/m/BF.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/BG.svg b/public/flags/m/BG.svg
new file mode 100644
index 0000000..3de5a0b
--- /dev/null
+++ b/public/flags/m/BG.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/BH.svg b/public/flags/m/BH.svg
new file mode 100644
index 0000000..728b110
--- /dev/null
+++ b/public/flags/m/BH.svg
@@ -0,0 +1,12 @@
+
diff --git a/public/flags/m/BI.svg b/public/flags/m/BI.svg
new file mode 100644
index 0000000..8714969
--- /dev/null
+++ b/public/flags/m/BI.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/m/BJ.svg b/public/flags/m/BJ.svg
new file mode 100644
index 0000000..6fc8a7b
--- /dev/null
+++ b/public/flags/m/BJ.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/BL.svg b/public/flags/m/BL.svg
new file mode 100644
index 0000000..9476156
--- /dev/null
+++ b/public/flags/m/BL.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/BM.svg b/public/flags/m/BM.svg
new file mode 100644
index 0000000..4029903
--- /dev/null
+++ b/public/flags/m/BM.svg
@@ -0,0 +1,38 @@
+
diff --git a/public/flags/m/BN.svg b/public/flags/m/BN.svg
new file mode 100644
index 0000000..501e434
--- /dev/null
+++ b/public/flags/m/BN.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/m/BO.svg b/public/flags/m/BO.svg
new file mode 100644
index 0000000..5f681b3
--- /dev/null
+++ b/public/flags/m/BO.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/m/BQ-BO.svg b/public/flags/m/BQ-BO.svg
new file mode 100644
index 0000000..4bcbf9a
--- /dev/null
+++ b/public/flags/m/BQ-BO.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/m/BQ-SA.svg b/public/flags/m/BQ-SA.svg
new file mode 100644
index 0000000..2eb35a9
--- /dev/null
+++ b/public/flags/m/BQ-SA.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/m/BQ-SE.svg b/public/flags/m/BQ-SE.svg
new file mode 100644
index 0000000..2d27c4e
--- /dev/null
+++ b/public/flags/m/BQ-SE.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/m/BR.svg b/public/flags/m/BR.svg
new file mode 100644
index 0000000..1a25444
--- /dev/null
+++ b/public/flags/m/BR.svg
@@ -0,0 +1,47 @@
+
diff --git a/public/flags/m/BS.svg b/public/flags/m/BS.svg
new file mode 100644
index 0000000..222fdd9
--- /dev/null
+++ b/public/flags/m/BS.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/BT.svg b/public/flags/m/BT.svg
new file mode 100644
index 0000000..ff384c9
--- /dev/null
+++ b/public/flags/m/BT.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/m/BV.svg b/public/flags/m/BV.svg
new file mode 100644
index 0000000..01fad26
--- /dev/null
+++ b/public/flags/m/BV.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/BW.svg b/public/flags/m/BW.svg
new file mode 100644
index 0000000..0e546e7
--- /dev/null
+++ b/public/flags/m/BW.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/BY.svg b/public/flags/m/BY.svg
new file mode 100644
index 0000000..2790025
--- /dev/null
+++ b/public/flags/m/BY.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/m/BZ.svg b/public/flags/m/BZ.svg
new file mode 100644
index 0000000..77b5c22
--- /dev/null
+++ b/public/flags/m/BZ.svg
@@ -0,0 +1,28 @@
+
diff --git a/public/flags/m/CA.svg b/public/flags/m/CA.svg
new file mode 100644
index 0000000..e01e084
--- /dev/null
+++ b/public/flags/m/CA.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/CC.svg b/public/flags/m/CC.svg
new file mode 100644
index 0000000..1612e83
--- /dev/null
+++ b/public/flags/m/CC.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/m/CD.svg b/public/flags/m/CD.svg
new file mode 100644
index 0000000..cfdc7fa
--- /dev/null
+++ b/public/flags/m/CD.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/CF.svg b/public/flags/m/CF.svg
new file mode 100644
index 0000000..9e7b225
--- /dev/null
+++ b/public/flags/m/CF.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/m/CG.svg b/public/flags/m/CG.svg
new file mode 100644
index 0000000..962d485
--- /dev/null
+++ b/public/flags/m/CG.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/CH.svg b/public/flags/m/CH.svg
new file mode 100644
index 0000000..d6cd5bb
--- /dev/null
+++ b/public/flags/m/CH.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/CI.svg b/public/flags/m/CI.svg
new file mode 100644
index 0000000..8d5fe64
--- /dev/null
+++ b/public/flags/m/CI.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/CK.svg b/public/flags/m/CK.svg
new file mode 100644
index 0000000..94ffb07
--- /dev/null
+++ b/public/flags/m/CK.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/m/CL.svg b/public/flags/m/CL.svg
new file mode 100644
index 0000000..cdf4377
--- /dev/null
+++ b/public/flags/m/CL.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/CM.svg b/public/flags/m/CM.svg
new file mode 100644
index 0000000..9e1854e
--- /dev/null
+++ b/public/flags/m/CM.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/CN.svg b/public/flags/m/CN.svg
new file mode 100644
index 0000000..ea05080
--- /dev/null
+++ b/public/flags/m/CN.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/m/CO.svg b/public/flags/m/CO.svg
new file mode 100644
index 0000000..a17752f
--- /dev/null
+++ b/public/flags/m/CO.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/CR.svg b/public/flags/m/CR.svg
new file mode 100644
index 0000000..88e321b
--- /dev/null
+++ b/public/flags/m/CR.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/CU.svg b/public/flags/m/CU.svg
new file mode 100644
index 0000000..d33c469
--- /dev/null
+++ b/public/flags/m/CU.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/m/CV.svg b/public/flags/m/CV.svg
new file mode 100644
index 0000000..9685f82
--- /dev/null
+++ b/public/flags/m/CV.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/m/CW.svg b/public/flags/m/CW.svg
new file mode 100644
index 0000000..f8d41ca
--- /dev/null
+++ b/public/flags/m/CW.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/m/CX.svg b/public/flags/m/CX.svg
new file mode 100644
index 0000000..1ea4bc5
--- /dev/null
+++ b/public/flags/m/CX.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/m/CY.svg b/public/flags/m/CY.svg
new file mode 100644
index 0000000..adbbfbe
--- /dev/null
+++ b/public/flags/m/CY.svg
@@ -0,0 +1,28 @@
+
diff --git a/public/flags/m/CZ.svg b/public/flags/m/CZ.svg
new file mode 100644
index 0000000..907fc1e
--- /dev/null
+++ b/public/flags/m/CZ.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/m/DE.svg b/public/flags/m/DE.svg
new file mode 100644
index 0000000..fa3dd78
--- /dev/null
+++ b/public/flags/m/DE.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/DJ.svg b/public/flags/m/DJ.svg
new file mode 100644
index 0000000..f5fc88c
--- /dev/null
+++ b/public/flags/m/DJ.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/m/DK.svg b/public/flags/m/DK.svg
new file mode 100644
index 0000000..b29d938
--- /dev/null
+++ b/public/flags/m/DK.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/DM.svg b/public/flags/m/DM.svg
new file mode 100644
index 0000000..cdeb4ee
--- /dev/null
+++ b/public/flags/m/DM.svg
@@ -0,0 +1,26 @@
+
diff --git a/public/flags/m/DO.svg b/public/flags/m/DO.svg
new file mode 100644
index 0000000..f27cf20
--- /dev/null
+++ b/public/flags/m/DO.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/m/DZ.svg b/public/flags/m/DZ.svg
new file mode 100644
index 0000000..57072ce
--- /dev/null
+++ b/public/flags/m/DZ.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/EC.svg b/public/flags/m/EC.svg
new file mode 100644
index 0000000..4e1aad2
--- /dev/null
+++ b/public/flags/m/EC.svg
@@ -0,0 +1,37 @@
+
diff --git a/public/flags/m/EE.svg b/public/flags/m/EE.svg
new file mode 100644
index 0000000..c88db1a
--- /dev/null
+++ b/public/flags/m/EE.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/EG.svg b/public/flags/m/EG.svg
new file mode 100644
index 0000000..4fc356a
--- /dev/null
+++ b/public/flags/m/EG.svg
@@ -0,0 +1,31 @@
+
diff --git a/public/flags/m/EH.svg b/public/flags/m/EH.svg
new file mode 100644
index 0000000..c37d4dc
--- /dev/null
+++ b/public/flags/m/EH.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/m/ER.svg b/public/flags/m/ER.svg
new file mode 100644
index 0000000..07f8b55
--- /dev/null
+++ b/public/flags/m/ER.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/ES.svg b/public/flags/m/ES.svg
new file mode 100644
index 0000000..e79fb87
--- /dev/null
+++ b/public/flags/m/ES.svg
@@ -0,0 +1,79 @@
+
diff --git a/public/flags/m/ET.svg b/public/flags/m/ET.svg
new file mode 100644
index 0000000..26c76f6
--- /dev/null
+++ b/public/flags/m/ET.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/m/FI.svg b/public/flags/m/FI.svg
new file mode 100644
index 0000000..fde502e
--- /dev/null
+++ b/public/flags/m/FI.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/FJ.svg b/public/flags/m/FJ.svg
new file mode 100644
index 0000000..155a49b
--- /dev/null
+++ b/public/flags/m/FJ.svg
@@ -0,0 +1,56 @@
+
diff --git a/public/flags/m/FK.svg b/public/flags/m/FK.svg
new file mode 100644
index 0000000..bdc0c2e
--- /dev/null
+++ b/public/flags/m/FK.svg
@@ -0,0 +1,26 @@
+
diff --git a/public/flags/m/FM.svg b/public/flags/m/FM.svg
new file mode 100644
index 0000000..6fe3524
--- /dev/null
+++ b/public/flags/m/FM.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/m/FO.svg b/public/flags/m/FO.svg
new file mode 100644
index 0000000..4b4c2b2
--- /dev/null
+++ b/public/flags/m/FO.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/FR.svg b/public/flags/m/FR.svg
new file mode 100644
index 0000000..e9261de
--- /dev/null
+++ b/public/flags/m/FR.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/GA.svg b/public/flags/m/GA.svg
new file mode 100644
index 0000000..cbbcf44
--- /dev/null
+++ b/public/flags/m/GA.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/GB-ENG.svg b/public/flags/m/GB-ENG.svg
new file mode 100644
index 0000000..5a18f9f
--- /dev/null
+++ b/public/flags/m/GB-ENG.svg
@@ -0,0 +1,12 @@
+
diff --git a/public/flags/m/GB-NIR.svg b/public/flags/m/GB-NIR.svg
new file mode 100644
index 0000000..864a419
--- /dev/null
+++ b/public/flags/m/GB-NIR.svg
@@ -0,0 +1,25 @@
+
diff --git a/public/flags/m/GB-SCT.svg b/public/flags/m/GB-SCT.svg
new file mode 100644
index 0000000..f7f4fc4
--- /dev/null
+++ b/public/flags/m/GB-SCT.svg
@@ -0,0 +1,11 @@
+
diff --git a/public/flags/m/GB-UKM.svg b/public/flags/m/GB-UKM.svg
new file mode 100644
index 0000000..691187c
--- /dev/null
+++ b/public/flags/m/GB-UKM.svg
@@ -0,0 +1,25 @@
+
diff --git a/public/flags/m/GB-WLS.svg b/public/flags/m/GB-WLS.svg
new file mode 100644
index 0000000..6788a5c
--- /dev/null
+++ b/public/flags/m/GB-WLS.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/GD.svg b/public/flags/m/GD.svg
new file mode 100644
index 0000000..533179f
--- /dev/null
+++ b/public/flags/m/GD.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/m/GE.svg b/public/flags/m/GE.svg
new file mode 100644
index 0000000..8f550f9
--- /dev/null
+++ b/public/flags/m/GE.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/m/GF.svg b/public/flags/m/GF.svg
new file mode 100644
index 0000000..80e1dd5
--- /dev/null
+++ b/public/flags/m/GF.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/GG.svg b/public/flags/m/GG.svg
new file mode 100644
index 0000000..12b08a2
--- /dev/null
+++ b/public/flags/m/GG.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/GH.svg b/public/flags/m/GH.svg
new file mode 100644
index 0000000..e91b304
--- /dev/null
+++ b/public/flags/m/GH.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/GI.svg b/public/flags/m/GI.svg
new file mode 100644
index 0000000..3e19a7e
--- /dev/null
+++ b/public/flags/m/GI.svg
@@ -0,0 +1,22 @@
+
diff --git a/public/flags/m/GL.svg b/public/flags/m/GL.svg
new file mode 100644
index 0000000..afaee71
--- /dev/null
+++ b/public/flags/m/GL.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/m/GM.svg b/public/flags/m/GM.svg
new file mode 100644
index 0000000..8cae9fb
--- /dev/null
+++ b/public/flags/m/GM.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/GN.svg b/public/flags/m/GN.svg
new file mode 100644
index 0000000..486877e
--- /dev/null
+++ b/public/flags/m/GN.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/GP.svg b/public/flags/m/GP.svg
new file mode 100644
index 0000000..fca29a0
--- /dev/null
+++ b/public/flags/m/GP.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/GQ.svg b/public/flags/m/GQ.svg
new file mode 100644
index 0000000..a528ade
--- /dev/null
+++ b/public/flags/m/GQ.svg
@@ -0,0 +1,34 @@
+
diff --git a/public/flags/m/GR.svg b/public/flags/m/GR.svg
new file mode 100644
index 0000000..52a492a
--- /dev/null
+++ b/public/flags/m/GR.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/GS.svg b/public/flags/m/GS.svg
new file mode 100644
index 0000000..22e087f
--- /dev/null
+++ b/public/flags/m/GS.svg
@@ -0,0 +1,67 @@
+
diff --git a/public/flags/m/GT.svg b/public/flags/m/GT.svg
new file mode 100644
index 0000000..46ab5c3
--- /dev/null
+++ b/public/flags/m/GT.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/GU.svg b/public/flags/m/GU.svg
new file mode 100644
index 0000000..0828b95
--- /dev/null
+++ b/public/flags/m/GU.svg
@@ -0,0 +1,35 @@
+
diff --git a/public/flags/m/GW.svg b/public/flags/m/GW.svg
new file mode 100644
index 0000000..5d11add
--- /dev/null
+++ b/public/flags/m/GW.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/GY.svg b/public/flags/m/GY.svg
new file mode 100644
index 0000000..14e9209
--- /dev/null
+++ b/public/flags/m/GY.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/HK.svg b/public/flags/m/HK.svg
new file mode 100644
index 0000000..7bdb90d
--- /dev/null
+++ b/public/flags/m/HK.svg
@@ -0,0 +1,33 @@
+
diff --git a/public/flags/m/HM.svg b/public/flags/m/HM.svg
new file mode 100644
index 0000000..27a8fbb
--- /dev/null
+++ b/public/flags/m/HM.svg
@@ -0,0 +1,34 @@
+
diff --git a/public/flags/m/HN.svg b/public/flags/m/HN.svg
new file mode 100644
index 0000000..2de787a
--- /dev/null
+++ b/public/flags/m/HN.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/m/HR.svg b/public/flags/m/HR.svg
new file mode 100644
index 0000000..3656e62
--- /dev/null
+++ b/public/flags/m/HR.svg
@@ -0,0 +1,60 @@
+
diff --git a/public/flags/m/HT.svg b/public/flags/m/HT.svg
new file mode 100644
index 0000000..71c4384
--- /dev/null
+++ b/public/flags/m/HT.svg
@@ -0,0 +1,47 @@
+
diff --git a/public/flags/m/HU.svg b/public/flags/m/HU.svg
new file mode 100644
index 0000000..c966306
--- /dev/null
+++ b/public/flags/m/HU.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/ID.svg b/public/flags/m/ID.svg
new file mode 100644
index 0000000..09f251c
--- /dev/null
+++ b/public/flags/m/ID.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/IE.svg b/public/flags/m/IE.svg
new file mode 100644
index 0000000..f0782af
--- /dev/null
+++ b/public/flags/m/IE.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/IL.svg b/public/flags/m/IL.svg
new file mode 100644
index 0000000..7ac0c6a
--- /dev/null
+++ b/public/flags/m/IL.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/m/IM.svg b/public/flags/m/IM.svg
new file mode 100644
index 0000000..1194ed7
--- /dev/null
+++ b/public/flags/m/IM.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/m/IN.svg b/public/flags/m/IN.svg
new file mode 100644
index 0000000..dbf3720
--- /dev/null
+++ b/public/flags/m/IN.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/m/IO.svg b/public/flags/m/IO.svg
new file mode 100644
index 0000000..82d721d
--- /dev/null
+++ b/public/flags/m/IO.svg
@@ -0,0 +1,44 @@
+
diff --git a/public/flags/m/IQ.svg b/public/flags/m/IQ.svg
new file mode 100644
index 0000000..5f28263
--- /dev/null
+++ b/public/flags/m/IQ.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/m/IR.svg b/public/flags/m/IR.svg
new file mode 100644
index 0000000..664e0ca
--- /dev/null
+++ b/public/flags/m/IR.svg
@@ -0,0 +1,89 @@
+
diff --git a/public/flags/m/IS.svg b/public/flags/m/IS.svg
new file mode 100644
index 0000000..9840fa2
--- /dev/null
+++ b/public/flags/m/IS.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/IT.svg b/public/flags/m/IT.svg
new file mode 100644
index 0000000..f71316e
--- /dev/null
+++ b/public/flags/m/IT.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/JE.svg b/public/flags/m/JE.svg
new file mode 100644
index 0000000..6be929e
--- /dev/null
+++ b/public/flags/m/JE.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/JM.svg b/public/flags/m/JM.svg
new file mode 100644
index 0000000..9d59d1f
--- /dev/null
+++ b/public/flags/m/JM.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/JO.svg b/public/flags/m/JO.svg
new file mode 100644
index 0000000..b000059
--- /dev/null
+++ b/public/flags/m/JO.svg
@@ -0,0 +1,25 @@
+
diff --git a/public/flags/m/JP.svg b/public/flags/m/JP.svg
new file mode 100644
index 0000000..30bd0e5
--- /dev/null
+++ b/public/flags/m/JP.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/KE.svg b/public/flags/m/KE.svg
new file mode 100644
index 0000000..8b3a32e
--- /dev/null
+++ b/public/flags/m/KE.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/m/KG.svg b/public/flags/m/KG.svg
new file mode 100644
index 0000000..51a5de2
--- /dev/null
+++ b/public/flags/m/KG.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/KH.svg b/public/flags/m/KH.svg
new file mode 100644
index 0000000..a6493bf
--- /dev/null
+++ b/public/flags/m/KH.svg
@@ -0,0 +1,77 @@
+
diff --git a/public/flags/m/KI.svg b/public/flags/m/KI.svg
new file mode 100644
index 0000000..408d88d
--- /dev/null
+++ b/public/flags/m/KI.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/m/KM.svg b/public/flags/m/KM.svg
new file mode 100644
index 0000000..bf50471
--- /dev/null
+++ b/public/flags/m/KM.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/m/KN.svg b/public/flags/m/KN.svg
new file mode 100644
index 0000000..deafe89
--- /dev/null
+++ b/public/flags/m/KN.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/m/KP.svg b/public/flags/m/KP.svg
new file mode 100644
index 0000000..16321b5
--- /dev/null
+++ b/public/flags/m/KP.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/m/KR.svg b/public/flags/m/KR.svg
new file mode 100644
index 0000000..e6e3e81
--- /dev/null
+++ b/public/flags/m/KR.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/m/KW.svg b/public/flags/m/KW.svg
new file mode 100644
index 0000000..999412c
--- /dev/null
+++ b/public/flags/m/KW.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/m/KY.svg b/public/flags/m/KY.svg
new file mode 100644
index 0000000..931e7f6
--- /dev/null
+++ b/public/flags/m/KY.svg
@@ -0,0 +1,52 @@
+
diff --git a/public/flags/m/KZ.svg b/public/flags/m/KZ.svg
new file mode 100644
index 0000000..313483f
--- /dev/null
+++ b/public/flags/m/KZ.svg
@@ -0,0 +1,32 @@
+
diff --git a/public/flags/m/LA.svg b/public/flags/m/LA.svg
new file mode 100644
index 0000000..4f6e175
--- /dev/null
+++ b/public/flags/m/LA.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/LB.svg b/public/flags/m/LB.svg
new file mode 100644
index 0000000..d629d50
--- /dev/null
+++ b/public/flags/m/LB.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/LC.svg b/public/flags/m/LC.svg
new file mode 100644
index 0000000..42a3cdc
--- /dev/null
+++ b/public/flags/m/LC.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/LI.svg b/public/flags/m/LI.svg
new file mode 100644
index 0000000..2a2f9bb
--- /dev/null
+++ b/public/flags/m/LI.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/m/LK.svg b/public/flags/m/LK.svg
new file mode 100644
index 0000000..87dcc63
--- /dev/null
+++ b/public/flags/m/LK.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/LR.svg b/public/flags/m/LR.svg
new file mode 100644
index 0000000..8bf61b4
--- /dev/null
+++ b/public/flags/m/LR.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/LS.svg b/public/flags/m/LS.svg
new file mode 100644
index 0000000..eba97e9
--- /dev/null
+++ b/public/flags/m/LS.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/LT.svg b/public/flags/m/LT.svg
new file mode 100644
index 0000000..2742910
--- /dev/null
+++ b/public/flags/m/LT.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/LU.svg b/public/flags/m/LU.svg
new file mode 100644
index 0000000..31cdbba
--- /dev/null
+++ b/public/flags/m/LU.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/LV.svg b/public/flags/m/LV.svg
new file mode 100644
index 0000000..5bc26f4
--- /dev/null
+++ b/public/flags/m/LV.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/LY.svg b/public/flags/m/LY.svg
new file mode 100644
index 0000000..4c014ff
--- /dev/null
+++ b/public/flags/m/LY.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/MA.svg b/public/flags/m/MA.svg
new file mode 100644
index 0000000..05bacfc
--- /dev/null
+++ b/public/flags/m/MA.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/MC.svg b/public/flags/m/MC.svg
new file mode 100644
index 0000000..f84ce47
--- /dev/null
+++ b/public/flags/m/MC.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/MD.svg b/public/flags/m/MD.svg
new file mode 100644
index 0000000..df1301d
--- /dev/null
+++ b/public/flags/m/MD.svg
@@ -0,0 +1,33 @@
+
diff --git a/public/flags/m/ME.svg b/public/flags/m/ME.svg
new file mode 100644
index 0000000..75c97d5
--- /dev/null
+++ b/public/flags/m/ME.svg
@@ -0,0 +1,34 @@
+
diff --git a/public/flags/m/MF.svg b/public/flags/m/MF.svg
new file mode 100644
index 0000000..1d5a08e
--- /dev/null
+++ b/public/flags/m/MF.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/MG.svg b/public/flags/m/MG.svg
new file mode 100644
index 0000000..cbe487e
--- /dev/null
+++ b/public/flags/m/MG.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/MH.svg b/public/flags/m/MH.svg
new file mode 100644
index 0000000..9d74b6f
--- /dev/null
+++ b/public/flags/m/MH.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/m/MK.svg b/public/flags/m/MK.svg
new file mode 100644
index 0000000..8b883dd
--- /dev/null
+++ b/public/flags/m/MK.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/ML.svg b/public/flags/m/ML.svg
new file mode 100644
index 0000000..b7c1d87
--- /dev/null
+++ b/public/flags/m/ML.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/MM.svg b/public/flags/m/MM.svg
new file mode 100644
index 0000000..12321db
--- /dev/null
+++ b/public/flags/m/MM.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/MN.svg b/public/flags/m/MN.svg
new file mode 100644
index 0000000..c5e3e9f
--- /dev/null
+++ b/public/flags/m/MN.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/MO.svg b/public/flags/m/MO.svg
new file mode 100644
index 0000000..40d6a58
--- /dev/null
+++ b/public/flags/m/MO.svg
@@ -0,0 +1,30 @@
+
diff --git a/public/flags/m/MP.svg b/public/flags/m/MP.svg
new file mode 100644
index 0000000..2a44780
--- /dev/null
+++ b/public/flags/m/MP.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/m/MQ.svg b/public/flags/m/MQ.svg
new file mode 100644
index 0000000..6cdb1a7
--- /dev/null
+++ b/public/flags/m/MQ.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/MR.svg b/public/flags/m/MR.svg
new file mode 100644
index 0000000..18a6d57
--- /dev/null
+++ b/public/flags/m/MR.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/m/MS.svg b/public/flags/m/MS.svg
new file mode 100644
index 0000000..dd95602
--- /dev/null
+++ b/public/flags/m/MS.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/m/MT.svg b/public/flags/m/MT.svg
new file mode 100644
index 0000000..52d36b1
--- /dev/null
+++ b/public/flags/m/MT.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/MU.svg b/public/flags/m/MU.svg
new file mode 100644
index 0000000..8d7c3b0
--- /dev/null
+++ b/public/flags/m/MU.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/m/MV.svg b/public/flags/m/MV.svg
new file mode 100644
index 0000000..39c260b
--- /dev/null
+++ b/public/flags/m/MV.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/m/MW.svg b/public/flags/m/MW.svg
new file mode 100644
index 0000000..c7152f6
--- /dev/null
+++ b/public/flags/m/MW.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/m/MX.svg b/public/flags/m/MX.svg
new file mode 100644
index 0000000..8a73731
--- /dev/null
+++ b/public/flags/m/MX.svg
@@ -0,0 +1,22 @@
+
diff --git a/public/flags/m/MY.svg b/public/flags/m/MY.svg
new file mode 100644
index 0000000..5195904
--- /dev/null
+++ b/public/flags/m/MY.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/m/MZ.svg b/public/flags/m/MZ.svg
new file mode 100644
index 0000000..62e279c
--- /dev/null
+++ b/public/flags/m/MZ.svg
@@ -0,0 +1,31 @@
+
diff --git a/public/flags/m/NA.svg b/public/flags/m/NA.svg
new file mode 100644
index 0000000..c877e7a
--- /dev/null
+++ b/public/flags/m/NA.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/m/NC.svg b/public/flags/m/NC.svg
new file mode 100644
index 0000000..5bff522
--- /dev/null
+++ b/public/flags/m/NC.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/NE.svg b/public/flags/m/NE.svg
new file mode 100644
index 0000000..ffa4104
--- /dev/null
+++ b/public/flags/m/NE.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/m/NF.svg b/public/flags/m/NF.svg
new file mode 100644
index 0000000..52e4b65
--- /dev/null
+++ b/public/flags/m/NF.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/NG.svg b/public/flags/m/NG.svg
new file mode 100644
index 0000000..25e0f0b
--- /dev/null
+++ b/public/flags/m/NG.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/NI.svg b/public/flags/m/NI.svg
new file mode 100644
index 0000000..55d62d5
--- /dev/null
+++ b/public/flags/m/NI.svg
@@ -0,0 +1,31 @@
+
diff --git a/public/flags/m/NL.svg b/public/flags/m/NL.svg
new file mode 100644
index 0000000..1ad1407
--- /dev/null
+++ b/public/flags/m/NL.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/NO.svg b/public/flags/m/NO.svg
new file mode 100644
index 0000000..e1f4661
--- /dev/null
+++ b/public/flags/m/NO.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/NP.svg b/public/flags/m/NP.svg
new file mode 100644
index 0000000..a3f0ae7
--- /dev/null
+++ b/public/flags/m/NP.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/m/NR.svg b/public/flags/m/NR.svg
new file mode 100644
index 0000000..779ac03
--- /dev/null
+++ b/public/flags/m/NR.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/NU.svg b/public/flags/m/NU.svg
new file mode 100644
index 0000000..61d315d
--- /dev/null
+++ b/public/flags/m/NU.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/m/NZ.svg b/public/flags/m/NZ.svg
new file mode 100644
index 0000000..773abc1
--- /dev/null
+++ b/public/flags/m/NZ.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/m/OM.svg b/public/flags/m/OM.svg
new file mode 100644
index 0000000..3266253
--- /dev/null
+++ b/public/flags/m/OM.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/m/PA.svg b/public/flags/m/PA.svg
new file mode 100644
index 0000000..0c5b4a3
--- /dev/null
+++ b/public/flags/m/PA.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/m/PE.svg b/public/flags/m/PE.svg
new file mode 100644
index 0000000..fb96648
--- /dev/null
+++ b/public/flags/m/PE.svg
@@ -0,0 +1,45 @@
+
diff --git a/public/flags/m/PF.svg b/public/flags/m/PF.svg
new file mode 100644
index 0000000..214d04a
--- /dev/null
+++ b/public/flags/m/PF.svg
@@ -0,0 +1,42 @@
+
diff --git a/public/flags/m/PG.svg b/public/flags/m/PG.svg
new file mode 100644
index 0000000..6518aa5
--- /dev/null
+++ b/public/flags/m/PG.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/PH.svg b/public/flags/m/PH.svg
new file mode 100644
index 0000000..6b41dde
--- /dev/null
+++ b/public/flags/m/PH.svg
@@ -0,0 +1,28 @@
+
diff --git a/public/flags/m/PK.svg b/public/flags/m/PK.svg
new file mode 100644
index 0000000..1317405
--- /dev/null
+++ b/public/flags/m/PK.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/PL.svg b/public/flags/m/PL.svg
new file mode 100644
index 0000000..5fc8c5e
--- /dev/null
+++ b/public/flags/m/PL.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/PM.svg b/public/flags/m/PM.svg
new file mode 100644
index 0000000..e49e5b3
--- /dev/null
+++ b/public/flags/m/PM.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/PN.svg b/public/flags/m/PN.svg
new file mode 100644
index 0000000..10e4955
--- /dev/null
+++ b/public/flags/m/PN.svg
@@ -0,0 +1,52 @@
+
diff --git a/public/flags/m/PR.svg b/public/flags/m/PR.svg
new file mode 100644
index 0000000..ac737a8
--- /dev/null
+++ b/public/flags/m/PR.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/m/PS.svg b/public/flags/m/PS.svg
new file mode 100644
index 0000000..828186c
--- /dev/null
+++ b/public/flags/m/PS.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/PT.svg b/public/flags/m/PT.svg
new file mode 100644
index 0000000..9daaa25
--- /dev/null
+++ b/public/flags/m/PT.svg
@@ -0,0 +1,121 @@
+
diff --git a/public/flags/m/PW.svg b/public/flags/m/PW.svg
new file mode 100644
index 0000000..41424da
--- /dev/null
+++ b/public/flags/m/PW.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/PY.svg b/public/flags/m/PY.svg
new file mode 100644
index 0000000..681592b
--- /dev/null
+++ b/public/flags/m/PY.svg
@@ -0,0 +1,22 @@
+
diff --git a/public/flags/m/QA.svg b/public/flags/m/QA.svg
new file mode 100644
index 0000000..c4d81d9
--- /dev/null
+++ b/public/flags/m/QA.svg
@@ -0,0 +1,12 @@
+
diff --git a/public/flags/m/RE.svg b/public/flags/m/RE.svg
new file mode 100644
index 0000000..932db60
--- /dev/null
+++ b/public/flags/m/RE.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/RO.svg b/public/flags/m/RO.svg
new file mode 100644
index 0000000..4bf9e9a
--- /dev/null
+++ b/public/flags/m/RO.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/RS.svg b/public/flags/m/RS.svg
new file mode 100644
index 0000000..d4b1c92
--- /dev/null
+++ b/public/flags/m/RS.svg
@@ -0,0 +1,34 @@
+
diff --git a/public/flags/m/RU.svg b/public/flags/m/RU.svg
new file mode 100644
index 0000000..91904d1
--- /dev/null
+++ b/public/flags/m/RU.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/RW.svg b/public/flags/m/RW.svg
new file mode 100644
index 0000000..9cc9a05
--- /dev/null
+++ b/public/flags/m/RW.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/m/SA.svg b/public/flags/m/SA.svg
new file mode 100644
index 0000000..7073c83
--- /dev/null
+++ b/public/flags/m/SA.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/m/SB.svg b/public/flags/m/SB.svg
new file mode 100644
index 0000000..3abf3d4
--- /dev/null
+++ b/public/flags/m/SB.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/m/SC.svg b/public/flags/m/SC.svg
new file mode 100644
index 0000000..992a85d
--- /dev/null
+++ b/public/flags/m/SC.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/m/SD.svg b/public/flags/m/SD.svg
new file mode 100644
index 0000000..71c1e93
--- /dev/null
+++ b/public/flags/m/SD.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/SE.svg b/public/flags/m/SE.svg
new file mode 100644
index 0000000..f6575fd
--- /dev/null
+++ b/public/flags/m/SE.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/SG.svg b/public/flags/m/SG.svg
new file mode 100644
index 0000000..a9aca23
--- /dev/null
+++ b/public/flags/m/SG.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/SH.svg b/public/flags/m/SH.svg
new file mode 100644
index 0000000..326e3aa
--- /dev/null
+++ b/public/flags/m/SH.svg
@@ -0,0 +1,26 @@
+
diff --git a/public/flags/m/SI.svg b/public/flags/m/SI.svg
new file mode 100644
index 0000000..00e333b
--- /dev/null
+++ b/public/flags/m/SI.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/m/SJ.svg b/public/flags/m/SJ.svg
new file mode 100644
index 0000000..8cc7bd9
--- /dev/null
+++ b/public/flags/m/SJ.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/SK.svg b/public/flags/m/SK.svg
new file mode 100644
index 0000000..8f1930f
--- /dev/null
+++ b/public/flags/m/SK.svg
@@ -0,0 +1,26 @@
+
diff --git a/public/flags/m/SL.svg b/public/flags/m/SL.svg
new file mode 100644
index 0000000..7edd585
--- /dev/null
+++ b/public/flags/m/SL.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/SM.svg b/public/flags/m/SM.svg
new file mode 100644
index 0000000..13a143c
--- /dev/null
+++ b/public/flags/m/SM.svg
@@ -0,0 +1,42 @@
+
diff --git a/public/flags/m/SN.svg b/public/flags/m/SN.svg
new file mode 100644
index 0000000..101e625
--- /dev/null
+++ b/public/flags/m/SN.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/SO.svg b/public/flags/m/SO.svg
new file mode 100644
index 0000000..5e20f8f
--- /dev/null
+++ b/public/flags/m/SO.svg
@@ -0,0 +1,12 @@
+
diff --git a/public/flags/m/SR.svg b/public/flags/m/SR.svg
new file mode 100644
index 0000000..70485a5
--- /dev/null
+++ b/public/flags/m/SR.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/SS.svg b/public/flags/m/SS.svg
new file mode 100644
index 0000000..29b51c6
--- /dev/null
+++ b/public/flags/m/SS.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/m/ST.svg b/public/flags/m/ST.svg
new file mode 100644
index 0000000..4ef6acd
--- /dev/null
+++ b/public/flags/m/ST.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/m/SV.svg b/public/flags/m/SV.svg
new file mode 100644
index 0000000..f1c0d49
--- /dev/null
+++ b/public/flags/m/SV.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/m/SX.svg b/public/flags/m/SX.svg
new file mode 100644
index 0000000..8c22149
--- /dev/null
+++ b/public/flags/m/SX.svg
@@ -0,0 +1,31 @@
+
diff --git a/public/flags/m/SY.svg b/public/flags/m/SY.svg
new file mode 100644
index 0000000..fbf0319
--- /dev/null
+++ b/public/flags/m/SY.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/m/SZ.svg b/public/flags/m/SZ.svg
new file mode 100644
index 0000000..91f0754
--- /dev/null
+++ b/public/flags/m/SZ.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/m/TC.svg b/public/flags/m/TC.svg
new file mode 100644
index 0000000..e896370
--- /dev/null
+++ b/public/flags/m/TC.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/m/TD.svg b/public/flags/m/TD.svg
new file mode 100644
index 0000000..ec837a7
--- /dev/null
+++ b/public/flags/m/TD.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/TF.svg b/public/flags/m/TF.svg
new file mode 100644
index 0000000..67686ee
--- /dev/null
+++ b/public/flags/m/TF.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/m/TG.svg b/public/flags/m/TG.svg
new file mode 100644
index 0000000..8002d19
--- /dev/null
+++ b/public/flags/m/TG.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/m/TH.svg b/public/flags/m/TH.svg
new file mode 100644
index 0000000..4ca266c
--- /dev/null
+++ b/public/flags/m/TH.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/TJ.svg b/public/flags/m/TJ.svg
new file mode 100644
index 0000000..a85e0cb
--- /dev/null
+++ b/public/flags/m/TJ.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/m/TK.svg b/public/flags/m/TK.svg
new file mode 100644
index 0000000..ceb651e
--- /dev/null
+++ b/public/flags/m/TK.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/m/TL.svg b/public/flags/m/TL.svg
new file mode 100644
index 0000000..64a2b2f
--- /dev/null
+++ b/public/flags/m/TL.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/TM.svg b/public/flags/m/TM.svg
new file mode 100644
index 0000000..91ecb66
--- /dev/null
+++ b/public/flags/m/TM.svg
@@ -0,0 +1,75 @@
+
diff --git a/public/flags/m/TN.svg b/public/flags/m/TN.svg
new file mode 100644
index 0000000..9759e58
--- /dev/null
+++ b/public/flags/m/TN.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/TO.svg b/public/flags/m/TO.svg
new file mode 100644
index 0000000..f25ee5b
--- /dev/null
+++ b/public/flags/m/TO.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/TR.svg b/public/flags/m/TR.svg
new file mode 100644
index 0000000..e26f5b6
--- /dev/null
+++ b/public/flags/m/TR.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/TT.svg b/public/flags/m/TT.svg
new file mode 100644
index 0000000..6fdf3db
--- /dev/null
+++ b/public/flags/m/TT.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/TV.svg b/public/flags/m/TV.svg
new file mode 100644
index 0000000..edb8fbf
--- /dev/null
+++ b/public/flags/m/TV.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/m/TW.svg b/public/flags/m/TW.svg
new file mode 100644
index 0000000..8fa7d34
--- /dev/null
+++ b/public/flags/m/TW.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/TZ.svg b/public/flags/m/TZ.svg
new file mode 100644
index 0000000..70b9604
--- /dev/null
+++ b/public/flags/m/TZ.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/UA.svg b/public/flags/m/UA.svg
new file mode 100644
index 0000000..ed1d4c3
--- /dev/null
+++ b/public/flags/m/UA.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/m/UG.svg b/public/flags/m/UG.svg
new file mode 100644
index 0000000..858b233
--- /dev/null
+++ b/public/flags/m/UG.svg
@@ -0,0 +1,28 @@
+
diff --git a/public/flags/m/UM.svg b/public/flags/m/UM.svg
new file mode 100644
index 0000000..4137f21
--- /dev/null
+++ b/public/flags/m/UM.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/US.svg b/public/flags/m/US.svg
new file mode 100644
index 0000000..00391b6
--- /dev/null
+++ b/public/flags/m/US.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/UY.svg b/public/flags/m/UY.svg
new file mode 100644
index 0000000..feed621
--- /dev/null
+++ b/public/flags/m/UY.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/m/UZ.svg b/public/flags/m/UZ.svg
new file mode 100644
index 0000000..ee3bd75
--- /dev/null
+++ b/public/flags/m/UZ.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/VA.svg b/public/flags/m/VA.svg
new file mode 100644
index 0000000..827a8c0
--- /dev/null
+++ b/public/flags/m/VA.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/m/VC.svg b/public/flags/m/VC.svg
new file mode 100644
index 0000000..eeae703
--- /dev/null
+++ b/public/flags/m/VC.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/m/VE.svg b/public/flags/m/VE.svg
new file mode 100644
index 0000000..571ad1f
--- /dev/null
+++ b/public/flags/m/VE.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/m/VG.svg b/public/flags/m/VG.svg
new file mode 100644
index 0000000..8e66a2b
--- /dev/null
+++ b/public/flags/m/VG.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/m/VI.svg b/public/flags/m/VI.svg
new file mode 100644
index 0000000..42ccdee
--- /dev/null
+++ b/public/flags/m/VI.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/m/VN.svg b/public/flags/m/VN.svg
new file mode 100644
index 0000000..5718449
--- /dev/null
+++ b/public/flags/m/VN.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/VU.svg b/public/flags/m/VU.svg
new file mode 100644
index 0000000..d3b9949
--- /dev/null
+++ b/public/flags/m/VU.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/m/WF.svg b/public/flags/m/WF.svg
new file mode 100644
index 0000000..a6beeca
--- /dev/null
+++ b/public/flags/m/WF.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/m/WS.svg b/public/flags/m/WS.svg
new file mode 100644
index 0000000..1888789
--- /dev/null
+++ b/public/flags/m/WS.svg
@@ -0,0 +1,22 @@
+
diff --git a/public/flags/m/YE.svg b/public/flags/m/YE.svg
new file mode 100644
index 0000000..72492c5
--- /dev/null
+++ b/public/flags/m/YE.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/m/YT.svg b/public/flags/m/YT.svg
new file mode 100644
index 0000000..e6c4f6f
--- /dev/null
+++ b/public/flags/m/YT.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/m/ZA.svg b/public/flags/m/ZA.svg
new file mode 100644
index 0000000..0ae0f50
--- /dev/null
+++ b/public/flags/m/ZA.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/m/ZM.svg b/public/flags/m/ZM.svg
new file mode 100644
index 0000000..cda79c6
--- /dev/null
+++ b/public/flags/m/ZM.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/m/ZW.svg b/public/flags/m/ZW.svg
new file mode 100644
index 0000000..2b7927a
--- /dev/null
+++ b/public/flags/m/ZW.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/s/AD.svg b/public/flags/s/AD.svg
new file mode 100644
index 0000000..96946ce
--- /dev/null
+++ b/public/flags/s/AD.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/s/AE.svg b/public/flags/s/AE.svg
new file mode 100644
index 0000000..2ec61c0
--- /dev/null
+++ b/public/flags/s/AE.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/AF.svg b/public/flags/s/AF.svg
new file mode 100644
index 0000000..9a87ddd
--- /dev/null
+++ b/public/flags/s/AF.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/AG.svg b/public/flags/s/AG.svg
new file mode 100644
index 0000000..4618075
--- /dev/null
+++ b/public/flags/s/AG.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/s/AI.svg b/public/flags/s/AI.svg
new file mode 100644
index 0000000..2f6be27
--- /dev/null
+++ b/public/flags/s/AI.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/s/AL.svg b/public/flags/s/AL.svg
new file mode 100644
index 0000000..7678fbe
--- /dev/null
+++ b/public/flags/s/AL.svg
@@ -0,0 +1,12 @@
+
diff --git a/public/flags/s/AM.svg b/public/flags/s/AM.svg
new file mode 100644
index 0000000..51a18c1
--- /dev/null
+++ b/public/flags/s/AM.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/AO.svg b/public/flags/s/AO.svg
new file mode 100644
index 0000000..e9a3838
--- /dev/null
+++ b/public/flags/s/AO.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/s/AQ.svg b/public/flags/s/AQ.svg
new file mode 100644
index 0000000..88bf912
--- /dev/null
+++ b/public/flags/s/AQ.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/s/AR.svg b/public/flags/s/AR.svg
new file mode 100644
index 0000000..0060ed1
--- /dev/null
+++ b/public/flags/s/AR.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/s/AS.svg b/public/flags/s/AS.svg
new file mode 100644
index 0000000..5afe9f3
--- /dev/null
+++ b/public/flags/s/AS.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/AT.svg b/public/flags/s/AT.svg
new file mode 100644
index 0000000..4574514
--- /dev/null
+++ b/public/flags/s/AT.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/AU.svg b/public/flags/s/AU.svg
new file mode 100644
index 0000000..bc10c93
--- /dev/null
+++ b/public/flags/s/AU.svg
@@ -0,0 +1,34 @@
+
diff --git a/public/flags/s/AW.svg b/public/flags/s/AW.svg
new file mode 100644
index 0000000..8d04ad3
--- /dev/null
+++ b/public/flags/s/AW.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/s/AX.svg b/public/flags/s/AX.svg
new file mode 100644
index 0000000..fd1b42a
--- /dev/null
+++ b/public/flags/s/AX.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/AZ.svg b/public/flags/s/AZ.svg
new file mode 100644
index 0000000..6de2448
--- /dev/null
+++ b/public/flags/s/AZ.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/s/BA.svg b/public/flags/s/BA.svg
new file mode 100644
index 0000000..6ffbad7
--- /dev/null
+++ b/public/flags/s/BA.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/BB.svg b/public/flags/s/BB.svg
new file mode 100644
index 0000000..628fa64
--- /dev/null
+++ b/public/flags/s/BB.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/BD.svg b/public/flags/s/BD.svg
new file mode 100644
index 0000000..a446559
--- /dev/null
+++ b/public/flags/s/BD.svg
@@ -0,0 +1,12 @@
+
diff --git a/public/flags/s/BE.svg b/public/flags/s/BE.svg
new file mode 100644
index 0000000..8bb7061
--- /dev/null
+++ b/public/flags/s/BE.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/BF.svg b/public/flags/s/BF.svg
new file mode 100644
index 0000000..1f86ca9
--- /dev/null
+++ b/public/flags/s/BF.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/BG.svg b/public/flags/s/BG.svg
new file mode 100644
index 0000000..0a37798
--- /dev/null
+++ b/public/flags/s/BG.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/BH.svg b/public/flags/s/BH.svg
new file mode 100644
index 0000000..f30949e
--- /dev/null
+++ b/public/flags/s/BH.svg
@@ -0,0 +1,12 @@
+
diff --git a/public/flags/s/BI.svg b/public/flags/s/BI.svg
new file mode 100644
index 0000000..3d5c380
--- /dev/null
+++ b/public/flags/s/BI.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/s/BJ.svg b/public/flags/s/BJ.svg
new file mode 100644
index 0000000..6bcbe5e
--- /dev/null
+++ b/public/flags/s/BJ.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/BL.svg b/public/flags/s/BL.svg
new file mode 100644
index 0000000..f577025
--- /dev/null
+++ b/public/flags/s/BL.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/BM.svg b/public/flags/s/BM.svg
new file mode 100644
index 0000000..c9aa77f
--- /dev/null
+++ b/public/flags/s/BM.svg
@@ -0,0 +1,38 @@
+
diff --git a/public/flags/s/BN.svg b/public/flags/s/BN.svg
new file mode 100644
index 0000000..915bd80
--- /dev/null
+++ b/public/flags/s/BN.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/s/BO.svg b/public/flags/s/BO.svg
new file mode 100644
index 0000000..648f77f
--- /dev/null
+++ b/public/flags/s/BO.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/s/BQ-BO.svg b/public/flags/s/BQ-BO.svg
new file mode 100644
index 0000000..3a120c7
--- /dev/null
+++ b/public/flags/s/BQ-BO.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/s/BQ-SA.svg b/public/flags/s/BQ-SA.svg
new file mode 100644
index 0000000..4c6e4ad
--- /dev/null
+++ b/public/flags/s/BQ-SA.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/s/BQ-SE.svg b/public/flags/s/BQ-SE.svg
new file mode 100644
index 0000000..781d30d
--- /dev/null
+++ b/public/flags/s/BQ-SE.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/s/BR.svg b/public/flags/s/BR.svg
new file mode 100644
index 0000000..30807f0
--- /dev/null
+++ b/public/flags/s/BR.svg
@@ -0,0 +1,47 @@
+
diff --git a/public/flags/s/BS.svg b/public/flags/s/BS.svg
new file mode 100644
index 0000000..cc0574a
--- /dev/null
+++ b/public/flags/s/BS.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/BT.svg b/public/flags/s/BT.svg
new file mode 100644
index 0000000..558f670
--- /dev/null
+++ b/public/flags/s/BT.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/s/BV.svg b/public/flags/s/BV.svg
new file mode 100644
index 0000000..2cea490
--- /dev/null
+++ b/public/flags/s/BV.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/BW.svg b/public/flags/s/BW.svg
new file mode 100644
index 0000000..5d25d1f
--- /dev/null
+++ b/public/flags/s/BW.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/BY.svg b/public/flags/s/BY.svg
new file mode 100644
index 0000000..e584216
--- /dev/null
+++ b/public/flags/s/BY.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/s/BZ.svg b/public/flags/s/BZ.svg
new file mode 100644
index 0000000..290a501
--- /dev/null
+++ b/public/flags/s/BZ.svg
@@ -0,0 +1,28 @@
+
diff --git a/public/flags/s/CA.svg b/public/flags/s/CA.svg
new file mode 100644
index 0000000..a6a9a44
--- /dev/null
+++ b/public/flags/s/CA.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/CC.svg b/public/flags/s/CC.svg
new file mode 100644
index 0000000..b9fa3fb
--- /dev/null
+++ b/public/flags/s/CC.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/s/CD.svg b/public/flags/s/CD.svg
new file mode 100644
index 0000000..26d9bd7
--- /dev/null
+++ b/public/flags/s/CD.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/CF.svg b/public/flags/s/CF.svg
new file mode 100644
index 0000000..3c048ec
--- /dev/null
+++ b/public/flags/s/CF.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/s/CG.svg b/public/flags/s/CG.svg
new file mode 100644
index 0000000..9469f72
--- /dev/null
+++ b/public/flags/s/CG.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/CH.svg b/public/flags/s/CH.svg
new file mode 100644
index 0000000..87fafac
--- /dev/null
+++ b/public/flags/s/CH.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/CI.svg b/public/flags/s/CI.svg
new file mode 100644
index 0000000..e518512
--- /dev/null
+++ b/public/flags/s/CI.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/CK.svg b/public/flags/s/CK.svg
new file mode 100644
index 0000000..696efdd
--- /dev/null
+++ b/public/flags/s/CK.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/s/CL.svg b/public/flags/s/CL.svg
new file mode 100644
index 0000000..a5f43ad
--- /dev/null
+++ b/public/flags/s/CL.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/CM.svg b/public/flags/s/CM.svg
new file mode 100644
index 0000000..2599f7d
--- /dev/null
+++ b/public/flags/s/CM.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/CN.svg b/public/flags/s/CN.svg
new file mode 100644
index 0000000..df86875
--- /dev/null
+++ b/public/flags/s/CN.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/s/CO.svg b/public/flags/s/CO.svg
new file mode 100644
index 0000000..2707069
--- /dev/null
+++ b/public/flags/s/CO.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/CR.svg b/public/flags/s/CR.svg
new file mode 100644
index 0000000..ac7a419
--- /dev/null
+++ b/public/flags/s/CR.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/CU.svg b/public/flags/s/CU.svg
new file mode 100644
index 0000000..106aaff
--- /dev/null
+++ b/public/flags/s/CU.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/s/CV.svg b/public/flags/s/CV.svg
new file mode 100644
index 0000000..53dc51a
--- /dev/null
+++ b/public/flags/s/CV.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/CW.svg b/public/flags/s/CW.svg
new file mode 100644
index 0000000..b4a0edd
--- /dev/null
+++ b/public/flags/s/CW.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/s/CX.svg b/public/flags/s/CX.svg
new file mode 100644
index 0000000..7d665dc
--- /dev/null
+++ b/public/flags/s/CX.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/s/CY.svg b/public/flags/s/CY.svg
new file mode 100644
index 0000000..bfd22f9
--- /dev/null
+++ b/public/flags/s/CY.svg
@@ -0,0 +1,28 @@
+
diff --git a/public/flags/s/CZ.svg b/public/flags/s/CZ.svg
new file mode 100644
index 0000000..e114aa7
--- /dev/null
+++ b/public/flags/s/CZ.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/s/DE.svg b/public/flags/s/DE.svg
new file mode 100644
index 0000000..8daa952
--- /dev/null
+++ b/public/flags/s/DE.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/DJ.svg b/public/flags/s/DJ.svg
new file mode 100644
index 0000000..317df23
--- /dev/null
+++ b/public/flags/s/DJ.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/s/DK.svg b/public/flags/s/DK.svg
new file mode 100644
index 0000000..365f0dd
--- /dev/null
+++ b/public/flags/s/DK.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/DM.svg b/public/flags/s/DM.svg
new file mode 100644
index 0000000..aeadd20
--- /dev/null
+++ b/public/flags/s/DM.svg
@@ -0,0 +1,26 @@
+
diff --git a/public/flags/s/DO.svg b/public/flags/s/DO.svg
new file mode 100644
index 0000000..6bf37cc
--- /dev/null
+++ b/public/flags/s/DO.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/s/DZ.svg b/public/flags/s/DZ.svg
new file mode 100644
index 0000000..a22704b
--- /dev/null
+++ b/public/flags/s/DZ.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/EC.svg b/public/flags/s/EC.svg
new file mode 100644
index 0000000..d63e442
--- /dev/null
+++ b/public/flags/s/EC.svg
@@ -0,0 +1,37 @@
+
diff --git a/public/flags/s/EE.svg b/public/flags/s/EE.svg
new file mode 100644
index 0000000..6e147b1
--- /dev/null
+++ b/public/flags/s/EE.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/EG.svg b/public/flags/s/EG.svg
new file mode 100644
index 0000000..cb3532a
--- /dev/null
+++ b/public/flags/s/EG.svg
@@ -0,0 +1,31 @@
+
diff --git a/public/flags/s/EH.svg b/public/flags/s/EH.svg
new file mode 100644
index 0000000..d1d7d9f
--- /dev/null
+++ b/public/flags/s/EH.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/s/ER.svg b/public/flags/s/ER.svg
new file mode 100644
index 0000000..b7f6b7a
--- /dev/null
+++ b/public/flags/s/ER.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/s/ES.svg b/public/flags/s/ES.svg
new file mode 100644
index 0000000..e92073e
--- /dev/null
+++ b/public/flags/s/ES.svg
@@ -0,0 +1,63 @@
+
diff --git a/public/flags/s/ET.svg b/public/flags/s/ET.svg
new file mode 100644
index 0000000..304b655
--- /dev/null
+++ b/public/flags/s/ET.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/s/FI.svg b/public/flags/s/FI.svg
new file mode 100644
index 0000000..e0f6d5b
--- /dev/null
+++ b/public/flags/s/FI.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/FJ.svg b/public/flags/s/FJ.svg
new file mode 100644
index 0000000..9c094da
--- /dev/null
+++ b/public/flags/s/FJ.svg
@@ -0,0 +1,56 @@
+
diff --git a/public/flags/s/FK.svg b/public/flags/s/FK.svg
new file mode 100644
index 0000000..9561752
--- /dev/null
+++ b/public/flags/s/FK.svg
@@ -0,0 +1,26 @@
+
diff --git a/public/flags/s/FM.svg b/public/flags/s/FM.svg
new file mode 100644
index 0000000..9e0a71b
--- /dev/null
+++ b/public/flags/s/FM.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/s/FO.svg b/public/flags/s/FO.svg
new file mode 100644
index 0000000..9f9e984
--- /dev/null
+++ b/public/flags/s/FO.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/FR.svg b/public/flags/s/FR.svg
new file mode 100644
index 0000000..1dd080e
--- /dev/null
+++ b/public/flags/s/FR.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/GA.svg b/public/flags/s/GA.svg
new file mode 100644
index 0000000..bc88dd8
--- /dev/null
+++ b/public/flags/s/GA.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/GB-ENG.svg b/public/flags/s/GB-ENG.svg
new file mode 100644
index 0000000..efe69dc
--- /dev/null
+++ b/public/flags/s/GB-ENG.svg
@@ -0,0 +1,12 @@
+
diff --git a/public/flags/s/GB-NIR.svg b/public/flags/s/GB-NIR.svg
new file mode 100644
index 0000000..1c5e556
--- /dev/null
+++ b/public/flags/s/GB-NIR.svg
@@ -0,0 +1,25 @@
+
diff --git a/public/flags/s/GB-SCT.svg b/public/flags/s/GB-SCT.svg
new file mode 100644
index 0000000..2b834b9
--- /dev/null
+++ b/public/flags/s/GB-SCT.svg
@@ -0,0 +1,11 @@
+
diff --git a/public/flags/s/GB-UKM.svg b/public/flags/s/GB-UKM.svg
new file mode 100644
index 0000000..f439f08
--- /dev/null
+++ b/public/flags/s/GB-UKM.svg
@@ -0,0 +1,25 @@
+
diff --git a/public/flags/s/GB-WLS.svg b/public/flags/s/GB-WLS.svg
new file mode 100644
index 0000000..3fcbe79
--- /dev/null
+++ b/public/flags/s/GB-WLS.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/GD.svg b/public/flags/s/GD.svg
new file mode 100644
index 0000000..51a559a
--- /dev/null
+++ b/public/flags/s/GD.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/s/GE.svg b/public/flags/s/GE.svg
new file mode 100644
index 0000000..716e02e
--- /dev/null
+++ b/public/flags/s/GE.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/s/GF.svg b/public/flags/s/GF.svg
new file mode 100644
index 0000000..82a60fa
--- /dev/null
+++ b/public/flags/s/GF.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/GG.svg b/public/flags/s/GG.svg
new file mode 100644
index 0000000..ed59e67
--- /dev/null
+++ b/public/flags/s/GG.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/GH.svg b/public/flags/s/GH.svg
new file mode 100644
index 0000000..19bc9b2
--- /dev/null
+++ b/public/flags/s/GH.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/GI.svg b/public/flags/s/GI.svg
new file mode 100644
index 0000000..f060941
--- /dev/null
+++ b/public/flags/s/GI.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/s/GL.svg b/public/flags/s/GL.svg
new file mode 100644
index 0000000..ee4b33b
--- /dev/null
+++ b/public/flags/s/GL.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/s/GM.svg b/public/flags/s/GM.svg
new file mode 100644
index 0000000..1fc7196
--- /dev/null
+++ b/public/flags/s/GM.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/GN.svg b/public/flags/s/GN.svg
new file mode 100644
index 0000000..78bf433
--- /dev/null
+++ b/public/flags/s/GN.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/GP.svg b/public/flags/s/GP.svg
new file mode 100644
index 0000000..e33f7aa
--- /dev/null
+++ b/public/flags/s/GP.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/GQ.svg b/public/flags/s/GQ.svg
new file mode 100644
index 0000000..900ec30
--- /dev/null
+++ b/public/flags/s/GQ.svg
@@ -0,0 +1,34 @@
+
diff --git a/public/flags/s/GR.svg b/public/flags/s/GR.svg
new file mode 100644
index 0000000..15667e1e
--- /dev/null
+++ b/public/flags/s/GR.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/GS.svg b/public/flags/s/GS.svg
new file mode 100644
index 0000000..3e83e24
--- /dev/null
+++ b/public/flags/s/GS.svg
@@ -0,0 +1,65 @@
+
diff --git a/public/flags/s/GT.svg b/public/flags/s/GT.svg
new file mode 100644
index 0000000..d949e95
--- /dev/null
+++ b/public/flags/s/GT.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/GU.svg b/public/flags/s/GU.svg
new file mode 100644
index 0000000..f8f869c
--- /dev/null
+++ b/public/flags/s/GU.svg
@@ -0,0 +1,35 @@
+
diff --git a/public/flags/s/GW.svg b/public/flags/s/GW.svg
new file mode 100644
index 0000000..560ef82
--- /dev/null
+++ b/public/flags/s/GW.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/GY.svg b/public/flags/s/GY.svg
new file mode 100644
index 0000000..dac36e7
--- /dev/null
+++ b/public/flags/s/GY.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/HK.svg b/public/flags/s/HK.svg
new file mode 100644
index 0000000..32b7c1f
--- /dev/null
+++ b/public/flags/s/HK.svg
@@ -0,0 +1,22 @@
+
diff --git a/public/flags/s/HM.svg b/public/flags/s/HM.svg
new file mode 100644
index 0000000..13a7a2c
--- /dev/null
+++ b/public/flags/s/HM.svg
@@ -0,0 +1,34 @@
+
diff --git a/public/flags/s/HN.svg b/public/flags/s/HN.svg
new file mode 100644
index 0000000..e745cb1
--- /dev/null
+++ b/public/flags/s/HN.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/s/HR.svg b/public/flags/s/HR.svg
new file mode 100644
index 0000000..245375d
--- /dev/null
+++ b/public/flags/s/HR.svg
@@ -0,0 +1,46 @@
+
diff --git a/public/flags/s/HT.svg b/public/flags/s/HT.svg
new file mode 100644
index 0000000..2f39958
--- /dev/null
+++ b/public/flags/s/HT.svg
@@ -0,0 +1,37 @@
+
diff --git a/public/flags/s/HU.svg b/public/flags/s/HU.svg
new file mode 100644
index 0000000..ec2a1cd
--- /dev/null
+++ b/public/flags/s/HU.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/ID.svg b/public/flags/s/ID.svg
new file mode 100644
index 0000000..5e05c18
--- /dev/null
+++ b/public/flags/s/ID.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/IE.svg b/public/flags/s/IE.svg
new file mode 100644
index 0000000..2f5a82a
--- /dev/null
+++ b/public/flags/s/IE.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/IL.svg b/public/flags/s/IL.svg
new file mode 100644
index 0000000..a70a553
--- /dev/null
+++ b/public/flags/s/IL.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/s/IM.svg b/public/flags/s/IM.svg
new file mode 100644
index 0000000..cab1ca8
--- /dev/null
+++ b/public/flags/s/IM.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/s/IN.svg b/public/flags/s/IN.svg
new file mode 100644
index 0000000..4494ae0
--- /dev/null
+++ b/public/flags/s/IN.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/s/IO.svg b/public/flags/s/IO.svg
new file mode 100644
index 0000000..2ae68f0
--- /dev/null
+++ b/public/flags/s/IO.svg
@@ -0,0 +1,40 @@
+
diff --git a/public/flags/s/IQ.svg b/public/flags/s/IQ.svg
new file mode 100644
index 0000000..778a2d0
--- /dev/null
+++ b/public/flags/s/IQ.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/s/IR.svg b/public/flags/s/IR.svg
new file mode 100644
index 0000000..00b3bcb
--- /dev/null
+++ b/public/flags/s/IR.svg
@@ -0,0 +1,89 @@
+
diff --git a/public/flags/s/IS.svg b/public/flags/s/IS.svg
new file mode 100644
index 0000000..30693ec
--- /dev/null
+++ b/public/flags/s/IS.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/IT.svg b/public/flags/s/IT.svg
new file mode 100644
index 0000000..a1a6122
--- /dev/null
+++ b/public/flags/s/IT.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/JE.svg b/public/flags/s/JE.svg
new file mode 100644
index 0000000..912ef30
--- /dev/null
+++ b/public/flags/s/JE.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/s/JM.svg b/public/flags/s/JM.svg
new file mode 100644
index 0000000..117e861
--- /dev/null
+++ b/public/flags/s/JM.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/JO.svg b/public/flags/s/JO.svg
new file mode 100644
index 0000000..de7d8be
--- /dev/null
+++ b/public/flags/s/JO.svg
@@ -0,0 +1,25 @@
+
diff --git a/public/flags/s/JP.svg b/public/flags/s/JP.svg
new file mode 100644
index 0000000..4adb946
--- /dev/null
+++ b/public/flags/s/JP.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/KE.svg b/public/flags/s/KE.svg
new file mode 100644
index 0000000..e8316b0
--- /dev/null
+++ b/public/flags/s/KE.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/s/KG.svg b/public/flags/s/KG.svg
new file mode 100644
index 0000000..14a8501
--- /dev/null
+++ b/public/flags/s/KG.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/KH.svg b/public/flags/s/KH.svg
new file mode 100644
index 0000000..e72aaa3
--- /dev/null
+++ b/public/flags/s/KH.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/KI.svg b/public/flags/s/KI.svg
new file mode 100644
index 0000000..6046984
--- /dev/null
+++ b/public/flags/s/KI.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/s/KM.svg b/public/flags/s/KM.svg
new file mode 100644
index 0000000..4ca469b
--- /dev/null
+++ b/public/flags/s/KM.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/s/KN.svg b/public/flags/s/KN.svg
new file mode 100644
index 0000000..68a37d2
--- /dev/null
+++ b/public/flags/s/KN.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/s/KP.svg b/public/flags/s/KP.svg
new file mode 100644
index 0000000..10cecce
--- /dev/null
+++ b/public/flags/s/KP.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/s/KR.svg b/public/flags/s/KR.svg
new file mode 100644
index 0000000..7b7bb6d
--- /dev/null
+++ b/public/flags/s/KR.svg
@@ -0,0 +1,31 @@
+
diff --git a/public/flags/s/KW.svg b/public/flags/s/KW.svg
new file mode 100644
index 0000000..d6e9e37
--- /dev/null
+++ b/public/flags/s/KW.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/s/KY.svg b/public/flags/s/KY.svg
new file mode 100644
index 0000000..292fc0d
--- /dev/null
+++ b/public/flags/s/KY.svg
@@ -0,0 +1,66 @@
+
diff --git a/public/flags/s/KZ.svg b/public/flags/s/KZ.svg
new file mode 100644
index 0000000..02bbcc6
--- /dev/null
+++ b/public/flags/s/KZ.svg
@@ -0,0 +1,33 @@
+
diff --git a/public/flags/s/LA.svg b/public/flags/s/LA.svg
new file mode 100644
index 0000000..57b6244
--- /dev/null
+++ b/public/flags/s/LA.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/LB.svg b/public/flags/s/LB.svg
new file mode 100644
index 0000000..adf1374
--- /dev/null
+++ b/public/flags/s/LB.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/LC.svg b/public/flags/s/LC.svg
new file mode 100644
index 0000000..8166d89
--- /dev/null
+++ b/public/flags/s/LC.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/LI.svg b/public/flags/s/LI.svg
new file mode 100644
index 0000000..5e09f26
--- /dev/null
+++ b/public/flags/s/LI.svg
@@ -0,0 +1,26 @@
+
diff --git a/public/flags/s/LK.svg b/public/flags/s/LK.svg
new file mode 100644
index 0000000..07b019d
--- /dev/null
+++ b/public/flags/s/LK.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/LR.svg b/public/flags/s/LR.svg
new file mode 100644
index 0000000..625119a
--- /dev/null
+++ b/public/flags/s/LR.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/LS.svg b/public/flags/s/LS.svg
new file mode 100644
index 0000000..d0ae3d8
--- /dev/null
+++ b/public/flags/s/LS.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/LT.svg b/public/flags/s/LT.svg
new file mode 100644
index 0000000..a9003b1
--- /dev/null
+++ b/public/flags/s/LT.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/LU.svg b/public/flags/s/LU.svg
new file mode 100644
index 0000000..838d4c5
--- /dev/null
+++ b/public/flags/s/LU.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/LV.svg b/public/flags/s/LV.svg
new file mode 100644
index 0000000..837b428
--- /dev/null
+++ b/public/flags/s/LV.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/LY.svg b/public/flags/s/LY.svg
new file mode 100644
index 0000000..cfe1500
--- /dev/null
+++ b/public/flags/s/LY.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/MA.svg b/public/flags/s/MA.svg
new file mode 100644
index 0000000..c25aa90
--- /dev/null
+++ b/public/flags/s/MA.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/MC.svg b/public/flags/s/MC.svg
new file mode 100644
index 0000000..c2fab8c
--- /dev/null
+++ b/public/flags/s/MC.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/MD.svg b/public/flags/s/MD.svg
new file mode 100644
index 0000000..2a99237
--- /dev/null
+++ b/public/flags/s/MD.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/s/ME.svg b/public/flags/s/ME.svg
new file mode 100644
index 0000000..77e08e1
--- /dev/null
+++ b/public/flags/s/ME.svg
@@ -0,0 +1,31 @@
+
diff --git a/public/flags/s/MF.svg b/public/flags/s/MF.svg
new file mode 100644
index 0000000..dd77b20
--- /dev/null
+++ b/public/flags/s/MF.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/MG.svg b/public/flags/s/MG.svg
new file mode 100644
index 0000000..4d9c2f2
--- /dev/null
+++ b/public/flags/s/MG.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/MH.svg b/public/flags/s/MH.svg
new file mode 100644
index 0000000..cf24d80
--- /dev/null
+++ b/public/flags/s/MH.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/s/MK.svg b/public/flags/s/MK.svg
new file mode 100644
index 0000000..14ae007
--- /dev/null
+++ b/public/flags/s/MK.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/ML.svg b/public/flags/s/ML.svg
new file mode 100644
index 0000000..224203f
--- /dev/null
+++ b/public/flags/s/ML.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/MM.svg b/public/flags/s/MM.svg
new file mode 100644
index 0000000..eedcdde
--- /dev/null
+++ b/public/flags/s/MM.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/MN.svg b/public/flags/s/MN.svg
new file mode 100644
index 0000000..34e8c30
--- /dev/null
+++ b/public/flags/s/MN.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/MO.svg b/public/flags/s/MO.svg
new file mode 100644
index 0000000..48b4c5b
--- /dev/null
+++ b/public/flags/s/MO.svg
@@ -0,0 +1,28 @@
+
diff --git a/public/flags/s/MP.svg b/public/flags/s/MP.svg
new file mode 100644
index 0000000..d357fb9
--- /dev/null
+++ b/public/flags/s/MP.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/s/MQ.svg b/public/flags/s/MQ.svg
new file mode 100644
index 0000000..30e9148
--- /dev/null
+++ b/public/flags/s/MQ.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/MR.svg b/public/flags/s/MR.svg
new file mode 100644
index 0000000..d115aaa
--- /dev/null
+++ b/public/flags/s/MR.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/s/MS.svg b/public/flags/s/MS.svg
new file mode 100644
index 0000000..afaca4a
--- /dev/null
+++ b/public/flags/s/MS.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/s/MT.svg b/public/flags/s/MT.svg
new file mode 100644
index 0000000..fb9eed6
--- /dev/null
+++ b/public/flags/s/MT.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/MU.svg b/public/flags/s/MU.svg
new file mode 100644
index 0000000..9c5aa12
--- /dev/null
+++ b/public/flags/s/MU.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/s/MV.svg b/public/flags/s/MV.svg
new file mode 100644
index 0000000..ab60057
--- /dev/null
+++ b/public/flags/s/MV.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/s/MW.svg b/public/flags/s/MW.svg
new file mode 100644
index 0000000..7380201
--- /dev/null
+++ b/public/flags/s/MW.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/s/MX.svg b/public/flags/s/MX.svg
new file mode 100644
index 0000000..e00a4c3
--- /dev/null
+++ b/public/flags/s/MX.svg
@@ -0,0 +1,22 @@
+
diff --git a/public/flags/s/MY.svg b/public/flags/s/MY.svg
new file mode 100644
index 0000000..87ed6e4
--- /dev/null
+++ b/public/flags/s/MY.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/s/MZ.svg b/public/flags/s/MZ.svg
new file mode 100644
index 0000000..fa87942
--- /dev/null
+++ b/public/flags/s/MZ.svg
@@ -0,0 +1,31 @@
+
diff --git a/public/flags/s/NA.svg b/public/flags/s/NA.svg
new file mode 100644
index 0000000..781983e
--- /dev/null
+++ b/public/flags/s/NA.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/s/NC.svg b/public/flags/s/NC.svg
new file mode 100644
index 0000000..c3765cd
--- /dev/null
+++ b/public/flags/s/NC.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/NE.svg b/public/flags/s/NE.svg
new file mode 100644
index 0000000..88ab465
--- /dev/null
+++ b/public/flags/s/NE.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/s/NF.svg b/public/flags/s/NF.svg
new file mode 100644
index 0000000..497ae18
--- /dev/null
+++ b/public/flags/s/NF.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/NG.svg b/public/flags/s/NG.svg
new file mode 100644
index 0000000..ae5cff0
--- /dev/null
+++ b/public/flags/s/NG.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/NI.svg b/public/flags/s/NI.svg
new file mode 100644
index 0000000..9f37e0a
--- /dev/null
+++ b/public/flags/s/NI.svg
@@ -0,0 +1,31 @@
+
diff --git a/public/flags/s/NL.svg b/public/flags/s/NL.svg
new file mode 100644
index 0000000..8a7f25f
--- /dev/null
+++ b/public/flags/s/NL.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/NO.svg b/public/flags/s/NO.svg
new file mode 100644
index 0000000..03737f5
--- /dev/null
+++ b/public/flags/s/NO.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/NP.svg b/public/flags/s/NP.svg
new file mode 100644
index 0000000..aaceae4
--- /dev/null
+++ b/public/flags/s/NP.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/s/NR.svg b/public/flags/s/NR.svg
new file mode 100644
index 0000000..abb9089
--- /dev/null
+++ b/public/flags/s/NR.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/NU.svg b/public/flags/s/NU.svg
new file mode 100644
index 0000000..e45d9e3
--- /dev/null
+++ b/public/flags/s/NU.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/s/NZ.svg b/public/flags/s/NZ.svg
new file mode 100644
index 0000000..90d1fb5
--- /dev/null
+++ b/public/flags/s/NZ.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/s/OM.svg b/public/flags/s/OM.svg
new file mode 100644
index 0000000..a3667e8
--- /dev/null
+++ b/public/flags/s/OM.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/s/PA.svg b/public/flags/s/PA.svg
new file mode 100644
index 0000000..aa0bab3
--- /dev/null
+++ b/public/flags/s/PA.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/s/PE.svg b/public/flags/s/PE.svg
new file mode 100644
index 0000000..7fb5a57
--- /dev/null
+++ b/public/flags/s/PE.svg
@@ -0,0 +1,43 @@
+
diff --git a/public/flags/s/PF.svg b/public/flags/s/PF.svg
new file mode 100644
index 0000000..c41c8dd
--- /dev/null
+++ b/public/flags/s/PF.svg
@@ -0,0 +1,43 @@
+
diff --git a/public/flags/s/PG.svg b/public/flags/s/PG.svg
new file mode 100644
index 0000000..3cf648d
--- /dev/null
+++ b/public/flags/s/PG.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/PH.svg b/public/flags/s/PH.svg
new file mode 100644
index 0000000..5c9d14f
--- /dev/null
+++ b/public/flags/s/PH.svg
@@ -0,0 +1,28 @@
+
diff --git a/public/flags/s/PK.svg b/public/flags/s/PK.svg
new file mode 100644
index 0000000..b8cafbb
--- /dev/null
+++ b/public/flags/s/PK.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/PL.svg b/public/flags/s/PL.svg
new file mode 100644
index 0000000..04631f8
--- /dev/null
+++ b/public/flags/s/PL.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/PM.svg b/public/flags/s/PM.svg
new file mode 100644
index 0000000..00eba27
--- /dev/null
+++ b/public/flags/s/PM.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/PN.svg b/public/flags/s/PN.svg
new file mode 100644
index 0000000..a3704d0
--- /dev/null
+++ b/public/flags/s/PN.svg
@@ -0,0 +1,52 @@
+
diff --git a/public/flags/s/PR.svg b/public/flags/s/PR.svg
new file mode 100644
index 0000000..530346a
--- /dev/null
+++ b/public/flags/s/PR.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/s/PS.svg b/public/flags/s/PS.svg
new file mode 100644
index 0000000..7854885
--- /dev/null
+++ b/public/flags/s/PS.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/PT.svg b/public/flags/s/PT.svg
new file mode 100644
index 0000000..2efb8d1
--- /dev/null
+++ b/public/flags/s/PT.svg
@@ -0,0 +1,40 @@
+
diff --git a/public/flags/s/PW.svg b/public/flags/s/PW.svg
new file mode 100644
index 0000000..d7adb4d
--- /dev/null
+++ b/public/flags/s/PW.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/PY.svg b/public/flags/s/PY.svg
new file mode 100644
index 0000000..adcb08e
--- /dev/null
+++ b/public/flags/s/PY.svg
@@ -0,0 +1,22 @@
+
diff --git a/public/flags/s/QA.svg b/public/flags/s/QA.svg
new file mode 100644
index 0000000..0efa27d
--- /dev/null
+++ b/public/flags/s/QA.svg
@@ -0,0 +1,12 @@
+
diff --git a/public/flags/s/RE.svg b/public/flags/s/RE.svg
new file mode 100644
index 0000000..a4dd467
--- /dev/null
+++ b/public/flags/s/RE.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/RO.svg b/public/flags/s/RO.svg
new file mode 100644
index 0000000..3df2033
--- /dev/null
+++ b/public/flags/s/RO.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/RS.svg b/public/flags/s/RS.svg
new file mode 100644
index 0000000..d61a9e3
--- /dev/null
+++ b/public/flags/s/RS.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/s/RU.svg b/public/flags/s/RU.svg
new file mode 100644
index 0000000..f3750cd
--- /dev/null
+++ b/public/flags/s/RU.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/RW.svg b/public/flags/s/RW.svg
new file mode 100644
index 0000000..116208c
--- /dev/null
+++ b/public/flags/s/RW.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/s/SA.svg b/public/flags/s/SA.svg
new file mode 100644
index 0000000..2b628fa
--- /dev/null
+++ b/public/flags/s/SA.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/s/SB.svg b/public/flags/s/SB.svg
new file mode 100644
index 0000000..e7963ff
--- /dev/null
+++ b/public/flags/s/SB.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/s/SC.svg b/public/flags/s/SC.svg
new file mode 100644
index 0000000..8f8c6e0
--- /dev/null
+++ b/public/flags/s/SC.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/s/SD.svg b/public/flags/s/SD.svg
new file mode 100644
index 0000000..e0c3995
--- /dev/null
+++ b/public/flags/s/SD.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/SE.svg b/public/flags/s/SE.svg
new file mode 100644
index 0000000..05370bf
--- /dev/null
+++ b/public/flags/s/SE.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/SG.svg b/public/flags/s/SG.svg
new file mode 100644
index 0000000..d6a706a
--- /dev/null
+++ b/public/flags/s/SG.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/SH.svg b/public/flags/s/SH.svg
new file mode 100644
index 0000000..1d6c747
--- /dev/null
+++ b/public/flags/s/SH.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/s/SI.svg b/public/flags/s/SI.svg
new file mode 100644
index 0000000..97dd420
--- /dev/null
+++ b/public/flags/s/SI.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/s/SJ.svg b/public/flags/s/SJ.svg
new file mode 100644
index 0000000..b7a059a
--- /dev/null
+++ b/public/flags/s/SJ.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/SK.svg b/public/flags/s/SK.svg
new file mode 100644
index 0000000..b5cd36f
--- /dev/null
+++ b/public/flags/s/SK.svg
@@ -0,0 +1,26 @@
+
diff --git a/public/flags/s/SL.svg b/public/flags/s/SL.svg
new file mode 100644
index 0000000..4a96130
--- /dev/null
+++ b/public/flags/s/SL.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/SM.svg b/public/flags/s/SM.svg
new file mode 100644
index 0000000..8f71cba
--- /dev/null
+++ b/public/flags/s/SM.svg
@@ -0,0 +1,42 @@
+
diff --git a/public/flags/s/SN.svg b/public/flags/s/SN.svg
new file mode 100644
index 0000000..c29697b
--- /dev/null
+++ b/public/flags/s/SN.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/SO.svg b/public/flags/s/SO.svg
new file mode 100644
index 0000000..35ac5b6
--- /dev/null
+++ b/public/flags/s/SO.svg
@@ -0,0 +1,12 @@
+
diff --git a/public/flags/s/SR.svg b/public/flags/s/SR.svg
new file mode 100644
index 0000000..92a3a00
--- /dev/null
+++ b/public/flags/s/SR.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/SS.svg b/public/flags/s/SS.svg
new file mode 100644
index 0000000..79360d7
--- /dev/null
+++ b/public/flags/s/SS.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/s/ST.svg b/public/flags/s/ST.svg
new file mode 100644
index 0000000..4698954
--- /dev/null
+++ b/public/flags/s/ST.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/s/SV.svg b/public/flags/s/SV.svg
new file mode 100644
index 0000000..3524d85
--- /dev/null
+++ b/public/flags/s/SV.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/s/SX.svg b/public/flags/s/SX.svg
new file mode 100644
index 0000000..36885c2
--- /dev/null
+++ b/public/flags/s/SX.svg
@@ -0,0 +1,31 @@
+
diff --git a/public/flags/s/SY.svg b/public/flags/s/SY.svg
new file mode 100644
index 0000000..44b96ac
--- /dev/null
+++ b/public/flags/s/SY.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/s/SZ.svg b/public/flags/s/SZ.svg
new file mode 100644
index 0000000..ed32815
--- /dev/null
+++ b/public/flags/s/SZ.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/s/TC.svg b/public/flags/s/TC.svg
new file mode 100644
index 0000000..19f13bc
--- /dev/null
+++ b/public/flags/s/TC.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/s/TD.svg b/public/flags/s/TD.svg
new file mode 100644
index 0000000..c3b64c2
--- /dev/null
+++ b/public/flags/s/TD.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/TF.svg b/public/flags/s/TF.svg
new file mode 100644
index 0000000..80bbee5
--- /dev/null
+++ b/public/flags/s/TF.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/s/TG.svg b/public/flags/s/TG.svg
new file mode 100644
index 0000000..457c3bf
--- /dev/null
+++ b/public/flags/s/TG.svg
@@ -0,0 +1,15 @@
+
diff --git a/public/flags/s/TH.svg b/public/flags/s/TH.svg
new file mode 100644
index 0000000..4afb7f7
--- /dev/null
+++ b/public/flags/s/TH.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/TJ.svg b/public/flags/s/TJ.svg
new file mode 100644
index 0000000..ce7c0c6
--- /dev/null
+++ b/public/flags/s/TJ.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/flags/s/TK.svg b/public/flags/s/TK.svg
new file mode 100644
index 0000000..8b26043
--- /dev/null
+++ b/public/flags/s/TK.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/s/TL.svg b/public/flags/s/TL.svg
new file mode 100644
index 0000000..344937d
--- /dev/null
+++ b/public/flags/s/TL.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/TM.svg b/public/flags/s/TM.svg
new file mode 100644
index 0000000..713bc3c
--- /dev/null
+++ b/public/flags/s/TM.svg
@@ -0,0 +1,75 @@
+
diff --git a/public/flags/s/TN.svg b/public/flags/s/TN.svg
new file mode 100644
index 0000000..33ca4c3
--- /dev/null
+++ b/public/flags/s/TN.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/TO.svg b/public/flags/s/TO.svg
new file mode 100644
index 0000000..5a1a806
--- /dev/null
+++ b/public/flags/s/TO.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/TR.svg b/public/flags/s/TR.svg
new file mode 100644
index 0000000..c653faa
--- /dev/null
+++ b/public/flags/s/TR.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/TT.svg b/public/flags/s/TT.svg
new file mode 100644
index 0000000..9e8976d
--- /dev/null
+++ b/public/flags/s/TT.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/TV.svg b/public/flags/s/TV.svg
new file mode 100644
index 0000000..a847d94
--- /dev/null
+++ b/public/flags/s/TV.svg
@@ -0,0 +1,28 @@
+
diff --git a/public/flags/s/TW.svg b/public/flags/s/TW.svg
new file mode 100644
index 0000000..244d2f7
--- /dev/null
+++ b/public/flags/s/TW.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/TZ.svg b/public/flags/s/TZ.svg
new file mode 100644
index 0000000..b51c5d1
--- /dev/null
+++ b/public/flags/s/TZ.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/UA.svg b/public/flags/s/UA.svg
new file mode 100644
index 0000000..790e0f1
--- /dev/null
+++ b/public/flags/s/UA.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/flags/s/UG.svg b/public/flags/s/UG.svg
new file mode 100644
index 0000000..4f457ea
--- /dev/null
+++ b/public/flags/s/UG.svg
@@ -0,0 +1,28 @@
+
diff --git a/public/flags/s/UM.svg b/public/flags/s/UM.svg
new file mode 100644
index 0000000..71567a2
--- /dev/null
+++ b/public/flags/s/UM.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/US.svg b/public/flags/s/US.svg
new file mode 100644
index 0000000..0d67c28
--- /dev/null
+++ b/public/flags/s/US.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/UY.svg b/public/flags/s/UY.svg
new file mode 100644
index 0000000..47933b9
--- /dev/null
+++ b/public/flags/s/UY.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/flags/s/UZ.svg b/public/flags/s/UZ.svg
new file mode 100644
index 0000000..64bed18
--- /dev/null
+++ b/public/flags/s/UZ.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/VA.svg b/public/flags/s/VA.svg
new file mode 100644
index 0000000..ae34556
--- /dev/null
+++ b/public/flags/s/VA.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/s/VC.svg b/public/flags/s/VC.svg
new file mode 100644
index 0000000..0a5b271
--- /dev/null
+++ b/public/flags/s/VC.svg
@@ -0,0 +1,14 @@
+
diff --git a/public/flags/s/VE.svg b/public/flags/s/VE.svg
new file mode 100644
index 0000000..5b6cb2a
--- /dev/null
+++ b/public/flags/s/VE.svg
@@ -0,0 +1,19 @@
+
diff --git a/public/flags/s/VG.svg b/public/flags/s/VG.svg
new file mode 100644
index 0000000..77a2ef8
--- /dev/null
+++ b/public/flags/s/VG.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/s/VI.svg b/public/flags/s/VI.svg
new file mode 100644
index 0000000..e22a2f6
--- /dev/null
+++ b/public/flags/s/VI.svg
@@ -0,0 +1,27 @@
+
diff --git a/public/flags/s/VN.svg b/public/flags/s/VN.svg
new file mode 100644
index 0000000..866eedd
--- /dev/null
+++ b/public/flags/s/VN.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/VU.svg b/public/flags/s/VU.svg
new file mode 100644
index 0000000..99434dc
--- /dev/null
+++ b/public/flags/s/VU.svg
@@ -0,0 +1,23 @@
+
diff --git a/public/flags/s/WF.svg b/public/flags/s/WF.svg
new file mode 100644
index 0000000..ab20c25
--- /dev/null
+++ b/public/flags/s/WF.svg
@@ -0,0 +1,13 @@
+
diff --git a/public/flags/s/WS.svg b/public/flags/s/WS.svg
new file mode 100644
index 0000000..184d20a
--- /dev/null
+++ b/public/flags/s/WS.svg
@@ -0,0 +1,22 @@
+
diff --git a/public/flags/s/YE.svg b/public/flags/s/YE.svg
new file mode 100644
index 0000000..6eb4d54
--- /dev/null
+++ b/public/flags/s/YE.svg
@@ -0,0 +1,18 @@
+
diff --git a/public/flags/s/YT.svg b/public/flags/s/YT.svg
new file mode 100644
index 0000000..fb6a151
--- /dev/null
+++ b/public/flags/s/YT.svg
@@ -0,0 +1,29 @@
+
diff --git a/public/flags/s/ZA.svg b/public/flags/s/ZA.svg
new file mode 100644
index 0000000..391fcbd
--- /dev/null
+++ b/public/flags/s/ZA.svg
@@ -0,0 +1,20 @@
+
diff --git a/public/flags/s/ZM.svg b/public/flags/s/ZM.svg
new file mode 100644
index 0000000..ced170f
--- /dev/null
+++ b/public/flags/s/ZM.svg
@@ -0,0 +1,21 @@
+
diff --git a/public/flags/s/ZW.svg b/public/flags/s/ZW.svg
new file mode 100644
index 0000000..a92f44a
--- /dev/null
+++ b/public/flags/s/ZW.svg
@@ -0,0 +1,27 @@
+
diff --git a/src/App.css b/src/App.css
index c35bfdb..10594ea 100644
--- a/src/App.css
+++ b/src/App.css
@@ -33,6 +33,15 @@
font-family: 'DM Mono';
}
+.ant-typography .id-text {
+ font-family: 'DM Mono';
+ font-size: 11.9px;
+}
+
+.flag {
+ line-height: 1;
+}
+
:root {
--unit-100vh: 100vh;
}
@@ -171,3 +180,11 @@ body {
max-width: 400px; /* Optionally set a maximum width */
}
/* --- End of src/components/Dashboard/common/DashboardSidebar.css --- */
+
+.objectTableDescritions >.ant-descriptions-view > table {
+ table-layout: fixed !important;
+}
+
+.objectTableDescritions >.ant-descriptions-view .ant-descriptions-row >.ant-descriptions-item-label {
+ width: 35%;
+}
diff --git a/src/App.jsx b/src/App.jsx
index d6e9d07..6f8843c 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -65,6 +65,7 @@ import PrintServerContextDebug from './components/Dashboard/Developer/PrintServe
import { ApiServerProvider } from './components/Dashboard/context/ApiServerContext.js'
import Users from './components/Dashboard/Management/Users.jsx'
import UserInfo from './components/Dashboard/Management/Users/UserInfo.jsx'
+import SubJobs from './components/Dashboard/Production/SubJobs.jsx'
const AppContent = () => {
const { themeConfig } = useThemeContext()
@@ -113,6 +114,7 @@ const AppContent = () => {
element={}
/>
} />
+ } />
}
diff --git a/src/components/Dashboard/Inventory/FilamentStocks.jsx b/src/components/Dashboard/Inventory/FilamentStocks.jsx
index 9517b56..d7be063 100644
--- a/src/components/Dashboard/Inventory/FilamentStocks.jsx
+++ b/src/components/Dashboard/Inventory/FilamentStocks.jsx
@@ -1,252 +1,29 @@
// src/filamentStocks.js
-import React, { useState, useContext, useRef } from 'react'
-import { useNavigate } from 'react-router-dom'
-import {
- Button,
- Flex,
- Space,
- Modal,
- Dropdown,
- Typography,
- message,
- Checkbox,
- Popover,
- Input
-} from 'antd'
+import React, { useState, useRef } from 'react'
-import { AuthContext } from '../context/AuthContext'
-import { PrintServerContext } from '../context/PrintServerContext'
+import { Button, Flex, Space, Modal, Dropdown, message } from 'antd'
import NewFilamentStock from './FilamentStocks/NewFilamentStock'
-import IdDisplay from '../common/IdDisplay'
-import FilamentStockIcon from '../../Icons/FilamentStockIcon'
-import InfoCircleIcon from '../../Icons/InfoCircleIcon'
import PlusIcon from '../../Icons/PlusIcon'
import ReloadIcon from '../../Icons/ReloadIcon'
-import FilamentStockState from '../common/FilamentStockState'
-import TimeDisplay from '../common/TimeDisplay'
-import XMarkIcon from '../../Icons/XMarkIcon'
-import CheckIcon from '../../Icons/CheckIcon'
import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTable from '../common/ObjectTable'
import ListIcon from '../../Icons/ListIcon'
import GridIcon from '../../Icons/GridIcon'
import useViewMode from '../hooks/useViewMode'
-
-import config from '../../../config'
-
-const { Text } = Typography
+import ColumnViewButton from '../common/ColumnViewButton'
const FilamentStocks = () => {
const [messageApi, contextHolder] = message.useMessage()
- const navigate = useNavigate()
- const { printServer } = useContext(PrintServerContext)
- const [initialized, setInitialized] = useState(false)
const tableRef = useRef()
const [newFilamentStockOpen, setNewFilamentStockOpen] = useState(false)
- const { authenticated } = useContext(AuthContext)
+ const [viewMode, setViewMode] = useViewMode('filamentStocks')
- const [viewMode, setViewMode] = useViewMode('FilamentStocks')
-
- const getFilterDropdown = ({
- setSelectedKeys,
- selectedKeys,
- confirm,
- clearFilters,
- propertyName
- }) => {
- return (
-
-
-
- setSelectedKeys(e.target.value ? [e.target.value] : [])
- }
- onPressEnter={() => confirm()}
- style={{ width: 200, display: 'block' }}
- />
-
-
- )
- }
-
- // Column definitions
- const columns = [
- {
- title: ,
- key: 'icon',
- width: 40,
- fixed: 'left',
- render: () =>
- },
- {
- title: 'Filament Name',
- dataIndex: 'filament',
- key: 'name',
- width: 200,
- fixed: 'left',
- sorter: true,
- filterDropdown: ({
- setSelectedKeys,
- selectedKeys,
- confirm,
- clearFilters
- }) =>
- getFilterDropdown({
- setSelectedKeys,
- selectedKeys,
- confirm,
- clearFilters,
- propertyName: 'filament name'
- }),
- render: (filament) => {filament?.name}
- },
- {
- title: 'ID',
- dataIndex: '_id',
- key: 'id',
- width: 180,
- render: (text) => (
-
- )
- },
- {
- title: 'State',
- key: 'state',
- width: 350,
- render: (record) =>
- },
- {
- title: 'Current (g)',
- dataIndex: 'currentNetWeight',
- key: 'currentNetWeight',
- width: 140,
- sorter: true,
- render: (currentNetWeight) => (
- {currentNetWeight?.toFixed(2) + 'g'}
- )
- },
- {
- title: 'Starting (g)',
- dataIndex: 'startingNetWeight',
- key: 'startingNetWeight',
- width: 140,
- sorter: true,
- render: (startingNetWeight) => (
- {startingNetWeight?.toFixed(2) + 'g'}
- )
- },
- {
- title: 'Created At',
- dataIndex: 'createdAt',
- key: 'createdAt',
- width: 180,
- sorter: true,
- defaultSortOrder: 'descend',
- render: (createdAt) => {
- if (createdAt) {
- return
- } else {
- return 'n/a'
- }
- }
- },
- {
- title: 'Updated At',
- dataIndex: 'updatedAt',
- key: 'updatedAt',
- width: 180,
- sorter: true,
- render: (updatedAt) => {
- if (updatedAt) {
- return
- } else {
- return 'n/a'
- }
- }
- },
- {
- title: 'Actions',
- key: 'actions',
- fixed: 'right',
- width: 150,
- render: (record) => {
- return (
-
- }
- onClick={() =>
- navigate(
- `/dashboard/inventory/filamentstocks/info?filamentStockId=${record._id}`
- )
- }
- />
-
- Actions
-
-
- )
- }
- }
- ]
-
- const [columnVisibility, updateColumnVisibility] = useColumnVisibility(
- 'FilamentStocks',
- columns
- )
-
- React.useEffect(() => {
- if (printServer && !initialized) {
- setInitialized(true)
- printServer.on('notify_filamentstock_update', (updateData) => {
- if (tableRef.current) {
- tableRef.current.updateData(updateData._id, updateData)
- }
- })
- }
-
- return () => {
- if (printServer && initialized) {
- printServer.off('notify_filamentstock_update')
- }
- }
- }, [printServer, initialized])
-
- const getFilamentStockActionItems = (id) => {
- return {
- items: [
- {
- label: 'Info',
- key: 'info',
- icon:
- }
- ],
- onClick: ({ key }) => {
- if (key === 'info') {
- navigate(
- `/dashboard/inventory/filamentstocks/info?filamentStockId=${id}`
- )
- }
- }
- }
- }
+ const [columnVisibility, setColumnVisibility] =
+ useColumnVisibility('filamentStocks')
const actionItems = {
items: [
@@ -271,34 +48,6 @@ const FilamentStocks = () => {
}
}
- const getViewDropdownItems = () => {
- const columnItems = columns
- .filter((col) => col.key && col.title !== '')
- .map((col) => (
- {
- updateColumnVisibility(col.key, e.target.checked)
- }}
- >
- {col.title}
-
- ))
-
- return (
-
-
- {columnItems}
-
-
- )
- }
-
- const visibleColumns = columns.filter(
- (col) => !col.key || columnVisibility[col.key]
- )
-
return (
<>
@@ -308,13 +57,12 @@ const FilamentStocks = () => {
Actions
-
- View
-
+
{
@@ -338,7 +85,7 @@ const FilamentStocks = () => {
open={newFilamentStockOpen}
styles={{ content: { paddingBottom: '24px' } }}
footer={null}
- width={700}
+ width={800}
onCancel={() => {
setNewFilamentStockOpen(false)
}}
diff --git a/src/components/Dashboard/Inventory/FilamentStocks/FilamentStockInfo.jsx b/src/components/Dashboard/Inventory/FilamentStocks/FilamentStockInfo.jsx
index b151059..407d110 100644
--- a/src/components/Dashboard/Inventory/FilamentStocks/FilamentStockInfo.jsx
+++ b/src/components/Dashboard/Inventory/FilamentStocks/FilamentStockInfo.jsx
@@ -1,54 +1,28 @@
-import React, { useState, useEffect, useContext } from 'react'
+import React from 'react'
import { useLocation } from 'react-router-dom'
-import axios from 'axios'
-import {
- Descriptions,
- Spin,
- Space,
- Button,
- message,
- Typography,
- Form,
- Badge,
- Collapse,
- Flex,
- Dropdown,
- Popover,
- Card,
- Checkbox
-} from 'antd'
-import { LoadingOutlined, CaretLeftOutlined } from '@ant-design/icons'
-import IdDisplay from '../../common/IdDisplay'
-import { PrintServerContext } from '../../context/PrintServerContext'
-import FilamentStockState from '../../common/FilamentStockState'
-import StockEventTable from '../../common/StockEventTable'
+import { Space, Flex, Card } from 'antd'
import useCollapseState from '../../hooks/useCollapseState'
-import TimeDisplay from '../../common/TimeDisplay'
-import FilamentIcon from '../../../Icons/FilamentIcon'
-import ReloadIcon from '../../../Icons/ReloadIcon'
-import AuditLogTable from '../../common/AuditLogTable'
+import EditObjectForm from '../../common/EditObjectForm'
+import ObjectInfo from '../../common/ObjectInfo'
+import ObjectTable from '../../common/ObjectTable'
+import ObjectActions from '../../common/ObjectActions'
+import ViewButton from '../../common/ViewButton'
+import EditButtons from '../../common/EditButtons'
+import ActionHandler from '../../common/ActionHandler'
+import InfoCollapse from '../../common/InfoCollapse'
import NotesPanel from '../../common/NotesPanel'
-
-import config from '../../../../config'
-import FilamentStockIcon from '../../../Icons/FilamentStockIcon'
+import LockIndicator from '../../Management/Filaments/LockIndicator'
import InfoCircleIcon from '../../../Icons/InfoCircleIcon'
+import FilamentStockIcon from '../../../Icons/FilamentStockIcon'
import NoteIcon from '../../../Icons/NoteIcon'
import AuditLogIcon from '../../../Icons/AuditLogIcon'
-
-const { Title, Text } = Typography
+import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder'
const FilamentStockInfo = () => {
- const [filamentStockData, setFilamentStockData] = useState(null)
- const [fetchLoading, setFetchLoading] = useState(true)
- const [error, setError] = useState(null)
- const [initialized, setInitialized] = useState(false)
const location = useLocation()
- const [messageApi, contextHolder] = message.useMessage()
const filamentStockId = new URLSearchParams(location.search).get(
'filamentStockId'
)
- const [form] = Form.useForm()
- const { printServer } = useContext(PrintServerContext)
const [collapseState, updateCollapseState] = useCollapseState(
'FilamentStockInfo',
{
@@ -59,411 +33,157 @@ const FilamentStockInfo = () => {
}
)
- useEffect(() => {
- if (filamentStockId) {
- fetchFilamentStockDetails()
- }
- }, [filamentStockId])
-
- useEffect(() => {
- if (filamentStockData) {
- form.setFieldsValue({
- filament: filamentStockData.filament || ''
- })
- }
- }, [filamentStockData, form])
-
- // Add WebSocket event listener for real-time updates
- useEffect(() => {
- if (printServer && !initialized && filamentStockId) {
- setInitialized(true)
- printServer.on('notify_filamentstock_update', (statusUpdate) => {
- setFilamentStockData((prevData) => {
- if (statusUpdate?._id === filamentStockId) {
- return {
- ...prevData,
- ...statusUpdate
- }
- }
- return prevData
- })
- })
- }
- return () => {
- if (printServer && initialized) {
- printServer.off('notify_filamentstock_update')
- }
- }
- }, [printServer, initialized, filamentStockId])
-
- const fetchFilamentStockDetails = async () => {
- try {
- setFetchLoading(true)
- const response = await axios.get(
- `${config.backendUrl}/filamentStocks/${filamentStockId}`,
- {
- headers: {
- Accept: 'application/json'
- },
- withCredentials: true
- }
- )
- setFilamentStockData(response.data)
- setError(null)
- } catch (err) {
- setError('Failed to fetch filament stock details')
- messageApi.error('Failed to fetch filament stock details')
- } finally {
- setFetchLoading(false)
- }
- }
-
- const actionItems = {
- items: [
- {
- label: 'Reload Filament Stock',
- key: 'reload',
- icon:
- }
- ],
- onClick: ({ key }) => {
- if (key === 'reload') {
- fetchFilamentStockDetails()
- }
- }
- }
-
- const getViewDropdownItems = () => {
- const sections = [
- { key: 'info', label: 'Filament Stock Information' },
- { key: 'events', label: 'Filament Stock Events' },
- { key: 'notes', label: 'Notes' },
- { key: 'auditLogs', label: 'Audit Logs' }
- ]
-
- return (
-
-
- {sections.map((section) => (
- {
- updateCollapseState(section.key, e.target.checked)
- }}
- >
- {section.label}
-
- ))}
-
-
- )
- }
-
- if (error) {
- return (
-
- {error || 'FilamentStock not found'}
- } onClick={fetchFilamentStockDetails}>
- Retry
-
-
- )
- }
-
return (
- <>
- {contextHolder}
-
-
-
-
- Actions
-
-
- View
-
-
-
-
- {error ? (
-
- {error || 'FilamentStock not found'}
- } onClick={fetchFilamentStockDetails}>
- Retry
-
-
- ) : (
-
-
-
- updateCollapseState('info', keys.length > 0)
- }
- expandIcon={({ isActive }) => (
-
- )}
- className='no-h-padding-collapse no-t-padding-collapse'
+
+ {({
+ loading,
+ isEditing,
+ formValid,
+ objectData,
+ editLoading,
+ lock,
+ fetchObject
+ }) => {
+ const actions = {
+ reload: () => {
+ fetchObject()
+ return true
+ }
+ }
+ return (
+
+ {({ callAction }) => (
+
-
-
-
- Filament Stock Information
-
-
- }
- key='1'
- >
-
-
-
-
-
- updateCollapseState('events', keys.length > 0)
- }
- expandIcon={({ isActive }) => (
-
- )}
- className='no-h-padding-collapse'
- >
-
-
-
- Filament Stock Events
-
-
- }
- key='2'
- >
-
} spinning={fetchLoading}>
-
+
+
+
+
+
+
+
+
+ {
+ callAction('finishEdit')
+ }}
+ cancelEditing={() => {
+ callAction('cancelEdit')
+ }}
+ startEditing={() => {
+ callAction('edit')
+ }}
+ editLoading={editLoading}
+ formValid={formValid}
+ disabled={true}
+ loading={editLoading}
/>
-
-
-
+
+
-
- updateCollapseState('notes', keys.length > 0)
- }
- expandIcon={({ isActive }) => (
-
- )}
- className='no-h-padding-collapse'
- >
-
-
-
- Notes
-
-
- }
- key='notes'
- >
-
-
-
-
-
+
+
+ }
+ active={collapseState.info}
+ onToggle={(expanded) =>
+ updateCollapseState('info', expanded)
+ }
+ key='info'
+ >
+
+
-
- updateCollapseState('auditLogs', keys.length > 0)
- }
- expandIcon={({ isActive }) => (
-
- )}
- className='no-h-padding-collapse'
- >
-
-
-
- Audit Logs
-
-
- }
- key='auditLogs'
- >
-
-
-
-
-
- )}
-
- >
+ }
+ active={collapseState.events}
+ onToggle={(expanded) =>
+ updateCollapseState('events', expanded)
+ }
+ key='events'
+ >
+ {loading ? (
+
+ ) : (
+
+ )}
+
+
+ }
+ active={collapseState.notes}
+ onToggle={(expanded) =>
+ updateCollapseState('notes', expanded)
+ }
+ key='notes'
+ >
+
+
+
+
+
+ }
+ active={collapseState.auditLogs}
+ onToggle={(expanded) =>
+ updateCollapseState('auditLogs', expanded)
+ }
+ key='auditLogs'
+ >
+ {loading ? (
+
+ ) : (
+
+ )}
+
+
+
+
+ )}
+
+ )
+ }}
+
)
}
diff --git a/src/components/Dashboard/Inventory/FilamentStocks/NewFilamentStock.jsx b/src/components/Dashboard/Inventory/FilamentStocks/NewFilamentStock.jsx
index 324c44c..5955430 100644
--- a/src/components/Dashboard/Inventory/FilamentStocks/NewFilamentStock.jsx
+++ b/src/components/Dashboard/Inventory/FilamentStocks/NewFilamentStock.jsx
@@ -1,238 +1,107 @@
import PropTypes from 'prop-types'
import React, { useState } from 'react'
-import axios from 'axios'
-import {
- Form,
- InputNumber,
- Button,
- message,
- Typography,
- Flex,
- Steps,
- Divider,
- Descriptions,
- Badge
-} from 'antd'
-import FilamentSelect from '../../common/FilamentSelect'
+import { useMediaQuery } from 'react-responsive'
+import { Typography, Flex, Steps, Divider } from 'antd'
-import config from '../../../../config'
+import ObjectInfo from '../../common/ObjectInfo'
+import NewObjectForm from '../../common/NewObjectForm'
+import NewObjectButtons from '../../common/NewObjectButtons'
const { Title } = Typography
-const initialNewFilamentStockForm = {
- filament: null,
- startingGrossWeight: 0
-}
-
const NewFilamentStock = ({ onOk, reset }) => {
- const [messageApi, contextHolder] = message.useMessage()
-
- const [newFilamentStockLoading, setNewFilamentStockLoading] = useState(false)
const [currentStep, setCurrentStep] = useState(0)
- const [nextEnabled, setNextEnabled] = useState(false)
-
- const [newFilamentStockForm] = Form.useForm()
- const [newFilamentStockFormValues, setNewFilamentStockFormValues] = useState(
- initialNewFilamentStockForm
- )
-
- const newFilamentStockFormUpdateValues = Form.useWatch(
- [],
- newFilamentStockForm
- )
-
- React.useEffect(() => {
- newFilamentStockForm
- .validateFields({
- validateOnly: true
- })
- .then(() => setNextEnabled(true))
- .catch(() => setNextEnabled(false))
- }, [newFilamentStockForm, newFilamentStockFormUpdateValues])
-
- const summaryItems = [
- {
- key: 'filament',
- label: 'Filament',
- children: (
-
- )
- },
- {
- key: 'emptySpoolWeight',
- label: 'Empty Spool Weight',
- children: newFilamentStockFormValues?.filament?.emptySpoolWeight + 'g'
- },
- {
- key: 'startingGrossWeight',
- label: 'Starting Gross Weight',
- children: newFilamentStockFormValues.startingGrossWeight + 'g'
- },
- {
- key: 'startingNetWeight',
- label: 'Starting Net Weight',
- children:
- newFilamentStockFormValues.startingGrossWeight -
- newFilamentStockFormValues?.filament?.emptySpoolWeight +
- 'g'
- }
- ]
-
- React.useEffect(() => {
- if (reset) {
- newFilamentStockForm.resetFields()
- }
- }, [reset, newFilamentStockForm])
-
- const handleNewFilamentStock = async () => {
- setNewFilamentStockLoading(true)
- try {
- await axios.post(
- `${config.backendUrl}/filamentstocks`,
- newFilamentStockFormValues,
- {
- withCredentials: true // Important for including cookies
- }
- )
- onOk()
- } catch (error) {
- messageApi.error('Error creating new filament stock: ' + error.message)
- } finally {
- setNewFilamentStockLoading(false)
- }
- }
-
- const steps = [
- {
- title: 'Details',
- key: 'details',
- content: (
- <>
-
-
-
-
-
- {
- if (!value) return ''
- return `${value}`
- }}
- step={0.01}
- style={{ width: '100%' }}
- addonAfter='g'
- />
-
- >
- )
- },
- {
- title: 'Summary',
- key: 'done',
- content: (
-
-
-
- )
- }
- ]
+ const isMobile = useMediaQuery({ maxWidth: 768 })
return (
-
- {contextHolder}
-
-
-
-
-
-
-
-
-
- New Filament Stock
-
-
-
-
+ )
+ }}
+
)
}
NewFilamentStock.propTypes = {
- reset: PropTypes.bool.isRequired,
- onOk: PropTypes.func.isRequired
+ onOk: PropTypes.func.isRequired,
+ reset: PropTypes.bool
}
export default NewFilamentStock
diff --git a/src/components/Dashboard/Inventory/StockEvents.jsx b/src/components/Dashboard/Inventory/StockEvents.jsx
index d7d224f..86d589a 100644
--- a/src/components/Dashboard/Inventory/StockEvents.jsx
+++ b/src/components/Dashboard/Inventory/StockEvents.jsx
@@ -1,245 +1,19 @@
-import React, { useState, useContext, useRef } from 'react'
-import {
- Button,
- Flex,
- Space,
- Popover,
- Checkbox,
- Dropdown,
- Typography,
- Input
-} from 'antd'
-
-import { AuthContext } from '../context/AuthContext'
-import { PrintServerContext } from '../context/PrintServerContext'
-import IdDisplay from '../common/IdDisplay'
-import TimeDisplay from '../common/TimeDisplay'
-import ReloadIcon from '../../Icons/ReloadIcon'
-import PlusMinusIcon from '../../Icons/PlusMinusIcon'
-import XMarkIcon from '../../Icons/XMarkIcon'
-import CheckIcon from '../../Icons/CheckIcon'
+import React, { useRef } from 'react'
+import { Button, Flex, Space, Dropdown } from 'antd'
import useColumnVisibility from '../hooks/useColumnVisibility'
import ObjectTable from '../common/ObjectTable'
import GridIcon from '../../Icons/GridIcon'
import ListIcon from '../../Icons/ListIcon'
import useViewMode from '../hooks/useViewMode'
-
-import config from '../../../config'
-import { getModelByName } from '../../../database/ObjectModels'
-import StockEventIcon from '../../Icons/StockEventIcon'
-
-const { Text } = Typography
+import ColumnViewButton from '../common/ColumnViewButton'
+import ReloadIcon from '../../Icons/ReloadIcon'
const StockEvents = () => {
- const { printServer } = useContext(PrintServerContext)
- const [initialized, setInitialized] = useState(false)
const tableRef = useRef()
- const [viewMode, setViewMode] = useViewMode('StockEvents')
+ const [viewMode, setViewMode] = useViewMode('stockEvents')
- // Column definitions for visibility
- const columns = [
- {
- title: ,
- key: 'icon',
- width: 40,
- fixed: 'left',
- render: () =>
- },
- {
- title: 'Type',
- dataIndex: 'type',
- key: 'type',
- width: 200,
- fixed: 'left',
- sorter: true,
- render: (type) => {
- return {getModelByName(type).title}
- },
- filterDropdown: ({
- setSelectedKeys,
- selectedKeys,
- confirm,
- clearFilters
- }) =>
- getFilterDropdown({
- setSelectedKeys,
- selectedKeys,
- confirm,
- clearFilters,
- propertyName: 'type'
- })
- },
- {
- title: 'ID',
- key: 'id',
- dataIndex: '_id',
- width: 170,
- render: (id) => {
- return
- }
- },
- {
- title: ,
- dataIndex: 'value',
- key: 'value',
- width: 100,
- sorter: true,
- render: (value, record) => {
- const formattedValue = value?.toFixed(2) + record?.unit
- return (
-
- {value > 0 ? '+' + formattedValue : formattedValue}
-
- )
- }
- },
- {
- title: 'Stock ID',
- key: 'stockId',
- width: 170,
- render: (record) => {
- if (record.filamentStock?._id) {
- return (
-
- )
- }
- return 'n/a'
- }
- },
- {
- title: 'Linked IDs',
- key: 'linkedIds',
- width: 170 * 2,
- render: (record) => {
- const ids = (
-
- {record.job ? (
-
- ) : null}
- {record.subJob?.number ? (
-
- ) : null}
- {record.stockAudit ? (
-
- ) : null}
-
- )
- if (!record.stockAudit && !record.job && !record.subJob) {
- return 'n/a'
- }
- return ids
- }
- },
- {
- title: 'Created At',
- dataIndex: 'createdAt',
- key: 'createdAt',
- width: 180,
- sorter: true,
- defaultSortOrder: 'descend',
- render: (createdAt) => {
- if (createdAt) {
- return
- } else {
- return 'n/a'
- }
- }
- },
- {
- title: 'Updated At',
- dataIndex: 'updatedAt',
- key: 'updatedAt',
- width: 180,
- sorter: true,
- render: (updatedAt) => {
- if (updatedAt) {
- return
- } else {
- return 'n/a'
- }
- }
- }
- ]
-
- const [columnVisibility, updateColumnVisibility] = useColumnVisibility(
- 'StockEvents',
- columns
- )
-
- const getFilterDropdown = ({
- setSelectedKeys,
- selectedKeys,
- confirm,
- clearFilters,
- propertyName
- }) => {
- return (
-
-
-
- setSelectedKeys(e.target.value ? [e.target.value] : [])
- }
- onPressEnter={() => confirm()}
- style={{ width: 200, display: 'block' }}
- />
- {
- clearFilters()
- confirm()
- }}
- icon={}
- />
- confirm()}
- icon={}
- />
-
-
- )
- }
-
- const { authenticated } = useContext(AuthContext)
-
- React.useEffect(() => {
- // Add WebSocket event listener for real-time updates
- if (printServer && !initialized) {
- setInitialized(true)
- printServer.on('notify_stockevent_update', (updateData) => {
- if (tableRef.current) {
- tableRef.current.updateData(updateData._id, updateData)
- }
- })
- }
-
- return () => {
- if (printServer && initialized) {
- printServer.off('notify_stockevent_update')
- }
- }
- }, [printServer, initialized])
+ const [columnVisibility, setColumnVisibility] =
+ useColumnVisibility('stockEvents')
const actionItems = {
items: [
@@ -256,34 +30,6 @@ const StockEvents = () => {
}
}
- const getViewDropdownItems = () => {
- const columnItems = columns
- .filter((col) => col.key && col.title !== '')
- .map((col) => (
- {
- updateColumnVisibility(col.key, e.target.checked)
- }}
- >
- {col.title}
-
- ))
-
- return (
-
-
- {columnItems}
-
-
- )
- }
-
- const visibleColumns = columns.filter(
- (col) => !col.key || columnVisibility[col.key]
- )
-
return (
<>
@@ -292,13 +38,12 @@ const StockEvents = () => {
Actions
-
- View
-
+
{
diff --git a/src/components/Dashboard/Management/Filaments.jsx b/src/components/Dashboard/Management/Filaments.jsx
index c084f19..4616452 100644
--- a/src/components/Dashboard/Management/Filaments.jsx
+++ b/src/components/Dashboard/Management/Filaments.jsx
@@ -60,8 +60,8 @@ const Filaments = () => {
diff --git a/src/components/Dashboard/Management/Filaments/FilamentInfo.jsx b/src/components/Dashboard/Management/Filaments/FilamentInfo.jsx
index 000e79b..304665f 100644
--- a/src/components/Dashboard/Management/Filaments/FilamentInfo.jsx
+++ b/src/components/Dashboard/Management/Filaments/FilamentInfo.jsx
@@ -19,6 +19,7 @@ import ActionHandler from '../../common/ActionHandler'
import ObjectActions from '../../common/ObjectActions.jsx'
import ObjectTable from '../../common/ObjectTable.jsx'
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
+import FilamentIcon from '../../../Icons/FilamentIcon.jsx'
const log = loglevel.getLogger('FilamentInfo')
log.setLevel(config.logLevel)
@@ -30,7 +31,7 @@ const FilamentInfo = () => {
'FilamentInfo',
{
info: true,
- details: true,
+ stocks: true,
notes: true,
auditLogs: true
}
@@ -93,6 +94,7 @@ const FilamentInfo = () => {
disabled={loading}
items={[
{ key: 'info', label: 'Filament Information' },
+ { key: 'stocks', label: 'Filament Stocks' },
{ key: 'notes', label: 'Notes' },
{ key: 'auditLogs', label: 'Audit Logs' }
]}
@@ -142,6 +144,30 @@ const FilamentInfo = () => {
/>
+ }
+ active={collapseState.stocks}
+ onToggle={(expanded) =>
+ updateCollapseState('stocks', expanded)
+ }
+ key='stocks'
+ >
+ {loading ? (
+
+ ) : (
+
+ )}
+
+
}
diff --git a/src/components/Dashboard/Management/Filaments/NewFilament.jsx b/src/components/Dashboard/Management/Filaments/NewFilament.jsx
index 311f9f4..4393555 100644
--- a/src/components/Dashboard/Management/Filaments/NewFilament.jsx
+++ b/src/components/Dashboard/Management/Filaments/NewFilament.jsx
@@ -1,428 +1,117 @@
import PropTypes from 'prop-types'
import React, { useState } from 'react'
-import axios from 'axios'
import { useMediaQuery } from 'react-responsive'
-import {
- Form,
- Input,
- InputNumber,
- Button,
- message,
- Typography,
- Select,
- Flex,
- Steps,
- Divider,
- ColorPicker,
- Upload,
- Descriptions,
- Badge
-} from 'antd'
-import { UploadOutlined, LinkOutlined } from '@ant-design/icons'
-import VendorSelect from '../../common/VendorSelect'
+import { Typography, Flex, Steps, Divider } from 'antd'
-import config from '../../../../config'
+import ObjectInfo from '../../common/ObjectInfo'
+import NewObjectForm from '../../common/NewObjectForm'
+import NewObjectButtons from '../../common/NewObjectButtons'
const { Title } = Typography
-const initialNewFilamentForm = {
- name: '',
- vendor: { id: null, name: '' },
- type: '',
- cost: 0,
- color: '#FFFFFF',
- diameter: '1.75',
- image: null,
- url: '',
- barcode: ''
-}
+const NewFilament = ({ onOk }) => {
+ const [currentStep, setCurrentStep] = useState(0)
-const NewFilament = ({ onOk, reset }) => {
- const [messageApi, contextHolder] = message.useMessage()
const isMobile = useMediaQuery({ maxWidth: 768 })
- const [newFilamentLoading, setNewFilamentLoading] = useState(false)
- const [currentStep, setCurrentStep] = useState(0)
- const [nextEnabled, setNextEnabled] = useState(false)
-
- const [newFilamentForm] = Form.useForm()
- const [newFilamentFormValues, setNewFilamentFormValues] = useState(
- initialNewFilamentForm
- )
-
- const [imageList, setImageList] = useState([])
-
- const newFilamentFormUpdateValues = Form.useWatch([], newFilamentForm)
-
- React.useEffect(() => {
- newFilamentForm
- .validateFields({
- validateOnly: true
- })
- .then(() => setNextEnabled(true))
- .catch(() => setNextEnabled(false))
- }, [newFilamentForm, newFilamentFormUpdateValues])
-
- const summaryItems = [
- {
- key: 'name',
- label: 'Name',
- children: newFilamentFormValues.name
- },
- {
- key: 'vendor',
- label: 'Vendor',
- children: newFilamentFormValues.vendor.name
- },
- {
- key: 'type',
- label: 'Material',
- children: newFilamentFormValues.type
- },
- {
- key: 'cost',
- label: 'Cost',
- children: '£' + newFilamentFormValues.cost + ' per kg'
- },
- {
- key: 'color',
- label: 'Colour',
- children: (
-
- )
- },
- {
- key: 'diameter',
- label: 'Diameter',
- children: newFilamentFormValues.diameter + 'mm'
- },
- {
- key: 'density',
- label: 'Density',
- children: newFilamentFormValues.diameter + 'g/cm³'
- },
- {
- key: 'image',
- label: 'Image',
- children: (
-
- )
- },
- {
- key: 'url',
- label: 'URL',
- children: newFilamentFormValues.url
- },
- {
- key: 'barcode',
- label: 'Barcode',
- children: newFilamentFormValues.barcode
- }
- ]
-
- React.useEffect(() => {
- if (reset) {
- newFilamentForm.resetFields()
- }
- }, [reset, newFilamentForm])
-
- const handleNewFilament = async () => {
- setNewFilamentLoading(true)
- try {
- await axios.post(
- `${config.backendUrl}/filaments`,
- newFilamentFormValues,
- {
- withCredentials: true // Important for including cookies
- }
- )
- onOk()
- } catch (error) {
- messageApi.error('Error creating new filament: ' + error.message)
- } finally {
- setNewFilamentLoading(false)
- }
- }
-
- const getBase64 = (file) => {
- return new Promise((resolve, reject) => {
- const reader = new FileReader()
- reader.readAsDataURL(file)
- reader.onload = () => resolve(reader.result)
- reader.onerror = (error) => reject(error)
- })
- }
-
- const handleImageUpload = async ({ file, fileList }) => {
- if (fileList.length === 0) {
- setImageList(fileList)
- newFilamentForm.setFieldsValue({ image: '' })
- return
- }
- const base64 = await getBase64(file)
- setNewFilamentFormValues((prevValues) => ({
- ...prevValues,
- image: base64
- }))
- fileList[0].name = 'Filament Image'
- setImageList(fileList)
- newFilamentForm.setFieldsValue({ image: base64 })
- }
-
- const steps = [
- {
- title: 'Details',
- key: 'details',
- content: (
- <>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {
- if (!value) return ''
- return `${value}`
- }}
- step={0.01}
- style={{ width: '100%' }}
- addonAfter='g/cm³'
- />
-
-
- {
- if (!value) return ''
- return `${value}`
- }}
- step={0.01}
- style={{ width: '100%' }}
- addonAfter='g'
- />
-
- >
- )
- },
- {
- title: 'Optional',
- key: 'optional',
- content: (
- <>
- {
- return '#' + color.toHex()
- }}
- >
-
-
- (Array.isArray(e) ? e : e && e.fileList)}
- >
- false} // Prevent automatic upload
- onChange={handleImageUpload}
- >
- }>Upload
-
-
-
- } />
-
-
- } />
-
- >
- )
- },
- {
- title: 'Summary',
- key: 'done',
- content: (
-
-
-
- )
- }
- ]
-
return (
-
- {contextHolder}
-
- {!isMobile && (
-
-
-
- )}
-
- {!isMobile && }
-
-
-
- New Filament
-
-
-
-
-
+ )
+ }}
+
)
}
NewFilament.propTypes = {
- reset: PropTypes.bool.isRequired,
- onOk: PropTypes.func.isRequired
+ onOk: PropTypes.func.isRequired,
+ reset: PropTypes.bool
}
export default NewFilament
diff --git a/src/components/Dashboard/Management/NoteTypes/NewNoteType.jsx b/src/components/Dashboard/Management/NoteTypes/NewNoteType.jsx
index ff60a4c..3ae5bb2 100644
--- a/src/components/Dashboard/Management/NoteTypes/NewNoteType.jsx
+++ b/src/components/Dashboard/Management/NoteTypes/NewNoteType.jsx
@@ -1,253 +1,115 @@
import PropTypes from 'prop-types'
import React, { useState } from 'react'
-import axios from 'axios'
import { useMediaQuery } from 'react-responsive'
-import {
- Form,
- Input,
- Button,
- message,
- Typography,
- Flex,
- Steps,
- Descriptions,
- Divider,
- ColorPicker,
- Switch,
- Badge,
- Checkbox
-} from 'antd'
+import { Typography, Flex, Steps, Divider } from 'antd'
-import config from '../../../../config'
-import BoolDisplay from '../../common/BoolDisplay'
+import ObjectInfo from '../../common/ObjectInfo'
+import NewObjectForm from '../../common/NewObjectForm'
+import NewObjectButtons from '../../common/NewObjectButtons'
-const { Title, Text } = Typography
+const { Title } = Typography
-const initialNewNoteTypeForm = {
- name: '',
- color: null,
- active: true
-}
-
-const NewNoteType = ({ onOk, reset }) => {
- const [messageApi, contextHolder] = message.useMessage()
- const [newNoteTypeLoading, setNewNoteTypeLoading] = useState(false)
+const NewNoteType = ({ onOk }) => {
const [currentStep, setCurrentStep] = useState(0)
- const [nextEnabled, setNextEnabled] = useState(false)
- const [colorEnabled, setColorEnabled] = useState(false)
- const [newNoteTypeForm] = Form.useForm()
- const [newNoteTypeFormValues, setNewNoteTypeFormValues] = useState(
- initialNewNoteTypeForm
- )
const isMobile = useMediaQuery({ maxWidth: 768 })
- const newNoteTypeFormUpdateValues = Form.useWatch([], newNoteTypeForm)
-
- React.useEffect(() => {
- newNoteTypeForm
- .validateFields({
- validateOnly: true
- })
- .then(() => setNextEnabled(true))
- .catch(() => setNextEnabled(false))
- }, [newNoteTypeForm, newNoteTypeFormUpdateValues])
-
- const summaryItems = [
- {
- key: 'name',
- label: 'Name',
- children: newNoteTypeFormValues.name
- },
- {
- key: 'color',
- label: 'Color',
- children: newNoteTypeFormValues.color ? (
-
- ) : (
- n/a
- )
- },
- {
- key: 'active',
- label: 'Active',
- children: newNoteTypeFormValues ? (
-
- ) : (
- n/a
- )
- }
- ]
-
- React.useEffect(() => {
- if (reset) {
- newNoteTypeForm.resetFields()
- }
- }, [reset, newNoteTypeForm])
-
- const handleNewNoteType = async () => {
- setNewNoteTypeLoading(true)
- try {
- await axios.post(
- `${config.backendUrl}/noteTypes`,
- newNoteTypeFormValues,
- {
- withCredentials: true
- }
- )
- onOk()
- } catch (error) {
- messageApi.error('Error creating new note type: ' + error.message)
- } finally {
- setNewNoteTypeLoading(false)
- }
- }
-
- const steps = [
- {
- title: 'Details',
- key: 'details',
- content: (
- <>
-
-
-
-
-
- {
- if (color != null) {
- return '#' + color.toHex()
- }
- return null
- }}
- >
-
-
- {
- setColorEnabled(e.target.checked)
- if (!e.target.checked) {
- setNewNoteTypeFormValues((prev) => ({ ...prev, color: null }))
- } else if (e.target.checked) {
- setNewNoteTypeFormValues((prev) => ({
- ...prev,
- color: newNoteTypeForm.getFieldValue('color')
- }))
- }
- }}
- />
-
-
-
-
- >
- )
- },
- {
- title: 'Summary',
- key: 'summary',
- content:
- }
- ]
-
return (
-
- {contextHolder}
-
- {!isMobile && (
-
-
-
- )}
-
- {!isMobile && }
-
-
-
- New Note Type
-
-
+ ]
+ return (
+
+ {!isMobile && (
+
+
+
+ )}
-
- {
- setCurrentStep((prev) => prev - 1)
- setNextEnabled(true)
- }}
- disabled={currentStep === 0}
- >
- Previous
-
+ {!isMobile && (
+
+ )}
- {currentStep < steps.length - 1 ? (
- {
- setCurrentStep((prev) => prev + 1)
- setNextEnabled(false)
- }}
- >
- Next
-
- ) : (
- {
- newNoteTypeForm.submit()
- }}
- >
- Done
-
- )}
-
-
-
+
+
+ New Note Type
+
+
+ {steps[currentStep].content}
+
+ setCurrentStep((prev) => prev - 1)}
+ onNext={() => setCurrentStep((prev) => prev + 1)}
+ onSubmit={() => {
+ handleSubmit()
+ onOk()
+ }}
+ formValid={formValid}
+ submitLoading={submitLoading}
+ />
+
+
+ )
+ }}
+
)
}
diff --git a/src/components/Dashboard/Management/Parts/PartInfo.jsx b/src/components/Dashboard/Management/Parts/PartInfo.jsx
index 5e7b75d..fb23e26 100644
--- a/src/components/Dashboard/Management/Parts/PartInfo.jsx
+++ b/src/components/Dashboard/Management/Parts/PartInfo.jsx
@@ -22,7 +22,7 @@ const PartInfo = () => {
const location = useLocation()
const partId = new URLSearchParams(location.search).get('partId')
- const { handleDownloadContent } = useContext(ApiServerContext)
+ const { fetchObjectContent } = useContext(ApiServerContext)
const [collapseState, updateCollapseState] = useCollapseState('PartInfo', {
info: true,
@@ -68,7 +68,7 @@ const PartInfo = () => {
},
download: () => {
if (partId) {
- handleDownloadContent(partId, 'part', `${objectData.name}.stl`)
+ fetchObjectContent(partId, 'part', `${objectData.name}.stl`)
return true
}
}
diff --git a/src/components/Dashboard/Management/Vendors/NewVendor.jsx b/src/components/Dashboard/Management/Vendors/NewVendor.jsx
index 8d7d5cb..bf008e2 100644
--- a/src/components/Dashboard/Management/Vendors/NewVendor.jsx
+++ b/src/components/Dashboard/Management/Vendors/NewVendor.jsx
@@ -1,258 +1,110 @@
import PropTypes from 'prop-types'
import React, { useState } from 'react'
-import axios from 'axios'
import { useMediaQuery } from 'react-responsive'
-import {
- Form,
- Input,
- Button,
- message,
- Typography,
- Flex,
- Steps,
- Descriptions,
- Divider
-} from 'antd'
+import { Typography, Flex, Steps, Divider } from 'antd'
-import CountrySelect from '../../common/CountrySelect'
-import CountryDisplay from '../../common/CountryDisplay'
-
-import config from '../../../../config'
+import ObjectInfo from '../../common/ObjectInfo'
+import NewObjectForm from '../../common/NewObjectForm'
+import NewObjectButtons from '../../common/NewObjectButtons'
const { Title } = Typography
-const initialNewVendorForm = {
- name: '',
- website: '',
- contact: '',
- country: '',
- email: '',
- phone: ''
-}
-
-const NewVendor = ({ onOk, reset }) => {
- const [messageApi, contextHolder] = message.useMessage()
- const [newVendorLoading, setNewVendorLoading] = useState(false)
+const NewVendor = ({ onOk }) => {
const [currentStep, setCurrentStep] = useState(0)
- const [nextEnabled, setNextEnabled] = useState(false)
- const [newVendorForm] = Form.useForm()
- const [newVendorFormValues, setNewVendorFormValues] =
- useState(initialNewVendorForm)
const isMobile = useMediaQuery({ maxWidth: 768 })
- const newVendorFormUpdateValues = Form.useWatch([], newVendorForm)
-
- React.useEffect(() => {
- newVendorForm
- .validateFields({
- validateOnly: true
- })
- .then(() => setNextEnabled(true))
- .catch(() => setNextEnabled(false))
- }, [newVendorForm, newVendorFormUpdateValues])
-
- const summaryItems = [
- {
- key: 'name',
- label: 'Name',
- children: newVendorFormValues.name
- },
- {
- key: 'website',
- label: 'Website',
- children: newVendorFormValues.website || 'n/a'
- },
- {
- key: 'country',
- label: 'Country',
- children: newVendorFormValues.country ? (
-
- ) : (
- 'n/a'
- )
- },
- {
- key: 'contact',
- label: 'Contact',
- children: newVendorFormValues.contact || 'n/a'
- },
- {
- key: 'email',
- label: 'Email',
- children: newVendorFormValues.email || 'n/a'
- },
- {
- key: 'phone',
- label: 'Phone',
- children: newVendorFormValues.phone || 'n/a'
- }
- ]
-
- React.useEffect(() => {
- if (reset) {
- newVendorForm.resetFields()
- }
- }, [reset, newVendorForm])
-
- const handleNewVendor = async () => {
- setNewVendorLoading(true)
- try {
- await axios.post(`${config.backendUrl}/vendors`, newVendorFormValues, {
- withCredentials: true
- })
- onOk()
- } catch (error) {
- messageApi.error('Error creating new vendor: ' + error.message)
- } finally {
- setNewVendorLoading(false)
- }
- }
-
- const steps = [
- {
- title: 'Details',
- key: 'details',
- content: (
- <>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
- )
- },
- {
- title: 'Summary',
- key: 'summary',
- content:
- }
- ]
-
return (
-
- {contextHolder}
-
- {!isMobile && (
-
-
-
- )}
-
- {!isMobile && }
-
-
-
- New Vendor
-
-
+ ]
+ return (
+
+ {!isMobile && (
+
+
+
+ )}
-
- {
- setCurrentStep((prev) => prev - 1)
- setNextEnabled(true)
- }}
- disabled={currentStep === 0}
- >
- Previous
-
+ {!isMobile && (
+
+ )}
- {currentStep < steps.length - 1 ? (
- {
- setCurrentStep((prev) => prev + 1)
- setNextEnabled(false)
- }}
- >
- Next
-
- ) : (
- {
- newVendorForm.submit()
- }}
- >
- Done
-
- )}
-
-
-
+
+
+ New Vendor
+
+
+ {steps[currentStep].content}
+
+ setCurrentStep((prev) => prev - 1)}
+ onNext={() => setCurrentStep((prev) => prev + 1)}
+ onSubmit={() => {
+ handleSubmit()
+ onOk()
+ }}
+ formValid={formValid}
+ submitLoading={submitLoading}
+ />
+
+
+ )
+ }}
+
)
}
diff --git a/src/components/Dashboard/Production/GCodeFiles/GCodeFileInfo.jsx b/src/components/Dashboard/Production/GCodeFiles/GCodeFileInfo.jsx
index 1d3f11f..cc8af11 100644
--- a/src/components/Dashboard/Production/GCodeFiles/GCodeFileInfo.jsx
+++ b/src/components/Dashboard/Production/GCodeFiles/GCodeFileInfo.jsx
@@ -26,7 +26,7 @@ const GCodeFileInfo = () => {
const location = useLocation()
const gcodeFileId = new URLSearchParams(location.search).get('gcodeFileId')
- const { handleDownloadContent } = useContext(ApiServerContext)
+ const { fetchObjectContent } = useContext(ApiServerContext)
const [collapseState, updateCollapseState] = useCollapseState(
'gcodeFileInfo',
{
@@ -75,7 +75,7 @@ const GCodeFileInfo = () => {
},
download: () => {
if (gcodeFileId) {
- handleDownloadContent(
+ fetchObjectContent(
gcodeFileId,
'gcodeFile',
`${objectData.name}.gcode`
diff --git a/src/components/Dashboard/Production/Jobs.jsx b/src/components/Dashboard/Production/Jobs.jsx
index dfb04f1..27ee6fd 100644
--- a/src/components/Dashboard/Production/Jobs.jsx
+++ b/src/components/Dashboard/Production/Jobs.jsx
@@ -88,8 +88,7 @@ const Jobs = () => {
{
setNewJobOpen(false)
}}
diff --git a/src/components/Dashboard/Production/Jobs/JobInfo.jsx b/src/components/Dashboard/Production/Jobs/JobInfo.jsx
index 2dd8ef7..42a4b9d 100644
--- a/src/components/Dashboard/Production/Jobs/JobInfo.jsx
+++ b/src/components/Dashboard/Production/Jobs/JobInfo.jsx
@@ -24,7 +24,7 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
const JobInfo = () => {
const location = useLocation()
const jobId = new URLSearchParams(location.search).get('jobId')
- const { handleDownloadContent } = useContext(ApiServerContext)
+ const { fetchObjectContent } = useContext(ApiServerContext)
const [collapseState, updateCollapseState] = useCollapseState('JobInfo', {
info: true,
subJobs: true,
@@ -70,7 +70,7 @@ const JobInfo = () => {
},
download: () => {
if (jobId) {
- handleDownloadContent(
+ fetchObjectContent(
jobId,
'job',
`${objectData.name || 'job'}.json`
@@ -120,7 +120,7 @@ const JobInfo = () => {
}}
editLoading={editLoading}
formValid={formValid}
- disabled={lock?.locked || loading}
+ disabled={true}
loading={editLoading}
/>
diff --git a/src/components/Dashboard/Production/Jobs/NewJob.jsx b/src/components/Dashboard/Production/Jobs/NewJob.jsx
index bcd13f6..feb85b4 100644
--- a/src/components/Dashboard/Production/Jobs/NewJob.jsx
+++ b/src/components/Dashboard/Production/Jobs/NewJob.jsx
@@ -1,216 +1,121 @@
import React, { useState } from 'react'
-import axios from 'axios'
-import { useMediaQuery } from 'react-responsive'
-import {
- Form,
- Button,
- message,
- Typography,
- Flex,
- Steps,
- Divider,
- Descriptions,
- InputNumber
-} from 'antd'
import PropTypes from 'prop-types'
+import { useMediaQuery } from 'react-responsive'
+import { Typography, Flex, Steps, Divider } from 'antd'
-import GCodeFileSelect from '../../common/GCodeFileSelect'
-import PrinterSelect from '../../common/PrinterSelect'
-
-import config from '../../../../config'
+import NewObjectButtons from '../../common/NewObjectButtons'
+import ObjectInfo from '../../common/ObjectInfo'
+import NewObjectForm from '../../common/NewObjectForm'
const { Title } = Typography
-const initialNewJobForm = {
- gcodeFile: null,
- quantity: 1
-}
-
-const NewJob = ({ onOk, reset }) => {
- NewJob.propTypes = {
- onOk: PropTypes.func.isRequired,
- reset: PropTypes.bool.isRequired
- }
-
- const [messageApi, contextHolder] = message.useMessage()
- const [newJobLoading, setNewJobLoading] = useState(false)
+const NewJob = ({ onOk }) => {
const [currentStep, setCurrentStep] = useState(0)
- const [nextEnabled, setNextEnabled] = useState(false)
- const [newJobForm] = Form.useForm()
- const [newJobFormValues, setNewJobFormValues] = useState(initialNewJobForm)
-
- const newJobFormUpdateValues = Form.useWatch([], newJobForm)
-
const isMobile = useMediaQuery({ maxWidth: 768 })
- React.useEffect(() => {
- newJobForm
- .validateFields({
- validateOnly: true
- })
- .then(() => setNextEnabled(true))
- .catch(() => setNextEnabled(false))
- }, [newJobForm, newJobFormUpdateValues])
-
- const summaryItems = [
- {
- key: 'quantity',
- label: 'Quantity',
- children: newJobFormValues.quantity
- }
- ]
-
- React.useEffect(() => {
- if (reset) {
- newJobForm.resetFields()
- }
- }, [reset, newJobForm])
-
- const handleNewJob = async () => {
- setNewJobLoading(true)
- try {
- await axios.post(`${config.backendUrl}/jobs`, newJobFormValues, {
- headers: {
- Accept: 'application/json'
- },
- withCredentials: true // Important for including cookies
- })
-
- onOk()
- } catch (error) {
- messageApi.error('Error creating new print job: ' + error.message)
- } finally {
- setNewJobLoading(false)
- }
- }
-
- const steps = [
- {
- title: 'Required',
- key: 'required',
- content: (
- <>
-
-
-
-
-
-
-
-
-
- >
- )
- },
- {
- title: 'Summary',
- key: 'done',
- content: (
-
-
-
- )
- }
- ]
-
return (
-
- {contextHolder}
- {!isMobile && (
-
-
-
- )}
-
- {!isMobile && }
-
-
-
- New Job
-
-
-
-
+ )
+ }}
+
)
}
+NewJob.propTypes = {
+ onOk: PropTypes.func.isRequired,
+ reset: PropTypes.bool
+}
+
export default NewJob
diff --git a/src/components/Dashboard/Production/ProductionSidebar.jsx b/src/components/Dashboard/Production/ProductionSidebar.jsx
index 65b3d50..ade625b 100644
--- a/src/components/Dashboard/Production/ProductionSidebar.jsx
+++ b/src/components/Dashboard/Production/ProductionSidebar.jsx
@@ -5,6 +5,7 @@ import ProductionIcon from '../../Icons/ProductionIcon'
import PrinterIcon from '../../Icons/PrinterIcon'
import JobIcon from '../../Icons/JobIcon'
import GCodeFileIcon from '../../Icons/GCodeFileIcon'
+import SubJobIcon from '../../Icons/SubJobIcon'
const items = [
{
@@ -27,7 +28,13 @@ const items = [
path: '/dashboard/production/jobs'
},
{
- key: 'gcodefiles',
+ key: 'subJobs',
+ icon: ,
+ label: 'Sub Jobs',
+ path: '/dashboard/production/subjobs'
+ },
+ {
+ key: 'gcodeFiles',
icon: ,
label: 'GCode Files',
path: '/dashboard/production/gcodefiles'
@@ -38,7 +45,8 @@ const routeKeyMap = {
'/dashboard/production/overview': 'overview',
'/dashboard/production/printers': 'printers',
'/dashboard/production/jobs': 'jobs',
- '/dashboard/production/gcodefiles': 'gcodefiles'
+ '/dashboard/production/subjobs': 'subJobs',
+ '/dashboard/production/gcodefiles': 'gcodeFiles'
}
const ProductionSidebar = (props) => {
diff --git a/src/components/Dashboard/Production/SubJobs.jsx b/src/components/Dashboard/Production/SubJobs.jsx
new file mode 100644
index 0000000..c2b7498
--- /dev/null
+++ b/src/components/Dashboard/Production/SubJobs.jsx
@@ -0,0 +1,75 @@
+// src/SubJobs.js
+
+import React, { useContext, useRef } from 'react'
+import { Button, Flex, Space, Dropdown } from 'antd'
+
+import { AuthContext } from '../context/AuthContext.js'
+import useColumnVisibility from '../hooks/useColumnVisibility.js'
+import ReloadIcon from '../../Icons/ReloadIcon.jsx'
+import ObjectTable from '../common/ObjectTable.jsx'
+import ListIcon from '../../Icons/ListIcon.jsx'
+import GridIcon from '../../Icons/GridIcon.jsx'
+import useViewMode from '../hooks/useViewMode.js'
+import ColumnViewButton from '../common/ColumnViewButton.jsx'
+
+const SubJobs = () => {
+ const tableRef = useRef()
+ const [viewMode, setViewMode] = useViewMode('subJob')
+ const { authenticated } = useContext(AuthContext)
+
+ const [columnVisibility, setColumnVisibility] = useColumnVisibility('subJob')
+
+ const actionItems = {
+ items: [
+ {
+ label: 'Reload List',
+ key: 'reloadList',
+ icon:
+ }
+ ],
+ onClick: ({ key }) => {
+ if (key === 'reloadList') {
+ tableRef.current?.reload()
+ }
+ }
+ }
+
+ return (
+ <>
+
+
+
+
+ Actions
+
+
+
+
+
+ : }
+ onClick={() =>
+ setViewMode(viewMode === 'cards' ? 'list' : 'cards')
+ }
+ />
+
+
+
+
+
+ >
+ )
+}
+
+export default SubJobs
diff --git a/src/components/Dashboard/common/ColorSelector.jsx b/src/components/Dashboard/common/ColorSelector.jsx
index 13f44e4..85dfb67 100644
--- a/src/components/Dashboard/common/ColorSelector.jsx
+++ b/src/components/Dashboard/common/ColorSelector.jsx
@@ -30,7 +30,7 @@ const ColorSelector = ({ value, onChange, disabled, required = false }) => {
showText
disabledAlpha
style={{ width: '100%', justifyContent: 'start' }}
- disabled={!colorEnabled || disabled}
+ disabled={(!colorEnabled && !required) || disabled}
value={value || '#000000'}
onChange={handleColorChange}
/>
diff --git a/src/components/Dashboard/common/CopyButton.jsx b/src/components/Dashboard/common/CopyButton.jsx
index d8e745f..1a6e0bf 100644
--- a/src/components/Dashboard/common/CopyButton.jsx
+++ b/src/components/Dashboard/common/CopyButton.jsx
@@ -3,13 +3,7 @@ import PropTypes from 'prop-types'
import { Button, Tooltip, message } from 'antd'
import CopyIcon from '../../Icons/CopyIcon'
-const CopyButton = ({
- text,
- style = {},
- iconStyle = {},
- tooltip = 'Copy',
- size = 'small'
-}) => {
+const CopyButton = ({ text, tooltip = 'Copy', size = 'small' }) => {
const [messageApi, contextHolder] = message.useMessage()
const doCopy = (copyText) => {
@@ -51,10 +45,11 @@ const CopyButton = ({
{contextHolder}
}
- type='text'
+ icon={}
+ style={{ minWidth: 25 }}
+ width={20}
size={size}
- style={{ height: '22px', ...style }}
+ type={'text'}
onClick={() => doCopy(text)}
/>
@@ -65,7 +60,6 @@ const CopyButton = ({
CopyButton.propTypes = {
text: PropTypes.string.isRequired,
style: PropTypes.object,
- iconStyle: PropTypes.object,
tooltip: PropTypes.string,
size: PropTypes.string
}
diff --git a/src/components/Dashboard/common/CountryDisplay.jsx b/src/components/Dashboard/common/CountryDisplay.jsx
index 24cfeaa..59ed97c 100644
--- a/src/components/Dashboard/common/CountryDisplay.jsx
+++ b/src/components/Dashboard/common/CountryDisplay.jsx
@@ -1,64 +1,10 @@
import React from 'react'
import PropTypes from 'prop-types'
-import { Space } from 'antd'
+import { Flex, Typography } from 'antd'
+import Flag from 'react-flagpack'
+import countries from '../../../database/Countries'
-const countries = [
- { code: 'US', name: 'United States', flag: '🇺🇸' },
- { code: 'GB', name: 'United Kingdom', flag: '🇬🇧' },
- { code: 'CA', name: 'Canada', flag: '🇨🇦' },
- { code: 'AU', name: 'Australia', flag: '🇦🇺' },
- { code: 'DE', name: 'Germany', flag: '🇩🇪' },
- { code: 'FR', name: 'France', flag: '🇫🇷' },
- { code: 'IT', name: 'Italy', flag: '🇮🇹' },
- { code: 'ES', name: 'Spain', flag: '🇪🇸' },
- { code: 'JP', name: 'Japan', flag: '🇯🇵' },
- { code: 'CN', name: 'China', flag: '🇨🇳' },
- { code: 'BR', name: 'Brazil', flag: '🇧🇷' },
- { code: 'IN', name: 'India', flag: '🇮🇳' },
- { code: 'RU', name: 'Russia', flag: '🇷🇺' },
- { code: 'ZA', name: 'South Africa', flag: '🇿🇦' },
- { code: 'MX', name: 'Mexico', flag: '🇲🇽' },
- { code: 'AR', name: 'Argentina', flag: '🇦🇷' },
- { code: 'AT', name: 'Austria', flag: '🇦🇹' },
- { code: 'BE', name: 'Belgium', flag: '🇧🇪' },
- { code: 'BG', name: 'Bulgaria', flag: '🇧🇬' },
- { code: 'CL', name: 'Chile', flag: '🇨🇱' },
- { code: 'CY', name: 'Cyprus', flag: '🇨🇾' },
- { code: 'CZ', name: 'Czech Republic', flag: '🇨🇿' },
- { code: 'CO', name: 'Colombia', flag: '🇨🇴' },
- { code: 'DK', name: 'Denmark', flag: '🇩🇰' },
- { code: 'EG', name: 'Egypt', flag: '🇪🇬' },
- { code: 'FI', name: 'Finland', flag: '🇫🇮' },
- { code: 'GR', name: 'Greece', flag: '🇬🇷' },
- { code: 'HR', name: 'Croatia', flag: '🇭🇷' },
- { code: 'HK', name: 'Hong Kong', flag: '🇭🇰' },
- { code: 'HU', name: 'Hungary', flag: '🇭🇺' },
- { code: 'ID', name: 'Indonesia', flag: '🇮🇩' },
- { code: 'IE', name: 'Ireland', flag: '🇮🇪' },
- { code: 'IS', name: 'Iceland', flag: '🇮🇸' },
- { code: 'IL', name: 'Israel', flag: '🇮🇱' },
- { code: 'KR', name: 'South Korea', flag: '🇰🇷' },
- { code: 'MY', name: 'Malaysia', flag: '🇲🇾' },
- { code: 'MT', name: 'Malta', flag: '🇲🇹' },
- { code: 'NL', name: 'Netherlands', flag: '🇳🇱' },
- { code: 'NZ', name: 'New Zealand', flag: '🇳🇿' },
- { code: 'NO', name: 'Norway', flag: '🇳🇴' },
- { code: 'PE', name: 'Peru', flag: '🇵🇪' },
- { code: 'PH', name: 'Philippines', flag: '🇵🇭' },
- { code: 'PL', name: 'Poland', flag: '🇵🇱' },
- { code: 'PT', name: 'Portugal', flag: '🇵🇹' },
- { code: 'RO', name: 'Romania', flag: '🇷🇴' },
- { code: 'SA', name: 'Saudi Arabia', flag: '🇸🇦' },
- { code: 'SG', name: 'Singapore', flag: '🇸🇬' },
- { code: 'SI', name: 'Slovenia', flag: '🇸🇮' },
- { code: 'SK', name: 'Slovakia', flag: '🇸🇰' },
- { code: 'SE', name: 'Sweden', flag: '🇸🇪' },
- { code: 'CH', name: 'Switzerland', flag: '🇨🇭' },
- { code: 'TH', name: 'Thailand', flag: '🇹🇭' },
- { code: 'TR', name: 'Turkey', flag: '🇹🇷' },
- { code: 'AE', name: 'United Arab Emirates', flag: '🇦🇪' },
- { code: 'VN', name: 'Vietnam', flag: '🇻🇳' }
-]
+const { Text } = Typography
const CountryDisplay = ({ countryCode }) => {
const country = countries.find((c) => c.code === countryCode)
@@ -68,10 +14,17 @@ const CountryDisplay = ({ countryCode }) => {
}
return (
-
- {country.flag}
- {country.name}
-
+
+
+ {country.name}
+
)
}
diff --git a/src/components/Dashboard/common/CountrySelect.jsx b/src/components/Dashboard/common/CountrySelect.jsx
index 49598c7..2a8316c 100644
--- a/src/components/Dashboard/common/CountrySelect.jsx
+++ b/src/components/Dashboard/common/CountrySelect.jsx
@@ -1,64 +1,10 @@
import React from 'react'
-import { Select, Flex } from 'antd'
+import { Select, Flex, Typography } from 'antd'
import PropTypes from 'prop-types'
+import Flag from 'react-flagpack'
+import countries from '../../../database/Countries'
-const countries = [
- { code: 'US', name: 'United States', flag: '🇺🇸' },
- { code: 'GB', name: 'United Kingdom', flag: '🇬🇧' },
- { code: 'CA', name: 'Canada', flag: '🇨🇦' },
- { code: 'AU', name: 'Australia', flag: '🇦🇺' },
- { code: 'DE', name: 'Germany', flag: '🇩🇪' },
- { code: 'FR', name: 'France', flag: '🇫🇷' },
- { code: 'IT', name: 'Italy', flag: '🇮🇹' },
- { code: 'ES', name: 'Spain', flag: '🇪🇸' },
- { code: 'JP', name: 'Japan', flag: '🇯🇵' },
- { code: 'CN', name: 'China', flag: '🇨🇳' },
- { code: 'BR', name: 'Brazil', flag: '🇧🇷' },
- { code: 'IN', name: 'India', flag: '🇮🇳' },
- { code: 'RU', name: 'Russia', flag: '🇷🇺' },
- { code: 'ZA', name: 'South Africa', flag: '🇿🇦' },
- { code: 'MX', name: 'Mexico', flag: '🇲🇽' },
- { code: 'AR', name: 'Argentina', flag: '🇦🇷' },
- { code: 'AT', name: 'Austria', flag: '🇦🇹' },
- { code: 'BE', name: 'Belgium', flag: '🇧🇪' },
- { code: 'BG', name: 'Bulgaria', flag: '🇧🇬' },
- { code: 'CL', name: 'Chile', flag: '🇨🇱' },
- { code: 'CY', name: 'Cyprus', flag: '🇨🇾' },
- { code: 'CZ', name: 'Czech Republic', flag: '🇨🇿' },
- { code: 'CO', name: 'Colombia', flag: '🇨🇴' },
- { code: 'DK', name: 'Denmark', flag: '🇩🇰' },
- { code: 'EG', name: 'Egypt', flag: '🇪🇬' },
- { code: 'FI', name: 'Finland', flag: '🇫🇮' },
- { code: 'GR', name: 'Greece', flag: '🇬🇷' },
- { code: 'HR', name: 'Croatia', flag: '🇭🇷' },
- { code: 'HK', name: 'Hong Kong', flag: '🇭🇰' },
- { code: 'HU', name: 'Hungary', flag: '🇭🇺' },
- { code: 'ID', name: 'Indonesia', flag: '🇮🇩' },
- { code: 'IE', name: 'Ireland', flag: '🇮🇪' },
- { code: 'IS', name: 'Iceland', flag: '🇮🇸' },
- { code: 'IL', name: 'Israel', flag: '🇮🇱' },
- { code: 'KR', name: 'South Korea', flag: '🇰🇷' },
- { code: 'MY', name: 'Malaysia', flag: '🇲🇾' },
- { code: 'MT', name: 'Malta', flag: '🇲🇹' },
- { code: 'NL', name: 'Netherlands', flag: '🇳🇱' },
- { code: 'NZ', name: 'New Zealand', flag: '🇳🇿' },
- { code: 'NO', name: 'Norway', flag: '🇳🇴' },
- { code: 'PE', name: 'Peru', flag: '🇵🇪' },
- { code: 'PH', name: 'Philippines', flag: '🇵🇭' },
- { code: 'PL', name: 'Poland', flag: '🇵🇱' },
- { code: 'PT', name: 'Portugal', flag: '🇵🇹' },
- { code: 'RO', name: 'Romania', flag: '🇷🇴' },
- { code: 'SA', name: 'Saudi Arabia', flag: '🇸🇦' },
- { code: 'SG', name: 'Singapore', flag: '🇸🇬' },
- { code: 'SI', name: 'Slovenia', flag: '🇸🇮' },
- { code: 'SK', name: 'Slovakia', flag: '🇸🇰' },
- { code: 'SE', name: 'Sweden', flag: '🇸🇪' },
- { code: 'CH', name: 'Switzerland', flag: '🇨🇭' },
- { code: 'TH', name: 'Thailand', flag: '🇹🇭' },
- { code: 'TR', name: 'Turkey', flag: '🇹🇷' },
- { code: 'AE', name: 'United Arab Emirates', flag: '🇦🇪' },
- { code: 'VN', name: 'Vietnam', flag: '🇻🇳' }
-]
+const { Text } = Typography
const CountrySelect = ({
value,
@@ -77,15 +23,18 @@ const CountrySelect = ({
filterOption={(input, option) =>
option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
- options={countries.map((country) => ({
- value: country.code,
- name: country.name,
- label: (
-
- {country.flag} {country.name}
-
- )
- }))}
+ options={countries
+ .sort((a, b) => a.name.localeCompare(b.name))
+ .map((country) => ({
+ value: country.code,
+ name: country.name,
+ label: (
+
+
+ {country.name}
+
+ )
+ }))}
/>
)
}
diff --git a/src/components/Dashboard/common/DashboardBreadcrumb.jsx b/src/components/Dashboard/common/DashboardBreadcrumb.jsx
index bee7906..38a3869 100644
--- a/src/components/Dashboard/common/DashboardBreadcrumb.jsx
+++ b/src/components/Dashboard/common/DashboardBreadcrumb.jsx
@@ -14,7 +14,8 @@ const breadcrumbNameMap = {
'/dashboard/production/printers': 'Printers',
'/dashboard/production/printers/control': 'Control',
'/dashboard/production/printers/info': 'Info',
- '/dashboard/production/jobs': 'Print Jobs',
+ '/dashboard/production/jobs': 'Jobs',
+ '/dashboard/production/subjobs': 'Sub Jobs',
'/dashboard/production/jobs/info': 'Info',
'/dashboard/production/gcodefiles': 'G Code Files',
'/dashboard/production/gcodefiles/info': 'Info',
diff --git a/src/components/Dashboard/common/DashboardNavigation.jsx b/src/components/Dashboard/common/DashboardNavigation.jsx
index 3e3b8a5..f87ad1a 100644
--- a/src/components/Dashboard/common/DashboardNavigation.jsx
+++ b/src/components/Dashboard/common/DashboardNavigation.jsx
@@ -176,8 +176,8 @@ const DashboardNavigation = () => {
showSpotlight()}
>
{
icon={}
type='text'
size='small'
+ style={{ minWidth: 25 }}
onClick={(e) => {
e.preventDefault()
window.location.href = `mailto:${email}`
diff --git a/src/components/Dashboard/common/FilamentStockState.jsx b/src/components/Dashboard/common/FilamentStockState.jsx
index 1d579a8..4ea6064 100644
--- a/src/components/Dashboard/common/FilamentStockState.jsx
+++ b/src/components/Dashboard/common/FilamentStockState.jsx
@@ -1,14 +1,11 @@
import PropTypes from 'prop-types'
-import { Badge, Progress, Flex, Space, Tag, Typography } from 'antd'
-import { green } from '@ant-design/colors'
-import React, { useState, useContext, useEffect } from 'react'
-import { PrintServerContext } from '../context/PrintServerContext'
-
-const { Text } = Typography
+import { Progress, Flex, Space } from 'antd'
+import React from 'react'
+import StateTag from './StateTag'
const getProgressColor = (percent) => {
if (percent <= 50) {
- return green[5]
+ return '#52c41a' // green[5]
} else if (percent <= 80) {
// Interpolate between green and yellow
const ratio = (percent - 50) / 30
@@ -21,111 +18,33 @@ const getProgressColor = (percent) => {
}
const FilamentStockState = ({
- filamentStock,
+ state = { type: 'unknown' },
showProgress = true,
- showStatus = true
+ showState = true
}) => {
- const { printServer } = useContext(PrintServerContext)
- const [badgeStatus, setBadgeStatus] = useState('unknown')
- const [badgeText, setBadgeText] = useState('Unknown')
- const [currentState, setCurrentState] = useState(
- filamentStock?.state || {
- type: 'unknown',
- progress: 0
- }
- )
- const [initialized, setInitialized] = useState(false)
-
- useEffect(() => {
- if (printServer && !initialized && filamentStock?._id) {
- setInitialized(true)
- printServer.on('notify_filamentstock_update', (statusUpdate) => {
- if (statusUpdate?._id === filamentStock?._id && statusUpdate?.state) {
- setCurrentState(statusUpdate.state)
- }
- })
- }
- return () => {
- if (printServer && initialized) {
- printServer.off('notify_filamentstock_update')
- }
- }
- }, [printServer, initialized, filamentStock?._id])
-
- useEffect(() => {
- switch (currentState.type) {
- case 'unconsumed':
- setBadgeStatus('success')
- setBadgeText('Unconsumed')
- break
- case 'partiallyconsumed':
- setBadgeStatus('warning')
- setBadgeText('Partial')
- break
- case 'fullyconsumed':
- setBadgeStatus('error')
- setBadgeText('Consumed')
- break
- case 'error':
- setBadgeStatus('error')
- setBadgeText('Error')
- break
- default:
- setBadgeStatus('default')
- setBadgeText(currentState.type)
- }
- }, [currentState])
-
return (
-
- {showStatus && (
+
+ {showState && (
-
-
-
- {badgeText}
-
-
+
)}
- {showProgress && currentState.type === 'partiallyconsumed' ? (
-
-
-
- {Math.round(currentState.percent * 100) + '%'}
-
-
+ {showProgress && state.type === 'partiallyconsumed' ? (
+
) : null}
)
}
FilamentStockState.propTypes = {
- filamentStock: PropTypes.shape({
- _id: PropTypes.string,
- name: PropTypes.string,
- state: PropTypes.shape({
- type: PropTypes.oneOf([
- 'unconsumed',
- 'partiallyconsumed',
- 'fullyconsumed',
- 'error',
- 'unknown'
- ]),
- progress: PropTypes.number
- })
- }),
+ state: PropTypes.object,
showProgress: PropTypes.bool,
- showStatus: PropTypes.bool
+ showState: PropTypes.bool
}
export default FilamentStockState
diff --git a/src/components/Dashboard/common/IdDisplay.jsx b/src/components/Dashboard/common/IdDisplay.jsx
index e01862e..1ef56c3 100644
--- a/src/components/Dashboard/common/IdDisplay.jsx
+++ b/src/components/Dashboard/common/IdDisplay.jsx
@@ -1,7 +1,7 @@
// PrinterSelect.js
import React from 'react'
import PropTypes from 'prop-types'
-import { Flex, Typography, Space, Popover } from 'antd'
+import { Flex, Typography, Popover } from 'antd'
import { useNavigate } from 'react-router-dom'
import { useMediaQuery } from 'react-responsive'
import CopyButton from './CopyButton'
@@ -25,7 +25,7 @@ const IdDisplay = ({
const prefix = model.prefix
const IconComponent = model.icon
- const icon =
+ const icon =
var hyperlink = null
@@ -52,18 +52,16 @@ const IdDisplay = ({
{(() => {
const content = (
-
+
{icon}
- {displayId}
-
+
+ {displayId}
+
+
)
const textElement = (
-
+
{content}
)
@@ -73,7 +71,8 @@ const IdDisplay = ({
const linkElement = (
navigate(hyperlink)}
- style={{ marginRight: 6 }}
+ ellipsis
+ style={showCopy ? { marginRight: 6 } : undefined}
>
{textElement}
diff --git a/src/components/Dashboard/common/NetGrossDisplay.jsx b/src/components/Dashboard/common/NetGrossDisplay.jsx
new file mode 100644
index 0000000..9c618e3
--- /dev/null
+++ b/src/components/Dashboard/common/NetGrossDisplay.jsx
@@ -0,0 +1,50 @@
+import React from 'react'
+import { Flex, Typography, Tag, Space } from 'antd'
+import PropTypes from 'prop-types'
+
+const { Text } = Typography
+
+const NetGrossDisplay = ({ value, prefix = '', suffix = '' }) => {
+ const net = value?.net
+ const gross = value?.gross
+
+ return (
+
+
+
+ {net != null && net !== '' ? (
+ prefix + net.toFixed(2).toString() + suffix
+ ) : (
+ n/a
+ )}
+
+
+ Net
+
+
+
+
+ {gross != null && gross !== '' ? (
+ prefix + gross.toFixed(2).toString() + suffix
+ ) : (
+ n/a
+ )}
+
+
+ Gross
+
+
+
+ )
+}
+
+NetGrossDisplay.propTypes = {
+ value: PropTypes.shape({
+ net: PropTypes.number,
+ gross: PropTypes.number
+ }),
+ prefix: PropTypes.string,
+ suffix: PropTypes.string
+}
+
+export default NetGrossDisplay
diff --git a/src/components/Dashboard/common/NetGrossInput.jsx b/src/components/Dashboard/common/NetGrossInput.jsx
new file mode 100644
index 0000000..47788a9
--- /dev/null
+++ b/src/components/Dashboard/common/NetGrossInput.jsx
@@ -0,0 +1,135 @@
+import React, { useState, useEffect } from 'react'
+import { Flex, InputNumber, Typography, Switch } from 'antd'
+import PropTypes from 'prop-types'
+
+const { Text } = Typography
+
+const NetGrossInput = ({
+ value = {},
+ onChange,
+ prefix = '',
+ suffix = '',
+ min,
+ max,
+ step,
+ disabled = false,
+ difference = 0
+}) => {
+ const net = value?.net
+ const gross = value?.gross
+
+ // State to track which input is enabled: true = Gross enabled, false = Net enabled
+ const [isGrossEnabled, setIsGrossEnabled] = useState(true)
+
+ // Helper to update both values based on which field is enabled
+ const handleChange = (field, val) => {
+ if (!onChange) return
+ if (field === 'net') {
+ const newNet = val
+ let newGross
+ if (typeof difference === 'number' && newNet != null) {
+ newGross = newNet + difference
+ } else {
+ newGross = undefined
+ }
+ onChange({ net: newNet, gross: newGross })
+ } else if (field === 'gross') {
+ const newGross = val
+ let newNet
+ if (typeof difference === 'number' && newGross != null) {
+ newNet = newGross - difference
+ } else {
+ newNet = undefined
+ }
+ onChange({ net: newNet, gross: newGross })
+ }
+ }
+
+ // When toggling between Net and Gross, recalculate the other value
+ const handleSwitch = (checked) => {
+ setIsGrossEnabled(checked)
+ if (!onChange) return
+ if (checked) {
+ // Switched to Gross: recalc net
+ if (typeof value?.gross === 'number' && typeof difference === 'number') {
+ onChange({ net: value.gross - difference, gross: value.gross })
+ }
+ } else {
+ // Switched to Net: recalc gross
+ if (typeof value?.net === 'number' && typeof difference === 'number') {
+ onChange({ net: value.net, gross: value.net + difference })
+ }
+ }
+ }
+
+ // When difference changes, recalculate the dependent value
+ useEffect(() => {
+ if (!onChange) return
+ if (isGrossEnabled) {
+ if (typeof value?.gross === 'number' && typeof difference === 'number') {
+ onChange({ net: value.gross - difference, gross: value.gross })
+ }
+ } else {
+ if (typeof value?.net === 'number' && typeof difference === 'number') {
+ onChange({ net: value.net, gross: value.net + difference })
+ }
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [difference])
+
+ return (
+
+ Net:}
+ value={net}
+ onChange={(val) => handleChange('net', val)}
+ prefix={prefix}
+ suffix={suffix}
+ min={min}
+ max={max}
+ step={step}
+ disabled={disabled || isGrossEnabled}
+ style={
+ isGrossEnabled ? { minWidth: 120 } : { minWidth: 120, width: '100%' }
+ }
+ />
+
+
+ Gross:}
+ onChange={(val) => handleChange('gross', val)}
+ prefix={prefix}
+ suffix={suffix}
+ min={min}
+ max={max}
+ step={step}
+ disabled={disabled || !isGrossEnabled}
+ style={
+ isGrossEnabled ? { minWidth: 120, width: '100%' } : { minWidth: 120 }
+ }
+ />
+
+ )
+}
+
+NetGrossInput.propTypes = {
+ value: PropTypes.shape({
+ net: PropTypes.number,
+ gross: PropTypes.number
+ }),
+ onChange: PropTypes.func,
+ prefix: PropTypes.string,
+ suffix: PropTypes.string,
+ min: PropTypes.number,
+ max: PropTypes.number,
+ step: PropTypes.number,
+ disabled: PropTypes.bool,
+ difference: PropTypes.number
+}
+
+export default NetGrossInput
diff --git a/src/components/Dashboard/common/NewObjectButtons.jsx b/src/components/Dashboard/common/NewObjectButtons.jsx
new file mode 100644
index 0000000..4707f6c
--- /dev/null
+++ b/src/components/Dashboard/common/NewObjectButtons.jsx
@@ -0,0 +1,54 @@
+import PropTypes from 'prop-types'
+import React from 'react'
+import { Button, Flex } from 'antd'
+
+const NewObjectButtons = ({
+ currentStep,
+ totalSteps,
+ onPrevious,
+ onNext,
+ onSubmit,
+ formValid,
+ submitLoading,
+ submitText = 'Done'
+}) => {
+ return (
+
+
+ Previous
+
+
+ {currentStep < totalSteps - 1 ? (
+
+ Next
+
+ ) : (
+
+ {submitText}
+
+ )}
+
+ )
+}
+
+NewObjectButtons.propTypes = {
+ currentStep: PropTypes.number.isRequired,
+ totalSteps: PropTypes.number.isRequired,
+ onPrevious: PropTypes.func.isRequired,
+ onNext: PropTypes.func.isRequired,
+ onSubmit: PropTypes.func.isRequired,
+ formValid: PropTypes.bool.isRequired,
+ submitLoading: PropTypes.bool,
+ submitText: PropTypes.string
+}
+
+export default NewObjectButtons
diff --git a/src/components/Dashboard/common/NewObjectForm.jsx b/src/components/Dashboard/common/NewObjectForm.jsx
index fdb3ed4..884e100 100644
--- a/src/components/Dashboard/common/NewObjectForm.jsx
+++ b/src/components/Dashboard/common/NewObjectForm.jsx
@@ -10,18 +10,26 @@ import PropTypes from 'prop-types'
* Props:
* - type: string (required)
* - formItems: array (for ObjectInfo/ObjectProperty items)
+ * - defaultValues: object (optional) - initial values for the form
* - children: function({
* loading, isSubmitting, handleSubmit, form, formValid, objectData, setObjectData
* }) => ReactNode
*/
-const NewObjectForm = ({ type, style, children }) => {
- const [objectData, setObjectData] = useState({})
+const NewObjectForm = ({ type, style, defaultValues = {}, children }) => {
+ const [objectData, setObjectData] = useState(defaultValues)
const [submitLoading, setSubmitLoading] = useState(false)
const [formValid, setFormValid] = useState(false)
const [form] = Form.useForm()
const formUpdateValues = Form.useWatch([], form)
const [messageApi, contextHolder] = message.useMessage()
- const { createObjectInfo, showError } = useContext(ApiServerContext)
+ const { createObject, showError } = useContext(ApiServerContext)
+
+ // Set initial form values when defaultValues change
+ useEffect(() => {
+ if (Object.keys(defaultValues).length > 0) {
+ form.setFieldsValue(defaultValues)
+ }
+ }, [form, defaultValues])
// Validate form on change
useEffect(() => {
@@ -33,9 +41,8 @@ const NewObjectForm = ({ type, style, children }) => {
const handleSubmit = async () => {
try {
- const values = await form.validateFields()
setSubmitLoading(true)
- const newObject = await createObjectInfo(type, values)
+ const newObject = await createObject(type, objectData)
messageApi.success('Object created successfully')
return newObject
} catch (err) {
@@ -63,8 +70,7 @@ const NewObjectForm = ({ type, style, children }) => {
>
{contextHolder}
{children({
- loading: false,
- isSubmitting: submitLoading,
+ submitLoading: submitLoading,
handleSubmit,
form,
formValid,
@@ -78,7 +84,8 @@ const NewObjectForm = ({ type, style, children }) => {
NewObjectForm.propTypes = {
type: PropTypes.string.isRequired,
children: PropTypes.func.isRequired,
- style: PropTypes.object
+ style: PropTypes.object,
+ defaultValues: PropTypes.object
}
export default NewObjectForm
diff --git a/src/components/Dashboard/common/ObjectInfo.jsx b/src/components/Dashboard/common/ObjectInfo.jsx
index b2a0cd1..397dff8 100644
--- a/src/components/Dashboard/common/ObjectInfo.jsx
+++ b/src/components/Dashboard/common/ObjectInfo.jsx
@@ -1,5 +1,5 @@
import React from 'react'
-import { Spin, Descriptions } from 'antd'
+import { Spin, Descriptions, Flex } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import PropTypes from 'prop-types'
import ObjectProperty from './ObjectProperty'
@@ -7,19 +7,51 @@ import { getModelProperties } from '../../../database/ObjectModels'
const ObjectInfo = ({
loading = false,
- bordered = true,
isEditing = false,
type = 'unknown',
- objectData = null
+ objectData = null,
+ properties = [],
+ required = undefined,
+ visibleProperties = {},
+ ...rest
}) => {
- const items = getModelProperties(type)
+ const allItems = getModelProperties(type)
+
+ // If properties array is empty, show all properties
+ // Otherwise, filter and order by the properties array
+ let items
+ if (properties.length === 0) {
+ items = allItems
+ } else {
+ items = properties
+ .map((propName) => allItems.find((item) => item.name === propName))
+ .filter(Boolean)
+ }
+
+ if (required != undefined) {
+ items = items.filter((item) => item.required === required)
+ }
+
+ // Filter items based on visibleProperties
+ // If a property key exists in visibleProperties and is false, hide it
+ items = items.filter((item) => {
+ const propertyName = item.name
+ return !(
+ propertyName in visibleProperties &&
+ visibleProperties[propertyName] === false
+ )
+ })
// Map items to Descriptions 'items' prop format
const descriptionItems = items.map((item, idx) => {
const key = item.name || item.label || idx
return {
key,
- label: item.label,
+ label: (
+
+ {item.label}
+
+ ),
children: (
}>
@@ -51,11 +84,14 @@ const ObjectInfo = ({
ObjectInfo.propTypes = {
loading: PropTypes.bool,
indicator: PropTypes.node,
+ properties: PropTypes.array,
bordered: PropTypes.bool,
items: PropTypes.arrayOf(PropTypes.object),
isEditing: PropTypes.bool,
type: PropTypes.string.isRequired,
- objectData: PropTypes.object
+ objectData: PropTypes.object,
+ required: PropTypes.bool,
+ visibleProperties: PropTypes.object
}
export default ObjectInfo
diff --git a/src/components/Dashboard/common/ObjectProperty.jsx b/src/components/Dashboard/common/ObjectProperty.jsx
index 0ac56ea..0a73426 100644
--- a/src/components/Dashboard/common/ObjectProperty.jsx
+++ b/src/components/Dashboard/common/ObjectProperty.jsx
@@ -35,6 +35,8 @@ import EyeSlashIcon from '../../Icons/EyeSlashIcon'
import FilamentStockState from './FilamentStockState'
import { getPropertyValue } from '../../../database/ObjectModels'
import PropertyChanges from './PropertyChanges'
+import NetGrossDisplay from './NetGrossDisplay'
+import NetGrossInput from './NetGrossInput'
const { Text } = Typography
@@ -54,6 +56,7 @@ const ObjectProperty = ({
value,
min,
max,
+ difference,
step,
isEditing = false,
formItemProps = {},
@@ -65,10 +68,11 @@ const ObjectProperty = ({
objectType = 'unknown',
readOnly = false,
disabled = false,
+ initial = false,
...rest
}) => {
if (typeof value == 'function' && objectData) {
- value = disabled(objectData)
+ value = value(objectData)
}
if (objectType && typeof objectType == 'function' && objectData) {
@@ -79,6 +83,10 @@ const ObjectProperty = ({
disabled = disabled(objectData)
}
+ if (difference && typeof difference == 'function' && objectData) {
+ difference = difference(objectData)
+ }
+
if (!value) {
value = getPropertyValue(objectData, name)
}
@@ -97,8 +105,12 @@ const ObjectProperty = ({
}
const renderProperty = () => {
- if (!isEditing || readOnly) {
+ if (!isEditing || (readOnly && !initial)) {
switch (type) {
+ case 'netGross':
+ return (
+
+ )
case 'secret':
if (value != null) {
return
@@ -193,7 +205,7 @@ const ObjectProperty = ({
return (
{prefix}
- {value}
+ {typeof value === 'number' ? value.toFixed(2) : value}
{suffix}
)
@@ -353,7 +365,7 @@ const ObjectProperty = ({
// Editable mode: wrap in Form.Item
// Merge required rule if needed
- let mergedFormItemProps = { ...formItemProps }
+ let mergedFormItemProps = { ...formItemProps, style: { flexGrow: 1 } }
if (required) {
let rules
if (mergedFormItemProps.rules) {
@@ -381,6 +393,16 @@ const ObjectProperty = ({
...(mergedFormItemProps.style || {})
}
switch (type) {
+ case 'netGross':
+ return (
+
+
+
+ )
case 'secret':
return (
@@ -559,26 +581,6 @@ const ObjectProperty = ({
)
}
- case 'density':
- return (
-
-
-
- )
- case 'mm':
- return (
-
-
-
- )
case 'tags':
return (
diff --git a/src/components/Dashboard/common/ObjectTable.jsx b/src/components/Dashboard/common/ObjectTable.jsx
index 42be76c..0c1439e 100644
--- a/src/components/Dashboard/common/ObjectTable.jsx
+++ b/src/components/Dashboard/common/ObjectTable.jsx
@@ -30,8 +30,7 @@ import config from '../../../config'
import loglevel from 'loglevel'
import {
getModelProperties,
- getModelByName,
- getPropertyValue
+ getModelByName
} from '../../../database/ObjectModels'
import ObjectProperty from './ObjectProperty'
import XMarkIcon from '../../Icons/XMarkIcon'
@@ -70,6 +69,7 @@ const ObjectTable = forwardRef(
}
const [, contextHolder] = message.useMessage()
const tableRef = useRef(null)
+ const model = getModelByName(type)
const [tableFilter, setTableFilter] = useState({})
const [tableSorter, setTableSorter] = useState({})
const [initialized, setInitialized] = useState(false)
@@ -80,6 +80,9 @@ const ObjectTable = forwardRef(
const [loading, setLoading] = useState(true)
const [lazyLoading, setLazyLoading] = useState(false)
+ const rowActions =
+ model.actions?.filter((action) => action.row == true) || []
+
const createSkeletonData = useCallback(() => {
return Array(pageSize)
.fill(null)
@@ -89,6 +92,34 @@ const ObjectTable = forwardRef(
}))
}, [pageSize])
+ const renderActions = (objectData) => {
+ return (
+
+ {rowActions.map((action, index) => (
+
+
+ )
+ }
+ type={'text'}
+ size={'small'}
+ onClick={() => {
+ console.log(objectData)
+ if (action.url) {
+ navigate(action.url(objectData._id))
+ }
+ }}
+ />
+
+ ))}
+
+ )
+ }
+
const fetchData = useCallback(
async (pageNum = 1, filter = null, sorter = null) => {
if (filter == null) {
@@ -340,8 +371,6 @@ const ObjectTable = forwardRef(
}
const modelProperties = getModelProperties(type)
- const model = getModelByName(type)
-
// Table columns from model properties
const columnsWithSkeleton = [
{
@@ -440,50 +469,20 @@ const ObjectTable = forwardRef(
}
})
- if (model.actions.length > 0) {
- const rowActions = model.actions.filter((action) => action.row == true)
- if (rowActions.length > 0) {
- columnsWithSkeleton.push({
- title: (
-
- {'Actions'}
-
- ),
- key: 'actions',
- fixed: 'right',
- width: 80 + rowActions.length * 40, // Adjust width based on number of actions
- render: (record) => {
- return (
-
- {rowActions.map((action, index) => (
-
-
- )
- }
- type={'text'}
- size={'small'}
- onClick={() => {
- if (action.onClick) {
- action.onClick(record)
- } else if (action.url) {
- navigate(action.url(record._id))
- } else {
- navigate(model.url(record._id))
- }
- }}
- />
-
- ))}
-
- )
- }
- })
- }
+ if (rowActions.length > 0) {
+ columnsWithSkeleton.push({
+ title: (
+
+ {'Actions'}
+
+ ),
+ key: 'actions',
+ fixed: 'right',
+ width: 80 + rowActions.length * 40, // Adjust width based on number of actions
+ render: (record) => {
+ return renderActions(record)
+ }
+ })
}
// Flatten pages array for table display
@@ -541,22 +540,63 @@ const ObjectTable = forwardRef(
-
- {modelProperties.map((prop) => (
-
-
-
- ))}
+
+ {(() => {
+ const descriptionItems = []
+
+ // Add columns in the order specified by model.columns (same logic as table)
+ model.columns.forEach((colName) => {
+ const prop = modelProperties.find(
+ (p) => p.name === colName
+ )
+ if (prop) {
+ // Check if column should be visible based on visibleColumns prop
+ if (
+ Object.keys(visibleColumns).length > 0 &&
+ visibleColumns[prop.name] === false
+ ) {
+ return // Skip this column if it's not visible
+ }
+
+ descriptionItems.push(
+
+
+
+ )
+ }
+ })
+
+ // Add actions if they exist (same as table)
+ if (rowActions.length > 0) {
+ descriptionItems.push(
+
+ {renderActions(record)}
+
+ )
+ }
+
+ return descriptionItems
+ })()}
diff --git a/src/components/Dashboard/common/PropertyChanges.jsx b/src/components/Dashboard/common/PropertyChanges.jsx
index 3051dc1..61eaa03 100644
--- a/src/components/Dashboard/common/PropertyChanges.jsx
+++ b/src/components/Dashboard/common/PropertyChanges.jsx
@@ -11,21 +11,37 @@ const PropertyChanges = ({ type, value }) => {
if (!value || !value.new) {
return n/a
}
- console.log('combined', { ...value?.old, ...value?.new })
+
+ // Helper to flatten nested objects into dot notation keys
+ function flattenObject(obj, prefix = '', res = {}) {
+ for (const key in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
+ const val = obj[key]
+ const newKey = prefix ? `${prefix}.${key}` : key
+ if (val && typeof val === 'object' && !Array.isArray(val)) {
+ flattenObject(val, newKey, res)
+ } else {
+ res[newKey] = val
+ }
+ }
+ }
+ return res
+ }
+
+ const flatOld = value?.old ? flattenObject(value.old) : {}
+ const flatNew = value?.new ? flattenObject(value.new) : {}
+ const combinedChanges = {
+ ...flatOld,
+ ...flatNew
+ }
+ console.log('combined', combinedChanges)
return (
- {Object.keys({ ...value?.old, ...value?.new }).map((key) => {
- console.log('tc', type, key)
+ {Object.keys(combinedChanges).map((key) => {
var changeProperty = getModelProperty(type, key)
- console.log('change prop', changeProperty)
- if (changeProperty?.type == 'object') {
- changeProperty = {
- ...changeProperty,
- name: changeProperty.name + '._id',
- type: 'id',
- showHyperlink: true
- }
+ if (!changeProperty) {
+ return null
}
return (
diff --git a/src/components/Dashboard/common/SpotlightTooltip.jsx b/src/components/Dashboard/common/SpotlightTooltip.jsx
index a8fad63..399277d 100644
--- a/src/components/Dashboard/common/SpotlightTooltip.jsx
+++ b/src/components/Dashboard/common/SpotlightTooltip.jsx
@@ -137,7 +137,10 @@ const SpotlightTooltip = ({ query, type }) => {
>
) : (
Object.entries(spotlightData).map(([key, value]) =>
- value !== undefined && value !== null && value !== '' ? (
+ value !== undefined &&
+ value !== null &&
+ value !== '' &&
+ key !== 'objectType' ? (
{
>
{
status = 'success'
text = 'Ready'
break
+ case 'unconsumed':
+ status = 'success'
+ text = 'Unconsumed'
+ break
case 'error':
status = 'error'
text = 'Error'
diff --git a/src/components/Dashboard/common/UrlDisplay.jsx b/src/components/Dashboard/common/UrlDisplay.jsx
index a1bbe0c..7ae3865 100644
--- a/src/components/Dashboard/common/UrlDisplay.jsx
+++ b/src/components/Dashboard/common/UrlDisplay.jsx
@@ -31,6 +31,7 @@ const UrlDisplay = ({ url, showCopy = true, showLink = false }) => {
icon={}
type='text'
size='small'
+ style={{ minWidth: 25 }}
onClick={(e) => {
e.preventDefault()
window.open(url, '_blank', 'noopener,noreferrer')
diff --git a/src/components/Dashboard/context/ApiServerContext.js b/src/components/Dashboard/context/ApiServerContext.js
index ca511c2..9d47033 100644
--- a/src/components/Dashboard/context/ApiServerContext.js
+++ b/src/components/Dashboard/context/ApiServerContext.js
@@ -249,6 +249,25 @@ const ApiServerProvider = ({ children }) => {
}
}
+ // Update filament information
+ const createObject = async (type, value) => {
+ const createUrl = `${config.backendUrl}/${type.toLowerCase()}s`
+ logger.debug('Creating object...')
+ try {
+ const response = await axios.post(createUrl, value, {
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ withCredentials: true
+ })
+ return response.data
+ } catch (err) {
+ logger.error('Failed to update filament information:', err)
+ // Don't automatically show error - let the component handle it
+ throw err
+ }
+ }
+
// Fetch table data with pagination, filtering, and sorting
const fetchTableData = async (type, params = {}) => {
const {
@@ -307,7 +326,7 @@ const ApiServerProvider = ({ children }) => {
}
// Download GCode file content
- const handleDownloadContent = async (id, type, fileName) => {
+ const fetchObjectContent = async (id, type, fileName) => {
if (!token) {
return
}
@@ -336,18 +355,18 @@ const ApiServerProvider = ({ children }) => {
if (error.response.status === 404) {
showError(
`The ${type} file "${fileName}" was not found on the server. It may have been deleted or moved.`,
- () => handleDownloadContent(id, type, fileName)
+ () => fetchObjectContent(id, type, fileName)
)
} else {
showError(
`Error downloading ${type} file: ${error.response.status} - ${error.response.statusText}`,
- () => handleDownloadContent(id, type, fileName)
+ () => fetchObjectContent(id, type, fileName)
)
}
} else {
showError(
'An unexpected error occurred while downloading. Please check your connection and try again.',
- () => handleDownloadContent(id, type, fileName)
+ () => fetchObjectContent(id, type, fileName)
)
}
}
@@ -363,6 +382,7 @@ const ApiServerProvider = ({ children }) => {
unlockObject,
fetchObjectLock,
updateObjectInfo,
+ createObject,
onLockEvent,
onUpdateEvent,
offUpdateEvent,
@@ -370,7 +390,7 @@ const ApiServerProvider = ({ children }) => {
fetchTableData,
fetchLoading,
showError,
- handleDownloadContent
+ fetchObjectContent
}}
>
{contextHolder}
diff --git a/src/components/Dashboard/context/SpotlightContext.js b/src/components/Dashboard/context/SpotlightContext.js
index 56dfefd..fe6a7e8 100644
--- a/src/components/Dashboard/context/SpotlightContext.js
+++ b/src/components/Dashboard/context/SpotlightContext.js
@@ -276,69 +276,18 @@ const SpotlightProvider = ({ children }) => {
}
}
- // Handle key down events for backspace behavior and navigation
- const handleKeyDown = (e) => {
- // If backspace is pressed and there's a prefix but the input is empty
- if (e.key === 'Backspace' && inputPrefix && query === '') {
- // Clear the prefix
- setInputPrefix(null)
- // Prevent the default backspace behavior in this case
- e.preventDefault()
- return
- }
+ // Helper to get row actions and default action for a model
+ const getRowActions = (model) =>
+ (model.actions || []).filter((action) => action.row === true)
- // Handle navigation shortcuts
- if (listData.length > 0) {
- // Enter key - navigate to first item
- if (e.key === 'Enter') {
- e.preventDefault()
- navigateToItem(listData[0])
- return
- }
+ const getDefaultRowAction = (model) =>
+ getRowActions(model).find((action) => action.default)
- // Number keys 0-9 - navigate to corresponding item
- if (/^[0-9]$/.test(e.key)) {
- e.preventDefault()
- const index = parseInt(e.key)
- // 0-9 keys map to items 1-9 (indices 0-8)
- const itemIndex = index + 1
- if (itemIndex < listData.length) {
- navigateToItem(listData[itemIndex])
- }
-
- return
- }
- }
- }
-
- // Function to navigate to item URL
- const navigateToItem = (item) => {
- // Determine type for model lookup
- let type = item.type || inputPrefix?.type
- // Fallback: try to infer type from known keys
- if (!type) {
- if (item.printer) type = 'printer'
- else if (item.job) type = 'job'
- // Add more inference as needed
- }
-
- const model = getModelByName(type)
-
- // Get the appropriate ID for the item
- let itemId = item._id || item.id
-
- // For printers, use the printer's _id
- if (type === 'printer' && item._id) {
- itemId = item._id
- }
-
- // For jobs, use the job's id
- if (type === 'job' && item.job && item.job.id) {
- itemId = item.job.id
- }
-
- if (itemId && model.url) {
- const url = model.url(itemId)
+ const triggerRowAction = (action, item) => {
+ if (action && action.url) {
+ // Try to get the id (support _id or id)
+ const itemId = item._id || item.id
+ const url = action.url(itemId)
if (url && url !== '#') {
navigate(url)
setShowModal(false)
@@ -346,6 +295,45 @@ const SpotlightProvider = ({ children }) => {
}
}
+ // Handle key down events for backspace behavior and navigation
+ const handleKeyDown = (e) => {
+ if (listData.length > 0) {
+ // Enter key - trigger default action for first item
+ if (e.key === 'Enter') {
+ e.preventDefault()
+ const item = listData[0]
+ let type = item.type || item.objectType || inputPrefix?.type
+ const model = getModelByName(type)
+ const defaultAction = getDefaultRowAction(model)
+ if (defaultAction) {
+ triggerRowAction(defaultAction, item)
+ }
+ return
+ }
+ // Number keys 1-9 - trigger default action for corresponding item
+ if (/^[1-9]$/.test(e.key)) {
+ e.preventDefault()
+ const index = parseInt(e.key, 10)
+ if (index < listData.length) {
+ const item = listData[index]
+ let type = item.type || item.objectType || inputPrefix?.type
+ const model = getModelByName(type)
+ const defaultAction = getDefaultRowAction(model)
+ if (defaultAction) {
+ triggerRowAction(defaultAction, item)
+ }
+ }
+ return
+ }
+ }
+ // If backspace is pressed and there's a prefix but the input is empty
+ if (e.key === 'Backspace' && inputPrefix && query === '') {
+ setInputPrefix(null)
+ e.preventDefault()
+ return
+ }
+ }
+
// Focus and select text in input when modal becomes visible
useEffect(() => {
if (showModal && inputRef.current) {
@@ -409,6 +397,7 @@ const SpotlightProvider = ({ children }) => {
onCancel={() => setShowModal(false)}
closeIcon={null}
footer={null}
+ width={700}
styles={{ content: { padding: 0 } }}
destroyOnHidden={true}
>
@@ -454,89 +443,110 @@ const SpotlightProvider = ({ children }) => {
{
- // Determine type for model lookup
- let type = item.type || inputPrefix?.type
- // Fallback: try to infer type from known keys
- if (!type) {
- if (item.printer) type = 'printer'
- else if (item.job) type = 'job'
- // Add more inference as needed
- }
+ let type = item.objectType || inputPrefix?.type
const model = getModelByName(type)
const Icon = model.icon
-
- // Determine shortcut text
+ const rowActions = getRowActions(model)
let shortcutText = ''
if (index === 0) {
shortcutText = 'ENTER'
- } else if (index <= 10) {
- shortcutText = (index - 1).toString()
+ } else if (index <= 9) {
+ shortcutText = index.toString()
}
-
return (
-
-
- {Icon ? (
-
- ) : null}
+
+
+
+ {Icon ? (
+
+ ) : null}
+
+ {item.name ? (
+
+ {item.name}
-
- {item.name ? {item.name} : null}
-
- {model.type == 'printer' ? (
-
- ) : null}
- {model.type == 'job' ? (
-
- ) : null}
-
- {model.type == 'subjob' ? (
-
- ) : null}
-
- {model.type == 'filamentstock' ? (
-
-
-
- ) : null}
-
+ ) : null}
+ {model.type == 'job' ? (
+
+ ) : null}
+ {model.type == 'subjob' ? (
+
+ ) : null}
+ {model.type == 'filamentstock' ? (
+
+
-
- }
- />
-
- {shortcutText && {shortcutText}}
- }
- size={'small'}
- type={'text'}
- onClick={() => navigateToItem(item)}
- />
+ ) : null}
+
+
+
+ {rowActions
+ .filter((action) => !action?.default)
+ .map((action, i) => (
+
+ )
+ }
+ size={'small'}
+ type={'text'}
+ onClick={() => triggerRowAction(action, item)}
+ />
+ ))}
+ {rowActions
+ .filter((action) => action?.default == true)
+ .map((action, i) => (
+
+ )
+ }
+ size={'small'}
+ type={'text'}
+ onClick={() => triggerRowAction(action, item)}
+ />
+ ))}
+ {shortcutText && {shortcutText}}
+
)
diff --git a/src/components/Dashboard/hooks/useViewMode.js b/src/components/Dashboard/hooks/useViewMode.js
index 64fc847..cec1e39 100644
--- a/src/components/Dashboard/hooks/useViewMode.js
+++ b/src/components/Dashboard/hooks/useViewMode.js
@@ -1,6 +1,6 @@
import { useState, useEffect } from 'react'
-const useViewMode = (componentName, defaultMode = 'cards') => {
+const useViewMode = (componentName, defaultMode = 'list') => {
const getInitialViewMode = () => {
const stored = sessionStorage.getItem(`${componentName}_viewMode`)
return stored ? stored : defaultMode
diff --git a/src/database/Countries.js b/src/database/Countries.js
new file mode 100644
index 0000000..b6e8ca3
--- /dev/null
+++ b/src/database/Countries.js
@@ -0,0 +1,258 @@
+const countries = [
+ { code: 'AD', name: 'Andorra' },
+ { code: 'AE', name: 'United Arab Emirates' },
+ { code: 'AF', name: 'Afghanistan' },
+ { code: 'AG', name: 'Antigua and Barbuda' },
+ { code: 'AI', name: 'Anguilla' },
+ { code: 'AL', name: 'Albania' },
+ { code: 'AM', name: 'Armenia' },
+ { code: 'AO', name: 'Angola' },
+ { code: 'AQ', name: 'Antarctica' },
+ { code: 'AR', name: 'Argentina' },
+ { code: 'AS', name: 'American Samoa' },
+ { code: 'AT', name: 'Austria' },
+ { code: 'AU', name: 'Australia' },
+ { code: 'AW', name: 'Aruba' },
+ { code: 'AX', name: 'Åland Islands' },
+ { code: 'AZ', name: 'Azerbaijan' },
+ { code: 'BA', name: 'Bosnia and Herzegovina' },
+ { code: 'BB', name: 'Barbados' },
+ { code: 'BD', name: 'Bangladesh' },
+ { code: 'BE', name: 'Belgium' },
+ { code: 'BF', name: 'Burkina Faso' },
+ { code: 'BG', name: 'Bulgaria' },
+ { code: 'BH', name: 'Bahrain' },
+ { code: 'BI', name: 'Burundi' },
+ { code: 'BJ', name: 'Benin' },
+ { code: 'BL', name: 'Saint Barthélemy' },
+ { code: 'BM', name: 'Bermuda' },
+ { code: 'BN', name: 'Brunei' },
+ { code: 'BO', name: 'Bolivia' },
+ { code: 'BQ-BO', name: 'Caribbean Netherlands' },
+ { code: 'BQ-SA', name: 'Sint Eustatius' },
+ { code: 'BQ-SE', name: 'Saba' },
+ { code: 'BR', name: 'Brazil' },
+ { code: 'BS', name: 'Bahamas' },
+ { code: 'BT', name: 'Bhutan' },
+ { code: 'BV', name: 'Bouvet Island' },
+ { code: 'BW', name: 'Botswana' },
+ { code: 'BY', name: 'Belarus' },
+ { code: 'BZ', name: 'Belize' },
+ { code: 'CA', name: 'Canada' },
+ { code: 'CC', name: 'Cocos Islands' },
+ { code: 'CD', name: 'Democratic Republic of the Congo' },
+ { code: 'CF', name: 'Central African Republic' },
+ { code: 'CG', name: 'Republic of the Congo' },
+ { code: 'CH', name: 'Switzerland' },
+ { code: 'CI', name: 'Ivory Coast' },
+ { code: 'CK', name: 'Cook Islands' },
+ { code: 'CL', name: 'Chile' },
+ { code: 'CM', name: 'Cameroon' },
+ { code: 'CN', name: 'China' },
+ { code: 'CO', name: 'Colombia' },
+ { code: 'CR', name: 'Costa Rica' },
+ { code: 'CU', name: 'Cuba' },
+ { code: 'CV', name: 'Cape Verde' },
+ { code: 'CW', name: 'Curaçao' },
+ { code: 'CX', name: 'Christmas Island' },
+ { code: 'CY', name: 'Cyprus' },
+ { code: 'CZ', name: 'Czech Republic' },
+ { code: 'DE', name: 'Germany' },
+ { code: 'DJ', name: 'Djibouti' },
+ { code: 'DK', name: 'Denmark' },
+ { code: 'DM', name: 'Dominica' },
+ { code: 'DO', name: 'Dominican Republic' },
+ { code: 'DZ', name: 'Algeria' },
+ { code: 'EC', name: 'Ecuador' },
+ { code: 'EE', name: 'Estonia' },
+ { code: 'EG', name: 'Egypt' },
+ { code: 'EH', name: 'Western Sahara' },
+ { code: 'ER', name: 'Eritrea' },
+ { code: 'ES', name: 'Spain' },
+ { code: 'ET', name: 'Ethiopia' },
+ { code: 'FI', name: 'Finland' },
+ { code: 'FJ', name: 'Fiji' },
+ { code: 'FK', name: 'Falkland Islands' },
+ { code: 'FM', name: 'Micronesia' },
+ { code: 'FO', name: 'Faroe Islands' },
+ { code: 'FR', name: 'France' },
+ { code: 'GA', name: 'Gabon' },
+ { code: 'GB-ENG', name: 'England' },
+ { code: 'GB-NIR', name: 'Northern Ireland' },
+ { code: 'GB-SCT', name: 'Scotland' },
+ { code: 'GB-UKM', name: 'United Kingdom' },
+ { code: 'GB-WLS', name: 'Wales' },
+ { code: 'GD', name: 'Grenada' },
+ { code: 'GE', name: 'Georgia' },
+ { code: 'GF', name: 'French Guiana' },
+ { code: 'GG', name: 'Guernsey' },
+ { code: 'GH', name: 'Ghana' },
+ { code: 'GI', name: 'Gibraltar' },
+ { code: 'GL', name: 'Greenland' },
+ { code: 'GM', name: 'Gambia' },
+ { code: 'GN', name: 'Guinea' },
+ { code: 'GP', name: 'Guadeloupe' },
+ { code: 'GQ', name: 'Equatorial Guinea' },
+ { code: 'GR', name: 'Greece' },
+ { code: 'GS', name: 'South Georgia' },
+ { code: 'GT', name: 'Guatemala' },
+ { code: 'GU', name: 'Guam' },
+ { code: 'GW', name: 'Guinea-Bissau' },
+ { code: 'GY', name: 'Guyana' },
+ { code: 'HK', name: 'Hong Kong' },
+ { code: 'HM', name: 'Heard and McDonald Islands' },
+ { code: 'HN', name: 'Honduras' },
+ { code: 'HR', name: 'Croatia' },
+ { code: 'HT', name: 'Haiti' },
+ { code: 'HU', name: 'Hungary' },
+ { code: 'ID', name: 'Indonesia' },
+ { code: 'IE', name: 'Ireland' },
+ { code: 'IL', name: 'Israel' },
+ { code: 'IM', name: 'Isle of Man' },
+ { code: 'IN', name: 'India' },
+ { code: 'IO', name: 'British Indian Ocean Territory' },
+ { code: 'IQ', name: 'Iraq' },
+ { code: 'IR', name: 'Iran' },
+ { code: 'IS', name: 'Iceland' },
+ { code: 'IT', name: 'Italy' },
+ { code: 'JE', name: 'Jersey' },
+ { code: 'JM', name: 'Jamaica' },
+ { code: 'JO', name: 'Jordan' },
+ { code: 'JP', name: 'Japan' },
+ { code: 'KE', name: 'Kenya' },
+ { code: 'KG', name: 'Kyrgyzstan' },
+ { code: 'KH', name: 'Cambodia' },
+ { code: 'KI', name: 'Kiribati' },
+ { code: 'KM', name: 'Comoros' },
+ { code: 'KN', name: 'Saint Kitts and Nevis' },
+ { code: 'KP', name: 'North Korea' },
+ { code: 'KR', name: 'South Korea' },
+ { code: 'KW', name: 'Kuwait' },
+ { code: 'KY', name: 'Cayman Islands' },
+ { code: 'KZ', name: 'Kazakhstan' },
+ { code: 'LA', name: 'Laos' },
+ { code: 'LB', name: 'Lebanon' },
+ { code: 'LC', name: 'Saint Lucia' },
+ { code: 'LI', name: 'Liechtenstein' },
+ { code: 'LK', name: 'Sri Lanka' },
+ { code: 'LR', name: 'Liberia' },
+ { code: 'LS', name: 'Lesotho' },
+ { code: 'LT', name: 'Lithuania' },
+ { code: 'LU', name: 'Luxembourg' },
+ { code: 'LV', name: 'Latvia' },
+ { code: 'LY', name: 'Libya' },
+ { code: 'MA', name: 'Morocco' },
+ { code: 'MC', name: 'Monaco' },
+ { code: 'MD', name: 'Moldova' },
+ { code: 'ME', name: 'Montenegro' },
+ { code: 'MF', name: 'Saint Martin' },
+ { code: 'MG', name: 'Madagascar' },
+ { code: 'MH', name: 'Marshall Islands' },
+ { code: 'MK', name: 'North Macedonia' },
+ { code: 'ML', name: 'Mali' },
+ { code: 'MM', name: 'Myanmar' },
+ { code: 'MN', name: 'Mongolia' },
+ { code: 'MO', name: 'Macau' },
+ { code: 'MP', name: 'Northern Mariana Islands' },
+ { code: 'MQ', name: 'Martinique' },
+ { code: 'MR', name: 'Mauritania' },
+ { code: 'MS', name: 'Montserrat' },
+ { code: 'MT', name: 'Malta' },
+ { code: 'MU', name: 'Mauritius' },
+ { code: 'MV', name: 'Maldives' },
+ { code: 'MW', name: 'Malawi' },
+ { code: 'MX', name: 'Mexico' },
+ { code: 'MY', name: 'Malaysia' },
+ { code: 'MZ', name: 'Mozambique' },
+ { code: 'NA', name: 'Namibia' },
+ { code: 'NC', name: 'New Caledonia' },
+ { code: 'NE', name: 'Niger' },
+ { code: 'NF', name: 'Norfolk Island' },
+ { code: 'NG', name: 'Nigeria' },
+ { code: 'NI', name: 'Nicaragua' },
+ { code: 'NL', name: 'Netherlands' },
+ { code: 'NO', name: 'Norway' },
+ { code: 'NP', name: 'Nepal' },
+ { code: 'NR', name: 'Nauru' },
+ { code: 'NU', name: 'Niue' },
+ { code: 'NZ', name: 'New Zealand' },
+ { code: 'OM', name: 'Oman' },
+ { code: 'PA', name: 'Panama' },
+ { code: 'PE', name: 'Peru' },
+ { code: 'PF', name: 'French Polynesia' },
+ { code: 'PG', name: 'Papua New Guinea' },
+ { code: 'PH', name: 'Philippines' },
+ { code: 'PK', name: 'Pakistan' },
+ { code: 'PL', name: 'Poland' },
+ { code: 'PM', name: 'Saint Pierre and Miquelon' },
+ { code: 'PN', name: 'Pitcairn Islands' },
+ { code: 'PR', name: 'Puerto Rico' },
+ { code: 'PS', name: 'Palestine' },
+ { code: 'PT', name: 'Portugal' },
+ { code: 'PW', name: 'Palau' },
+ { code: 'PY', name: 'Paraguay' },
+ { code: 'QA', name: 'Qatar' },
+ { code: 'RE', name: 'Réunion' },
+ { code: 'RO', name: 'Romania' },
+ { code: 'RS', name: 'Serbia' },
+ { code: 'RU', name: 'Russia' },
+ { code: 'RW', name: 'Rwanda' },
+ { code: 'SA', name: 'Saudi Arabia' },
+ { code: 'SB', name: 'Solomon Islands' },
+ { code: 'SC', name: 'Seychelles' },
+ { code: 'SD', name: 'Sudan' },
+ { code: 'SE', name: 'Sweden' },
+ { code: 'SG', name: 'Singapore' },
+ { code: 'SH', name: 'Saint Helena' },
+ { code: 'SI', name: 'Slovenia' },
+ { code: 'SJ', name: 'Svalbard and Jan Mayen' },
+ { code: 'SK', name: 'Slovakia' },
+ { code: 'SL', name: 'Sierra Leone' },
+ { code: 'SM', name: 'San Marino' },
+ { code: 'SN', name: 'Senegal' },
+ { code: 'SO', name: 'Somalia' },
+ { code: 'SR', name: 'Suriname' },
+ { code: 'SS', name: 'South Sudan' },
+ { code: 'ST', name: 'São Tomé and Príncipe' },
+ { code: 'SV', name: 'El Salvador' },
+ { code: 'SX', name: 'Sint Maarten' },
+ { code: 'SY', name: 'Syria' },
+ { code: 'SZ', name: 'Eswatini' },
+ { code: 'TC', name: 'Turks and Caicos Islands' },
+ { code: 'TD', name: 'Chad' },
+ { code: 'TF', name: 'French Southern Territories' },
+ { code: 'TG', name: 'Togo' },
+ { code: 'TH', name: 'Thailand' },
+ { code: 'TJ', name: 'Tajikistan' },
+ { code: 'TK', name: 'Tokelau' },
+ { code: 'TL', name: 'Timor-Leste' },
+ { code: 'TM', name: 'Turkmenistan' },
+ { code: 'TN', name: 'Tunisia' },
+ { code: 'TO', name: 'Tonga' },
+ { code: 'TR', name: 'Turkey' },
+ { code: 'TT', name: 'Trinidad and Tobago' },
+ { code: 'TV', name: 'Tuvalu' },
+ { code: 'TW', name: 'Taiwan' },
+ { code: 'TZ', name: 'Tanzania' },
+ { code: 'UA', name: 'Ukraine' },
+ { code: 'UG', name: 'Uganda' },
+ { code: 'US', name: 'United States' },
+ { code: 'UY', name: 'Uruguay' },
+ { code: 'UZ', name: 'Uzbekistan' },
+ { code: 'VA', name: 'Vatican City' },
+ { code: 'VC', name: 'Saint Vincent and the Grenadines' },
+ { code: 'VE', name: 'Venezuela' },
+ { code: 'VG', name: 'British Virgin Islands' },
+ { code: 'VI', name: 'U.S. Virgin Islands' },
+ { code: 'VN', name: 'Vietnam' },
+ { code: 'VU', name: 'Vanuatu' },
+ { code: 'WF', name: 'Wallis and Futuna' },
+ { code: 'WS', name: 'Samoa' },
+ { code: 'YE', name: 'Yemen' },
+ { code: 'YT', name: 'Mayotte' },
+ { code: 'ZA', name: 'South Africa' },
+ { code: 'ZM', name: 'Zambia' },
+ { code: 'ZW', name: 'Zimbabwe' }
+]
+
+export default countries
diff --git a/src/database/models/AuditLog.js b/src/database/models/AuditLog.js
index edab88b..bd80473 100644
--- a/src/database/models/AuditLog.js
+++ b/src/database/models/AuditLog.js
@@ -8,7 +8,7 @@ export const AuditLog = {
actions: [],
columns: ['_id', 'owner', 'owner._id', 'parent._id', 'changes', 'createdAt'],
filters: ['_id', 'owner._id', 'parent._id'],
- sorters: [],
+ sorters: ['createdAt'],
properties: [
{
name: '_id',
diff --git a/src/database/models/Filament.js b/src/database/models/Filament.js
index 310bb08..3408f38 100644
--- a/src/database/models/Filament.js
+++ b/src/database/models/Filament.js
@@ -126,14 +126,24 @@ export const Filament = {
required: true,
type: 'density'
},
+ {
+ name: 'emptySpoolWeight',
+ label: 'Spool Weight',
+ required: true,
+ columnWidth: 150,
+ type: 'number',
+ suffix: 'g'
+ },
{
name: 'url',
label: 'Link',
+ required: false,
type: 'url'
},
{
name: 'barcode',
label: 'Barcode',
+ required: false,
type: 'text'
}
]
diff --git a/src/database/models/FilamentStock.js b/src/database/models/FilamentStock.js
index a31a2ad..6eab65a 100644
--- a/src/database/models/FilamentStock.js
+++ b/src/database/models/FilamentStock.js
@@ -2,7 +2,7 @@ import FilamentStockIcon from '../../components/Icons/FilamentStockIcon'
import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
export const FilamentStock = {
- name: 'filamentstock',
+ name: 'filamentStock',
label: 'Filament Stock',
prefix: 'FLS',
icon: FilamentStockIcon,
@@ -17,5 +17,91 @@ export const FilamentStock = {
`/dashboard/inventory/filamentstocks/info?filamentStockId=${_id}`
}
],
- url: (id) => `/dashboard/inventory/filamentstocks/info?filamentStockId=${id}`
+ columns: [
+ '_id',
+ 'state',
+ 'currentWeight',
+ 'startingWeight',
+ 'filament',
+ 'filament._id',
+ 'createdAt',
+ 'updatedAt'
+ ],
+ filters: ['_id'],
+ sorters: ['createdAt', 'updatedAt'],
+ properties: [
+ {
+ name: '_id',
+ label: 'ID',
+ type: 'id',
+ columnFixed: 'left',
+ objectType: 'filamentStock',
+ showCopy: true
+ },
+ {
+ name: 'createdAt',
+ label: 'Created At',
+ type: 'dateTime',
+ readOnly: true
+ },
+ {
+ name: 'state',
+ label: 'State',
+ type: 'state',
+ objectType: 'filamentStock',
+ readOnly: true
+ },
+ {
+ name: 'updatedAt',
+ label: 'Updated At',
+ type: 'dateTime',
+ readOnly: true
+ },
+ {
+ name: 'filament',
+ label: 'Filament',
+ type: 'object',
+ objectType: 'filament',
+ readOnly: true,
+ initial: true,
+ required: true
+ },
+ {
+ name: 'filament._id',
+ label: 'Filament ID',
+ type: 'id',
+ objectType: 'filament',
+ showHyperlink: true,
+ readOnly: true
+ },
+ {
+ name: 'currentWeight',
+ label: 'Current Weight',
+ type: 'netGross',
+ suffix: 'g',
+ readOnly: true,
+ required: true,
+ columnWidth: 300,
+ value: (objectData) => {
+ if (!objectData.currentWeight) {
+ return objectData?.startingWeight
+ } else {
+ return objectData.currentWeight
+ }
+ }
+ },
+ {
+ name: 'startingWeight',
+ label: 'Starting Weight',
+ type: 'netGross',
+ suffix: 'g',
+ readOnly: true,
+ initial: true,
+ required: true,
+ columnWidth: 300,
+ difference: (objectData) => {
+ return objectData?.filament?.emptySpoolWeight
+ }
+ }
+ ]
}
diff --git a/src/database/models/GCodeFile.js b/src/database/models/GCodeFile.js
index 587d5ff..fed59b4 100644
--- a/src/database/models/GCodeFile.js
+++ b/src/database/models/GCodeFile.js
@@ -99,9 +99,10 @@ export const GCodeFile = {
{
name: 'cost',
label: 'Cost',
- type: 'currency',
+ type: 'number',
value: null,
- readOnly: true
+ readOnly: true,
+ prefix: '£'
},
{
name: 'gcodeFileInfo.estimatedPrintingTimeNormalMode',
@@ -114,7 +115,7 @@ export const GCodeFile = {
name: 'gcodeFileInfo.sparseInfillDensity',
label: 'Infill Density',
columnWidth: 150,
- type: 'number',
+ type: 'text',
readOnly: true
},
{
@@ -126,44 +127,42 @@ export const GCodeFile = {
{
name: 'gcodeFileInfo.filamentUsedMm',
label: 'Filament Used (mm)',
- value: null,
- type: 'mm',
- readOnly: true
+ type: 'number',
+ readOnly: true,
+ suffix: 'mm'
},
{
name: 'gcodeFileInfo.filamentUsedG',
label: 'Filament Used (g)',
- value: null,
- type: 'weight',
+ type: 'number',
+ suffix: 'g',
readOnly: true
},
{
name: 'gcodeFileInfo.nozzleTemperature',
label: 'Hotend Temp',
columnWidth: 150,
- value: null,
type: 'number',
+ suffix: '°',
readOnly: true
},
{
name: 'gcodeFileInfo.hotPlateTemp',
label: 'Bed Temp',
columnWidth: 150,
- value: null,
type: 'number',
+ suffix: '°',
readOnly: true
},
{
name: 'gcodeFileInfo.filamentSettingsId',
label: 'Filament Profile',
- value: null,
type: 'text',
readOnly: true
},
{
name: 'gcodeFileInfo.printSettingsId',
label: 'Print Profile',
- value: null,
type: 'text',
readOnly: true
}
diff --git a/src/database/models/Job.js b/src/database/models/Job.js
index bac89b3..e980e26 100644
--- a/src/database/models/Job.js
+++ b/src/database/models/Job.js
@@ -52,7 +52,7 @@ export const Job = {
},
{
name: 'state',
- label: 'Status',
+ label: 'State',
type: 'state',
objectType: 'job',
showStatus: true,
diff --git a/src/database/models/NoteType.js b/src/database/models/NoteType.js
index caf4f4e..6a2cd27 100644
--- a/src/database/models/NoteType.js
+++ b/src/database/models/NoteType.js
@@ -65,11 +65,13 @@ export const NoteType = {
{
name: 'color',
label: 'Color',
+ required: false,
type: 'color'
},
{
name: 'active',
label: 'Active',
+ required: true,
type: 'bool'
}
]
diff --git a/src/database/models/StockEvent.js b/src/database/models/StockEvent.js
index bd8a85d..d5ba282 100644
--- a/src/database/models/StockEvent.js
+++ b/src/database/models/StockEvent.js
@@ -1,20 +1,86 @@
import StockEventIcon from '../../components/Icons/StockEventIcon'
-import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
export const StockEvent = {
- name: 'stockevent',
+ name: 'stockEvent',
label: 'Stock Event',
prefix: 'SEV',
icon: StockEventIcon,
- actions: [
+ actions: [],
+ columns: ['_id', 'owner', 'owner._id', 'parent._id', 'value', 'createdAt'],
+ filters: ['_id', 'owner._id', 'parent._id'],
+ sorters: ['createdAt'],
+ properties: [
{
- name: 'info',
- label: 'Info',
- default: true,
- row: true,
- icon: InfoCircleIcon,
- url: (_id) => `/dashboard/inventory/stockevents/info?stockEventId=${_id}`
+ name: '_id',
+ label: 'ID',
+ type: 'id',
+ objectType: 'stockEvent',
+ columnFixed: 'left',
+ value: null,
+ showCopy: true
+ },
+ {
+ name: 'createdAt',
+ label: 'Created At',
+ type: 'dateTime',
+ value: null,
+ readOnly: true
+ },
+ {
+ name: 'updatedAt',
+ label: 'Updated At',
+ type: 'dateTime',
+ value: null,
+ readOnly: true
+ },
+ {
+ name: 'owner',
+ label: 'Owner',
+ type: 'object',
+ objectType: (objectData) => {
+ return objectData.ownerType
+ },
+ columnFixed: 'left',
+ value: null,
+ showCopy: true
+ },
+ {
+ name: 'owner._id',
+ label: 'Owner ID',
+ type: 'id',
+ objectType: (objectData) => {
+ return objectData.ownerType
+ },
+ columnFixed: 'left',
+ showHyperlink: true,
+ showCopy: true
+ },
+ {
+ name: 'parent',
+ label: 'Parent',
+ type: 'object',
+ objectType: (objectData) => {
+ return objectData.parentType
+ },
+ value: null,
+ showCopy: true
+ },
+ {
+ name: 'parent._id',
+ label: 'Parent ID',
+ type: 'id',
+ objectType: (objectData) => {
+ return objectData.parentType
+ },
+ showHyperlink: true,
+ showCopy: true
+ },
+ {
+ name: 'value',
+ label: 'Value',
+ columnWidth: 100,
+ type: 'number',
+ showCopy: true
}
- ],
- url: () => `#`
+ ]
}
diff --git a/src/database/models/SubJob.js b/src/database/models/SubJob.js
index af1186b..634675a 100644
--- a/src/database/models/SubJob.js
+++ b/src/database/models/SubJob.js
@@ -1,20 +1,62 @@
import SubJobIcon from '../../components/Icons/SubJobIcon'
-import InfoCircleIcon from '../../components/Icons/InfoCircleIcon'
export const SubJob = {
- name: 'subjob',
+ name: 'subJob',
label: 'Sub Job',
prefix: 'SJB',
icon: SubJobIcon,
- actions: [
+ actions: [],
+ columns: ['_id', 'printer', 'printer._id', 'job._id', 'state', 'createdAt'],
+ filters: ['state', '_id'],
+ sorters: ['createdAt', 'state'],
+ properties: [
{
- name: 'info',
- label: 'Info',
- default: true,
- row: true,
- icon: InfoCircleIcon,
- url: (_id) => `/dashboard/production/subjobs/info?subJobId=${_id}`
+ name: '_id',
+ label: 'ID',
+ type: 'id',
+ columnFixed: 'left',
+ objectType: 'subJob',
+ showCopy: true
+ },
+ {
+ name: 'printer',
+ label: 'Printer',
+ type: 'object',
+ columnFixed: 'left',
+ objectType: 'printer'
+ },
+ {
+ name: 'printer._id',
+ label: 'Printer ID',
+ type: 'id',
+ columnFixed: 'left',
+ showHyperlink: true,
+ objectType: 'printer'
+ },
+ {
+ name: 'job._id',
+ label: 'Job ID',
+ type: 'id',
+ showHyperlink: true,
+ objectType: 'job'
+ },
+ {
+ name: 'state',
+ label: 'State',
+ type: 'state',
+ objectType: 'subJob',
+ showStatus: true,
+ showProgress: true,
+ showId: false,
+ showQuantity: false,
+ columnWidth: 150,
+ readOnly: true
+ },
+ {
+ name: 'createdAt',
+ label: 'Created At',
+ type: 'dateTime',
+ readOnly: true
}
- ],
- url: () => `#`
+ ]
}