SyuanYu 1 jaar geleden
commit
6e29a82ee0
54 gewijzigde bestanden met toevoegingen van 4619 en 0 verwijderingen
  1. 24 0
      .gitignore
  2. 3 0
      .vscode/extensions.json
  3. 7 0
      README.md
  4. 22 0
      index.html
  5. 1755 0
      package-lock.json
  6. 29 0
      package.json
  7. 1 0
      public/vite.svg
  8. 22 0
      src/App.vue
  9. 57 0
      src/assets/css/style.css
  10. 1 0
      src/assets/css/style.css.map
  11. 60 0
      src/assets/css/style.scss
  12. BIN
      src/assets/img/banner-0615.webp
  13. BIN
      src/assets/img/icon/date_icon.png
  14. BIN
      src/assets/img/icon/location_icon.png
  15. BIN
      src/assets/img/icon/search.png
  16. BIN
      src/assets/img/img-01.jpg
  17. BIN
      src/assets/img/img-02.jpg
  18. BIN
      src/assets/img/img-03.jpg
  19. BIN
      src/assets/img/img-04.jpg
  20. BIN
      src/assets/img/img-05.jpg
  21. BIN
      src/assets/img/img-06.jpg
  22. BIN
      src/assets/img/img-07.jpg
  23. BIN
      src/assets/img/img-08.jpg
  24. BIN
      src/assets/img/img-09.jpg
  25. BIN
      src/assets/img/img-10.jpg
  26. BIN
      src/assets/img/img-11.jpg
  27. BIN
      src/assets/img/img-12.jpg
  28. BIN
      src/assets/img/logo.png
  29. BIN
      src/assets/img/map-icon/icon_house01.png
  30. BIN
      src/assets/img/map-icon/icon_house02.png
  31. BIN
      src/assets/img/map-icon/icon_house03.png
  32. BIN
      src/assets/img/map-icon/icon_house04.png
  33. BIN
      src/assets/img/map-icon/icon_house05.png
  34. BIN
      src/assets/img/map-icon/icon_house06.png
  35. BIN
      src/assets/img/map-icon/icon_house07.png
  36. BIN
      src/assets/img/map-icon/icon_house10.png
  37. BIN
      src/assets/img/map-icon/icon_house11.png
  38. 1352 0
      src/assets/mapData.json
  39. 66 0
      src/assets/testData.json
  40. 1 0
      src/assets/vue.svg
  41. 21 0
      src/components/Carousels.vue
  42. 40 0
      src/components/HelloWorld.vue
  43. 102 0
      src/components/Map.vue
  44. 128 0
      src/components/Navbar.vue
  45. 118 0
      src/components/NavbarSub.vue
  46. 17 0
      src/main.js
  47. 29 0
      src/plugins/vuetify.js
  48. 38 0
      src/router/index.js
  49. 91 0
      src/views/CourseDetail.vue
  50. 185 0
      src/views/CourseList.vue
  51. 72 0
      src/views/Home-back.vue
  52. 284 0
      src/views/Home.vue
  53. 72 0
      src/views/Login.vue
  54. 22 0
      vite.config.js

+ 24 - 0
.gitignore

@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 3 - 0
.vscode/extensions.json

@@ -0,0 +1,3 @@
+{
+  "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
+}

+ 7 - 0
README.md

@@ -0,0 +1,7 @@
+# Vue 3 + Vite
+
+This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
+
+## Recommended IDE Setup
+
+- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).

+ 22 - 0
index.html

@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+  <meta charset="UTF-8" />
+  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+
+  <!-- Google Font -->
+  <link rel="preconnect" href="https://fonts.googleapis.com">
+  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+  <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@100;300;400;500&display=swap" rel="stylesheet">
+
+  <title>國立臺灣工藝研究發展中心</title>
+</head>
+
+<body>
+  <div id="app"></div>
+  <script type="module" src="/src/main.js"></script>
+</body>
+
+</html>

+ 1755 - 0
package-lock.json

@@ -0,0 +1,1755 @@
+{
+  "name": "ntcri",
+  "version": "0.0.0",
+  "lockfileVersion": 2,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "ntcri",
+      "version": "0.0.0",
+      "dependencies": {
+        "@mdi/font": "^7.2.96",
+        "animate.css": "^4.1.1",
+        "axios": "^1.4.0",
+        "leaflet": "^1.9.4",
+        "leaflet.markercluster": "^1.5.3",
+        "moment": "^2.29.4",
+        "vue": "^3.2.47",
+        "vue-router": "^4.2.2",
+        "vuetify": "^3.3.2"
+      },
+      "devDependencies": {
+        "@mdi/js": "^7.2.96",
+        "@types/leaflet": "^1.9.3",
+        "@vitejs/plugin-vue": "^4.1.0",
+        "sass": "^1.63.3",
+        "vite": "^4.3.9"
+      }
+    },
+    "node_modules/@babel/parser": {
+      "version": "7.22.4",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.4.tgz",
+      "integrity": "sha512-VLLsx06XkEYqBtE5YGPwfSGwfrjnyPP5oiGty3S8pQLFDFLaS8VwWSIxkTXpcvr5zeYLE6+MBNl2npl/YnfofA==",
+      "bin": {
+        "parser": "bin/babel-parser.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@esbuild/android-arm": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz",
+      "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/android-arm64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz",
+      "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/android-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz",
+      "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/darwin-arm64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz",
+      "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/darwin-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz",
+      "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/freebsd-arm64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz",
+      "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/freebsd-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz",
+      "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-arm": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz",
+      "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-arm64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz",
+      "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-ia32": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz",
+      "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-loong64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz",
+      "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==",
+      "cpu": [
+        "loong64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-mips64el": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz",
+      "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==",
+      "cpu": [
+        "mips64el"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-ppc64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz",
+      "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-riscv64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz",
+      "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-s390x": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz",
+      "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz",
+      "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/netbsd-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz",
+      "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/openbsd-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz",
+      "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/sunos-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz",
+      "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-arm64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz",
+      "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-ia32": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz",
+      "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz",
+      "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@jridgewell/sourcemap-codec": {
+      "version": "1.4.15",
+      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
+    },
+    "node_modules/@mdi/font": {
+      "version": "7.2.96",
+      "resolved": "https://registry.npmjs.org/@mdi/font/-/font-7.2.96.tgz",
+      "integrity": "sha512-e//lmkmpFUMZKhmCY9zdjRe4zNXfbOIJnn6xveHbaV2kSw5aJ5dLXUxcRt1Gxfi7ZYpFLUWlkG2MGSFAiqAu7w=="
+    },
+    "node_modules/@mdi/js": {
+      "version": "7.2.96",
+      "resolved": "https://registry.npmjs.org/@mdi/js/-/js-7.2.96.tgz",
+      "integrity": "sha512-paR9M9ZT7rKbh2boksNUynuSZMHhqRYnEZOm/KrZTjQ4/FzyhjLHuvw/8XYzP+E7fS4+/Ms/82EN1pl/OFsiIA==",
+      "dev": true
+    },
+    "node_modules/@types/geojson": {
+      "version": "7946.0.10",
+      "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz",
+      "integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==",
+      "dev": true
+    },
+    "node_modules/@types/leaflet": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.3.tgz",
+      "integrity": "sha512-Caa1lYOgKVqDkDZVWkto2Z5JtVo09spEaUt2S69LiugbBpoqQu92HYFMGUbYezZbnBkyOxMNPXHSgRrRY5UyIA==",
+      "dev": true,
+      "dependencies": {
+        "@types/geojson": "*"
+      }
+    },
+    "node_modules/@vitejs/plugin-vue": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.2.3.tgz",
+      "integrity": "sha512-R6JDUfiZbJA9cMiguQ7jxALsgiprjBeHL5ikpXfJCH62pPHtI+JdJ5xWj6Ev73yXSlYl86+blXn1kZHQ7uElxw==",
+      "dev": true,
+      "engines": {
+        "node": "^14.18.0 || >=16.0.0"
+      },
+      "peerDependencies": {
+        "vite": "^4.0.0",
+        "vue": "^3.2.25"
+      }
+    },
+    "node_modules/@vue/compiler-core": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.4.tgz",
+      "integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==",
+      "dependencies": {
+        "@babel/parser": "^7.21.3",
+        "@vue/shared": "3.3.4",
+        "estree-walker": "^2.0.2",
+        "source-map-js": "^1.0.2"
+      }
+    },
+    "node_modules/@vue/compiler-dom": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz",
+      "integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==",
+      "dependencies": {
+        "@vue/compiler-core": "3.3.4",
+        "@vue/shared": "3.3.4"
+      }
+    },
+    "node_modules/@vue/compiler-sfc": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz",
+      "integrity": "sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==",
+      "dependencies": {
+        "@babel/parser": "^7.20.15",
+        "@vue/compiler-core": "3.3.4",
+        "@vue/compiler-dom": "3.3.4",
+        "@vue/compiler-ssr": "3.3.4",
+        "@vue/reactivity-transform": "3.3.4",
+        "@vue/shared": "3.3.4",
+        "estree-walker": "^2.0.2",
+        "magic-string": "^0.30.0",
+        "postcss": "^8.1.10",
+        "source-map-js": "^1.0.2"
+      }
+    },
+    "node_modules/@vue/compiler-ssr": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz",
+      "integrity": "sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==",
+      "dependencies": {
+        "@vue/compiler-dom": "3.3.4",
+        "@vue/shared": "3.3.4"
+      }
+    },
+    "node_modules/@vue/devtools-api": {
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz",
+      "integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
+    },
+    "node_modules/@vue/reactivity": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.4.tgz",
+      "integrity": "sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==",
+      "dependencies": {
+        "@vue/shared": "3.3.4"
+      }
+    },
+    "node_modules/@vue/reactivity-transform": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz",
+      "integrity": "sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==",
+      "dependencies": {
+        "@babel/parser": "^7.20.15",
+        "@vue/compiler-core": "3.3.4",
+        "@vue/shared": "3.3.4",
+        "estree-walker": "^2.0.2",
+        "magic-string": "^0.30.0"
+      }
+    },
+    "node_modules/@vue/runtime-core": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.3.4.tgz",
+      "integrity": "sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==",
+      "dependencies": {
+        "@vue/reactivity": "3.3.4",
+        "@vue/shared": "3.3.4"
+      }
+    },
+    "node_modules/@vue/runtime-dom": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz",
+      "integrity": "sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==",
+      "dependencies": {
+        "@vue/runtime-core": "3.3.4",
+        "@vue/shared": "3.3.4",
+        "csstype": "^3.1.1"
+      }
+    },
+    "node_modules/@vue/server-renderer": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.3.4.tgz",
+      "integrity": "sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==",
+      "dependencies": {
+        "@vue/compiler-ssr": "3.3.4",
+        "@vue/shared": "3.3.4"
+      },
+      "peerDependencies": {
+        "vue": "3.3.4"
+      }
+    },
+    "node_modules/@vue/shared": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz",
+      "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ=="
+    },
+    "node_modules/animate.css": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/animate.css/-/animate.css-4.1.1.tgz",
+      "integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ=="
+    },
+    "node_modules/anymatch": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+      "dev": true,
+      "dependencies": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+    },
+    "node_modules/axios": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
+      "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
+      "dependencies": {
+        "follow-redirects": "^1.15.0",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
+      }
+    },
+    "node_modules/binary-extensions": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+      "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/braces": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+      "dev": true,
+      "dependencies": {
+        "fill-range": "^7.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/chokidar": {
+      "version": "3.5.3",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+      "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://paulmillr.com/funding/"
+        }
+      ],
+      "dependencies": {
+        "anymatch": "~3.1.2",
+        "braces": "~3.0.2",
+        "glob-parent": "~5.1.2",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.6.0"
+      },
+      "engines": {
+        "node": ">= 8.10.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/csstype": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
+      "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
+    },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/esbuild": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz",
+      "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==",
+      "dev": true,
+      "hasInstallScript": true,
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "optionalDependencies": {
+        "@esbuild/android-arm": "0.17.19",
+        "@esbuild/android-arm64": "0.17.19",
+        "@esbuild/android-x64": "0.17.19",
+        "@esbuild/darwin-arm64": "0.17.19",
+        "@esbuild/darwin-x64": "0.17.19",
+        "@esbuild/freebsd-arm64": "0.17.19",
+        "@esbuild/freebsd-x64": "0.17.19",
+        "@esbuild/linux-arm": "0.17.19",
+        "@esbuild/linux-arm64": "0.17.19",
+        "@esbuild/linux-ia32": "0.17.19",
+        "@esbuild/linux-loong64": "0.17.19",
+        "@esbuild/linux-mips64el": "0.17.19",
+        "@esbuild/linux-ppc64": "0.17.19",
+        "@esbuild/linux-riscv64": "0.17.19",
+        "@esbuild/linux-s390x": "0.17.19",
+        "@esbuild/linux-x64": "0.17.19",
+        "@esbuild/netbsd-x64": "0.17.19",
+        "@esbuild/openbsd-x64": "0.17.19",
+        "@esbuild/sunos-x64": "0.17.19",
+        "@esbuild/win32-arm64": "0.17.19",
+        "@esbuild/win32-ia32": "0.17.19",
+        "@esbuild/win32-x64": "0.17.19"
+      }
+    },
+    "node_modules/estree-walker": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+      "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
+    },
+    "node_modules/fill-range": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+      "dev": true,
+      "dependencies": {
+        "to-regex-range": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/follow-redirects": {
+      "version": "1.15.2",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
+      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/RubenVerborgh"
+        }
+      ],
+      "engines": {
+        "node": ">=4.0"
+      },
+      "peerDependenciesMeta": {
+        "debug": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/form-data": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+      "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/fsevents": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
+    "node_modules/glob-parent": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+      "dev": true,
+      "dependencies": {
+        "is-glob": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/immutable": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz",
+      "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==",
+      "dev": true
+    },
+    "node_modules/is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+      "dev": true,
+      "dependencies": {
+        "binary-extensions": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-glob": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+      "dev": true,
+      "dependencies": {
+        "is-extglob": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-number": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/leaflet": {
+      "version": "1.9.4",
+      "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
+      "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA=="
+    },
+    "node_modules/leaflet.markercluster": {
+      "version": "1.5.3",
+      "resolved": "https://registry.npmjs.org/leaflet.markercluster/-/leaflet.markercluster-1.5.3.tgz",
+      "integrity": "sha512-vPTw/Bndq7eQHjLBVlWpnGeLa3t+3zGiuM7fJwCkiMFq+nmRuG3RI3f7f4N4TDX7T4NpbAXpR2+NTRSEGfCSeA==",
+      "peerDependencies": {
+        "leaflet": "^1.3.1"
+      }
+    },
+    "node_modules/magic-string": {
+      "version": "0.30.0",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz",
+      "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==",
+      "dependencies": {
+        "@jridgewell/sourcemap-codec": "^1.4.13"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/moment": {
+      "version": "2.29.4",
+      "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
+      "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/nanoid": {
+      "version": "3.3.6",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
+      "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "bin": {
+        "nanoid": "bin/nanoid.cjs"
+      },
+      "engines": {
+        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+      }
+    },
+    "node_modules/normalize-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/picocolors": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
+    },
+    "node_modules/picomatch": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/postcss": {
+      "version": "8.4.24",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz",
+      "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "dependencies": {
+        "nanoid": "^3.3.6",
+        "picocolors": "^1.0.0",
+        "source-map-js": "^1.0.2"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
+    "node_modules/proxy-from-env": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+    },
+    "node_modules/readdirp": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+      "dev": true,
+      "dependencies": {
+        "picomatch": "^2.2.1"
+      },
+      "engines": {
+        "node": ">=8.10.0"
+      }
+    },
+    "node_modules/rollup": {
+      "version": "3.23.0",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.23.0.tgz",
+      "integrity": "sha512-h31UlwEi7FHihLe1zbk+3Q7z1k/84rb9BSwmBSr/XjOCEaBJ2YyedQDuM0t/kfOS0IxM+vk1/zI9XxYj9V+NJQ==",
+      "dev": true,
+      "bin": {
+        "rollup": "dist/bin/rollup"
+      },
+      "engines": {
+        "node": ">=14.18.0",
+        "npm": ">=8.0.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/sass": {
+      "version": "1.63.3",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.63.3.tgz",
+      "integrity": "sha512-ySdXN+DVpfwq49jG1+hmtDslYqpS7SkOR5GpF6o2bmb1RL/xS+wvPmegMvMywyfsmAV6p7TgwXYGrCZIFFbAHg==",
+      "dev": true,
+      "dependencies": {
+        "chokidar": ">=3.0.0 <4.0.0",
+        "immutable": "^4.0.0",
+        "source-map-js": ">=0.6.2 <2.0.0"
+      },
+      "bin": {
+        "sass": "sass.js"
+      },
+      "engines": {
+        "node": ">=14.0.0"
+      }
+    },
+    "node_modules/source-map-js": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/to-regex-range": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+      "dev": true,
+      "dependencies": {
+        "is-number": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=8.0"
+      }
+    },
+    "node_modules/vite": {
+      "version": "4.3.9",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz",
+      "integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==",
+      "dev": true,
+      "dependencies": {
+        "esbuild": "^0.17.5",
+        "postcss": "^8.4.23",
+        "rollup": "^3.21.0"
+      },
+      "bin": {
+        "vite": "bin/vite.js"
+      },
+      "engines": {
+        "node": "^14.18.0 || >=16.0.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      },
+      "peerDependencies": {
+        "@types/node": ">= 14",
+        "less": "*",
+        "sass": "*",
+        "stylus": "*",
+        "sugarss": "*",
+        "terser": "^5.4.0"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        },
+        "less": {
+          "optional": true
+        },
+        "sass": {
+          "optional": true
+        },
+        "stylus": {
+          "optional": true
+        },
+        "sugarss": {
+          "optional": true
+        },
+        "terser": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/vue": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz",
+      "integrity": "sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==",
+      "dependencies": {
+        "@vue/compiler-dom": "3.3.4",
+        "@vue/compiler-sfc": "3.3.4",
+        "@vue/runtime-dom": "3.3.4",
+        "@vue/server-renderer": "3.3.4",
+        "@vue/shared": "3.3.4"
+      }
+    },
+    "node_modules/vue-router": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.2.2.tgz",
+      "integrity": "sha512-cChBPPmAflgBGmy3tBsjeoe3f3VOSG6naKyY5pjtrqLGbNEXdzCigFUHgBvp9e3ysAtFtEx7OLqcSDh/1Cq2TQ==",
+      "dependencies": {
+        "@vue/devtools-api": "^6.5.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/posva"
+      },
+      "peerDependencies": {
+        "vue": "^3.2.0"
+      }
+    },
+    "node_modules/vuetify": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.3.2.tgz",
+      "integrity": "sha512-m/R42di8FlyMaoktUe6k8JbF+A0vbJMpjQrZK7nH1ptK8VinVVQcaw+9m94wlO74IMR+LubxLh5t9I2ZtVCvjw==",
+      "engines": {
+        "node": "^12.20 || >=14.13"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/johnleider"
+      },
+      "peerDependencies": {
+        "typescript": ">=4.7",
+        "vite-plugin-vuetify": "^1.0.0-alpha.12",
+        "vue": "^3.2.0",
+        "vue-i18n": "^9.0.0",
+        "webpack-plugin-vuetify": "^2.0.0-alpha.11"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        },
+        "vite-plugin-vuetify": {
+          "optional": true
+        },
+        "vue-i18n": {
+          "optional": true
+        },
+        "webpack-plugin-vuetify": {
+          "optional": true
+        }
+      }
+    }
+  },
+  "dependencies": {
+    "@babel/parser": {
+      "version": "7.22.4",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.4.tgz",
+      "integrity": "sha512-VLLsx06XkEYqBtE5YGPwfSGwfrjnyPP5oiGty3S8pQLFDFLaS8VwWSIxkTXpcvr5zeYLE6+MBNl2npl/YnfofA=="
+    },
+    "@esbuild/android-arm": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz",
+      "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/android-arm64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz",
+      "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/android-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz",
+      "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/darwin-arm64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz",
+      "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/darwin-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz",
+      "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/freebsd-arm64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz",
+      "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/freebsd-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz",
+      "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-arm": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz",
+      "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-arm64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz",
+      "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-ia32": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz",
+      "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-loong64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz",
+      "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-mips64el": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz",
+      "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-ppc64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz",
+      "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-riscv64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz",
+      "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-s390x": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz",
+      "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz",
+      "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/netbsd-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz",
+      "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/openbsd-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz",
+      "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/sunos-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz",
+      "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/win32-arm64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz",
+      "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/win32-ia32": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz",
+      "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/win32-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz",
+      "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==",
+      "dev": true,
+      "optional": true
+    },
+    "@jridgewell/sourcemap-codec": {
+      "version": "1.4.15",
+      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
+    },
+    "@mdi/font": {
+      "version": "7.2.96",
+      "resolved": "https://registry.npmjs.org/@mdi/font/-/font-7.2.96.tgz",
+      "integrity": "sha512-e//lmkmpFUMZKhmCY9zdjRe4zNXfbOIJnn6xveHbaV2kSw5aJ5dLXUxcRt1Gxfi7ZYpFLUWlkG2MGSFAiqAu7w=="
+    },
+    "@mdi/js": {
+      "version": "7.2.96",
+      "resolved": "https://registry.npmjs.org/@mdi/js/-/js-7.2.96.tgz",
+      "integrity": "sha512-paR9M9ZT7rKbh2boksNUynuSZMHhqRYnEZOm/KrZTjQ4/FzyhjLHuvw/8XYzP+E7fS4+/Ms/82EN1pl/OFsiIA==",
+      "dev": true
+    },
+    "@types/geojson": {
+      "version": "7946.0.10",
+      "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz",
+      "integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==",
+      "dev": true
+    },
+    "@types/leaflet": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.3.tgz",
+      "integrity": "sha512-Caa1lYOgKVqDkDZVWkto2Z5JtVo09spEaUt2S69LiugbBpoqQu92HYFMGUbYezZbnBkyOxMNPXHSgRrRY5UyIA==",
+      "dev": true,
+      "requires": {
+        "@types/geojson": "*"
+      }
+    },
+    "@vitejs/plugin-vue": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.2.3.tgz",
+      "integrity": "sha512-R6JDUfiZbJA9cMiguQ7jxALsgiprjBeHL5ikpXfJCH62pPHtI+JdJ5xWj6Ev73yXSlYl86+blXn1kZHQ7uElxw==",
+      "dev": true,
+      "requires": {}
+    },
+    "@vue/compiler-core": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.4.tgz",
+      "integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==",
+      "requires": {
+        "@babel/parser": "^7.21.3",
+        "@vue/shared": "3.3.4",
+        "estree-walker": "^2.0.2",
+        "source-map-js": "^1.0.2"
+      }
+    },
+    "@vue/compiler-dom": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz",
+      "integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==",
+      "requires": {
+        "@vue/compiler-core": "3.3.4",
+        "@vue/shared": "3.3.4"
+      }
+    },
+    "@vue/compiler-sfc": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz",
+      "integrity": "sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==",
+      "requires": {
+        "@babel/parser": "^7.20.15",
+        "@vue/compiler-core": "3.3.4",
+        "@vue/compiler-dom": "3.3.4",
+        "@vue/compiler-ssr": "3.3.4",
+        "@vue/reactivity-transform": "3.3.4",
+        "@vue/shared": "3.3.4",
+        "estree-walker": "^2.0.2",
+        "magic-string": "^0.30.0",
+        "postcss": "^8.1.10",
+        "source-map-js": "^1.0.2"
+      }
+    },
+    "@vue/compiler-ssr": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz",
+      "integrity": "sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==",
+      "requires": {
+        "@vue/compiler-dom": "3.3.4",
+        "@vue/shared": "3.3.4"
+      }
+    },
+    "@vue/devtools-api": {
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz",
+      "integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
+    },
+    "@vue/reactivity": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.4.tgz",
+      "integrity": "sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==",
+      "requires": {
+        "@vue/shared": "3.3.4"
+      }
+    },
+    "@vue/reactivity-transform": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz",
+      "integrity": "sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==",
+      "requires": {
+        "@babel/parser": "^7.20.15",
+        "@vue/compiler-core": "3.3.4",
+        "@vue/shared": "3.3.4",
+        "estree-walker": "^2.0.2",
+        "magic-string": "^0.30.0"
+      }
+    },
+    "@vue/runtime-core": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.3.4.tgz",
+      "integrity": "sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==",
+      "requires": {
+        "@vue/reactivity": "3.3.4",
+        "@vue/shared": "3.3.4"
+      }
+    },
+    "@vue/runtime-dom": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz",
+      "integrity": "sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==",
+      "requires": {
+        "@vue/runtime-core": "3.3.4",
+        "@vue/shared": "3.3.4",
+        "csstype": "^3.1.1"
+      }
+    },
+    "@vue/server-renderer": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.3.4.tgz",
+      "integrity": "sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==",
+      "requires": {
+        "@vue/compiler-ssr": "3.3.4",
+        "@vue/shared": "3.3.4"
+      }
+    },
+    "@vue/shared": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz",
+      "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ=="
+    },
+    "animate.css": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/animate.css/-/animate.css-4.1.1.tgz",
+      "integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ=="
+    },
+    "anymatch": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+      "dev": true,
+      "requires": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      }
+    },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+    },
+    "axios": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
+      "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
+      "requires": {
+        "follow-redirects": "^1.15.0",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
+      }
+    },
+    "binary-extensions": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+      "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+      "dev": true
+    },
+    "braces": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+      "dev": true,
+      "requires": {
+        "fill-range": "^7.0.1"
+      }
+    },
+    "chokidar": {
+      "version": "3.5.3",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+      "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+      "dev": true,
+      "requires": {
+        "anymatch": "~3.1.2",
+        "braces": "~3.0.2",
+        "fsevents": "~2.3.2",
+        "glob-parent": "~5.1.2",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.6.0"
+      }
+    },
+    "combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "requires": {
+        "delayed-stream": "~1.0.0"
+      }
+    },
+    "csstype": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
+      "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
+    },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
+    },
+    "esbuild": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz",
+      "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==",
+      "dev": true,
+      "requires": {
+        "@esbuild/android-arm": "0.17.19",
+        "@esbuild/android-arm64": "0.17.19",
+        "@esbuild/android-x64": "0.17.19",
+        "@esbuild/darwin-arm64": "0.17.19",
+        "@esbuild/darwin-x64": "0.17.19",
+        "@esbuild/freebsd-arm64": "0.17.19",
+        "@esbuild/freebsd-x64": "0.17.19",
+        "@esbuild/linux-arm": "0.17.19",
+        "@esbuild/linux-arm64": "0.17.19",
+        "@esbuild/linux-ia32": "0.17.19",
+        "@esbuild/linux-loong64": "0.17.19",
+        "@esbuild/linux-mips64el": "0.17.19",
+        "@esbuild/linux-ppc64": "0.17.19",
+        "@esbuild/linux-riscv64": "0.17.19",
+        "@esbuild/linux-s390x": "0.17.19",
+        "@esbuild/linux-x64": "0.17.19",
+        "@esbuild/netbsd-x64": "0.17.19",
+        "@esbuild/openbsd-x64": "0.17.19",
+        "@esbuild/sunos-x64": "0.17.19",
+        "@esbuild/win32-arm64": "0.17.19",
+        "@esbuild/win32-ia32": "0.17.19",
+        "@esbuild/win32-x64": "0.17.19"
+      }
+    },
+    "estree-walker": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+      "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
+    },
+    "fill-range": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+      "dev": true,
+      "requires": {
+        "to-regex-range": "^5.0.1"
+      }
+    },
+    "follow-redirects": {
+      "version": "1.15.2",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
+      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
+    },
+    "form-data": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+      "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+      "requires": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "mime-types": "^2.1.12"
+      }
+    },
+    "fsevents": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+      "dev": true,
+      "optional": true
+    },
+    "glob-parent": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+      "dev": true,
+      "requires": {
+        "is-glob": "^4.0.1"
+      }
+    },
+    "immutable": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz",
+      "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==",
+      "dev": true
+    },
+    "is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+      "dev": true,
+      "requires": {
+        "binary-extensions": "^2.0.0"
+      }
+    },
+    "is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+      "dev": true
+    },
+    "is-glob": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+      "dev": true,
+      "requires": {
+        "is-extglob": "^2.1.1"
+      }
+    },
+    "is-number": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+      "dev": true
+    },
+    "leaflet": {
+      "version": "1.9.4",
+      "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
+      "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA=="
+    },
+    "leaflet.markercluster": {
+      "version": "1.5.3",
+      "resolved": "https://registry.npmjs.org/leaflet.markercluster/-/leaflet.markercluster-1.5.3.tgz",
+      "integrity": "sha512-vPTw/Bndq7eQHjLBVlWpnGeLa3t+3zGiuM7fJwCkiMFq+nmRuG3RI3f7f4N4TDX7T4NpbAXpR2+NTRSEGfCSeA==",
+      "requires": {}
+    },
+    "magic-string": {
+      "version": "0.30.0",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz",
+      "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==",
+      "requires": {
+        "@jridgewell/sourcemap-codec": "^1.4.13"
+      }
+    },
+    "mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
+    },
+    "mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "requires": {
+        "mime-db": "1.52.0"
+      }
+    },
+    "moment": {
+      "version": "2.29.4",
+      "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
+      "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
+    },
+    "nanoid": {
+      "version": "3.3.6",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
+      "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA=="
+    },
+    "normalize-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+      "dev": true
+    },
+    "picocolors": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
+    },
+    "picomatch": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+      "dev": true
+    },
+    "postcss": {
+      "version": "8.4.24",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz",
+      "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==",
+      "requires": {
+        "nanoid": "^3.3.6",
+        "picocolors": "^1.0.0",
+        "source-map-js": "^1.0.2"
+      }
+    },
+    "proxy-from-env": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+    },
+    "readdirp": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+      "dev": true,
+      "requires": {
+        "picomatch": "^2.2.1"
+      }
+    },
+    "rollup": {
+      "version": "3.23.0",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.23.0.tgz",
+      "integrity": "sha512-h31UlwEi7FHihLe1zbk+3Q7z1k/84rb9BSwmBSr/XjOCEaBJ2YyedQDuM0t/kfOS0IxM+vk1/zI9XxYj9V+NJQ==",
+      "dev": true,
+      "requires": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "sass": {
+      "version": "1.63.3",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.63.3.tgz",
+      "integrity": "sha512-ySdXN+DVpfwq49jG1+hmtDslYqpS7SkOR5GpF6o2bmb1RL/xS+wvPmegMvMywyfsmAV6p7TgwXYGrCZIFFbAHg==",
+      "dev": true,
+      "requires": {
+        "chokidar": ">=3.0.0 <4.0.0",
+        "immutable": "^4.0.0",
+        "source-map-js": ">=0.6.2 <2.0.0"
+      }
+    },
+    "source-map-js": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw=="
+    },
+    "to-regex-range": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+      "dev": true,
+      "requires": {
+        "is-number": "^7.0.0"
+      }
+    },
+    "vite": {
+      "version": "4.3.9",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz",
+      "integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==",
+      "dev": true,
+      "requires": {
+        "esbuild": "^0.17.5",
+        "fsevents": "~2.3.2",
+        "postcss": "^8.4.23",
+        "rollup": "^3.21.0"
+      }
+    },
+    "vue": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz",
+      "integrity": "sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==",
+      "requires": {
+        "@vue/compiler-dom": "3.3.4",
+        "@vue/compiler-sfc": "3.3.4",
+        "@vue/runtime-dom": "3.3.4",
+        "@vue/server-renderer": "3.3.4",
+        "@vue/shared": "3.3.4"
+      }
+    },
+    "vue-router": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.2.2.tgz",
+      "integrity": "sha512-cChBPPmAflgBGmy3tBsjeoe3f3VOSG6naKyY5pjtrqLGbNEXdzCigFUHgBvp9e3ysAtFtEx7OLqcSDh/1Cq2TQ==",
+      "requires": {
+        "@vue/devtools-api": "^6.5.0"
+      }
+    },
+    "vuetify": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.3.2.tgz",
+      "integrity": "sha512-m/R42di8FlyMaoktUe6k8JbF+A0vbJMpjQrZK7nH1ptK8VinVVQcaw+9m94wlO74IMR+LubxLh5t9I2ZtVCvjw==",
+      "requires": {}
+    }
+  }
+}

+ 29 - 0
package.json

@@ -0,0 +1,29 @@
+{
+  "name": "ntcri",
+  "private": true,
+  "version": "0.0.0",
+  "type": "module",
+  "scripts": {
+    "dev": "vite",
+    "build": "vite build",
+    "preview": "vite preview"
+  },
+  "dependencies": {
+    "@mdi/font": "^7.2.96",
+    "animate.css": "^4.1.1",
+    "axios": "^1.4.0",
+    "leaflet": "^1.9.4",
+    "leaflet.markercluster": "^1.5.3",
+    "moment": "^2.29.4",
+    "vue": "^3.2.47",
+    "vue-router": "^4.2.2",
+    "vuetify": "^3.3.2"
+  },
+  "devDependencies": {
+    "@mdi/js": "^7.2.96",
+    "@types/leaflet": "^1.9.3",
+    "@vitejs/plugin-vue": "^4.1.0",
+    "sass": "^1.63.3",
+    "vite": "^4.3.9"
+  }
+}

+ 1 - 0
public/vite.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

+ 22 - 0
src/App.vue

@@ -0,0 +1,22 @@
+<script setup>
+import { RouterView } from "vue-router";
+</script>
+
+<template>
+  <RouterView />
+</template>
+
+<style scoped>
+.logo {
+  height: 6em;
+  padding: 1.5em;
+  will-change: filter;
+  transition: filter 300ms;
+}
+.logo:hover {
+  filter: drop-shadow(0 0 2em #646cffaa);
+}
+.logo.vue:hover {
+  filter: drop-shadow(0 0 2em #42b883aa);
+}
+</style>

+ 57 - 0
src/assets/css/style.css

@@ -0,0 +1,57 @@
+/* CSS Reset */
+html,
+body,
+div,
+span,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+a,
+img,
+ul,
+ol,
+li,
+form,
+label,
+fieldset,
+legend {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  font-size: 100%;
+  vertical-align: baseline;
+  box-sizing: border-box;
+}
+
+/* Additional Resets */
+body {
+  line-height: 1;
+}
+
+ol,
+ul {
+  list-style: none;
+}
+
+img {
+  max-width: 100%;
+  height: auto;
+}
+
+a {
+  text-decoration: none;
+  color: inherit;
+}
+
+/* CSS Reset End */
+:root {
+  --main-color: #C39F68;
+}
+
+* {
+  font-family: "Noto Sans TC", sans-serif;
+}/*# sourceMappingURL=style.css.map */

+ 1 - 0
src/assets/css/style.css.map

@@ -0,0 +1 @@
+{"version":3,"sources":["style.scss","style.css"],"names":[],"mappings":"AAAA,cAAA;AAEA;;;;;;;;;;;;;;;;;;;;EAoBE,SAAA;EACA,UAAA;EACA,SAAA;EACA,eAAA;EACA,wBAAA;EACA,sBAAA;ACAF;;ADGA,sBAAA;AAEA;EACE,cAAA;ACDF;;ADIA;;EAEE,gBAAA;ACDF;;ADIA;EACE,eAAA;EACA,YAAA;ACDF;;ADIA;EACE,qBAAA;EACA,cAAA;ACDF;;ADIA,kBAAA;AAEA;EACI,qBAAA;ACFJ;;ADKA;EACI,uCAAA;ACFJ","file":"style.css"}

+ 60 - 0
src/assets/css/style.scss

@@ -0,0 +1,60 @@
+/* CSS Reset */
+
+html,
+body,
+div,
+span,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+a,
+img,
+ul,
+ol,
+li,
+form,
+label,
+fieldset,
+legend {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  font-size: 100%;
+  vertical-align: baseline;
+  box-sizing: border-box;
+}
+
+/* Additional Resets */
+
+body {
+  line-height: 1;
+}
+
+ol,
+ul {
+  list-style: none;
+}
+
+img {
+  max-width: 100%;
+  height: auto;
+}
+
+a {
+  text-decoration: none;
+  color: inherit;
+}
+
+/* CSS Reset End */
+
+:root {
+    --main-color: #C39F68;
+}
+
+* {
+    font-family: 'Noto Sans TC', sans-serif;
+}

BIN
src/assets/img/banner-0615.webp


BIN
src/assets/img/icon/date_icon.png


BIN
src/assets/img/icon/location_icon.png


BIN
src/assets/img/icon/search.png


BIN
src/assets/img/img-01.jpg


BIN
src/assets/img/img-02.jpg


BIN
src/assets/img/img-03.jpg


BIN
src/assets/img/img-04.jpg


BIN
src/assets/img/img-05.jpg


BIN
src/assets/img/img-06.jpg


BIN
src/assets/img/img-07.jpg


BIN
src/assets/img/img-08.jpg


BIN
src/assets/img/img-09.jpg


BIN
src/assets/img/img-10.jpg


BIN
src/assets/img/img-11.jpg


BIN
src/assets/img/img-12.jpg


BIN
src/assets/img/logo.png


BIN
src/assets/img/map-icon/icon_house01.png


BIN
src/assets/img/map-icon/icon_house02.png


BIN
src/assets/img/map-icon/icon_house03.png


BIN
src/assets/img/map-icon/icon_house04.png


BIN
src/assets/img/map-icon/icon_house05.png


BIN
src/assets/img/map-icon/icon_house06.png


BIN
src/assets/img/map-icon/icon_house07.png


BIN
src/assets/img/map-icon/icon_house10.png


BIN
src/assets/img/map-icon/icon_house11.png


+ 1352 - 0
src/assets/mapData.json

@@ -0,0 +1,1352 @@
+[
+    {
+        "Id": 302,
+        "Subject": "36彎茶韻濃.雲上說陶再見炊煙",
+        "UnitName": "嘉義縣梅山鄉太平社區發展協會",
+        "Lat": 23.5596059,
+        "Lng": 120.6012383,
+        "CuName": "嘉義縣梅山鄉太平社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 301,
+        "Subject": "走過兩個世紀.南投陶與你再次相遇",
+        "UnitName": "南投縣陶藝學會",
+        "Lat": 23.772822,
+        "Lng": 120.6789377,
+        "CuName": "南投、集集、名間、水里、竹山\t等地",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 300,
+        "Subject": "白米新心.木屐舊情-環境危機轉個彎看見新生屐",
+        "UnitName": "保證責任宜蘭縣蘇澳鎮白米社區合作社",
+        "Lat": 24.5829333,
+        "Lng": 121.8444922,
+        "CuName": "宜蘭縣蘇澳鎮白米社區",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 299,
+        "Subject": "阿里山的茶香飄下山.染布飄曳隨風上山",
+        "UnitName": "社團法人嘉義縣茶文化協進會",
+        "Lat": 23.4438533,
+        "Lng": 120.496841,
+        "CuName": "嘉義縣中埔鄉金蘭社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 298,
+        "Subject": "石山部落喚千客萬來.體驗原鄉的工藝農作和慶典",
+        "UnitName": "臺東縣臺東市富豐社區發展協會",
+        "Lat": 22.7842778,
+        "Lng": 121.1572207,
+        "CuName": "臺東縣臺東市富豐社區",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 297,
+        "Subject": "青年農夫再生循環經濟.掀起老農村一股新巨峰",
+        "UnitName": "彰化縣大村鄉新興社區發展協會",
+        "Lat": 23.9731886,
+        "Lng": 120.535446,
+        "CuName": "彰化縣大村鄉新興社區",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 296,
+        "Subject": "善的循環打造.最有溫度的木頭",
+        "UnitName": "臺中市西區大忠社區發展協會",
+        "Lat": 24.1382718,
+        "Lng": 120.6532593,
+        "CuName": "臺中市西區大忠社區",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 295,
+        "Subject": "鹿北工藝新絲路.番麥也能變黃金",
+        "UnitName": "雲林縣元長鄉鹿北社區發展協會",
+        "Lat": 23.6478129,
+        "Lng": 120.3756263,
+        "CuName": "雲林縣元長鄉鹿北社區",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 294,
+        "Subject": "蚵化東石陶.傳統漁村的再生與永續",
+        "UnitName": "社團法人嘉義縣鄉村永續發展協會",
+        "Lat": 23.4517729,
+        "Lng": 120.1915383,
+        "CuName": "嘉義縣東石鄉東石社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 293,
+        "Subject": "傳統織布牽起部落情.傳承技藝走過彩虹橋",
+        "UnitName": "南投縣仁愛鄉松林社區發展協會",
+        "Lat": 23.9695969,
+        "Lng": 121.0960943,
+        "CuName": "南投縣仁愛鄉松林社區",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 292,
+        "Subject": "以龍眼花果柴燒生活陶.展現農村新的生活方式",
+        "UnitName": "南投縣中寮鄉永福社區發展協會",
+        "Lat": 23.8889802,
+        "Lng": 120.7270912,
+        "CuName": "南投縣中寮鄉永福社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 291,
+        "Subject": "拋磚引玉後的磚新生活—磚戶水,人歡喜",
+        "UnitName": "彰化縣花壇鄉橋頭社區發展協會",
+        "Lat": 24.023513,
+        "Lng": 120.5471585,
+        "CuName": "彰化縣花壇鄉橋頭社區",
+        "Icon": "icon_house04.png"
+    },
+    {
+        "Id": 290,
+        "Subject": "竹仔坑天然植物與皇帝紙.根留故鄉展工藝風華",
+        "UnitName": "臺中市大里區竹仔坑社區發展協會",
+        "Lat": 24.0895904,
+        "Lng": 120.727312,
+        "CuName": "臺中市大里區竹仔坑社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 289,
+        "Subject": "綠野香坡發現山後的陶花園.阿美族原味陶趣",
+        "UnitName": "花蓮縣綠野香坡農村發展協會",
+        "Lat": 23.6369411,
+        "Lng": 121.4223933,
+        "CuName": "花蓮縣光復鄉馬佛社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 288,
+        "Subject": "留不住的九降風與豔陽天.傳承兩世紀的柿餅與柿染",
+        "UnitName": "新竹縣柿染文化協會",
+        "Lat": 24.833209,
+        "Lng": 121.0770883,
+        "CuName": "新竹縣新埔鎮旱坑社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 287,
+        "Subject": "香蕉絲看見噶瑪蘭族百年來的民族韌性",
+        "UnitName": "花蓮縣噶瑪蘭族發展協會",
+        "Lat": 23.6566581,
+        "Lng": 121.5374249,
+        "CuName": "花蓮縣豐濱鄉新社部落",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 286,
+        "Subject": "融入自然的藺編工藝.織起有溫度的家傳承母愛光輝",
+        "UnitName": "臺灣藺草協會",
+        "Lat": 24.4167079,
+        "Lng": 120.6843219,
+        "CuName": "苗栗縣苑裡山腳社區",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 285,
+        "Subject": "體會三生的人文共好之旅",
+        "UnitName": "高雄市寶來人文協會",
+        "Lat": 23.1055658,
+        "Lng": 120.6942759,
+        "CuName": "高雄市六龜區寶來社區(檨仔腳文化共享空間)",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 284,
+        "Subject": "漫遊三界:藥草飄香的工藝花園",
+        "UnitName": "社團法人三界埔文化發展協會",
+        "Lat": 23.4339942,
+        "Lng": 120.475478,
+        "CuName": "嘉義縣水上鄉三界埔社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 283,
+        "Subject": "回首磚窯廠裡的時光隧道",
+        "UnitName": "彰化縣花壇鄉橋頭社區發展協會",
+        "Lat": 24.0235081,
+        "Lng": 120.5471585,
+        "CuName": "彰化縣花壇鄉橋頭社區",
+        "Icon": "icon_house04.png"
+    },
+    {
+        "Id": 282,
+        "Subject": "美味臺三線:秋柿、烤雞、芬多精",
+        "UnitName": "嘉義縣臺三產業發展協會",
+        "Lat": 23.4652539,
+        "Lng": 120.5506163,
+        "CuName": "嘉義縣番路鄉番路社區(番路鄉農會購物中心)",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 281,
+        "Subject": "琴人的微笑:曾文水庫畔最優美樂章",
+        "UnitName": "嘉義縣大埔鄉和平社區發展協會",
+        "Lat": 23.301767,
+        "Lng": 120.589742,
+        "CuName": "嘉義縣大埔鄉和平社區",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 280,
+        "Subject": "畫工藝話當年,長輩也能微笑的手藝",
+        "UnitName": "南投縣國姓鄉石門社區發展協會",
+        "Lat": 24.0424659,
+        "Lng": 120.8591483,
+        "CuName": "南投縣國姓鄉石門社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 279,
+        "Subject": "臺中郊區新玩藝!入山林而藍染",
+        "UnitName": "財團法人水源地文教基金會",
+        "Lat": 24.1052694,
+        "Lng": 120.7831834,
+        "CuName": "臺中市太平區頭汴坑社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 278,
+        "Subject": "太陽底下的新鮮事!柿子還能這樣玩",
+        "UnitName": "新竹縣柿染文化協會",
+        "Lat": 24.8332041,
+        "Lng": 121.0770883,
+        "CuName": "新竹縣新埔鎮新埔社區(新埔柿染坊)",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 277,
+        "Subject": "竹入生活:發現工藝的第一步",
+        "UnitName": "嘉義縣崙尾天赦竹編發展協會",
+        "Lat": 23.5852749,
+        "Lng": 120.3741748,
+        "CuName": "嘉義縣溪口鄉天赦社區",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 276,
+        "Subject": "苗栗三角社區裡的臺灣好手藺",
+        "UnitName": "臺灣藺草學會",
+        "Lat": 24.416703,
+        "Lng": 120.6865106,
+        "CuName": "苗栗縣苑裡山腳社區",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 275,
+        "Subject": "貓屋裡的心工藝,交織出社區裡人情味",
+        "UnitName": "雲林縣虎尾鎮頂溪社區發展協會",
+        "Lat": 23.7298619,
+        "Lng": 120.4607435,
+        "CuName": "雲林縣虎尾鎮頂溪社區",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 274,
+        "Subject": "走訪編織故鄉最不能錯過的月桃及稻草原民手藝",
+        "UnitName": "有限責任臺東縣東海岸原住民社區合作社",
+        "Lat": 22.767586,
+        "Lng": 121.1257323,
+        "CuName": "石山部落",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 273,
+        "Subject": "掃地掃地掃心地,竹林掃把有意義!",
+        "UnitName": "南投縣鹿谷鄉竹林社區發展協會",
+        "Lat": 23.7268663,
+        "Lng": 120.753299,
+        "CuName": "南投縣鹿谷鄉竹林社區",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 272,
+        "Subject": "在地苧麻的復育之路!賽德克族人的知識與織事",
+        "UnitName": "南投縣仁愛鄉松林社區發展協會",
+        "Lat": 23.9695761,
+        "Lng": 121.0282426,
+        "CuName": "南投縣仁愛鄉松林社區",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 271,
+        "Subject": "部落行旅:臺11線上的新絲路",
+        "UnitName": "花蓮縣噶瑪蘭族發展協會 (新社香蕉絲工坊)",
+        "Lat": 23.6566532,
+        "Lng": 121.5396136,
+        "CuName": "花蓮縣豐濱鄉新社社區",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 270,
+        "Subject": "聽月桃唱土地的歌喚回漂浪百年的祖靈-月桃編織的跨界創新",
+        "UnitName": "臺東縣臺東市富豐社區發展協會",
+        "Lat": 22.7840102,
+        "Lng": 121.1599266,
+        "CuName": "富豐社區",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 269,
+        "Subject": "漂泊一世紀的民族用它接起斷裂的歷史-全臺唯一香蕉絲工藝復育",
+        "UnitName": "花蓮縣噶瑪蘭族發展協會",
+        "Lat": 23.9947067,
+        "Lng": 121.6262904,
+        "CuName": "新社部落",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 268,
+        "Subject": "三峽古宅的模糊石刻驚藏上世紀的藍染傳奇-推動重振藍染風華再起",
+        "UnitName": "新北市三峽區三角湧文化協進會",
+        "Lat": 24.9330989,
+        "Lng": 121.369173,
+        "CuName": "新北市三峽區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 267,
+        "Subject": "一場天搖地動震出驚艷的巴黎的太平藍-用客家藍染重建受傷家園",
+        "UnitName": "財團法人水源地文教基金會",
+        "Lat": 24.1489161,
+        "Lng": 120.6864532,
+        "CuName": "太平頭汴坑社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 266,
+        "Subject": "百年菁寮醫生老宅邸救回失傳不知年的小青染-無米樂故鄉染出青春艷陽天",
+        "UnitName": "臺南市後壁區墨林社區發展協會",
+        "Lat": 23.3795348,
+        "Lng": 120.3395869,
+        "CuName": "墨林社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 265,
+        "Subject": "用工藝重建家園找回溫泉鄉的榮景-展現生命色彩的陶藝與草木染",
+        "UnitName": "高雄市寶來人文協會",
+        "Lat": 23.1055985,
+        "Lng": 120.6943702,
+        "CuName": "寶來社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 264,
+        "Subject": "以染繪為筆記憶耆老的故事-用染布工藝紀錄在地",
+        "UnitName": "南投縣國姓鄉石門社區發展協會",
+        "Lat": 24.0473093,
+        "Lng": 120.8849819,
+        "CuName": "石門社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 263,
+        "Subject": "用太陽曬出來的顏色寫一封獻給柿鄉的情書-從柿餅到柿染的物產創作",
+        "UnitName": "新竹縣柿染文化協會",
+        "Lat": 0,
+        "Lng": 0,
+        "CuName": "旱坑里社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 262,
+        "Subject": "老製蓆廠創力爆發用藺草包再現工藝風華-臺灣「加給仔」的麻雀變鳳凰",
+        "UnitName": "臺南市西港區檨林社區發展協會",
+        "Lat": 23.13424,
+        "Lng": 120.232013,
+        "CuName": "檨林社區",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 261,
+        "Subject": "不裝西瓜裝文青.農用籠變身時髦吊書袋-竹籠村落的復活之路",
+        "UnitName": "嘉義縣崙尾天赦竹編發展協會",
+        "Lat": 23.587549,
+        "Lng": 120.372741,
+        "CuName": "天赦庄",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 260,
+        "Subject": "藺草阿嬤征服紅毯女神.美炸時尚圈的藺草編-藺草故鄉的八年扎根之路",
+        "UnitName": "臺灣藺草學會",
+        "Lat": 24.4167518,
+        "Lng": 120.6862592,
+        "CuName": "苑裡鎮山腳社區",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 259,
+        "Subject": "原味陶趣- 陶珠、陶器技藝培訓",
+        "UnitName": "綠野香坡農村發展協會",
+        "Lat": 23.6370633,
+        "Lng": 121.4279991,
+        "CuName": "馬佛社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 258,
+        "Subject": "植物染與客家阿婆",
+        "UnitName": "富源社區發展協會",
+        "Lat": 23.5786332,
+        "Lng": 121.3757987,
+        "CuName": "富源社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 257,
+        "Subject": "達蘭埠部落工藝祭與傳承",
+        "UnitName": "達蘭埠文化農業產業推廣協會",
+        "Lat": 23.226102,
+        "Lng": 121.289896,
+        "CuName": "達蘭埠",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 256,
+        "Subject": "原民風傳統特色文化永續發展計畫",
+        "UnitName": "富豐社區發展協會",
+        "Lat": 22.7840102,
+        "Lng": 121.1599266,
+        "CuName": "富豐社區",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 255,
+        "Subject": "邁向融合與創新- 杉林微型工藝產業培力計畫",
+        "UnitName": "集來社區發展協會",
+        "Lat": 22.9645123,
+        "Lng": 120.5424136,
+        "CuName": "集來社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 254,
+        "Subject": "臺灣木棉花植物染及其作品之色彩研究",
+        "UnitName": "月津文史發展協會",
+        "Lat": 23.3198545,
+        "Lng": 120.2667209,
+        "CuName": "田寮社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 253,
+        "Subject": "墨林藍染型染培力加強計畫",
+        "UnitName": "墨林社區發展協會",
+        "Lat": 23.3782434,
+        "Lng": 120.3363593,
+        "CuName": "墨林社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 252,
+        "Subject": "繽紛柿季千里飄茶香",
+        "UnitName": "下坑社區發展協會",
+        "Lat": 23.472964,
+        "Lng": 120.535963,
+        "CuName": "下坑社區",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 251,
+        "Subject": "「山茶花演義」~ 文學陶板裝飾技藝之培訓",
+        "UnitName": "太平社區發展協會",
+        "Lat": 23.5612812,
+        "Lng": 120.6062775,
+        "CuName": "太平社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 250,
+        "Subject": "傳統手作春仔花藝文造鄉計畫",
+        "UnitName": "頂溪社區發展協會",
+        "Lat": 23.7298619,
+        "Lng": 120.4607435,
+        "CuName": "頂溪社區",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 249,
+        "Subject": "陶瓷工藝坊",
+        "UnitName": "永福社區發展協會",
+        "Lat": 23.8889295,
+        "Lng": 120.7356736,
+        "CuName": "永福社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 248,
+        "Subject": "漆情六藝- 牛尾農村生活漆器推廣與漆文化產業體驗計畫",
+        "UnitName": "牛尾農村發展協會",
+        "Lat": 23.996556,
+        "Lng": 120.982454,
+        "CuName": "牛尾社區",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 247,
+        "Subject": "磚雕工藝- 牆面磚藝及裝置人才技藝培訓",
+        "UnitName": "橋頭社區發展協會",
+        "Lat": 24.02629,
+        "Lng": 120.558262,
+        "CuName": "橋頭社區",
+        "Icon": "icon_house04.png"
+    },
+    {
+        "Id": 246,
+        "Subject": "木語熊( 木頭的語言與熊的對話) ",
+        "UnitName": "烏石坑社區發展協會",
+        "Lat": 24.2921867,
+        "Lng": 120.9109773,
+        "CuName": "烏石坑社區",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 245,
+        "Subject": "知「竹」藏「梨」",
+        "UnitName": "慶東社區發展協會",
+        "Lat": 24.2437872,
+        "Lng": 120.8336556,
+        "CuName": "慶東社區",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 244,
+        "Subject": "永豐社區意象形塑計畫",
+        "UnitName": "永豐社區發展協會",
+        "Lat": 24.3314107,
+        "Lng": 120.6884706,
+        "CuName": "永豐社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 243,
+        "Subject": "蒲瓜百變藝術創作",
+        "UnitName": "龍昇社區發展協會",
+        "Lat": 24.641293,
+        "Lng": 120.829636,
+        "CuName": "龍昇社區",
+        "Icon": "icon_house10.png"
+    },
+    {
+        "Id": 242,
+        "Subject": "花蓮縣光復鄉原鄉文創商品微型計畫",
+        "UnitName": "有限責任花蓮縣琺達岸運銷合作社",
+        "Lat": 23.662456,
+        "Lng": 121.422208,
+        "CuName": "花蓮縣光復鄉阿美族部落",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 241,
+        "Subject": "高士鑫綜合工精藝傳情計畫",
+        "UnitName": "高士社區發展協會",
+        "Lat": 22.122528,
+        "Lng": 120.8389385,
+        "CuName": "高士社區",
+        "Icon": "icon_house02.png"
+    },
+    {
+        "Id": 240,
+        "Subject": "生命的彩虹",
+        "UnitName": "力里社區發展協會",
+        "Lat": 22.4305947,
+        "Lng": 120.6409888,
+        "CuName": "春日鄉力里社區",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 239,
+        "Subject": "南方生活美學的邂逅- 山茶˙ 好陶˙ 手染布",
+        "UnitName": "高雄市寶來人文協會",
+        "Lat": 23.1055985,
+        "Lng": 120.6943702,
+        "CuName": "寶來社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 238,
+        "Subject": "看見,檨林藺草",
+        "UnitName": "檨林社區發展協會",
+        "Lat": 23.1355241,
+        "Lng": 120.2299151,
+        "CuName": "檨林社區",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 237,
+        "Subject": "「興」藝術‧「中」於自我",
+        "UnitName": "興中社區發展協會",
+        "Lat": 23.5331744,
+        "Lng": 120.4155972,
+        "CuName": "興中社區",
+        "Icon": "icon_house02.png"
+    },
+    {
+        "Id": 236,
+        "Subject": "福漆安康‧金藝傳漆",
+        "UnitName": "南投縣生活重建協會",
+        "Lat": 24.011802,
+        "Lng": 120.8221701,
+        "CuName": "國姓鄉福龜社區",
+        "Icon": "icon_house11.png"
+    },
+    {
+        "Id": 235,
+        "Subject": "設計時尚天藍生活化用品",
+        "UnitName": "財團法人水源地文教基金會",
+        "Lat": 24.1083289,
+        "Lng": 120.7813697,
+        "CuName": "頭汴社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 234,
+        "Subject": "染柿生活- 染染四季",
+        "UnitName": "新竹縣柿染文化協會",
+        "Lat": 24.8279165,
+        "Lng": 121.0750938,
+        "CuName": "新埔柿染坊",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 233,
+        "Subject": "藍峽客-再現三角湧染布色",
+        "UnitName": "三角湧文化協進會",
+        "Lat": 24.9346731,
+        "Lng": 121.3691419,
+        "CuName": "新北市三峽區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 232,
+        "Subject": "刻畫謝厝木藝村願景",
+        "UnitName": "弘聖藝雕刻實業有限公司",
+        "Lat": 23.5842365,
+        "Lng": 120.2022239,
+        "CuName": "雲林縣口湖鄉謝厝社區",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 231,
+        "Subject": "蓮鄉工藝白荷陶",
+        "UnitName": "白荷陶坊",
+        "Lat": 23.363257,
+        "Lng": 120.426081,
+        "CuName": "臺南市白河區昇安社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 230,
+        "Subject": "平安香火陶",
+        "UnitName": "磐的陶坊",
+        "Lat": 23.308333,
+        "Lng": 120.313889,
+        "CuName": "台南區新營區太子社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 229,
+        "Subject": "陽光‧海風‧柴燒陶",
+        "UnitName": "深耕文化工作坊",
+        "Lat": 23.5654787,
+        "Lng": 119.6151426,
+        "CuName": "澎湖縣隘門社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 228,
+        "Subject": "尋找崙背燒",
+        "UnitName": "老土藝術工作室",
+        "Lat": 23.76803,
+        "Lng": 120.355896,
+        "CuName": "崙背詔安客家文化社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 227,
+        "Subject": "老窯慢慢燒",
+        "UnitName": "三和瓦廠",
+        "Lat": 22.6635406,
+        "Lng": 120.4239959,
+        "CuName": "竹寮社區",
+        "Icon": "icon_house04.png"
+    },
+    {
+        "Id": 226,
+        "Subject": "濁水石頭記",
+        "UnitName": "台灣意匠工房",
+        "Lat": 23.818552,
+        "Lng": 120.69302,
+        "CuName": "南投縣名間鄉新民社區發展協會",
+        "Icon": "icon_house05.png"
+    },
+    {
+        "Id": 225,
+        "Subject": "木鈴‧山城‧水湳洞",
+        "UnitName": "迷石文化事業有限公司",
+        "Lat": 24.9157122,
+        "Lng": 121.6739371,
+        "CuName": "山城美館、水湳洞社區",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 224,
+        "Subject": "幸福臺灣號‧添興窯",
+        "UnitName": "添興磁器工廠",
+        "Lat": 23.83288,
+        "Lng": 120.755518,
+        "CuName": "南投縣集集鎮綠色隧道社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 223,
+        "Subject": "藝竹靜好 金黃色的竹產業",
+        "UnitName": "藝邨精品企業有限公司",
+        "Lat": 23.77488,
+        "Lng": 120.710587,
+        "CuName": "南投縣竹山鎮",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 222,
+        "Subject": "浬陶夢風鈴",
+        "UnitName": "水里蛇窯陶藝文化園區(合興窯業工廠)",
+        "Lat": 23.796933,
+        "Lng": 120.866053,
+        "CuName": "南投縣水里鄉頂崁社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 221,
+        "Subject": "無名樹:將人從房子帶回環境",
+        "UnitName": "德豐木業股份有限公司",
+        "Lat": 23.7911704,
+        "Lng": 120.6947551,
+        "CuName": "南投縣竹山鎮延正社區",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 220,
+        "Subject": "山形玫瑰生活陶",
+        "UnitName": "心陶園工作室",
+        "Lat": 23.9776999,
+        "Lng": 120.685469,
+        "CuName": "南投縣草屯鎮復興里社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 219,
+        "Subject": "木藝‧美學‧新生活",
+        "UnitName": "弘聖藝雕刻實業有限公司",
+        "Lat": 23.5842365,
+        "Lng": 120.2022239,
+        "CuName": "雲林縣口湖鄉謝厝社區",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 218,
+        "Subject": "在田中央燒出陶的堅持",
+        "UnitName": "田中窯陶藝工坊",
+        "Lat": 23.8654638,
+        "Lng": 120.5685379,
+        "CuName": "彰化縣田中鎮三民社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 217,
+        "Subject": "苑裡手編‧藺",
+        "UnitName": "苗栗縣苑裡鎮山腳社區發展協會",
+        "Lat": 24.443117,
+        "Lng": 120.6500479,
+        "CuName": "苗栗縣苑裡鎮山腳社區",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 216,
+        "Subject": "窯藝雅器麥鄉文化生活圈",
+        "UnitName": "趙家窯工藝坊",
+        "Lat": 24.171434,
+        "Lng": 120.709678,
+        "CuName": "台中縣大雅社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 215,
+        "Subject": "水稻的一生",
+        "UnitName": "南投縣草屯鎮草鞋墩鄉土文教協會",
+        "Lat": 23.9762529,
+        "Lng": 120.681445,
+        "CuName": "南投縣草屯鎮",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 214,
+        "Subject": "鸚哥石‧梅仔花",
+        "UnitName": "新北市鸚哥石文化夢想協會",
+        "Lat": 25.000466,
+        "Lng": 121.318159,
+        "CuName": "新北市鶯歌區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 213,
+        "Subject": "金山‧布‧藍泥",
+        "UnitName": "布藍泥手染工坊",
+        "Lat": 25.212654,
+        "Lng": 121.592246,
+        "CuName": "新北市金山區磺溪頭社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 212,
+        "Subject": "茶鄉陶器",
+        "UnitName": "台客藍工坊",
+        "Lat": 24.924444,
+        "Lng": 121.726667,
+        "CuName": "新北市坪林區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 211,
+        "Subject": "美如天織",
+        "UnitName": "新北市鄉土文藝推廣協會",
+        "Lat": 24.950083,
+        "Lng": 121.530476,
+        "CuName": "臺北縣新店市平潭社區",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 210,
+        "Subject": "新太平洋美學.台東部落手創工藝",
+        "UnitName": "社團法人台東縣原住民族全人發展關懷協會",
+        "Lat": 22.6040987,
+        "Lng": 120.9964819,
+        "CuName": "台東縣原住民族全人發展關懷協會",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 209,
+        "Subject": "靚北投 再現北投藍染的原鄉",
+        "UnitName": "財團法人台北市北投文化基金會",
+        "Lat": 25.1363615,
+        "Lng": 121.5027404,
+        "CuName": "台北市北投區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 208,
+        "Subject": "三峽藍‧染三峽",
+        "UnitName": "三角湧文化協進會",
+        "Lat": 24.9330989,
+        "Lng": 121.369173,
+        "CuName": "新北市三峽區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 207,
+        "Subject": "府城工藝新機",
+        "UnitName": "安藝實業社",
+        "Lat": 23.038476,
+        "Lng": 120.205175,
+        "CuName": "台南市安南區",
+        "Icon": "icon_house10.png"
+    },
+    {
+        "Id": 206,
+        "Subject": "染藝新柿界",
+        "UnitName": "新竹縣新埔鎮九芎湖文化發展協會",
+        "Lat": 24.847945,
+        "Lng": 121.114567,
+        "CuName": "新竹縣新埔鎮旱坑、照門社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 205,
+        "Subject": "無字天書 與科技結合的泰雅染織工藝",
+        "UnitName": "石壁染織工坊",
+        "Lat": 24.600899,
+        "Lng": 121.040048,
+        "CuName": "苗栗縣南庄鄉東河社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 204,
+        "Subject": "追求幸福生活的十鼓文化村",
+        "UnitName": "十鼓股份有限公司",
+        "Lat": 22.944681,
+        "Lng": 120.220858,
+        "CuName": "十鼓文化村",
+        "Icon": "icon_house10.png"
+    },
+    {
+        "Id": 203,
+        "Subject": "林北之音傳千里,洞蕭之情永流傳",
+        "UnitName": "雲林縣社區產業文化協會",
+        "Lat": 23.764107,
+        "Lng": 120.624158,
+        "CuName": "雲林縣林內鄉林北社區",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 202,
+        "Subject": "卓也染布",
+        "UnitName": "卓也小屋手工坊",
+        "Lat": 24.416667,
+        "Lng": 120.766667,
+        "CuName": "苗栗縣三義鄉雙潭社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 201,
+        "Subject": "昇起虹橋",
+        "UnitName": "野桐工坊",
+        "Lat": 24.360438,
+        "Lng": 120.946864,
+        "CuName": "苗栗縣泰安鄉象鼻村",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 200,
+        "Subject": "台江幸福錦囊",
+        "UnitName": "社團法人台灣螞蟻拼布研究會(更名台灣藝術拼布研究會)",
+        "Lat": 0,
+        "Lng": 0,
+        "CuName": "台江虎尾寮社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 199,
+        "Subject": "水漾美陶傳達蓮想初心",
+        "UnitName": "蓮想美學創意有限公司",
+        "Lat": 23.333636,
+        "Lng": 120.458806,
+        "CuName": "臺南市白河區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 198,
+        "Subject": "府城繡‧八仙彩",
+        "UnitName": "府城光彩繡莊",
+        "Lat": 22.9958916,
+        "Lng": 120.2021162,
+        "CuName": "台南市永福社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 196,
+        "Subject": "冬鳴春蝶藝助茶文化",
+        "UnitName": "龍鳳祥交趾陶藝社",
+        "Lat": 23.4754488,
+        "Lng": 120.447285,
+        "CuName": "龍鳳祥交趾陶藝社",
+        "Icon": "icon_house11.png"
+    },
+    {
+        "Id": 195,
+        "Subject": "蝴蝶變成雲",
+        "UnitName": "彭春林生活創意工房",
+        "Lat": 22.839685,
+        "Lng": 120.637144,
+        "CuName": "屏東縣三地門鄉青葉社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 194,
+        "Subject": "產學激盪向陽發新意",
+        "UnitName": "臺東縣原愛工坊協會",
+        "Lat": 22.6376247,
+        "Lng": 121.0053627,
+        "CuName": "臺東縣太麻里鄉多良社區",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 193,
+        "Subject": "重現VUVU的傳統織紋",
+        "UnitName": "屏東縣春日鄉力里社區發展協會",
+        "Lat": 22.434343,
+        "Lng": 120.647483,
+        "CuName": "屏東縣春日鄉力里社區",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 192,
+        "Subject": "集集陶藝老幹發新枝",
+        "UnitName": "添興窯陶藝事業股份有限公司",
+        "Lat": 23.83288,
+        "Lng": 120.755518,
+        "CuName": "南投縣集集鎮 ",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 191,
+        "Subject": "原民工藝光點聚落",
+        "UnitName": "社團法人台東縣原住民族全人發展關懷協會",
+        "Lat": 22.7679249,
+        "Lng": 121.1282169,
+        "CuName": "原社手創生活館",
+        "Icon": "icon_house11.png"
+    },
+    {
+        "Id": 190,
+        "Subject": "開門七寶打響苗栗陶",
+        "UnitName": "苗栗縣陶瓷文化協會",
+        "Lat": 24.4892686,
+        "Lng": 120.9417368,
+        "CuName": "苗栗縣",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 189,
+        "Subject": "樂活石藝創意加值",
+        "UnitName": "田心藝術設計工作室",
+        "Lat": 23.9790021,
+        "Lng": 121.5699356,
+        "CuName": "花蓮縣吉安鄉",
+        "Icon": "icon_house05.png"
+    },
+    {
+        "Id": 188,
+        "Subject": "雕刻小琉球海洋藝想",
+        "UnitName": "屏東縣琉球鄉漂流木人文藝術協會",
+        "Lat": 22.341667,
+        "Lng": 120.369444,
+        "CuName": "屏東縣琉球鄉力里社區",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 187,
+        "Subject": "編織飛越大武山的彩虹",
+        "UnitName": "屏東縣春日鄉力里社區發展協會",
+        "Lat": 22.434343,
+        "Lng": 120.647483,
+        "CuName": "屏東縣春日鄉力里社區",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 186,
+        "Subject": "精製漆器尊貴品味",
+        "UnitName": "台灣七寶軒有限公司",
+        "Lat": 24.2592933,
+        "Lng": 120.713426,
+        "CuName": "台中市葫蘆墩社區",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 185,
+        "Subject": "金木巧飾排灣琉璃珠",
+        "UnitName": "屏東縣地磨兒文化產業藝術協會",
+        "Lat": 22.716667,
+        "Lng": 120.65,
+        "CuName": "屏東縣三地門鄉",
+        "Icon": "icon_house02.png"
+    },
+    {
+        "Id": 184,
+        "Subject": "灌注靈魂與希望的皮雕",
+        "UnitName": "都拉巴拉斯工作坊",
+        "Lat": 22.7025121,
+        "Lng": 120.6087342,
+        "CuName": "屏東縣瑪家鄉",
+        "Icon": "icon_house10.png"
+    },
+    {
+        "Id": 183,
+        "Subject": "光彩府城繡摩登變身",
+        "UnitName": "府城光彩繡莊",
+        "Lat": 22.995915,
+        "Lng": 120.202138,
+        "CuName": "府城光彩繡莊",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 182,
+        "Subject": "陶染手作中信心升揚",
+        "UnitName": "高雄市六龜寶來重建協會",
+        "Lat": 23.1080251,
+        "Lng": 120.6989362,
+        "CuName": "高雄市六龜區寶來社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 181,
+        "Subject": "生漆原鄉傳藝扎根基",
+        "UnitName": "南投縣國姓鄉生活美學協會",
+        "Lat": 24.0564429,
+        "Lng": 120.8728615,
+        "CuName": "南投縣國姓鄉",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 180,
+        "Subject": "客庄柿染樸美情懷",
+        "UnitName": "新竹縣新埔鎮九芎湖文化發展協會",
+        "Lat": 24.8332041,
+        "Lng": 121.079277,
+        "CuName": "新竹縣新埔鎮",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 179,
+        "Subject": "染出客家人質樸色彩",
+        "UnitName": "新竹縣柿染文化協會",
+        "Lat": 24.8496061,
+        "Lng": 121.0908329,
+        "CuName": "新竹縣新埔鎮",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 178,
+        "Subject": "電繡文創融入生活美學",
+        "UnitName": "臺灣電繡藝術教育發展協會",
+        "Lat": 24.9506114,
+        "Lng": 121.223292,
+        "CuName": "桃園市中壢區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 177,
+        "Subject": "木藝新趣開拓藍海",
+        "UnitName": "陳彫刻處",
+        "Lat": 24.2332076,
+        "Lng": 120.9417368,
+        "CuName": "台中市",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 176,
+        "Subject": "變出台灣意象文化工藝木偶",
+        "UnitName": "老樹根魔法木工坊(老樹根實業有限公司)",
+        "Lat": 24.109834,
+        "Lng": 120.652693,
+        "CuName": "台中市南區樹義里社區",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 175,
+        "Subject": "童趣讓木頭活起來",
+        "UnitName": "木匠兄妹科技有限公司",
+        "Lat": 24.2930061,
+        "Lng": 120.7194854,
+        "CuName": "木匠兄妹科技有限公司",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 174,
+        "Subject": "竹崎鄉情燒進陶泥裡",
+        "UnitName": "竹崎文化藝術基金會",
+        "Lat": 23.5540738,
+        "Lng": 120.5633563,
+        "CuName": "嘉義縣竹崎鄉",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 173,
+        "Subject": "水里蛇窯古法創新",
+        "UnitName": "合興窯業工廠(水里蛇窯陶藝文化園區)",
+        "Lat": 23.8009727,
+        "Lng": 120.8645832,
+        "CuName": "南投縣水里鄉",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 172,
+        "Subject": "從心詮釋「南投陶」",
+        "UnitName": "心陶園工作室",
+        "Lat": 23.9776999,
+        "Lng": 120.685469,
+        "CuName": "心陶園工作室",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 171,
+        "Subject": "捏塑哪吒信仰的印記",
+        "UnitName": "磐的陶坊",
+        "Lat": 23.2860531,
+        "Lng": 120.2653471,
+        "CuName": "台南市新營區太子社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 170,
+        "Subject": "田園稻香樂「陶」然",
+        "UnitName": "田中窯陶藝工坊",
+        "Lat": 23.8715813,
+        "Lng": 120.5595696,
+        "CuName": "彰化縣田中鎮社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 169,
+        "Subject": "山村農趣染一抹藍",
+        "UnitName": "卓也小屋手工坊",
+        "Lat": 24.3914118,
+        "Lng": 120.795562,
+        "CuName": "苗栗縣三義鄉雙潭社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 168,
+        "Subject": "三角湧的幸福藍染",
+        "UnitName": "新北市三峽區三角湧文化協進會",
+        "Lat": 24.9346739,
+        "Lng": 121.3674819,
+        "CuName": "新北市三峽區三角湧社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 167,
+        "Subject": "打造金工共享平台",
+        "UnitName": "ZAMAMA金屬物件工作室",
+        "Lat": 24.135687,
+        "Lng": 120.6837718,
+        "CuName": "ZAMAMA金屬物件工作室",
+        "Icon": "icon_house02.png"
+    },
+    {
+        "Id": 166,
+        "Subject": "鍛鑄高雄新穎意象",
+        "UnitName": "三峰金屬漆藝設計工作室",
+        "Lat": 22.6830967,
+        "Lng": 120.3099163,
+        "CuName": "三峰金屬漆藝設計工作室",
+        "Icon": "icon_house02.png"
+    },
+    {
+        "Id": 165,
+        "Subject": "鄉土稻藝不解之緣",
+        "UnitName": "南投縣草屯鎮草鞋墩鄉土文教協會",
+        "Lat": 23.983,
+        "Lng": 120.7326,
+        "CuName": "南投縣草屯鎮",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 164,
+        "Subject": "為林北洞簫試新裝",
+        "UnitName": "雲林縣社區產業文化協會",
+        "Lat": 23.764107,
+        "Lng": 120.624158,
+        "CuName": "雲林縣林內鄉林北社區",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 163,
+        "Subject": "捏塑魚迷海洋文化",
+        "UnitName": "深耕文化工作坊陶藝",
+        "Lat": 23.5654787,
+        "Lng": 119.6151426,
+        "CuName": "澎湖縣隘門社區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 162,
+        "Subject": "愛心堆疊福漆安康",
+        "UnitName": "南投縣生活重建協會漆器",
+        "Lat": 24.011912,
+        "Lng": 120.819475,
+        "CuName": "南投縣國姓鄉福龜社區",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 161,
+        "Subject": "時尚玩藝繡出多采生活",
+        "UnitName": "台灣電繡藝術教育發展協會",
+        "Lat": 24.956944,
+        "Lng": 121.223611,
+        "CuName": "桃園市中壢區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 160,
+        "Subject": "細縫密繡親親寶「被」",
+        "UnitName": "彰化縣鹿港鎮菜園社區發展協會拼布",
+        "Lat": 24.052951,
+        "Lng": 120.432762,
+        "CuName": "彰化縣鹿港鎮菜園社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 159,
+        "Subject": "拼布演繹客家風情",
+        "UnitName": "桃園市龍潭區三林社區發展協會",
+        "Lat": 24.844444,
+        "Lng": 121.205278,
+        "CuName": "桃園市龍潭區三林社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 158,
+        "Subject": "花蝶交織魯凱染繡夢",
+        "UnitName": "彭春林生活創意工房",
+        "Lat": 22.709807,
+        "Lng": 120.645724,
+        "CuName": "屏東縣三地門鄉青葉村",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 157,
+        "Subject": "竹藝新境因材施用",
+        "UnitName": "藝邨精品企業有限公司",
+        "Lat": 23.77488,
+        "Lng": 120.710587,
+        "CuName": "南投縣竹山鎮",
+        "Icon": "icon_house07.png"
+    },
+    {
+        "Id": 156,
+        "Subject": "打造碧潭左岸染織流域",
+        "UnitName": "新北市鄉土文藝推廣協會",
+        "Lat": 0,
+        "Lng": 0,
+        "CuName": "新北市新店區平潭社區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 155,
+        "Subject": "竹編跨界時尚探險",
+        "UnitName": "錦緞竹編工作室",
+        "Lat": 23.766383,
+        "Lng": 120.715502,
+        "CuName": "南投縣竹山鎮",
+        "Icon": "icon_house06.png"
+    },
+    {
+        "Id": 154,
+        "Subject": "喚起北投陶瓷繁華記憶",
+        "UnitName": "臺北市北投文化基金會",
+        "Lat": 25.1363615,
+        "Lng": 121.5027404,
+        "CuName": "臺北市北投區",
+        "Icon": "icon_house01.png"
+    },
+    {
+        "Id": 153,
+        "Subject": "歷久彌新幸福三峽染",
+        "UnitName": "新北市三峽區三角湧文化協進會",
+        "Lat": 24.933333,
+        "Lng": 121.366667,
+        "CuName": "新北市三峽區",
+        "Icon": "icon_house03.png"
+    },
+    {
+        "Id": 152,
+        "Subject": "頭城展藝千龜來朝",
+        "UnitName": "宜蘭縣頭城文化發展協會",
+        "Lat": 24.8599739,
+        "Lng": 121.823136,
+        "CuName": "宜蘭縣頭城社區",
+        "Icon": "icon_house03.png"
+    }
+]

+ 66 - 0
src/assets/testData.json

@@ -0,0 +1,66 @@
+[
+    {
+        "name": "據點_1",
+        "data": [
+            {
+                "Id": 302,
+                "Subject": "36彎茶韻濃.雲上說陶再見炊煙",
+                "UnitName": "嘉義縣梅山鄉太平社區發展協會",
+                "Lat": 23.5596059,
+                "Lng": 120.6012383,
+                "CuName": "嘉義縣梅山鄉太平社區",
+                "Icon": "icon_house01.png"
+            },
+            {
+                "Id": 299,
+                "Subject": "阿里山的茶香飄下山.染布飄曳隨風上山",
+                "UnitName": "社團法人嘉義縣茶文化協進會",
+                "Lat": 23.4438533,
+                "Lng": 120.496841,
+                "CuName": "嘉義縣中埔鄉金蘭社區",
+                "Icon": "icon_house03.png"
+            },
+            {
+                "Id": 284,
+                "Subject": "漫遊三界:藥草飄香的工藝花園",
+                "UnitName": "社團法人三界埔文化發展協會",
+                "Lat": 23.4339942,
+                "Lng": 120.475478,
+                "CuName": "嘉義縣水上鄉三界埔社區",
+                "Icon": "icon_house01.png"
+            }
+        ]
+    },
+    {
+        "name": "據點_2",
+        "data": [
+            {
+                "Id": 285,
+                "Subject": "體會三生的人文共好之旅",
+                "UnitName": "高雄市寶來人文協會",
+                "Lat": 23.1055658,
+                "Lng": 120.6942759,
+                "CuName": "高雄市六龜區寶來社區(檨仔腳文化共享空間)",
+                "Icon": "icon_house01.png"
+            },
+            {
+                "Id": 265,
+                "Subject": "用工藝重建家園找回溫泉鄉的榮景-展現生命色彩的陶藝與草木染",
+                "UnitName": "高雄市寶來人文協會",
+                "Lat": 23.1055985,
+                "Lng": 120.6943702,
+                "CuName": "寶來社區",
+                "Icon": "icon_house03.png"
+            },
+            {
+                "Id": 239,
+                "Subject": "南方生活美學的邂逅- 山茶˙ 好陶˙ 手染布",
+                "UnitName": "高雄市寶來人文協會",
+                "Lat": 23.1055985,
+                "Lng": 120.6943702,
+                "CuName": "寶來社區",
+                "Icon": "icon_house01.png"
+            }
+        ]
+    }
+]

+ 1 - 0
src/assets/vue.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

+ 21 - 0
src/components/Carousels.vue

@@ -0,0 +1,21 @@
+<script setup>
+// import { defineProps } from "vue";
+const props = defineProps({
+  imgList: {
+    type: Array,
+    required: true,
+  },
+});
+</script>
+
+<template>
+  <v-carousel cycle height="400" width="500" hide-delimiter-background show-arrows="hover">
+    <v-carousel-item v-for="(slide, i) in imgList" :key="i">
+      <v-sheet :color="colors[i]" height="100%">
+        <div class="d-flex fill-height justify-center align-center">
+          <div class="text-h2">{{ slide }} Slide</div>
+        </div>
+      </v-sheet>
+    </v-carousel-item>
+  </v-carousel>
+</template>

+ 40 - 0
src/components/HelloWorld.vue

@@ -0,0 +1,40 @@
+<script setup>
+import { ref } from 'vue'
+
+defineProps({
+  msg: String,
+})
+
+const count = ref(0)
+</script>
+
+<template>
+  <h1>{{ msg }}</h1>
+
+  <div class="card">
+    <button type="button" @click="count++">count is {{ count }}</button>
+    <p>
+      Edit
+      <code>components/HelloWorld.vue</code> to test HMR
+    </p>
+  </div>
+
+  <p>
+    Check out
+    <a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
+      >create-vue</a
+    >, the official Vue + Vite starter
+  </p>
+  <p>
+    Install
+    <a href="https://github.com/vuejs/language-tools" target="_blank">Volar</a>
+    in your IDE for a better DX
+  </p>
+  <p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
+</template>
+
+<style scoped>
+.read-the-docs {
+  color: #888;
+}
+</style>

+ 102 - 0
src/components/Map.vue

@@ -0,0 +1,102 @@
+<script setup>
+import L from "leaflet";
+import "leaflet.markercluster";
+import "leaflet/dist/leaflet.css";
+import "leaflet.markercluster/dist/MarkerCluster.css";
+import "leaflet.markercluster/dist/MarkerCluster.Default.css";
+import { ref, reactive, onMounted, getCurrentInstance } from "vue";
+import axios from "axios";
+// import mapData from "@/assets/mapData.json";
+
+const mapContainer = ref(null);
+const location_id = ref("");
+const { proxy } = getCurrentInstance();
+
+onMounted(() => {
+  let mapData = reactive({
+    data: [],
+  });
+
+  (async function getData() {
+    try {
+      const response = await axios.get("https://cmm.ai:8088/api/get_school");
+      mapData.data = response.data.schools;
+      console.log("data", mapData.data);
+      console.log("response.data", response.data);
+
+      mapData.data.forEach((item) => {
+        let customIcon = L.icon({
+          iconUrl: getImageUrl('icon_house07.png'),
+          iconSize: [30, 50],
+        });
+
+        let marker = L.marker(new L.LatLng(item.Lat, item.Lng), {
+          icon: customIcon,
+        }).bindPopup(`<p>${item.location_name}</p>`);
+
+        // let marker = L.marker(new L.LatLng(item.Lat, item.Lng)).bindPopup(
+        //   `<p>${item.location_name}</p>`
+        // );
+
+        marker.on("mouseover", function () {
+          this.openPopup();
+        });
+
+        marker.on("mouseout", function () {
+          this.closePopup();
+        });
+
+        marker.on("click", function () {
+          location_id.value = item.location_id;
+          proxy.$emit("locationId", location_id.value);
+        });
+
+        markers.addLayer(marker);
+      });
+    } catch (error) {
+      console.error(error);
+    }
+  })();
+
+  // 創建地圖
+  const map = L.map(mapContainer.value, {
+    center: [23.611, 120.768],
+    zoom: 8,
+  });
+
+  // 加入圖層
+  L.tileLayer(
+    "https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}"
+  ).addTo(map);
+
+  // const popup = L.popup();
+  const markers = L.markerClusterGroup();
+
+  // 限制在台灣範圍
+  const taiwanBounds = L.latLngBounds(
+    L.latLng(20.68, 119.16),
+    L.latLng(25.56, 122.48)
+  );
+  map.setMaxBounds(taiwanBounds);
+
+  const getImageUrl = (name) => {
+    return new URL(`/src/assets/img/map-icon/${name}`, import.meta.url).href;
+  };
+
+  map.setMaxZoom(16); // 最大縮放級別
+  map.setMinZoom(8); // 最小縮放級別
+
+  map.addLayer(markers);
+});
+</script>
+
+<template>
+  <div id="map" class="mapContainer" ref="mapContainer"></div>
+</template>
+
+<style>
+#map {
+  width: 100%;
+  height: 100%;
+}
+</style>

+ 128 - 0
src/components/Navbar.vue

@@ -0,0 +1,128 @@
+<script setup>
+import { ref } from "vue";
+
+let menuShow = ref(false);
+
+function toggleMenu() {
+  menuShow.value = !menuShow.value;
+}
+</script>
+
+<template>
+  <div class="d-flex justify-space-between align-center navbar">
+    <router-link :to="'/'">
+      <img src="@/assets/img/logo.png" alt="" />
+    </router-link>
+    <ul class="menu d-md-flex align-center" :class="{ slider: menuShow }">
+      <li>最新消息</li>
+      <li>
+        <router-link :to="'/course-list'">探索課程</router-link>
+      </li>
+      <li>瀕危工藝</li>
+      <li>知識文章</li>
+      <li>
+        <router-link :to="'/login'">學員登入</router-link>
+      </li>
+      <li>EN</li>
+      <li>
+        <v-icon icon="mdi-magnify"></v-icon>
+      </li>
+      <li>
+        <v-icon icon="mdi-menu"></v-icon>
+      </li>
+    </ul>
+
+    <a href="javascript:;" class="icon" @click="toggleMenu()">
+      <v-icon icon="mdi-menu" class="mx-2"></v-icon>
+    </a>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+.navbar {
+  width: 90vw;
+  max-width: 1200px;
+  margin: 40px auto;
+  padding: 20px 50px 20px 30px;
+  border: 1px solid;
+  position: absolute;
+  z-index: 1000;
+  background: #fff;
+  top: 0;
+  left: 0;
+  right: 50%;
+
+  @media (max-width: 1200px) {
+    margin: 40px;
+    padding: 10px 20px 10px 10px;
+  }
+
+  img {
+    width: 100%;
+    max-width: 370px;
+    margin-top: 5px;
+  }
+
+  .menu {
+    list-style: none;
+    overflow: hidden;
+    transition: height 0.3s ease-in-out;
+
+    @media (max-width: 1200px) {
+      height: 0;
+      position: absolute;
+      background: #fff;
+      top: 80px;
+      left: 0;
+      right: 0;
+      z-index: 100;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+    }
+
+    &.slider {
+      height: 285px;
+    }
+
+    li {
+      margin-left: 30px;
+      font-weight: 400;
+
+      @media (max-width: 1200px) {
+        margin-left: 0;
+        border-bottom: 1px solid #f0f0f0;
+        font-weight: 500;
+        width: 100%;
+        text-align: center;
+        padding: 20px 0;
+      }
+      a {
+        color: #000;
+        text-decoration: none;
+        transition: all 0.3s;
+        &:hover {
+          opacity: 0.8;
+        }
+      }
+    }
+  }
+
+  .icon {
+    display: none;
+    transition: all 0.3s;
+
+    @media (max-width: 1200px) {
+      display: block;
+    }
+
+    &:hover {
+      opacity: 0.8;
+    }
+
+    .v-icon {
+      font-size: 2rem;
+    }
+  }
+}
+</style>

+ 118 - 0
src/components/NavbarSub.vue

@@ -0,0 +1,118 @@
+<script setup>
+import { ref } from "vue";
+
+let menuShow = ref(false);
+
+function toggleMenu() {
+  menuShow.value = !menuShow.value;
+}
+</script>
+
+<template>
+  <div class="d-flex justify-space-between align-center navbar">
+    <router-link :to="'/'">
+      <img src="@/assets/img/logo.png" alt="" />
+    </router-link>
+    <ul class="menu d-md-flex align-center" :class="{ slider: menuShow }">
+      <li>最新消息</li>
+      <li>
+        <router-link :to="'/course-list'">探索課程</router-link>
+      </li>
+      <li>瀕危工藝</li>
+      <li>知識文章</li>
+      <li>
+        <router-link :to="'/login'">學員登入</router-link>
+      </li>
+      <li>EN</li>
+      <li>
+        <v-icon icon="mdi-magnify"></v-icon>
+      </li>
+      <li>
+        <v-icon icon="mdi-menu"></v-icon>
+      </li>
+    </ul>
+
+    <a href="javascript:;" class="icon" @click="toggleMenu()">
+      <v-icon icon="mdi-menu" class="me-2"></v-icon>
+    </a>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+.navbar {
+  padding: 10px 50px 10px 30px;
+  border-top: 10px solid var(--main-color);
+
+  @media (max-width: 1200px) {
+    padding: 10px 20px 10px 10px;
+  }
+
+  img {
+    width: 100%;
+    max-width: 400px;
+    margin-top: 5px;
+  }
+
+  .menu {
+    list-style: none;
+    overflow: hidden;
+    transition: height 0.3s ease-in-out;
+
+    @media (max-width: 1200px) {
+      height: 0;
+      position: absolute;
+      background: #fff;
+      top: 80px;
+      left: 0;
+      right: 0;
+      z-index: 100;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+    }
+
+    &.slider {
+      height: 285px;
+    }
+
+    li {
+      margin-left: 30px;
+      font-weight: 500;
+
+      @media (max-width: 1200px) {
+        margin-left: 0;
+        border-bottom: 1px solid #f0f0f0;
+        font-weight: 500;
+        width: 100%;
+        text-align: center;
+        padding: 20px 0;
+      }
+      a {
+        color: #000;
+        text-decoration: none;
+        transition: all 0.3s;
+        &:hover {
+          opacity: 0.8;
+        }
+      }
+    }
+  }
+
+  .icon {
+    display: none;
+    transition: all 0.3s;
+
+    @media (max-width: 1200px) {
+      display: block;
+    }
+
+    &:hover {
+      opacity: 0.8;
+    }
+
+    .v-icon {
+      font-size: 2rem;
+    }
+  }
+}
+</style>

+ 17 - 0
src/main.js

@@ -0,0 +1,17 @@
+import { createApp } from 'vue'
+import '@/assets/css/style.css'
+import App from './App.vue'
+import router from "./router";
+import vuetify from './plugins/vuetify'
+
+const script = document.createElement('script');
+script.src = 'https://accounts.google.com/gsi/client';
+script.async = true;
+script.defer = true;
+document.head.appendChild(script);
+
+// 加載完成後再掛載 Vue
+script.onload = () => {
+    createApp(App).use(router).use(vuetify).mount('#app')
+};
+

+ 29 - 0
src/plugins/vuetify.js

@@ -0,0 +1,29 @@
+import 'vuetify/styles'
+import { createVuetify } from 'vuetify'
+import * as components from 'vuetify/components'
+import * as directives from 'vuetify/directives'
+import { aliases, mdi } from 'vuetify/iconsets/mdi'
+import '@mdi/font/css/materialdesignicons.css'
+
+export default createVuetify({
+  components,
+  directives,
+  icons: {
+    defaultSet: 'mdi',
+    aliases,
+    sets: {
+      mdi,
+    },
+  },
+  theme: {
+    themes: {
+      light: {
+        dark: false,
+        colors: {
+          primary: '#C39F68',
+          gray: '#888888'
+        },
+      },
+    },
+  },
+})

+ 38 - 0
src/router/index.js

@@ -0,0 +1,38 @@
+import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router';
+import { defineAsyncComponent } from 'vue';
+
+const home = defineAsyncComponent(() => import('@/views/Home.vue'));
+const login = defineAsyncComponent(() => import('@/views/Login.vue'));
+const courseList = defineAsyncComponent(() => import('@/views/CourseList.vue'));
+const courseDetail = defineAsyncComponent(() => import('@/views/CourseDetail.vue'));
+
+const routes = [
+  {
+    path: '/',
+    name: 'Home',
+    component: home,
+  },
+  {
+    path: '/login',
+    name: 'Login',
+    component: login,
+  },
+  {
+    path: '/course-list',
+    name: 'CourseList',
+    component: courseList
+  },
+  {
+    path: '/course-detail/:id',
+    name: 'CourseDetail',
+    component: courseDetail
+  },
+];
+
+const router = createRouter({
+  // history: createWebHashHistory(),
+  history: createWebHistory(import.meta.env.BASE_URL),
+  routes
+});
+
+export default router;

+ 91 - 0
src/views/CourseDetail.vue

@@ -0,0 +1,91 @@
+<script setup>
+import { reactive } from "vue";
+import { useRoute } from "vue-router";
+import axios from "axios";
+import Navbar from "@/components/NavbarSub.vue";
+
+const route = useRoute();
+const courseId = route.params.id; // 網址參數
+const course = reactive({
+  data: [],
+});
+
+// 取得課程資訊
+(async function getData() {
+  try {
+    const response = await axios.get(
+      `https://cmm.ai:8088/api/get_class_name?class_name_id=${courseId}`
+    );
+    course.data = response.data.classes[0];
+    console.log("courseData", course.data);
+  } catch (error) {
+    console.error(error);
+  }
+})();
+</script>
+
+<template>
+  <Navbar />
+
+  <v-container class="mt-16 course-detail">
+    <v-row>
+      <v-col cols="12">
+        <img :src="`https://cmm.ai/ntcri/${course.data.cover_img}`" alt="" />
+      </v-col>
+      <v-col cols="12">
+        <div class="h-100 d-flex flex-column">
+          <h2>{{ course.data.name }}</h2>
+          <section>
+            <h4 class="mb-5">課程簡介:</h4>
+            <p class="mb-5">
+              {{ course.data.introduction }}
+            </p>
+          </section>
+        </div>
+      </v-col>
+      <v-col cols="12">
+        <p>
+          {{ course.data.content }}
+        </p>
+      </v-col>
+    </v-row>
+  </v-container>
+</template>
+
+<style lang="scss">
+.course-detail {
+  width: 1000px;
+
+  @media (max-width: 991px) {
+    width: 100%;
+  }
+
+  img {
+    width: 100%;
+    height: 100%;
+    object-fit: cover;
+  }
+  h2 {
+    padding: 20px;
+    margin-bottom: 20px;
+    font-size: 22px;
+    font-weight: 500;
+    text-align: center;
+    color: #fff;
+    background-color: var(--main-color);
+    letter-spacing: 2px;
+  }
+  section {
+    height: 100%;
+    padding: 30px;
+    border: 2px solid var(--main-color);
+    h4 {
+      font-weight: normal;
+    }
+  }
+  p {
+    line-height: 30px;
+    white-space: pre-line;
+  }
+}
+</style>

+ 185 - 0
src/views/CourseList.vue

@@ -0,0 +1,185 @@
+<script setup>
+import { ref, reactive } from "vue";
+import axios from "axios";
+import moment from "moment";
+import Navbar from "@/components/NavbarSub.vue";
+
+let searchInput = ref("");
+let searchError = ref(false);
+const courseAll = reactive({
+  classes: [],
+});
+const courseData = reactive({
+  classes: [],
+});
+
+// 取得課程清單
+(async function getData() {
+  try {
+    const response = await axios.get("https://cmm.ai:8088/api/get_class_name");
+    console.log("response.data.classes", response.data.classes);
+    courseAll.classes = response.data.classes;
+    courseData.classes = response.data.classes;
+  } catch (error) {
+    console.error(error);
+  }
+})();
+
+// 課程搜尋
+async function search() {
+  searchError.value = false;
+  let keyword = searchInput.value;
+  if (keyword !== "") {
+    try {
+      const response = await axios.get(
+        `https://cmm.ai:8088/api/search_class_like?keyword=${keyword}`
+      );
+      if (response.data.classes.length !== 0) {
+        courseData.classes = response.data.classes;
+      } else {
+        searchError.value = true;
+      }
+    } catch (error) {
+      console.error(error);
+    }
+  } else {
+    courseData.classes = courseAll.classes;
+  }
+}
+</script>
+
+<template>
+  <Navbar />
+  <div class="banner">
+    <img src="@/assets/img/img-01.jpg" alt="" />
+    <h3>課程清單</h3>
+  </div>
+
+  <v-container class="my-16 pa-0">
+    <div
+      class="d-flex align-center ms-auto mb-16 search-btn"
+      style="max-width: 300px"
+    >
+      <v-text-field
+        label="課程搜尋"
+        v-model="searchInput"
+        variant="outlined"
+        density="compact"
+        hide-details
+        @keyup.enter="search()"
+      ></v-text-field>
+      <div v-if="searchError" class="d-flex justify-center error">
+        <v-icon color="primary" icon="mdi-alert" class="me-2"></v-icon>
+        沒有符合搜尋條件的項目
+      </div>
+      <button @click="search()" class="btn">
+        <img src="@/assets/img/icon/search.png" alt="" width="25" />
+      </button>
+    </div>
+    <v-row no-gutters>
+      <v-col
+        v-for="item in courseData.classes"
+        :key="item"
+        cols="12"
+        xl="3"
+        lg="4"
+        sm="6"
+        class="mb-10"
+      >
+        <v-card class="mx-5 h-100">
+          <!-- 傳遞課程 id -->
+          <router-link
+            :to="`/course-detail/${item.class_name_id}`"
+            class="cover-img"
+          >
+            <v-img
+              :src="`https://cmm.ai/ntcri/${item.cover_img}`"
+              height="220px"
+              cover
+            ></v-img>
+          </router-link>
+          <v-card-title class="font-weight-medium">
+            {{ item.name }}
+          </v-card-title>
+
+          <v-card-text>
+            <ul>
+              <li class="d-flex align-center">
+                <img src="@/assets/img/icon/date_icon.png" alt="" />
+                <p class="mb-0 ms-3">
+                  {{ moment(`${item.start_time}`).format("YYYY/MM/DD") }} -
+                  {{ moment(`${item.end_time}`).format("YYYY/MM/DD") }}
+                </p>
+              </li>
+              <li class="d-flex align-center mt-2">
+                <img src="@/assets/img/icon/location_icon.png" alt="" />
+                <p class="mb-0 ms-3">
+                  {{ item.location }}
+                </p>
+              </li>
+            </ul>
+          </v-card-text>
+        </v-card>
+      </v-col>
+    </v-row>
+  </v-container>
+</template>
+
+<style lang="scss" scoped>
+.banner {
+  position: relative;
+  img {
+    width: 100%;
+    height: 400px;
+    object-fit: cover;
+    object-position: 0 80%;
+    @media (max-width: 767px) {
+      object-position: center;
+    }
+  }
+  h3 {
+    display: inline-block;
+    padding: 30px 80px;
+    font-size: 26px;
+    font-weight: 500;
+    position: absolute;
+    z-index: 10;
+    top: 50%;
+    left: 50%;
+    letter-spacing: 1px;
+    transform: translate(-50%, -50%);
+    color: #fff;
+    background-color: var(--main-color);
+    @media (max-width: 575px) {
+      padding: 25px 50px;
+      font-size: 20px;
+    }
+  }
+}
+
+.search-btn {
+  position: relative;
+  .btn {
+    margin: 2px 10px 0;
+    transition: all 0.3s;
+    &:hover {
+      opacity: 0.8;
+    }
+  }
+  .error {
+    position: absolute;
+    bottom: -30px;
+  }
+}
+
+.cover-img {
+  display: block;
+  overflow: hidden;
+  .v-img {
+    transition: all 0.5s;
+    &:hover {
+      transform: scale(1.2);
+    }
+  }
+}
+</style>

+ 72 - 0
src/views/Home-back.vue

@@ -0,0 +1,72 @@
+<script setup>
+import { reactive } from "vue";
+import Navbar from "@/components/Navbar.vue";
+import Carousels from "@/components/Carousels.vue";
+import Map from "@/components/Map.vue";
+
+function handleScroll(event) {
+  const container = event.currentTarget;
+  console.log('event.deltaY',event.deltaY);
+  if (event.deltaY > 0) {
+    container.scrollLeft += 150;
+  } else {
+    container.scrollLeft -= 150;
+  }
+}
+
+let initialTouchPosition = null;
+
+function handleTouchStart(event) {
+  initialTouchPosition = event.touches[0].clientX;
+}
+
+function handleTouchMove(event) {
+  if (!initialTouchPosition) return;
+
+  const currentTouchPosition = event.touches[0].clientX;
+  const diff = currentTouchPosition - initialTouchPosition;
+
+  const container = document.querySelector('.main-container');
+  if (diff > 0) {
+    container.scrollLeft -= 150;
+  } else {
+    container.scrollLeft += 150;
+  }
+
+  initialTouchPosition = null;
+}
+</script>
+
+<template>
+  <!-- <Navbar /> -->
+  <div class="main-container" @wheel="handleScroll" @touchstart="handleTouchStart" @touchmove="handleTouchMove">
+    <Navbar />
+    <div class="d-flex content">
+      <img src="@/assets/img/banner-0615.webp" alt="" />
+      <div class="map">
+        <Map />
+      </div>
+    </div>
+    <!-- <Carousels :imgList="images" /> -->
+    <!-- <Map /> -->
+  </div>
+</template>
+
+<style lang="scss">
+.main-container {
+  width: 100%;
+  height: 100vh;
+  overflow-x: hidden;
+  overflow-y: hidden;
+  .content {
+    // width: 200%;
+    width: 3000px; // 圖片+地圖的寬度
+    height: 100%;
+    padding-top: 170px;
+    white-space: nowrap;
+    .map {
+      width: 1500px;
+    }
+  }
+}
+</style>

+ 284 - 0
src/views/Home.vue

@@ -0,0 +1,284 @@
+<script setup>
+import { ref, reactive, onMounted, onBeforeUnmount } from "vue";
+import axios from "axios";
+import Map from "@/components/Map.vue";
+import Navbar from "@/components/Navbar.vue";
+
+(async function getData() {
+  try {
+    const response = await axios.get("https://cmm.ai:8088/api/get_school");
+    console.log("response.data", response.data);
+  } catch (error) {
+    console.error(error);
+  }
+})();
+
+const scrollLeft = ref(0);
+let shouldAnimate = ref(false);
+let shouldFadeOut = ref(false);
+let scrollCount = 1;
+
+const handleScroll = () => {
+  const windowWidth = window.innerWidth; // 螢幕寬度
+  const windowHeight = window.innerHeight;
+  const documentHeight = document.body.scrollHeight - windowHeight;
+  const windowScrollable = windowWidth * scrollCount; // 可捲動寬度
+  const scrollTop = window.pageYOffset;
+  const steps = windowScrollable / documentHeight;
+  const goLeft = scrollTop * steps;
+
+  // console.log('windowWidth',windowWidth);
+  // console.log('windowScrollable',windowScrollable);
+
+  if (scrollTop > 0) {
+    shouldAnimate.value = true;
+    shouldFadeOut.value = false;
+  } else {
+    shouldFadeOut.value = true;
+  }
+
+  scrollLeft.value = goLeft;
+};
+
+let innerWidth = ref("");
+const handleResize = () => {
+  innerWidth.value = window.innerWidth;
+  console.log(innerWidth.value);
+  if (window.innerWidth <= 991) {
+    scrollCount = 2;
+  } else {
+    scrollCount = 1;
+  }
+};
+
+onMounted(() => {
+  handleResize(); // 初始化檢查一次
+  window.addEventListener("resize", handleResize);
+});
+
+let classes = reactive({
+  data: [],
+});
+
+// 取得該據點所有課程
+const getClassList = async (locationId) => {
+  console.log("locationId", locationId);
+
+  try {
+    const response = await axios.get(
+      `https://cmm.ai:8088/api/get_class_name?location_id=${locationId}`
+    );
+    console.log("response", response);
+    classes.data = response.data.classes;
+    console.log("classes.data", classes.data);
+  } catch (error) {
+    console.log("error", error);
+  }
+};
+
+onMounted(() => {
+  window.addEventListener("scroll", handleScroll);
+});
+
+onBeforeUnmount(() => {
+  window.removeEventListener("scroll", handleScroll);
+});
+
+const previous = () => {
+  window.scrollTo({ top: 0, behavior: "smooth" });
+};
+</script>
+
+<template>
+  <!-- <Navbar /> -->
+  <div class="home-container">
+    <div class="wrapper">
+      <div>
+        <!-- <Navbar /> -->
+      </div>
+      <div
+        class="scrollable"
+        :style="{ transform: `translateX(-${scrollLeft}px)` }"
+      >
+        <section class="main-block">
+          <Navbar />
+          <div class="img-item">
+            <img src="@/assets/img/banner-0615.webp" alt="" />
+            <p
+              v-show="shouldAnimate"
+              :class="{
+                animate__animated: shouldAnimate,
+                animate__fadeInRight: shouldAnimate && !shouldFadeOut,
+                animate__fadeOutRight: shouldAnimate && shouldFadeOut,
+              }"
+            >
+              臺灣工藝學校 <br />
+              以佈局具國際視野之工藝學習共享平台為目標,藉由「工藝學校」的主體概念,推動臺灣工藝學校全球學習平台,以共享、友善、全人、全民的終身工藝手作台進行人才、課程、知識、教材之工藝資源嫁接媒合與內容設計,以在地、就近、線上、線下等多元方式提供不同型態之學習體驗內容及選擇。
+            </p>
+          </div>
+        </section>
+        <section class="map-block">
+          <div class="back-btn">
+            <p @click="previous()">回到首頁</p>
+          </div>
+          <div class="content">
+            <div class="map">
+              <Map @locationId="getClassList" />
+            </div>
+            <v-list lines="three" class="list">
+              <v-list-item v-for="item in classes.data" :key="item.id">
+                <div class="d-flex align-center">
+                  <img :src="`https://cmm.ai/ntcri/${item.cover_img}`" alt="" />
+                  <section>
+                    <h2>{{ item.name }}</h2>
+                    <p>主辦單位:{{ item.organizer }}</p>
+                    <p>據點名稱:{{ item.school }}</p>
+                  </section>
+                </div>
+              </v-list-item>
+            </v-list>
+          </div>
+        </section>
+      </div>
+    </div>
+  </div>
+</template>
+
+<style lang="scss">
+@import "animate.css/animate.min.css";
+
+.home-container {
+  height: 150vw; // 捲軸高度
+  overflow: hidden;
+  @media (max-width: 991px) {
+    height: 300vw;
+  }
+
+  .wrapper {
+    overflow: hidden;
+    position: fixed;
+  }
+
+  .scrollable {
+    height: 100vh;
+    display: flex;
+    align-items: end;
+    .img-item {
+      width: 100%;
+      height: 100%;
+      position: relative;
+      img {
+        width: 100%;
+        height: 100%;
+        object-fit: cover;
+        object-position: top;
+      }
+      p {
+        width: 600px;
+        top: 170px;
+        right: 7.5%;
+        position: absolute;
+        z-index: 100;
+        font-size: 24px;
+        line-height: 38px;
+        color: #fff;
+        text-shadow: 2px 2px 5px #333;
+
+        @media (max-width: 1700px) {
+          width: 33vw;
+          top: 140px;
+          right: 6%;
+        }
+        @media (max-width: 767px) {
+          display: none !important;
+        }
+      }
+    }
+    &::after {
+      content: "";
+      display: table;
+      clear: both;
+    }
+
+    .main-block,
+    .map-block {
+      width: 100vw;
+      display: flex;
+      align-items: center;
+      @media (max-width: 1200px) {
+        height: 84vh;
+      }
+      @media (max-width: 991px) {
+        width: 150vw;
+      }
+    }
+
+    .main-block {
+      height: 82vh;
+    }
+
+    .map-block {
+      height: 100vh;
+      .content {
+        width: 100%;
+        height: 100%;
+        display: flex;
+        .map,
+        .list {
+          @media (max-width: 991px) {
+            width: 100%;
+          }
+        }
+        .map {
+          width: 60%;
+        }
+        .list {
+          width: 40%;
+          img {
+            width: 200px;
+            margin-right: 20px;
+            border-radius: 5px;
+            box-shadow: 2px 2px 4px #aaaaaa;
+          }
+          h2 {
+            font-size: 18px;
+          }
+          h2,
+          p {
+            line-height: 30px;
+          }
+          .v-list-item {
+            padding: 30px 20px;
+            border-bottom: 1px solid #cccccc;
+            .v-list-item__content {
+              overflow: initial !important;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  .back-btn {
+    height: 18vh;
+    position: absolute;
+    // top: 0;
+    // right: 80px;
+    top: -4%;
+    right: 22%;
+    z-index: 1000;
+    display: flex;
+    align-items: center;
+    @media (max-width: 1200px) {
+      height: 16vh;
+    }
+    p {
+      cursor: pointer;
+      transition: all 0.3s;
+      &:hover {
+        opacity: 0.8;
+      }
+    }
+  }
+}
+</style>

+ 72 - 0
src/views/Login.vue

@@ -0,0 +1,72 @@
+<script setup>
+import { ref, onMounted } from "vue";
+import axios from "axios";
+import Navbar from "@/components/NavbarSub.vue";
+
+const handleSignIn = async (response) => {
+  const credential = response.credential;
+  const profile = JSON.parse(
+    decodeURIComponent(
+      escape(
+        window.atob(
+          credential.split(".")[1].replace(/-/g, "+").replace(/_/g, "/")
+        )
+      )
+    )
+  );
+
+  console.log("profile", profile);
+
+  const target = document.getElementById("GOOGLE_STATUS_1");
+  const html = `
+    ID: ${profile.sub}<br/>
+    會員暱稱: ${profile.name}<br/>
+    會員頭像: ${profile.picture}<br/>
+    會員 email: ${profile.email}<br/>
+  `;
+  target.innerHTML = html;
+
+  let data = {
+    username: profile.name,
+    password: "googleLogin",
+    email: profile.email,
+  };
+
+  try {
+    const response = await axios.post(
+      "https://cmm.ai:8088/api/login/google/access-token",
+      data
+    );
+    console.log("response", response);
+  } catch (error) {
+    console.error(error);
+  }
+};
+
+onMounted(() => {
+  const script = document.createElement("script");
+  script.src = "https://accounts.google.com/gsi/client";
+  script.async = true;
+  script.defer = true;
+  document.head.appendChild(script);
+
+  window.onSignIn1 = handleSignIn;
+});
+</script>
+
+<template>
+  <Navbar />
+  <div>Login</div>
+  <div style="width: 200px; margin: 20px 0">
+    <div
+      id="g_id_onload"
+      data-client_id="626437744072-q6djn202411is5vdk2v0tu8fo7n07qr0.apps.googleusercontent.com"
+      data-callback="onSignIn1"
+    ></div>
+    <div class="g_id_signin" data-type="standard"></div>
+
+    <p class="mt-3">目前狀態:</p>
+
+    <span id="GOOGLE_STATUS_1"></span>
+  </div>
+</template>

+ 22 - 0
vite.config.js

@@ -0,0 +1,22 @@
+import { defineConfig } from 'vite';
+import { resolve } from 'path';
+import vue from '@vitejs/plugin-vue';
+
+export default defineConfig({
+  base: '/ntcri/',
+  plugins: [vue()],
+  resolve: {
+    alias: {
+      '@': resolve(__dirname, 'src'),
+    }
+  },
+  build: {
+    rollupOptions: {
+      output: {
+        entryFileNames: `assets/[name].js`,
+        chunkFileNames: `assets/[name].js`,
+        assetFileNames: `assets/[name].[ext]`
+      }
+    },
+  }
+})