diff --git a/plugins/exchange-rates/.gitignore b/plugins/exchange-rates/.gitignore new file mode 100644 index 000000000..f06235c46 --- /dev/null +++ b/plugins/exchange-rates/.gitignore @@ -0,0 +1,2 @@ +node_modules +dist diff --git a/plugins/exchange-rates/CHANGELOG.md b/plugins/exchange-rates/CHANGELOG.md new file mode 100644 index 000000000..9c6161a63 --- /dev/null +++ b/plugins/exchange-rates/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +## 1.0.0 - 2026-11-11 + +### Added + +- 以單一基準貨幣換算比較清單中的多種貨幣。金額在確認後於本機計算。 +- 匯率來自 Frankfurter v2 的日更參考價,以歐元為樞紐,一次取回全表。 +- 趨勢層顯示較上一個觀測日的漲跌,以及近 30 個觀測日的折線。 +- 介面依系統語言使用繁體中文或英文。 +- 國旗使用隨插件附帶的 SVG,執行時不向旗幟網站請求圖片。 +- 插件圖示使用 SVG Repo 上標為 CC0 的歐元換匯圖。 +- 比較列可由序號到符號長按拖曳排序。 +- 序號到符號五欄等寬,折算金額占用剩餘寬度。 diff --git a/plugins/exchange-rates/LICENSE b/plugins/exchange-rates/LICENSE new file mode 100644 index 000000000..b425a7d50 --- /dev/null +++ b/plugins/exchange-rates/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Kazma + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/plugins/exchange-rates/README.md b/plugins/exchange-rates/README.md new file mode 100644 index 000000000..a4945e1e2 --- /dev/null +++ b/plugins/exchange-rates/README.md @@ -0,0 +1,42 @@ +# 匯率換算 + +ZTools 插件。識別碼 `exchange-rates`,顯示名稱「匯率換算」,作者 Kazma258。 + +在搜尋框輸入「匯率」「貨幣」「錢」或 `money` 即可打開。選定一筆基準金額後,比較清單裡的貨幣會一起換算。 + +## 功能 + +- 基準列與比較列的金額都可以修改。在比較列確認一筆金額時,該貨幣成為新的基準,並仍留在比較列。 +- 小數位數從 0 到 11。趨勢層的匯率固定顯示 6 位小數。 +- 匯率資料為 Frankfurter v2 的日更中間價。更新時間顯示資料裡的觀測日。 +- 深色模式第一次跟隨 ZTools 主題,手動切換後記住選擇。 +- 已廢棄貨幣的勾選只影響選擇清單,不移除已經加入的列。 + +## 開發 + +需要 Node.js 20 或更新版本。 + +```bash +npm install +npm run dev +npm run check +npm run build +``` + +`npm run dev` 會在 `http://localhost:5173` 提供介面。ZTools 開發模式讀取根目錄 `plugin.json` 的 `development.main`。 + +`npm run build` 的成品在 `dist/`。根目錄 `plugin.json` 的 `main` 指向 `dist/index.html`,插件中心的打包腳本會把這個目錄打成發布包。`dist/plugin.json` 裡的入口則是 `index.html`、`preload.js` 和 `logo.png`。 + +## 授權 + +MIT。見 [LICENSE](LICENSE)。 + +## 發布前仍待補充 + +這些項目需要你本人完成,這次沒有代做: + +- 在本機 ZTools 客戶端載入並走一次主要功能。 +- 準備截圖或 GIF,放到發布說明。 +- 安裝 `@ztools-center/plugin-cli` 後,在乾淨的工作區執行 `ztools publish`。 +- 到 Pull Request 勾選自檢清單,並把 Draft 改成 Ready for review。 +- 若要替換現在的純色 `logo.png`,換成你的圖檔即可。 diff --git a/plugins/exchange-rates/index.html b/plugins/exchange-rates/index.html new file mode 100644 index 000000000..6f31f7298 --- /dev/null +++ b/plugins/exchange-rates/index.html @@ -0,0 +1,12 @@ + + + + + + 匯率換算 + + +
+ + + diff --git a/plugins/exchange-rates/package-lock.json b/plugins/exchange-rates/package-lock.json new file mode 100644 index 000000000..427afbf4c --- /dev/null +++ b/plugins/exchange-rates/package-lock.json @@ -0,0 +1,1391 @@ +{ + "name": "exchange-rates", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "exchange-rates", + "version": "1.0.0", + "dependencies": { + "vue": "^3.5.13" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.2.1", + "typescript": "^5.7.3", + "vite": "^6.0.7" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.13", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.13.tgz", + "integrity": "sha512-fWegr+WsEsiMVW4KUNdIIzzMTZSzNiqhy0//6+2MRi2d5NFNsL/AYwBQW8eBnRbTBVRnDVzjaJEUqKaCWjMMdQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.13.tgz", + "integrity": "sha512-fJM50YYjlTiBhgdkGmC1tBpv+FMAyo4annf2X6Aks+0yRlaiVkYW/3f07xAfVVkYIoZ9fFZp+mEThUFnuybhkQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.11" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.11", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.11.tgz", + "integrity": "sha512-WCsemW40Cpc6gouC1SrY6PBaZ+oLRlEVY9XBvZBI7il/HyUrb2nJ505wE1MHEFyDZNnrWDEuy4jL50WVHfTTSQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.11", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.68.2.tgz", + "integrity": "sha512-ItKrNMkEL3hy85kLBXwB0+M6CWWVI8vr7RV+Eb7oDlQIMXLaiEhGfdaj5jAUadYn2v3nwzAhIRl/nLyjAqV9vQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.68.2.tgz", + "integrity": "sha512-dCkT8BMPLo6X6GCFVtuzrnr981PpJSeK4ZO/d/mZdJ/ao61Qa1Usd/OHIQ69MQgw4qQclR/X6uRRUONiWwD8cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-x64": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-x64/-/rollup-android-x64-4.68.2.tgz", + "integrity": "sha512-p2jkKiscqQOGmyL6qu+KvJctvBc3SQTd+Xi2lQYn5QvFLEWz+QI8Z9iI+xcIjez6vKRsSnWP56Y3Ep7g3Stiug==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.68.2.tgz", + "integrity": "sha512-aVIfOteo5zoX8aL742H/S3QsyN6aokNYjdzrLnQBKxgRVoh4cibTErpi61RzSmrv2hBzDB1i751hwwdc8QK0vQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.68.2.tgz", + "integrity": "sha512-+Wuf4TFTHiE/WnjKgH1SkNf/9D5ddoed1UR0p3jxjNAGemdeeQRL+r1bJ1LlZyha0VKDBYLB2U/a9a9KlSw4Kw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.68.2.tgz", + "integrity": "sha512-feKK2dc13j/6D9mAp7XKhBM/VUqn0N/xRgP6rT7/mdRVVJUaeZ4lsJ9hN90aTi0k3OD+mkjlcN01vQ96Ac9VzQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.68.2.tgz", + "integrity": "sha512-s1oGXPGX1PNqdi9TLWD+RwtPEYf/BOTbCcq4anJBqNbzyjucti86ldYH37eKvsyTP7Bl5/Hf8XmbIxCz/iafTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.68.2.tgz", + "integrity": "sha512-ksR3ZmzHrm6HOUP8UlDBy5hNTcG9cEIa3EyGnxn5BjorLRjBh4ucxhwjwwVEm0dqcIN4Egc/XjDUiPQwN1ic9A==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.68.2.tgz", + "integrity": "sha512-STZVVBM35wULVsQah0xKfCBQMPpHliOfjnRaUNT35jrbpfapUrD8ix6Yhl7tLHW0xQSWotXSSghjUi/DclwRSw==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.68.2.tgz", + "integrity": "sha512-Fm/GPC2R0zlJYQIp9aY9L1lO2z+P+UrcvXG6fhubfo/BbMOLZlLXshnbECOTqr3pxfZFb6nNn0QgDETDtrX7TQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.68.2.tgz", + "integrity": "sha512-VoqlckWcwNF3WqsUkLZg91zYFgBvrC37Lc5e8AU+BKdCUFDMPoN0Rsin/LvF+rBVF527gWo5KT0oHkaAZaL1GA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.68.2.tgz", + "integrity": "sha512-Zr8X/SUf7Jjwxt99BqPDF/Wq+sz4oUBIP6HBaFQWwb8wO1nV6LBIpD6jB9cMybLho93Z+B8rrN0uXEL6oNOUJQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.68.2.tgz", + "integrity": "sha512-2EhrYEJNXIyhSZESwm/kCke1tiH7QAPOU3v3MsLM9J+Nfn2QCDe/pGROUAvYFK0BL2MEbzNgfrqrbnE5CFXkLw==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.68.2.tgz", + "integrity": "sha512-IC0dYuEQknw0m2FYBNBKlbrgBJBH5OMRiaRfCc4CFSpYnmDnqTpNSv+TgX+loezGTdRjBNZuYZi3t+Oc5NxNYg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.68.2.tgz", + "integrity": "sha512-Zlzm6fGuDvtAqMEl071/g17vxq6u2Y2v/rON/gDY4NvzWLJ41BGAlwhF3QuAzwq05zIPo4LYzdqwhx3oisYCUw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.68.2.tgz", + "integrity": "sha512-KhEpYRtHZ3Kj4shavjXeH+K1bQlA6UbP6MJ45rMPF/11JlZb1SRNLeuWCdigUEoMMaFO4+LwwcS+ew1SoLJu/g==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.68.2.tgz", + "integrity": "sha512-LPn9qvPsM/Ofd6Ekq3im6nB8Tk1ruJhTd3x/2bJkTR8m/XTsfxA+EU0RJ23WJqgJg123kitHAqbEK7B4cL1uPg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.68.2.tgz", + "integrity": "sha512-Q1+E+pzSP+FiXuIZtxKR+pK7l2KQ9gsM+VaFPv1LR277kp7l61crG46WGLKLLay3Js5cvyU9Keqdzxa1EcFO+g==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.68.2.tgz", + "integrity": "sha512-3Btp4Lca/WzsmbaKu9Lh9d/XwyRDIegd/5khRBusHGw/Ll6SoF5Shn63OrjPdkLcpNi2PGDApXzNmxriRxGYjA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.68.2.tgz", + "integrity": "sha512-5SKVaUiVs18+DGBnpg0mORGxgq/0udczngGxV/vf2nvK1djqpOKIxY/+8rBWxAbWGRE4RnnwxWabDwJN3pCwIQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.68.2.tgz", + "integrity": "sha512-KBpm48/lESsHgWd+dRlcy18APBYhXU4Jb6VlJoqbpWNwfpztFXwP22qVv9aHd3k1quSrmLeJwYLc7rpQ+BFZrw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.68.2.tgz", + "integrity": "sha512-o0D0bfRW8QGA1Ph6OzqVHMq5LRu1xkr1iM7qQIXUSFuR60ddXeDhN9UR4bUBPLYsrT46sZwwgQa51TWtBV3r5g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.68.2.tgz", + "integrity": "sha512-r17kcu5kmd6WQwokYmfBnfwM/icureCWCPjpJVALcrSv5Lfy6Ggk9azxXor6hILhCHbc/4IfEiv+L5RXaOHinA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.68.2.tgz", + "integrity": "sha512-yUtOqq7ZrQoZ3WiHSR6QGTdOl4YgMHqXIYSBYU6siIcC0YF0pEwx7aGsPTm2mRwrmW6SMJkxzEdFm6wqXpmbNw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.68.2.tgz", + "integrity": "sha512-5IYoWxQGo5WECbJbImIf2w33uCHJNLv4o/FQtSyeYDed7AC6zx84NsEcGYccoI2geDEYkrxUXcsYK/6EhwVSIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.68.2.tgz", + "integrity": "sha512-ee+c14ggUiM7lg4PtCjSBYU9O9dHp4FFespRnd5yj7SilUBJCL3x3aHlB+sIqbGjcPo3pEyODASnfKJuZ26YBw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.10.tgz", + "integrity": "sha512-lTyOMnOcmRBzdCv6/4zUZCrEhV0xrqQiUZBZtVcbmLHBXKLnN8q89v/wKRF/Q0HbwVsqbIG3o5HDoFl9sduM+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitejs/plugin-vue": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz", + "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.45.tgz", + "integrity": "sha512-XGHJrM6ufZARAc/w+tyOswStw9tdKiqCKBScI4gGaNxD+aaGu/HQWgKJ+JItjRLPqenQ7iE7G8AJC7T5ew1p+g==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.12", + "@vue/shared": "3.5.45", + "entities": "^7.0.1", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.2" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.45.tgz", + "integrity": "sha512-LbP2d19GSOYGPmvMBBCVJVlv7TKtjM1Cfeyu3cYia720pknZP+1cLX7H5MVatvruT6MuJhiPuNbQBW/MDn/EwA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.45", + "@vue/shared": "3.5.45" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.45.tgz", + "integrity": "sha512-MKFjb2UX0M/l/jhfzqMLrI8VM4pfvFKG3pqFZkSZFHRLtNld/O4RtUPZFWSwhro/14qP88UQEkWzHxAZAQ0tsw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.12", + "@vue/compiler-core": "3.5.45", + "@vue/compiler-dom": "3.5.45", + "@vue/compiler-ssr": "3.5.45", + "@vue/shared": "3.5.45", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.21", + "postcss": "^8.5.32", + "source-map-js": "^1.2.2" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.45.tgz", + "integrity": "sha512-RF5sbZOfYz5AK00tOJUn2PwFXR2fS1u2HVzI8D9VF9rGAFxuGBqg2bB1kJ3ZHMprqSltXnT9MZE1IsqjSM8oew==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.45", + "@vue/shared": "3.5.45" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.45", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.45.tgz", + "integrity": "sha512-WqkyubNWpI4OYBOipSrjIssMdJO8K1i9Zts/Wm8Er10/0msOEwCyWWWvZnAI7WW3kQsTong6DJp8Cbb+vd4cPA==", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.45" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.45", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.45.tgz", + "integrity": "sha512-bzIO3+FABjpj85uIKSc+Qnj36/sxDNI3tcH9i6w6xKA1k6e0ejv0G0jMCfeJBvK3yGL5XbJ3DMZj+ClqyCHFYw==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.45", + "@vue/shared": "3.5.45" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.45", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.45.tgz", + "integrity": "sha512-ZvRTFMDgfqTDYWvJfoVpQTJx1RN5M6l7Pyd6wfdY2NaXzbPQVh9ezeQYFbNPP6bIcRVn2SqSSR25N/jSW69BFw==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.45", + "@vue/runtime-core": "3.5.45", + "@vue/shared": "3.5.45", + "csstype": "^3.2.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.45", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.45.tgz", + "integrity": "sha512-1fNXUHhhsWf4EVL4XixbGBU5mKdiIXJAB82feHRTyPPo6ZUEYWIJuEeUl3mVV6QDBp50HJOX4obLhxYXlrjrzA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.45", + "@vue/runtime-dom": "3.5.45", + "@vue/shared": "3.5.45" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.45", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.45.tgz", + "integrity": "sha512-ue9fgHmVNPlP7iW3+cxoBX/Cnlw53dHlVSw0JKGY6z1lObg8pHoj928M2nzG4/yVsMZ3NaRZ2s2z61uC16NDwQ==", + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" + }, + "node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/nanoid": { + "version": "3.3.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz", + "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.32.tgz", + "integrity": "sha512-LJlKCCAUFKOuZxipUdYw1NzIITEsPcgyOG9LkvRJvuKj/bRzbuRY0ARXvL0pWGpsZvn8jku+LMep2eU0seHp8g==", + "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" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.20", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "4.68.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.68.2.tgz", + "integrity": "sha512-xzt45rKOxzEuqjTdkGTIEaePcq9xRELlFI1uoazlKap8T6bENJkONSCfhK51P6XFTixa4rosPcDHihSdduXndQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.10" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.68.2", + "@rollup/rollup-android-arm64": "4.68.2", + "@rollup/rollup-android-x64": "4.68.2", + "@rollup/rollup-darwin-arm64": "4.68.2", + "@rollup/rollup-darwin-x64": "4.68.2", + "@rollup/rollup-freebsd-arm64": "4.68.2", + "@rollup/rollup-freebsd-x64": "4.68.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.68.2", + "@rollup/rollup-linux-arm-musleabihf": "4.68.2", + "@rollup/rollup-linux-arm64-gnu": "4.68.2", + "@rollup/rollup-linux-arm64-musl": "4.68.2", + "@rollup/rollup-linux-loong64-gnu": "4.68.2", + "@rollup/rollup-linux-loong64-musl": "4.68.2", + "@rollup/rollup-linux-ppc64-gnu": "4.68.2", + "@rollup/rollup-linux-ppc64-musl": "4.68.2", + "@rollup/rollup-linux-riscv64-gnu": "4.68.2", + "@rollup/rollup-linux-riscv64-musl": "4.68.2", + "@rollup/rollup-linux-s390x-gnu": "4.68.2", + "@rollup/rollup-linux-x64-gnu": "4.68.2", + "@rollup/rollup-linux-x64-musl": "4.68.2", + "@rollup/rollup-openbsd-x64": "4.68.2", + "@rollup/rollup-openharmony-arm64": "4.68.2", + "@rollup/rollup-win32-arm64-msvc": "4.68.2", + "@rollup/rollup-win32-ia32-msvc": "4.68.2", + "@rollup/rollup-win32-x64-gnu": "4.68.2", + "@rollup/rollup-win32-x64-msvc": "4.68.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/vite": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.6.tgz", + "integrity": "sha512-RtsraAwEG68idOA6iUOoIpOlcSKROnf815aIq9qHTSrDNpLoBrBa12suyfcEd8qn0xwOVQI1Yhm1GbmTjF600A==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vue": { + "version": "3.5.45", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.45.tgz", + "integrity": "sha512-3cvsib8m9c0vB24+MDKsgcW4+Da4xaBl9Z/5Tbm2pmSIsRPxcil4cdXjXlVsmJ2g64XJo5h+IRd7rsdGT9pZaw==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.45", + "@vue/compiler-sfc": "3.5.45", + "@vue/runtime-dom": "3.5.45", + "@vue/server-renderer": "3.5.45", + "@vue/shared": "3.5.45" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + } + } +} diff --git a/plugins/exchange-rates/package.json b/plugins/exchange-rates/package.json new file mode 100644 index 000000000..a2a4bfb9f --- /dev/null +++ b/plugins/exchange-rates/package.json @@ -0,0 +1,25 @@ +{ + "name": "exchange-rates", + "version": "1.0.0", + "private": true, + "description": "把一筆基準金額換算成多種貨幣,並查看近 30 個觀測日的變動。", + "author": "Kazma258", + "license": "MIT", + "type": "module", + "engines": { + "node": ">=20" + }, + "scripts": { + "dev": "vite", + "build": "vite build", + "check": "node --experimental-strip-types src/convert.check.mjs" + }, + "dependencies": { + "vue": "^3.5.13" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.2.1", + "typescript": "^5.7.3", + "vite": "^6.0.7" + } +} diff --git a/plugins/exchange-rates/plugin.json b/plugins/exchange-rates/plugin.json new file mode 100644 index 000000000..325a937d9 --- /dev/null +++ b/plugins/exchange-rates/plugin.json @@ -0,0 +1,20 @@ +{ + "name": "exchange-rates", + "title": "匯率換算", + "description": "把一筆基準金額換算成多種貨幣,並查看近 30 個觀測日的變動。", + "author": "Kazma258", + "version": "1.0.0", + "main": "dist/index.html", + "logo": "public/logo.png", + "preload": "public/preload.js", + "development": { + "main": "http://localhost:5173" + }, + "features": [ + { + "code": "convert", + "explain": "一對多匯率換算", + "cmds": ["匯率", "貨幣", "錢", "money"] + } + ] +} diff --git a/plugins/exchange-rates/public/flags/ad.svg b/plugins/exchange-rates/public/flags/ad.svg new file mode 100644 index 000000000..655fc8a22 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ad.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ae.svg b/plugins/exchange-rates/public/flags/ae.svg new file mode 100644 index 000000000..92be1ebdd --- /dev/null +++ b/plugins/exchange-rates/public/flags/ae.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/af.svg b/plugins/exchange-rates/public/flags/af.svg new file mode 100644 index 000000000..d9e49f9ac --- /dev/null +++ b/plugins/exchange-rates/public/flags/af.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ag.svg b/plugins/exchange-rates/public/flags/ag.svg new file mode 100644 index 000000000..f60599e96 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ag.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ai.svg b/plugins/exchange-rates/public/flags/ai.svg new file mode 100644 index 000000000..429ce3bf1 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ai.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/al.svg b/plugins/exchange-rates/public/flags/al.svg new file mode 100644 index 000000000..f8d555026 --- /dev/null +++ b/plugins/exchange-rates/public/flags/al.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/am.svg b/plugins/exchange-rates/public/flags/am.svg new file mode 100644 index 000000000..1e74af0f0 --- /dev/null +++ b/plugins/exchange-rates/public/flags/am.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ao.svg b/plugins/exchange-rates/public/flags/ao.svg new file mode 100644 index 000000000..6384b4463 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ao.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/aq.svg b/plugins/exchange-rates/public/flags/aq.svg new file mode 100644 index 000000000..cef722d39 --- /dev/null +++ b/plugins/exchange-rates/public/flags/aq.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ar.svg b/plugins/exchange-rates/public/flags/ar.svg new file mode 100644 index 000000000..db54af597 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/as.svg b/plugins/exchange-rates/public/flags/as.svg new file mode 100644 index 000000000..4d6661559 --- /dev/null +++ b/plugins/exchange-rates/public/flags/as.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/at.svg b/plugins/exchange-rates/public/flags/at.svg new file mode 100644 index 000000000..1229a26cf --- /dev/null +++ b/plugins/exchange-rates/public/flags/at.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/au.svg b/plugins/exchange-rates/public/flags/au.svg new file mode 100644 index 000000000..38a47dee0 --- /dev/null +++ b/plugins/exchange-rates/public/flags/au.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/aw.svg b/plugins/exchange-rates/public/flags/aw.svg new file mode 100644 index 000000000..a80f4e795 --- /dev/null +++ b/plugins/exchange-rates/public/flags/aw.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ax.svg b/plugins/exchange-rates/public/flags/ax.svg new file mode 100644 index 000000000..3af6b6eb3 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ax.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/az.svg b/plugins/exchange-rates/public/flags/az.svg new file mode 100644 index 000000000..f88d08033 --- /dev/null +++ b/plugins/exchange-rates/public/flags/az.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ba.svg b/plugins/exchange-rates/public/flags/ba.svg new file mode 100644 index 000000000..177c78d3a --- /dev/null +++ b/plugins/exchange-rates/public/flags/ba.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/bb.svg b/plugins/exchange-rates/public/flags/bb.svg new file mode 100644 index 000000000..820297aa6 --- /dev/null +++ b/plugins/exchange-rates/public/flags/bb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/bd.svg b/plugins/exchange-rates/public/flags/bd.svg new file mode 100644 index 000000000..8cf230bfa --- /dev/null +++ b/plugins/exchange-rates/public/flags/bd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/be.svg b/plugins/exchange-rates/public/flags/be.svg new file mode 100644 index 000000000..107b639af --- /dev/null +++ b/plugins/exchange-rates/public/flags/be.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/bf.svg b/plugins/exchange-rates/public/flags/bf.svg new file mode 100644 index 000000000..3a649ae80 --- /dev/null +++ b/plugins/exchange-rates/public/flags/bf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/bg.svg b/plugins/exchange-rates/public/flags/bg.svg new file mode 100644 index 000000000..541c9e535 --- /dev/null +++ b/plugins/exchange-rates/public/flags/bg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/bh.svg b/plugins/exchange-rates/public/flags/bh.svg new file mode 100644 index 000000000..5ec75602a --- /dev/null +++ b/plugins/exchange-rates/public/flags/bh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/bi.svg b/plugins/exchange-rates/public/flags/bi.svg new file mode 100644 index 000000000..2b796ab0a --- /dev/null +++ b/plugins/exchange-rates/public/flags/bi.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/bj.svg b/plugins/exchange-rates/public/flags/bj.svg new file mode 100644 index 000000000..b8d1bd2c4 --- /dev/null +++ b/plugins/exchange-rates/public/flags/bj.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/bl.svg b/plugins/exchange-rates/public/flags/bl.svg new file mode 100644 index 000000000..64cc17f8b --- /dev/null +++ b/plugins/exchange-rates/public/flags/bl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/bm.svg b/plugins/exchange-rates/public/flags/bm.svg new file mode 100644 index 000000000..1059eaed1 --- /dev/null +++ b/plugins/exchange-rates/public/flags/bm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/bn.svg b/plugins/exchange-rates/public/flags/bn.svg new file mode 100644 index 000000000..98ce7f884 --- /dev/null +++ b/plugins/exchange-rates/public/flags/bn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/bo.svg b/plugins/exchange-rates/public/flags/bo.svg new file mode 100644 index 000000000..3bf24b0ac --- /dev/null +++ b/plugins/exchange-rates/public/flags/bo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/bq.svg b/plugins/exchange-rates/public/flags/bq.svg new file mode 100644 index 000000000..2632a89b7 --- /dev/null +++ b/plugins/exchange-rates/public/flags/bq.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/br.svg b/plugins/exchange-rates/public/flags/br.svg new file mode 100644 index 000000000..203e64d40 --- /dev/null +++ b/plugins/exchange-rates/public/flags/br.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/bs.svg b/plugins/exchange-rates/public/flags/bs.svg new file mode 100644 index 000000000..852306a57 --- /dev/null +++ b/plugins/exchange-rates/public/flags/bs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/bt.svg b/plugins/exchange-rates/public/flags/bt.svg new file mode 100644 index 000000000..16045d085 --- /dev/null +++ b/plugins/exchange-rates/public/flags/bt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/bv.svg b/plugins/exchange-rates/public/flags/bv.svg new file mode 100644 index 000000000..ebb8fbdae --- /dev/null +++ b/plugins/exchange-rates/public/flags/bv.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/bw.svg b/plugins/exchange-rates/public/flags/bw.svg new file mode 100644 index 000000000..4c602337f --- /dev/null +++ b/plugins/exchange-rates/public/flags/bw.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/by.svg b/plugins/exchange-rates/public/flags/by.svg new file mode 100644 index 000000000..b5afd5b47 --- /dev/null +++ b/plugins/exchange-rates/public/flags/by.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/bz.svg b/plugins/exchange-rates/public/flags/bz.svg new file mode 100644 index 000000000..0f538533d --- /dev/null +++ b/plugins/exchange-rates/public/flags/bz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ca.svg b/plugins/exchange-rates/public/flags/ca.svg new file mode 100644 index 000000000..154cb1933 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ca.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/cc.svg b/plugins/exchange-rates/public/flags/cc.svg new file mode 100644 index 000000000..0e35450ad --- /dev/null +++ b/plugins/exchange-rates/public/flags/cc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/cd.svg b/plugins/exchange-rates/public/flags/cd.svg new file mode 100644 index 000000000..5892af08e --- /dev/null +++ b/plugins/exchange-rates/public/flags/cd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/cf.svg b/plugins/exchange-rates/public/flags/cf.svg new file mode 100644 index 000000000..e23b56799 --- /dev/null +++ b/plugins/exchange-rates/public/flags/cf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/cg.svg b/plugins/exchange-rates/public/flags/cg.svg new file mode 100644 index 000000000..c383ee8b6 --- /dev/null +++ b/plugins/exchange-rates/public/flags/cg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ch.svg b/plugins/exchange-rates/public/flags/ch.svg new file mode 100644 index 000000000..f7833a5d0 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ch.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ci.svg b/plugins/exchange-rates/public/flags/ci.svg new file mode 100644 index 000000000..444831965 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ci.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ck.svg b/plugins/exchange-rates/public/flags/ck.svg new file mode 100644 index 000000000..237aa8727 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ck.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/cl.svg b/plugins/exchange-rates/public/flags/cl.svg new file mode 100644 index 000000000..1cbed4372 --- /dev/null +++ b/plugins/exchange-rates/public/flags/cl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/cm.svg b/plugins/exchange-rates/public/flags/cm.svg new file mode 100644 index 000000000..04a5c7f75 --- /dev/null +++ b/plugins/exchange-rates/public/flags/cm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/cn.svg b/plugins/exchange-rates/public/flags/cn.svg new file mode 100644 index 000000000..3227c3df9 --- /dev/null +++ b/plugins/exchange-rates/public/flags/cn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/co.svg b/plugins/exchange-rates/public/flags/co.svg new file mode 100644 index 000000000..2f3901d1e --- /dev/null +++ b/plugins/exchange-rates/public/flags/co.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/cr.svg b/plugins/exchange-rates/public/flags/cr.svg new file mode 100644 index 000000000..d0b9fb1c1 --- /dev/null +++ b/plugins/exchange-rates/public/flags/cr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/cu.svg b/plugins/exchange-rates/public/flags/cu.svg new file mode 100644 index 000000000..6777e9c5e --- /dev/null +++ b/plugins/exchange-rates/public/flags/cu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/cv.svg b/plugins/exchange-rates/public/flags/cv.svg new file mode 100644 index 000000000..0fd3001ff --- /dev/null +++ b/plugins/exchange-rates/public/flags/cv.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/cw.svg b/plugins/exchange-rates/public/flags/cw.svg new file mode 100644 index 000000000..e8953e6df --- /dev/null +++ b/plugins/exchange-rates/public/flags/cw.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/cx.svg b/plugins/exchange-rates/public/flags/cx.svg new file mode 100644 index 000000000..8c79df8c3 --- /dev/null +++ b/plugins/exchange-rates/public/flags/cx.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/cy.svg b/plugins/exchange-rates/public/flags/cy.svg new file mode 100644 index 000000000..c81cc8f11 --- /dev/null +++ b/plugins/exchange-rates/public/flags/cy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/cz.svg b/plugins/exchange-rates/public/flags/cz.svg new file mode 100644 index 000000000..391539952 --- /dev/null +++ b/plugins/exchange-rates/public/flags/cz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/de.svg b/plugins/exchange-rates/public/flags/de.svg new file mode 100644 index 000000000..60e5efca6 --- /dev/null +++ b/plugins/exchange-rates/public/flags/de.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/dj.svg b/plugins/exchange-rates/public/flags/dj.svg new file mode 100644 index 000000000..6b96f378b --- /dev/null +++ b/plugins/exchange-rates/public/flags/dj.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/dk.svg b/plugins/exchange-rates/public/flags/dk.svg new file mode 100644 index 000000000..1ecf992de --- /dev/null +++ b/plugins/exchange-rates/public/flags/dk.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/dm.svg b/plugins/exchange-rates/public/flags/dm.svg new file mode 100644 index 000000000..b11ebe503 --- /dev/null +++ b/plugins/exchange-rates/public/flags/dm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/do.svg b/plugins/exchange-rates/public/flags/do.svg new file mode 100644 index 000000000..3ed50b61e --- /dev/null +++ b/plugins/exchange-rates/public/flags/do.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/dz.svg b/plugins/exchange-rates/public/flags/dz.svg new file mode 100644 index 000000000..2b23ca4ad --- /dev/null +++ b/plugins/exchange-rates/public/flags/dz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ec.svg b/plugins/exchange-rates/public/flags/ec.svg new file mode 100644 index 000000000..61979d7c5 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ec.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ee.svg b/plugins/exchange-rates/public/flags/ee.svg new file mode 100644 index 000000000..2b64555d0 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ee.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/eg.svg b/plugins/exchange-rates/public/flags/eg.svg new file mode 100644 index 000000000..95fdd19df --- /dev/null +++ b/plugins/exchange-rates/public/flags/eg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/eh.svg b/plugins/exchange-rates/public/flags/eh.svg new file mode 100644 index 000000000..de9ede400 --- /dev/null +++ b/plugins/exchange-rates/public/flags/eh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/er.svg b/plugins/exchange-rates/public/flags/er.svg new file mode 100644 index 000000000..8cb578322 --- /dev/null +++ b/plugins/exchange-rates/public/flags/er.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/es.svg b/plugins/exchange-rates/public/flags/es.svg new file mode 100644 index 000000000..8e6e4c252 --- /dev/null +++ b/plugins/exchange-rates/public/flags/es.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/et.svg b/plugins/exchange-rates/public/flags/et.svg new file mode 100644 index 000000000..53e79aae3 --- /dev/null +++ b/plugins/exchange-rates/public/flags/et.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/eu.svg b/plugins/exchange-rates/public/flags/eu.svg new file mode 100644 index 000000000..8e67cb66e --- /dev/null +++ b/plugins/exchange-rates/public/flags/eu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/fi.svg b/plugins/exchange-rates/public/flags/fi.svg new file mode 100644 index 000000000..cc3510e54 --- /dev/null +++ b/plugins/exchange-rates/public/flags/fi.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/fj.svg b/plugins/exchange-rates/public/flags/fj.svg new file mode 100644 index 000000000..6eebe60bc --- /dev/null +++ b/plugins/exchange-rates/public/flags/fj.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/fk.svg b/plugins/exchange-rates/public/flags/fk.svg new file mode 100644 index 000000000..08209e878 --- /dev/null +++ b/plugins/exchange-rates/public/flags/fk.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/fm.svg b/plugins/exchange-rates/public/flags/fm.svg new file mode 100644 index 000000000..09532fab9 --- /dev/null +++ b/plugins/exchange-rates/public/flags/fm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/fo.svg b/plugins/exchange-rates/public/flags/fo.svg new file mode 100644 index 000000000..1e962c569 --- /dev/null +++ b/plugins/exchange-rates/public/flags/fo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/fr.svg b/plugins/exchange-rates/public/flags/fr.svg new file mode 100644 index 000000000..6eb0e18b7 --- /dev/null +++ b/plugins/exchange-rates/public/flags/fr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ga.svg b/plugins/exchange-rates/public/flags/ga.svg new file mode 100644 index 000000000..3fd1d2590 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ga.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gb-eng.svg b/plugins/exchange-rates/public/flags/gb-eng.svg new file mode 100644 index 000000000..f474d109b --- /dev/null +++ b/plugins/exchange-rates/public/flags/gb-eng.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gb-nir.svg b/plugins/exchange-rates/public/flags/gb-nir.svg new file mode 100644 index 000000000..8918d2c85 --- /dev/null +++ b/plugins/exchange-rates/public/flags/gb-nir.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gb-sct.svg b/plugins/exchange-rates/public/flags/gb-sct.svg new file mode 100644 index 000000000..be27bb294 --- /dev/null +++ b/plugins/exchange-rates/public/flags/gb-sct.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gb-wls.svg b/plugins/exchange-rates/public/flags/gb-wls.svg new file mode 100644 index 000000000..6b0d02504 --- /dev/null +++ b/plugins/exchange-rates/public/flags/gb-wls.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gb.svg b/plugins/exchange-rates/public/flags/gb.svg new file mode 100644 index 000000000..82b1fad72 --- /dev/null +++ b/plugins/exchange-rates/public/flags/gb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gd.svg b/plugins/exchange-rates/public/flags/gd.svg new file mode 100644 index 000000000..bc51894e4 --- /dev/null +++ b/plugins/exchange-rates/public/flags/gd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ge.svg b/plugins/exchange-rates/public/flags/ge.svg new file mode 100644 index 000000000..7e0459b40 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ge.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gf.svg b/plugins/exchange-rates/public/flags/gf.svg new file mode 100644 index 000000000..cbe2c8c3c --- /dev/null +++ b/plugins/exchange-rates/public/flags/gf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gg.svg b/plugins/exchange-rates/public/flags/gg.svg new file mode 100644 index 000000000..9e482a95d --- /dev/null +++ b/plugins/exchange-rates/public/flags/gg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gh.svg b/plugins/exchange-rates/public/flags/gh.svg new file mode 100644 index 000000000..fae895679 --- /dev/null +++ b/plugins/exchange-rates/public/flags/gh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gi.svg b/plugins/exchange-rates/public/flags/gi.svg new file mode 100644 index 000000000..400c8d074 --- /dev/null +++ b/plugins/exchange-rates/public/flags/gi.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gl.svg b/plugins/exchange-rates/public/flags/gl.svg new file mode 100644 index 000000000..2e355e8c8 --- /dev/null +++ b/plugins/exchange-rates/public/flags/gl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gm.svg b/plugins/exchange-rates/public/flags/gm.svg new file mode 100644 index 000000000..594918531 --- /dev/null +++ b/plugins/exchange-rates/public/flags/gm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gn.svg b/plugins/exchange-rates/public/flags/gn.svg new file mode 100644 index 000000000..9967a7bcd --- /dev/null +++ b/plugins/exchange-rates/public/flags/gn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gp.svg b/plugins/exchange-rates/public/flags/gp.svg new file mode 100644 index 000000000..250d60be8 --- /dev/null +++ b/plugins/exchange-rates/public/flags/gp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gq.svg b/plugins/exchange-rates/public/flags/gq.svg new file mode 100644 index 000000000..459b5a17b --- /dev/null +++ b/plugins/exchange-rates/public/flags/gq.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gr.svg b/plugins/exchange-rates/public/flags/gr.svg new file mode 100644 index 000000000..e3a582cee --- /dev/null +++ b/plugins/exchange-rates/public/flags/gr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gs.svg b/plugins/exchange-rates/public/flags/gs.svg new file mode 100644 index 000000000..56e473d43 --- /dev/null +++ b/plugins/exchange-rates/public/flags/gs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gt.svg b/plugins/exchange-rates/public/flags/gt.svg new file mode 100644 index 000000000..b784b2745 --- /dev/null +++ b/plugins/exchange-rates/public/flags/gt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gu.svg b/plugins/exchange-rates/public/flags/gu.svg new file mode 100644 index 000000000..ca41e91ab --- /dev/null +++ b/plugins/exchange-rates/public/flags/gu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gw.svg b/plugins/exchange-rates/public/flags/gw.svg new file mode 100644 index 000000000..808b89c02 --- /dev/null +++ b/plugins/exchange-rates/public/flags/gw.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/gy.svg b/plugins/exchange-rates/public/flags/gy.svg new file mode 100644 index 000000000..d48e3144f --- /dev/null +++ b/plugins/exchange-rates/public/flags/gy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/hk.svg b/plugins/exchange-rates/public/flags/hk.svg new file mode 100644 index 000000000..c4287fdd1 --- /dev/null +++ b/plugins/exchange-rates/public/flags/hk.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/hm.svg b/plugins/exchange-rates/public/flags/hm.svg new file mode 100644 index 000000000..f6e409706 --- /dev/null +++ b/plugins/exchange-rates/public/flags/hm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/hn.svg b/plugins/exchange-rates/public/flags/hn.svg new file mode 100644 index 000000000..3ddeb2c88 --- /dev/null +++ b/plugins/exchange-rates/public/flags/hn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/hr.svg b/plugins/exchange-rates/public/flags/hr.svg new file mode 100644 index 000000000..ad24ab9f0 --- /dev/null +++ b/plugins/exchange-rates/public/flags/hr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ht.svg b/plugins/exchange-rates/public/flags/ht.svg new file mode 100644 index 000000000..b6ca967c7 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ht.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/hu.svg b/plugins/exchange-rates/public/flags/hu.svg new file mode 100644 index 000000000..af288852e --- /dev/null +++ b/plugins/exchange-rates/public/flags/hu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/id.svg b/plugins/exchange-rates/public/flags/id.svg new file mode 100644 index 000000000..08c1098ea --- /dev/null +++ b/plugins/exchange-rates/public/flags/id.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ie.svg b/plugins/exchange-rates/public/flags/ie.svg new file mode 100644 index 000000000..ff76bd85e --- /dev/null +++ b/plugins/exchange-rates/public/flags/ie.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/il.svg b/plugins/exchange-rates/public/flags/il.svg new file mode 100644 index 000000000..de884eab2 --- /dev/null +++ b/plugins/exchange-rates/public/flags/il.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/im.svg b/plugins/exchange-rates/public/flags/im.svg new file mode 100644 index 000000000..d86c8447e --- /dev/null +++ b/plugins/exchange-rates/public/flags/im.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/in.svg b/plugins/exchange-rates/public/flags/in.svg new file mode 100644 index 000000000..52179283c --- /dev/null +++ b/plugins/exchange-rates/public/flags/in.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/io.svg b/plugins/exchange-rates/public/flags/io.svg new file mode 100644 index 000000000..1f15f046d --- /dev/null +++ b/plugins/exchange-rates/public/flags/io.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/iq.svg b/plugins/exchange-rates/public/flags/iq.svg new file mode 100644 index 000000000..2b62c5810 --- /dev/null +++ b/plugins/exchange-rates/public/flags/iq.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ir.svg b/plugins/exchange-rates/public/flags/ir.svg new file mode 100644 index 000000000..272eff0c3 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ir.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/is.svg b/plugins/exchange-rates/public/flags/is.svg new file mode 100644 index 000000000..c1d7fc372 --- /dev/null +++ b/plugins/exchange-rates/public/flags/is.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/it.svg b/plugins/exchange-rates/public/flags/it.svg new file mode 100644 index 000000000..554137885 --- /dev/null +++ b/plugins/exchange-rates/public/flags/it.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/je.svg b/plugins/exchange-rates/public/flags/je.svg new file mode 100644 index 000000000..90e7368fc --- /dev/null +++ b/plugins/exchange-rates/public/flags/je.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/jm.svg b/plugins/exchange-rates/public/flags/jm.svg new file mode 100644 index 000000000..7273742b6 --- /dev/null +++ b/plugins/exchange-rates/public/flags/jm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/jo.svg b/plugins/exchange-rates/public/flags/jo.svg new file mode 100644 index 000000000..5a4eccf46 --- /dev/null +++ b/plugins/exchange-rates/public/flags/jo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/jp.svg b/plugins/exchange-rates/public/flags/jp.svg new file mode 100644 index 000000000..0f0294929 --- /dev/null +++ b/plugins/exchange-rates/public/flags/jp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ke.svg b/plugins/exchange-rates/public/flags/ke.svg new file mode 100644 index 000000000..370a13fac --- /dev/null +++ b/plugins/exchange-rates/public/flags/ke.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/kg.svg b/plugins/exchange-rates/public/flags/kg.svg new file mode 100644 index 000000000..fccd63981 --- /dev/null +++ b/plugins/exchange-rates/public/flags/kg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/kh.svg b/plugins/exchange-rates/public/flags/kh.svg new file mode 100644 index 000000000..828e54a79 --- /dev/null +++ b/plugins/exchange-rates/public/flags/kh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ki.svg b/plugins/exchange-rates/public/flags/ki.svg new file mode 100644 index 000000000..ff58c038f --- /dev/null +++ b/plugins/exchange-rates/public/flags/ki.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/km.svg b/plugins/exchange-rates/public/flags/km.svg new file mode 100644 index 000000000..88f36bf75 --- /dev/null +++ b/plugins/exchange-rates/public/flags/km.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/kn.svg b/plugins/exchange-rates/public/flags/kn.svg new file mode 100644 index 000000000..8764dd78c --- /dev/null +++ b/plugins/exchange-rates/public/flags/kn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/kp.svg b/plugins/exchange-rates/public/flags/kp.svg new file mode 100644 index 000000000..42affa73a --- /dev/null +++ b/plugins/exchange-rates/public/flags/kp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/kr.svg b/plugins/exchange-rates/public/flags/kr.svg new file mode 100644 index 000000000..a44c6e1ce --- /dev/null +++ b/plugins/exchange-rates/public/flags/kr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/kw.svg b/plugins/exchange-rates/public/flags/kw.svg new file mode 100644 index 000000000..b4bffefd2 --- /dev/null +++ b/plugins/exchange-rates/public/flags/kw.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ky.svg b/plugins/exchange-rates/public/flags/ky.svg new file mode 100644 index 000000000..ad1e433c5 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ky.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/kz.svg b/plugins/exchange-rates/public/flags/kz.svg new file mode 100644 index 000000000..96855b086 --- /dev/null +++ b/plugins/exchange-rates/public/flags/kz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/la.svg b/plugins/exchange-rates/public/flags/la.svg new file mode 100644 index 000000000..0f596b270 --- /dev/null +++ b/plugins/exchange-rates/public/flags/la.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/lb.svg b/plugins/exchange-rates/public/flags/lb.svg new file mode 100644 index 000000000..f69dfa665 --- /dev/null +++ b/plugins/exchange-rates/public/flags/lb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/lc.svg b/plugins/exchange-rates/public/flags/lc.svg new file mode 100644 index 000000000..887ad78d4 --- /dev/null +++ b/plugins/exchange-rates/public/flags/lc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/li.svg b/plugins/exchange-rates/public/flags/li.svg new file mode 100644 index 000000000..9cd6ae1b9 --- /dev/null +++ b/plugins/exchange-rates/public/flags/li.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/lk.svg b/plugins/exchange-rates/public/flags/lk.svg new file mode 100644 index 000000000..33f6e0906 --- /dev/null +++ b/plugins/exchange-rates/public/flags/lk.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/lr.svg b/plugins/exchange-rates/public/flags/lr.svg new file mode 100644 index 000000000..660ab03f4 --- /dev/null +++ b/plugins/exchange-rates/public/flags/lr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ls.svg b/plugins/exchange-rates/public/flags/ls.svg new file mode 100644 index 000000000..0dc59f9fd --- /dev/null +++ b/plugins/exchange-rates/public/flags/ls.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/lt.svg b/plugins/exchange-rates/public/flags/lt.svg new file mode 100644 index 000000000..90a3ec1c4 --- /dev/null +++ b/plugins/exchange-rates/public/flags/lt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/lu.svg b/plugins/exchange-rates/public/flags/lu.svg new file mode 100644 index 000000000..b754681be --- /dev/null +++ b/plugins/exchange-rates/public/flags/lu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/lv.svg b/plugins/exchange-rates/public/flags/lv.svg new file mode 100644 index 000000000..0037f2773 --- /dev/null +++ b/plugins/exchange-rates/public/flags/lv.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ly.svg b/plugins/exchange-rates/public/flags/ly.svg new file mode 100644 index 000000000..8c9ee587c --- /dev/null +++ b/plugins/exchange-rates/public/flags/ly.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ma.svg b/plugins/exchange-rates/public/flags/ma.svg new file mode 100644 index 000000000..d6b54a3c7 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ma.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/mc.svg b/plugins/exchange-rates/public/flags/mc.svg new file mode 100644 index 000000000..395adc575 --- /dev/null +++ b/plugins/exchange-rates/public/flags/mc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/md.svg b/plugins/exchange-rates/public/flags/md.svg new file mode 100644 index 000000000..6fc829635 --- /dev/null +++ b/plugins/exchange-rates/public/flags/md.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/me.svg b/plugins/exchange-rates/public/flags/me.svg new file mode 100644 index 000000000..8b3f1ab6f --- /dev/null +++ b/plugins/exchange-rates/public/flags/me.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/mf.svg b/plugins/exchange-rates/public/flags/mf.svg new file mode 100644 index 000000000..6eb0e18b7 --- /dev/null +++ b/plugins/exchange-rates/public/flags/mf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/mg.svg b/plugins/exchange-rates/public/flags/mg.svg new file mode 100644 index 000000000..d83543fc1 --- /dev/null +++ b/plugins/exchange-rates/public/flags/mg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/mh.svg b/plugins/exchange-rates/public/flags/mh.svg new file mode 100644 index 000000000..4ca4b6673 --- /dev/null +++ b/plugins/exchange-rates/public/flags/mh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/mk.svg b/plugins/exchange-rates/public/flags/mk.svg new file mode 100644 index 000000000..e10ed70f9 --- /dev/null +++ b/plugins/exchange-rates/public/flags/mk.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ml.svg b/plugins/exchange-rates/public/flags/ml.svg new file mode 100644 index 000000000..df345c248 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ml.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/mm.svg b/plugins/exchange-rates/public/flags/mm.svg new file mode 100644 index 000000000..4509bb3ed --- /dev/null +++ b/plugins/exchange-rates/public/flags/mm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/mn.svg b/plugins/exchange-rates/public/flags/mn.svg new file mode 100644 index 000000000..f1805f8ee --- /dev/null +++ b/plugins/exchange-rates/public/flags/mn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/mo.svg b/plugins/exchange-rates/public/flags/mo.svg new file mode 100644 index 000000000..739c35bb2 --- /dev/null +++ b/plugins/exchange-rates/public/flags/mo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/mp.svg b/plugins/exchange-rates/public/flags/mp.svg new file mode 100644 index 000000000..645fab797 --- /dev/null +++ b/plugins/exchange-rates/public/flags/mp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/mq.svg b/plugins/exchange-rates/public/flags/mq.svg new file mode 100644 index 000000000..0e5c3ce05 --- /dev/null +++ b/plugins/exchange-rates/public/flags/mq.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/mr.svg b/plugins/exchange-rates/public/flags/mr.svg new file mode 100644 index 000000000..8c3785949 --- /dev/null +++ b/plugins/exchange-rates/public/flags/mr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ms.svg b/plugins/exchange-rates/public/flags/ms.svg new file mode 100644 index 000000000..0c199ca4e --- /dev/null +++ b/plugins/exchange-rates/public/flags/ms.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/mt.svg b/plugins/exchange-rates/public/flags/mt.svg new file mode 100644 index 000000000..a880f1fc2 --- /dev/null +++ b/plugins/exchange-rates/public/flags/mt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/mu.svg b/plugins/exchange-rates/public/flags/mu.svg new file mode 100644 index 000000000..7b1af9ccb --- /dev/null +++ b/plugins/exchange-rates/public/flags/mu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/mv.svg b/plugins/exchange-rates/public/flags/mv.svg new file mode 100644 index 000000000..82f77be6f --- /dev/null +++ b/plugins/exchange-rates/public/flags/mv.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/mw.svg b/plugins/exchange-rates/public/flags/mw.svg new file mode 100644 index 000000000..2c8088419 --- /dev/null +++ b/plugins/exchange-rates/public/flags/mw.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/mx.svg b/plugins/exchange-rates/public/flags/mx.svg new file mode 100644 index 000000000..b82436bf9 --- /dev/null +++ b/plugins/exchange-rates/public/flags/mx.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/my.svg b/plugins/exchange-rates/public/flags/my.svg new file mode 100644 index 000000000..bb160fda0 --- /dev/null +++ b/plugins/exchange-rates/public/flags/my.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/mz.svg b/plugins/exchange-rates/public/flags/mz.svg new file mode 100644 index 000000000..29e8856a8 --- /dev/null +++ b/plugins/exchange-rates/public/flags/mz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/na.svg b/plugins/exchange-rates/public/flags/na.svg new file mode 100644 index 000000000..472a82e36 --- /dev/null +++ b/plugins/exchange-rates/public/flags/na.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/nc.svg b/plugins/exchange-rates/public/flags/nc.svg new file mode 100644 index 000000000..35a2125cb --- /dev/null +++ b/plugins/exchange-rates/public/flags/nc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ne.svg b/plugins/exchange-rates/public/flags/ne.svg new file mode 100644 index 000000000..3da73140d --- /dev/null +++ b/plugins/exchange-rates/public/flags/ne.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/nf.svg b/plugins/exchange-rates/public/flags/nf.svg new file mode 100644 index 000000000..959a85b5c --- /dev/null +++ b/plugins/exchange-rates/public/flags/nf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ng.svg b/plugins/exchange-rates/public/flags/ng.svg new file mode 100644 index 000000000..ca4a19fcd --- /dev/null +++ b/plugins/exchange-rates/public/flags/ng.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ni.svg b/plugins/exchange-rates/public/flags/ni.svg new file mode 100644 index 000000000..f1d41a1ab --- /dev/null +++ b/plugins/exchange-rates/public/flags/ni.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/nl.svg b/plugins/exchange-rates/public/flags/nl.svg new file mode 100644 index 000000000..6598c0bae --- /dev/null +++ b/plugins/exchange-rates/public/flags/nl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/no.svg b/plugins/exchange-rates/public/flags/no.svg new file mode 100644 index 000000000..ebb8fbdae --- /dev/null +++ b/plugins/exchange-rates/public/flags/no.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/np.svg b/plugins/exchange-rates/public/flags/np.svg new file mode 100644 index 000000000..ae7b651d9 --- /dev/null +++ b/plugins/exchange-rates/public/flags/np.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/nr.svg b/plugins/exchange-rates/public/flags/nr.svg new file mode 100644 index 000000000..22e5bc49c --- /dev/null +++ b/plugins/exchange-rates/public/flags/nr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/nu.svg b/plugins/exchange-rates/public/flags/nu.svg new file mode 100644 index 000000000..cd34cea63 --- /dev/null +++ b/plugins/exchange-rates/public/flags/nu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/nz.svg b/plugins/exchange-rates/public/flags/nz.svg new file mode 100644 index 000000000..4f6af3c39 --- /dev/null +++ b/plugins/exchange-rates/public/flags/nz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/om.svg b/plugins/exchange-rates/public/flags/om.svg new file mode 100644 index 000000000..9b80e4b35 --- /dev/null +++ b/plugins/exchange-rates/public/flags/om.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/pa.svg b/plugins/exchange-rates/public/flags/pa.svg new file mode 100644 index 000000000..c625603c7 --- /dev/null +++ b/plugins/exchange-rates/public/flags/pa.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/pe.svg b/plugins/exchange-rates/public/flags/pe.svg new file mode 100644 index 000000000..93618a332 --- /dev/null +++ b/plugins/exchange-rates/public/flags/pe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/pf.svg b/plugins/exchange-rates/public/flags/pf.svg new file mode 100644 index 000000000..eb69b3c6d --- /dev/null +++ b/plugins/exchange-rates/public/flags/pf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/pg.svg b/plugins/exchange-rates/public/flags/pg.svg new file mode 100644 index 000000000..aa5a7b7e5 --- /dev/null +++ b/plugins/exchange-rates/public/flags/pg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ph.svg b/plugins/exchange-rates/public/flags/ph.svg new file mode 100644 index 000000000..be4ac14c8 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ph.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/pk.svg b/plugins/exchange-rates/public/flags/pk.svg new file mode 100644 index 000000000..91cd2f189 --- /dev/null +++ b/plugins/exchange-rates/public/flags/pk.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/pl.svg b/plugins/exchange-rates/public/flags/pl.svg new file mode 100644 index 000000000..4a39bfaf0 --- /dev/null +++ b/plugins/exchange-rates/public/flags/pl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/pm.svg b/plugins/exchange-rates/public/flags/pm.svg new file mode 100644 index 000000000..1780f1ef2 --- /dev/null +++ b/plugins/exchange-rates/public/flags/pm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/pn.svg b/plugins/exchange-rates/public/flags/pn.svg new file mode 100644 index 000000000..35f2a3d34 --- /dev/null +++ b/plugins/exchange-rates/public/flags/pn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/pr.svg b/plugins/exchange-rates/public/flags/pr.svg new file mode 100644 index 000000000..5ed5f8aa8 --- /dev/null +++ b/plugins/exchange-rates/public/flags/pr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ps.svg b/plugins/exchange-rates/public/flags/ps.svg new file mode 100644 index 000000000..786c8ca78 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ps.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/pt.svg b/plugins/exchange-rates/public/flags/pt.svg new file mode 100644 index 000000000..0c610beea --- /dev/null +++ b/plugins/exchange-rates/public/flags/pt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/pw.svg b/plugins/exchange-rates/public/flags/pw.svg new file mode 100644 index 000000000..7ab6c7574 --- /dev/null +++ b/plugins/exchange-rates/public/flags/pw.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/py.svg b/plugins/exchange-rates/public/flags/py.svg new file mode 100644 index 000000000..63f38a7da --- /dev/null +++ b/plugins/exchange-rates/public/flags/py.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/qa.svg b/plugins/exchange-rates/public/flags/qa.svg new file mode 100644 index 000000000..65b21848a --- /dev/null +++ b/plugins/exchange-rates/public/flags/qa.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/re.svg b/plugins/exchange-rates/public/flags/re.svg new file mode 100644 index 000000000..7df560611 --- /dev/null +++ b/plugins/exchange-rates/public/flags/re.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ro.svg b/plugins/exchange-rates/public/flags/ro.svg new file mode 100644 index 000000000..8dc284833 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ro.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/rs.svg b/plugins/exchange-rates/public/flags/rs.svg new file mode 100644 index 000000000..40c9d6d64 --- /dev/null +++ b/plugins/exchange-rates/public/flags/rs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ru.svg b/plugins/exchange-rates/public/flags/ru.svg new file mode 100644 index 000000000..9c0cc49fd --- /dev/null +++ b/plugins/exchange-rates/public/flags/ru.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/rw.svg b/plugins/exchange-rates/public/flags/rw.svg new file mode 100644 index 000000000..d23794134 --- /dev/null +++ b/plugins/exchange-rates/public/flags/rw.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/sa.svg b/plugins/exchange-rates/public/flags/sa.svg new file mode 100644 index 000000000..5eee1b544 --- /dev/null +++ b/plugins/exchange-rates/public/flags/sa.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/sb.svg b/plugins/exchange-rates/public/flags/sb.svg new file mode 100644 index 000000000..e4bb3ff0d --- /dev/null +++ b/plugins/exchange-rates/public/flags/sb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/sc.svg b/plugins/exchange-rates/public/flags/sc.svg new file mode 100644 index 000000000..ea40823f4 --- /dev/null +++ b/plugins/exchange-rates/public/flags/sc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/sd.svg b/plugins/exchange-rates/public/flags/sd.svg new file mode 100644 index 000000000..477877f68 --- /dev/null +++ b/plugins/exchange-rates/public/flags/sd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/se.svg b/plugins/exchange-rates/public/flags/se.svg new file mode 100644 index 000000000..b32a8f9cd --- /dev/null +++ b/plugins/exchange-rates/public/flags/se.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/sg.svg b/plugins/exchange-rates/public/flags/sg.svg new file mode 100644 index 000000000..4d4a817e5 --- /dev/null +++ b/plugins/exchange-rates/public/flags/sg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/sh.svg b/plugins/exchange-rates/public/flags/sh.svg new file mode 100644 index 000000000..d4431b7cf --- /dev/null +++ b/plugins/exchange-rates/public/flags/sh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/si.svg b/plugins/exchange-rates/public/flags/si.svg new file mode 100644 index 000000000..bb23bb328 --- /dev/null +++ b/plugins/exchange-rates/public/flags/si.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/sj.svg b/plugins/exchange-rates/public/flags/sj.svg new file mode 100644 index 000000000..ebb8fbdae --- /dev/null +++ b/plugins/exchange-rates/public/flags/sj.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/sk.svg b/plugins/exchange-rates/public/flags/sk.svg new file mode 100644 index 000000000..2abe6f497 --- /dev/null +++ b/plugins/exchange-rates/public/flags/sk.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/sl.svg b/plugins/exchange-rates/public/flags/sl.svg new file mode 100644 index 000000000..ee46023bc --- /dev/null +++ b/plugins/exchange-rates/public/flags/sl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/sm.svg b/plugins/exchange-rates/public/flags/sm.svg new file mode 100644 index 000000000..98fdaf422 --- /dev/null +++ b/plugins/exchange-rates/public/flags/sm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/sn.svg b/plugins/exchange-rates/public/flags/sn.svg new file mode 100644 index 000000000..3860b33f4 --- /dev/null +++ b/plugins/exchange-rates/public/flags/sn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/so.svg b/plugins/exchange-rates/public/flags/so.svg new file mode 100644 index 000000000..44ce2fd20 --- /dev/null +++ b/plugins/exchange-rates/public/flags/so.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/sr.svg b/plugins/exchange-rates/public/flags/sr.svg new file mode 100644 index 000000000..117d76d93 --- /dev/null +++ b/plugins/exchange-rates/public/flags/sr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ss.svg b/plugins/exchange-rates/public/flags/ss.svg new file mode 100644 index 000000000..20cc8218c --- /dev/null +++ b/plugins/exchange-rates/public/flags/ss.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/st.svg b/plugins/exchange-rates/public/flags/st.svg new file mode 100644 index 000000000..555952c9e --- /dev/null +++ b/plugins/exchange-rates/public/flags/st.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/sv.svg b/plugins/exchange-rates/public/flags/sv.svg new file mode 100644 index 000000000..c81ee73bf --- /dev/null +++ b/plugins/exchange-rates/public/flags/sv.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/sx.svg b/plugins/exchange-rates/public/flags/sx.svg new file mode 100644 index 000000000..dcc7c8116 --- /dev/null +++ b/plugins/exchange-rates/public/flags/sx.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/sy.svg b/plugins/exchange-rates/public/flags/sy.svg new file mode 100644 index 000000000..ca5d90efe --- /dev/null +++ b/plugins/exchange-rates/public/flags/sy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/sz.svg b/plugins/exchange-rates/public/flags/sz.svg new file mode 100644 index 000000000..25117b299 --- /dev/null +++ b/plugins/exchange-rates/public/flags/sz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/tc.svg b/plugins/exchange-rates/public/flags/tc.svg new file mode 100644 index 000000000..dea56647f --- /dev/null +++ b/plugins/exchange-rates/public/flags/tc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/td.svg b/plugins/exchange-rates/public/flags/td.svg new file mode 100644 index 000000000..f94d6e537 --- /dev/null +++ b/plugins/exchange-rates/public/flags/td.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/tf.svg b/plugins/exchange-rates/public/flags/tf.svg new file mode 100644 index 000000000..ea39af959 --- /dev/null +++ b/plugins/exchange-rates/public/flags/tf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/tg.svg b/plugins/exchange-rates/public/flags/tg.svg new file mode 100644 index 000000000..27582f185 --- /dev/null +++ b/plugins/exchange-rates/public/flags/tg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/th.svg b/plugins/exchange-rates/public/flags/th.svg new file mode 100644 index 000000000..3f22b44da --- /dev/null +++ b/plugins/exchange-rates/public/flags/th.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/tj.svg b/plugins/exchange-rates/public/flags/tj.svg new file mode 100644 index 000000000..ec4e481d9 --- /dev/null +++ b/plugins/exchange-rates/public/flags/tj.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/tk.svg b/plugins/exchange-rates/public/flags/tk.svg new file mode 100644 index 000000000..16aa66ae0 --- /dev/null +++ b/plugins/exchange-rates/public/flags/tk.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/tl.svg b/plugins/exchange-rates/public/flags/tl.svg new file mode 100644 index 000000000..1d6bb5638 --- /dev/null +++ b/plugins/exchange-rates/public/flags/tl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/tm.svg b/plugins/exchange-rates/public/flags/tm.svg new file mode 100644 index 000000000..f49a64753 --- /dev/null +++ b/plugins/exchange-rates/public/flags/tm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/tn.svg b/plugins/exchange-rates/public/flags/tn.svg new file mode 100644 index 000000000..482b55a90 --- /dev/null +++ b/plugins/exchange-rates/public/flags/tn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/to.svg b/plugins/exchange-rates/public/flags/to.svg new file mode 100644 index 000000000..62cfb73e9 --- /dev/null +++ b/plugins/exchange-rates/public/flags/to.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/tr.svg b/plugins/exchange-rates/public/flags/tr.svg new file mode 100644 index 000000000..5b046e64c --- /dev/null +++ b/plugins/exchange-rates/public/flags/tr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/tt.svg b/plugins/exchange-rates/public/flags/tt.svg new file mode 100644 index 000000000..7479d1b8e --- /dev/null +++ b/plugins/exchange-rates/public/flags/tt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/tv.svg b/plugins/exchange-rates/public/flags/tv.svg new file mode 100644 index 000000000..b3f930806 --- /dev/null +++ b/plugins/exchange-rates/public/flags/tv.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/tw.svg b/plugins/exchange-rates/public/flags/tw.svg new file mode 100644 index 000000000..500d0f328 --- /dev/null +++ b/plugins/exchange-rates/public/flags/tw.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/tz.svg b/plugins/exchange-rates/public/flags/tz.svg new file mode 100644 index 000000000..5cbeb7a83 --- /dev/null +++ b/plugins/exchange-rates/public/flags/tz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ua.svg b/plugins/exchange-rates/public/flags/ua.svg new file mode 100644 index 000000000..4d09b7c8e --- /dev/null +++ b/plugins/exchange-rates/public/flags/ua.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ug.svg b/plugins/exchange-rates/public/flags/ug.svg new file mode 100644 index 000000000..463d425ac --- /dev/null +++ b/plugins/exchange-rates/public/flags/ug.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/um.svg b/plugins/exchange-rates/public/flags/um.svg new file mode 100644 index 000000000..9735dfac8 --- /dev/null +++ b/plugins/exchange-rates/public/flags/um.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/us.svg b/plugins/exchange-rates/public/flags/us.svg new file mode 100644 index 000000000..9735dfac8 --- /dev/null +++ b/plugins/exchange-rates/public/flags/us.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/uy.svg b/plugins/exchange-rates/public/flags/uy.svg new file mode 100644 index 000000000..9f5b3d6c8 --- /dev/null +++ b/plugins/exchange-rates/public/flags/uy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/uz.svg b/plugins/exchange-rates/public/flags/uz.svg new file mode 100644 index 000000000..379ab12c0 --- /dev/null +++ b/plugins/exchange-rates/public/flags/uz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/va.svg b/plugins/exchange-rates/public/flags/va.svg new file mode 100644 index 000000000..9101c9f2f --- /dev/null +++ b/plugins/exchange-rates/public/flags/va.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/vc.svg b/plugins/exchange-rates/public/flags/vc.svg new file mode 100644 index 000000000..f3892d7db --- /dev/null +++ b/plugins/exchange-rates/public/flags/vc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ve.svg b/plugins/exchange-rates/public/flags/ve.svg new file mode 100644 index 000000000..912a069e0 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ve.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/vg.svg b/plugins/exchange-rates/public/flags/vg.svg new file mode 100644 index 000000000..6d51bf8f8 --- /dev/null +++ b/plugins/exchange-rates/public/flags/vg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/vi.svg b/plugins/exchange-rates/public/flags/vi.svg new file mode 100644 index 000000000..606b364aa --- /dev/null +++ b/plugins/exchange-rates/public/flags/vi.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/vn.svg b/plugins/exchange-rates/public/flags/vn.svg new file mode 100644 index 000000000..691cd96c9 --- /dev/null +++ b/plugins/exchange-rates/public/flags/vn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/vu.svg b/plugins/exchange-rates/public/flags/vu.svg new file mode 100644 index 000000000..5e1cb1a55 --- /dev/null +++ b/plugins/exchange-rates/public/flags/vu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/wf.svg b/plugins/exchange-rates/public/flags/wf.svg new file mode 100644 index 000000000..5b7479da3 --- /dev/null +++ b/plugins/exchange-rates/public/flags/wf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ws.svg b/plugins/exchange-rates/public/flags/ws.svg new file mode 100644 index 000000000..d7d19c2d0 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ws.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/xk.svg b/plugins/exchange-rates/public/flags/xk.svg new file mode 100644 index 000000000..e1c6eec60 --- /dev/null +++ b/plugins/exchange-rates/public/flags/xk.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/ye.svg b/plugins/exchange-rates/public/flags/ye.svg new file mode 100644 index 000000000..c32376c96 --- /dev/null +++ b/plugins/exchange-rates/public/flags/ye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/yt.svg b/plugins/exchange-rates/public/flags/yt.svg new file mode 100644 index 000000000..67c962212 --- /dev/null +++ b/plugins/exchange-rates/public/flags/yt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/za.svg b/plugins/exchange-rates/public/flags/za.svg new file mode 100644 index 000000000..a00b44a83 --- /dev/null +++ b/plugins/exchange-rates/public/flags/za.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/zm.svg b/plugins/exchange-rates/public/flags/zm.svg new file mode 100644 index 000000000..65cc2dd48 --- /dev/null +++ b/plugins/exchange-rates/public/flags/zm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/flags/zw.svg b/plugins/exchange-rates/public/flags/zw.svg new file mode 100644 index 000000000..92f8e2573 --- /dev/null +++ b/plugins/exchange-rates/public/flags/zw.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/exchange-rates/public/fx-parse.mjs b/plugins/exchange-rates/public/fx-parse.mjs new file mode 100644 index 000000000..117054ff3 --- /dev/null +++ b/plugins/exchange-rates/public/fx-parse.mjs @@ -0,0 +1,60 @@ +function objects(text) { + const found = []; + const re = /\{[^{}]*\}/g; + let match; + while ((match = re.exec(text))) { + const obj = match[0]; + const quote = /"quote"\s*:\s*"([^"]+)"/.exec(obj); + const rate = /"rate"\s*:\s*(-?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?\d+)?)/.exec(obj); + const date = /"date"\s*:\s*"([^"]+)"/.exec(obj); + if (!quote || !rate) continue; + found.push({ + date: date ? date[1] : "", + quote: quote[1].toUpperCase(), + rate: rate[1], + }); + } + return found; +} + +export function parseLatest(text) { + const rows = objects(text); + const rates = {}; + let date = ""; + for (const row of rows) { + rates[row.quote] = row.rate; + if (row.date > date) date = row.date; + } + if (!rates.EUR) rates.EUR = "1"; + return { date, fetchedAt: Date.now(), rates }; +} + +function isoCodes(text) { + const codes = []; + const re = /"iso_code"\s*:\s*"([^"]+)"/g; + let match; + while ((match = re.exec(text))) codes.push(match[1].toUpperCase()); + return codes; +} + +export function parseCurrencies(currentText, allText) { + const current = new Set(isoCodes(currentText)); + const all = isoCodes(allText); + const seen = new Set(); + const list = []; + const source = all.length ? all : [...current]; + for (const code of source) { + if (seen.has(code)) continue; + seen.add(code); + list.push({ code, deprecated: !current.has(code) }); + } + for (const code of current) { + if (seen.has(code)) continue; + list.push({ code, deprecated: false }); + } + return list; +} + +export function parseSeries(text) { + return objects(text); +} diff --git a/plugins/exchange-rates/public/logo.png b/plugins/exchange-rates/public/logo.png new file mode 100644 index 000000000..a85e2811f Binary files /dev/null and b/plugins/exchange-rates/public/logo.png differ diff --git a/plugins/exchange-rates/public/package.json b/plugins/exchange-rates/public/package.json new file mode 100644 index 000000000..5bbefffba --- /dev/null +++ b/plugins/exchange-rates/public/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/plugins/exchange-rates/public/plugin.json b/plugins/exchange-rates/public/plugin.json new file mode 100644 index 000000000..a7527ee3c --- /dev/null +++ b/plugins/exchange-rates/public/plugin.json @@ -0,0 +1,20 @@ +{ + "name": "exchange-rates", + "title": "匯率換算", + "description": "把一筆基準金額換算成多種貨幣,並查看近 30 個觀測日的變動。", + "author": "Kazma258", + "version": "1.0.0", + "main": "index.html", + "logo": "logo.png", + "preload": "preload.js", + "development": { + "main": "http://localhost:5173" + }, + "features": [ + { + "code": "convert", + "explain": "一對多匯率換算", + "cmds": ["匯率", "貨幣", "錢", "money"] + } + ] +} diff --git a/plugins/exchange-rates/public/preload.js b/plugins/exchange-rates/public/preload.js new file mode 100644 index 000000000..4cca63796 --- /dev/null +++ b/plugins/exchange-rates/public/preload.js @@ -0,0 +1,71 @@ +"use strict"; + +const https = require("https"); + +const API = "https://api.frankfurter.dev/v2"; + +function getText(url) { + return new Promise((resolve, reject) => { + const req = https.get(url, { headers: { accept: "application/json" } }, (res) => { + const status = res.statusCode || 0; + if (status >= 300 && status < 400 && res.headers.location) { + res.resume(); + resolve(getText(new URL(res.headers.location, url).href)); + return; + } + const chunks = []; + res.on("data", (chunk) => chunks.push(chunk)); + res.on("end", () => { + const text = Buffer.concat(chunks).toString("utf8"); + if (status !== 200) { + const error = new Error("HTTP " + status); + error.status = status; + error.retryAfter = res.headers["retry-after"] || ""; + error.body = text.slice(0, 300); + reject(error); + return; + } + resolve(text); + }); + }); + req.on("error", reject); + }); +} + +function storageGet(key) { + try { + if (window.ztools && window.ztools.dbStorage) return window.ztools.dbStorage.getItem(key); + } catch (error) { + console.error(error); + } + return null; +} + +function storageSet(key, value) { + try { + if (window.ztools && window.ztools.dbStorage) window.ztools.dbStorage.setItem(key, value); + } catch (error) { + console.error(error); + } +} + +window.fx = { + getItem: storageGet, + setItem: storageSet, + async fetchRates() { + const { parseLatest } = await import("./fx-parse.mjs"); + return parseLatest(await getText(API + "/rates?base=eur")); + }, + async fetchCurrencies() { + const { parseCurrencies } = await import("./fx-parse.mjs"); + const current = await getText(API + "/currencies"); + const all = await getText(API + "/currencies?scope=all"); + return parseCurrencies(current, all); + }, + async fetchSeries(from, quotes) { + const { parseSeries } = await import("./fx-parse.mjs"); + const list = quotes.map((code) => encodeURIComponent(String(code).toLowerCase())).join(","); + const text = await getText(API + "/rates?base=eur&from=" + from + ""es=" + list); + return parseSeries(text); + }, +}; diff --git a/plugins/exchange-rates/src/App.vue b/plugins/exchange-rates/src/App.vue new file mode 100644 index 000000000..22f57549c --- /dev/null +++ b/plugins/exchange-rates/src/App.vue @@ -0,0 +1,656 @@ + + + diff --git a/plugins/exchange-rates/src/browser-fx.ts b/plugins/exchange-rates/src/browser-fx.ts new file mode 100644 index 000000000..3e21d413a --- /dev/null +++ b/plugins/exchange-rates/src/browser-fx.ts @@ -0,0 +1,48 @@ +import { parseCurrencies, parseLatest, parseSeries } from "../public/fx-parse.mjs"; +import type { FxBridge } from "./types"; + +const API = "https://api.frankfurter.dev/v2"; + +async function getText(url: string): Promise { + const response = await fetch(url, { headers: { accept: "application/json" } }); + const text = await response.text(); + if (!response.ok) { + const error = new Error(`HTTP ${response.status}`); + (error as Error & { status?: number }).status = response.status; + throw error; + } + return text; +} + +export function installBrowserFx(): FxBridge { + const fx: FxBridge = { + getItem(key) { + const raw = localStorage.getItem(key); + if (raw == null) return null; + try { + return JSON.parse(raw) as unknown; + } catch { + return null; + } + }, + setItem(key, value) { + localStorage.setItem(key, JSON.stringify(value)); + }, + async fetchRates() { + return parseLatest(await getText(`${API}/rates?base=eur`)); + }, + async fetchCurrencies() { + const [current, all] = await Promise.all([ + getText(`${API}/currencies`), + getText(`${API}/currencies?scope=all`), + ]); + return parseCurrencies(current, all); + }, + async fetchSeries(from, quotes) { + const list = quotes.map((code) => encodeURIComponent(code.toLowerCase())).join(","); + return parseSeries(await getText(`${API}/rates?base=eur&from=${from}"es=${list}`)); + }, + }; + window.fx = fx; + return fx; +} diff --git a/plugins/exchange-rates/src/convert.check.mjs b/plugins/exchange-rates/src/convert.check.mjs new file mode 100644 index 000000000..9b05b338a --- /dev/null +++ b/plugins/exchange-rates/src/convert.check.mjs @@ -0,0 +1,59 @@ +import { + appendMissing, + canonicalAmount, + commitRowAmount, + convertAmount, + formatAmount, + formatPercent, + moveItem, + reselectCurrency, +} from "./convert.ts"; +import { parseCurrencies, parseLatest } from "../public/fx-parse.mjs"; + +function assert(condition, message) { + if (!condition) throw new Error(message); +} + +const rates = { EUR: "1", USD: "2", JPY: "200" }; + +assert(convertAmount("10.50", "USD", "USD", rates) === "10.5", "base to itself keeps the amount"); +assert(convertAmount("2", "USD", "EUR", rates) === "1", "cross rate uses the euro pivot"); +assert(convertAmount("1", "USD", "ZZZ", rates) === null, "missing rate is empty"); +assert(formatAmount("1.005", 2) === "1.01", "half up at the display digit"); +assert(formatAmount("1.004", 2) === "1.00", "below half stays down"); +assert(formatAmount("0", 2) === "0.00", "zero pads to the selected digits"); +assert(formatPercent("1", "1.002897") === "+0.2897%", "percent keeps four digits and a sign"); +assert(formatPercent("2", "1") === "-50.0000%", "a drop is negative"); + +const board = { base: "USD", amount: "0", codes: ["CNY", "USD", "EUR", "JPY", "HKD", "TWD"] }; +const committed = commitRowAmount(board, "JPY", "10.50"); +assert(committed?.base === "JPY" && committed.amount === "10.5", "committing another row switches the base"); +assert(committed.codes.includes("JPY") && committed.codes.includes("USD"), "the switched currency stays in the list"); +assert(commitRowAmount(board, "USD", "nope") === null, "a bad amount does not commit"); + +const switched = reselectCurrency( + { base: "USD", amount: "2", codes: ["USD", "EUR"] }, + "EUR", + rates, +); +assert(switched?.base === "EUR" && switched.amount === "1", "reselect keeps the money value"); +assert(canonicalAmount("00.50") === "0.5", "canonical amount strips extra zeros"); + +const added = appendMissing(["CNY"], ["USD", "CNY", "EUR"]); +assert(added.join() === "CNY,USD,EUR", "add all skips codes already in the list"); +assert(moveItem(["A", "B", "C"], 0, 2).join() === "B,C,A", "drag moves a row"); + +const parsed = parseLatest( + '[{"date":"2026-11-10","base":"EUR","quote":"IRR","rate":0.00000054341},{"date":"2026-11-09","base":"EUR","quote":"EUR","rate":1}]', +); +assert(parsed.rates.IRR === "0.00000054341", "rate text keeps every fraction digit"); +assert(parsed.date === "2026-11-10", "update date is the newest observation"); + +const currencies = parseCurrencies( + '[{"iso_code":"USD","name":"US Dollar"}]', + '[{"iso_code":"USD"},{"iso_code":"DEM"}]', +); +assert(currencies.find((item) => item.code === "DEM")?.deprecated === true, "legacy code is deprecated"); +assert(currencies.find((item) => item.code === "USD")?.deprecated === false, "current code stays available"); + +console.log("convert.check ok"); diff --git a/plugins/exchange-rates/src/convert.ts b/plugins/exchange-rates/src/convert.ts new file mode 100644 index 000000000..c03ab21e1 --- /dev/null +++ b/plugins/exchange-rates/src/convert.ts @@ -0,0 +1,160 @@ +// ponytail: Frankfurter blended rates keep 5 significant figures below 1. +// Their plain-decimal example 0.00000054341 has 11 fraction digits. +// The latest table fetched on 2026-11-11 topped out at 9, so the cap stays 11. +export const MAX_FRACTION_DIGITS = 11; +const SCALE = 17; +const POW = 10n ** BigInt(SCALE); + +export const COMMON_ORDER = [ + "USD", "EUR", "GBP", "CAD", "AUD", "JPY", "CNY", "HKD", "TWD", "SGD", + "CHF", "NZD", "KRW", "THB", "MYR", "INR", "PHP", "IDR", "VND", "MXN", + "BRL", "ZAR", "SEK", "NOK", "DKK", "PLN", "CZK", "HUF", "TRY", "AED", + "SAR", "ILS", +]; + +export type Board = { base: string; amount: string; codes: string[] }; + +export function canonicalAmount(raw: string): string | null { + const text = raw.trim(); + if (!/^\d+(\.\d+)?$/.test(text)) return null; + const [ints, frac] = text.split("."); + const whole = ints.replace(/^0+/, "") || "0"; + if (frac == null) return whole; + const tail = frac.replace(/0+$/, ""); + return tail ? `${whole}.${tail}` : whole; +} + +export function parseScaled(raw: string): bigint | null { + const text = canonicalAmount(raw); + if (text == null) return null; + const [ints, frac = ""] = text.split("."); + const head = frac.slice(0, SCALE).padEnd(SCALE, "0"); + let value = BigInt(ints + head); + if (frac.length > SCALE && frac[SCALE] >= "5") value += 1n; + return value; +} + +function scaledToCanonical(value: bigint): string { + const negative = value < 0n; + const abs = negative ? -value : value; + const digits = abs.toString().padStart(SCALE + 1, "0"); + const whole = digits.slice(0, -SCALE).replace(/^0+/, "") || "0"; + const frac = digits.slice(-SCALE).replace(/0+$/, ""); + const body = frac ? `${whole}.${frac}` : whole; + return negative && body !== "0" ? `-${body}` : body; +} + +function mulDiv(amount: bigint, quote: bigint, base: bigint): bigint | null { + if (base === 0n) return null; + const product = amount * quote; + let value = product / base; + const rest = product % base; + if (rest * 2n >= base) value += 1n; + return value; +} + +export function convertAmount( + amount: string, + base: string, + quote: string, + rates: Record, +): string | null { + const canonical = canonicalAmount(amount); + if (canonical == null) return null; + if (base === quote) return canonical; + const baseRate = rates[base]; + const quoteRate = rates[quote]; + if (!baseRate || !quoteRate) return null; + const amountScaled = parseScaled(canonical); + const baseScaled = parseScaled(baseRate); + const quoteScaled = parseScaled(quoteRate); + if (amountScaled == null || baseScaled == null || quoteScaled == null) return null; + const value = mulDiv(amountScaled, quoteScaled, baseScaled); + if (value == null) return null; + return scaledToCanonical(value); +} + +export function formatAmount(raw: string, digits: number): string | null { + const scaled = parseScaled(raw); + if (scaled == null) return null; + const places = Math.min(MAX_FRACTION_DIGITS, Math.max(0, digits)); + const factor = 10n ** BigInt(places); + const negative = scaled < 0n; + const abs = negative ? -scaled : scaled; + let rounded = (abs * factor + POW / 2n) / POW; + const whole = rounded / factor; + const frac = rounded % factor; + let text = whole.toString(); + if (places > 0) text += `.${frac.toString().padStart(places, "0")}`; + return negative ? `-${text}` : text; +} + +export function formatGrouped(raw: string, digits: number): string | null { + const plain = formatAmount(raw, digits); + if (plain == null) return null; + const negative = plain.startsWith("-"); + const body = negative ? plain.slice(1) : plain; + const [whole, frac] = body.split("."); + const grouped = whole.replace(/\B(?=(\d{3})+(?!\d))/g, ","); + const text = frac != null ? `${grouped}.${frac}` : grouped; + return negative ? `-${text}` : text; +} + +export function formatPercent(prev: string, next: string): string | null { + const prevScaled = parseScaled(prev); + const nextScaled = parseScaled(next); + if (prevScaled == null || nextScaled == null || prevScaled === 0n) return null; + const diff = nextScaled - prevScaled; + const negative = diff < 0n; + const divisor = prevScaled < 0n ? -prevScaled : prevScaled; + const ticks = ((negative ? -diff : diff) * 1_000_000n + divisor / 2n) / divisor; + const whole = ticks / 10000n; + const frac = ticks % 10000n; + return `${negative ? "-" : "+"}${whole.toString()}.${frac.toString().padStart(4, "0")}%`; +} + +export function commitRowAmount(board: Board, code: string, raw: string): Board | null { + const amount = canonicalAmount(raw); + if (amount == null) return null; + const codes = board.codes.includes(code) ? board.codes : board.codes.concat(code); + if (code === board.base) return { base: board.base, amount, codes }; + return { base: code, amount, codes }; +} + +export function reselectCurrency( + board: Board, + code: string, + rates: Record, +): Board | null { + if (!board.codes.includes(code)) return null; + if (code === board.base) return board; + const amount = convertAmount(board.amount, board.base, code, rates); + if (amount == null) return null; + return { base: code, amount, codes: board.codes }; +} + +export function appendMissing(codes: string[], adding: string[]): string[] { + const have = new Set(codes); + return codes.concat(adding.filter((code) => !have.has(code))); +} + +export function sortCodes(codes: string[]): string[] { + return codes.slice().sort((a, b) => { + const ia = COMMON_ORDER.indexOf(a); + const ib = COMMON_ORDER.indexOf(b); + if (ia !== -1 || ib !== -1) { + if (ia === -1) return 1; + if (ib === -1) return -1; + return ia - ib; + } + return a.localeCompare(b); + }); +} + +export function moveItem(list: T[], from: number, to: number): T[] { + if (from === to || from < 0 || to < 0 || from >= list.length || to >= list.length) return list.slice(); + const next = list.slice(); + const [item] = next.splice(from, 1); + next.splice(to, 0, item); + return next; +} diff --git a/plugins/exchange-rates/src/dev-preview.css b/plugins/exchange-rates/src/dev-preview.css new file mode 100644 index 000000000..2dae3797e --- /dev/null +++ b/plugins/exchange-rates/src/dev-preview.css @@ -0,0 +1,16 @@ +/* Browser stand-in for the ZTools panel. Imported only while `npm run dev` is running. */ + +html.dev-host { + background: #ececec; +} + +html.dev-host.dev-dark { + background: #2b2b2b; +} + +html.dev-host body { + box-sizing: border-box; + width: min(980px, 100%); + min-height: 720px; + margin: 0 auto; +} diff --git a/plugins/exchange-rates/src/flags-map.ts b/plugins/exchange-rates/src/flags-map.ts new file mode 100644 index 000000000..120a49098 --- /dev/null +++ b/plugins/exchange-rates/src/flags-map.ts @@ -0,0 +1,30 @@ +const FLAG_REGION: Record = { + AED: "ae", AFN: "af", ALL: "al", AMD: "am", ANG: "cw", AOA: "ao", ARS: "ar", AUD: "au", + AWG: "aw", AZN: "az", BAM: "ba", BBD: "bb", BDT: "bd", BHD: "bh", BIF: "bi", BMD: "bm", + BND: "bn", BOB: "bo", BRL: "br", BSD: "bs", BTN: "bt", BWP: "bw", BYN: "by", BZD: "bz", + CAD: "ca", CDF: "cd", CHF: "ch", CLP: "cl", CNY: "cn", COP: "co", CRC: "cr", CUP: "cu", + CVE: "cv", CZK: "cz", DJF: "dj", DKK: "dk", DOP: "do", DZD: "dz", EGP: "eg", ERN: "er", + ETB: "et", EUR: "eu", FJD: "fj", FKP: "fk", GBP: "gb", GEL: "ge", GHS: "gh", GIP: "gi", + GMD: "gm", GNF: "gn", GTQ: "gt", GYD: "gy", HKD: "hk", HNL: "hn", HTG: "ht", HUF: "hu", + IDR: "id", ILS: "il", INR: "in", IQD: "iq", IRR: "ir", ISK: "is", JMD: "jm", JOD: "jo", + JPY: "jp", KES: "ke", KGS: "kg", KHR: "kh", KMF: "km", KPW: "kp", KRW: "kr", KWD: "kw", + KYD: "ky", KZT: "kz", LAK: "la", LBP: "lb", LKR: "lk", LRD: "lr", LSL: "ls", LYD: "ly", + MAD: "ma", MDL: "md", MGA: "mg", MKD: "mk", MMK: "mm", MNT: "mn", MOP: "mo", MRU: "mr", + MUR: "mu", MVR: "mv", MWK: "mw", MXN: "mx", MYR: "my", MZN: "mz", NAD: "na", NGN: "ng", + NIO: "ni", NOK: "no", NPR: "np", NZD: "nz", OMR: "om", PAB: "pa", PEN: "pe", PGK: "pg", + PHP: "ph", PKR: "pk", PLN: "pl", PYG: "py", QAR: "qa", RON: "ro", RSD: "rs", RUB: "ru", + RWF: "rw", SAR: "sa", SBD: "sb", SCR: "sc", SDG: "sd", SEK: "se", SGD: "sg", SHP: "sh", + SLE: "sl", SOS: "so", SRD: "sr", SSP: "ss", STN: "st", SYP: "sy", SZL: "sz", THB: "th", + TJS: "tj", TMT: "tm", TND: "tn", TOP: "to", TRY: "tr", TTD: "tt", TWD: "tw", TZS: "tz", + UAH: "ua", UGX: "ug", USD: "us", UYU: "uy", UZS: "uz", VES: "ve", VND: "vn", VUV: "vu", + WST: "ws", YER: "ye", ZAR: "za", ZMW: "zm", ZWG: "zw", + ATS: "at", BEF: "be", DEM: "de", ESP: "es", FIM: "fi", FRF: "fr", GRD: "gr", IEP: "ie", + ITL: "it", LUF: "lu", NLG: "nl", PTE: "pt", CYP: "cy", EEK: "ee", LVL: "lv", LTL: "lt", + MTL: "mt", SIT: "si", SKK: "sk", HRK: "hr", BGN: "bg", ROL: "ro", TRL: "tr", BYR: "by", + ZMK: "zm", AZM: "az", AFA: "af", CSD: "rs", VEF: "ve", VEB: "ve", GHC: "gh", MZM: "mz", + TMM: "tm", ZWD: "zw", RUR: "ru", ADP: "ad", AON: "ao", BAD: "ba", CUC: "cu", +}; + +export function flagRegion(code: string): string | null { + return FLAG_REGION[code] ?? null; +} diff --git a/plugins/exchange-rates/src/i18n.ts b/plugins/exchange-rates/src/i18n.ts new file mode 100644 index 000000000..c01bdfdb9 --- /dev/null +++ b/plugins/exchange-rates/src/i18n.ts @@ -0,0 +1,87 @@ +export type Locale = "zh-Hant" | "en"; + +export type Messages = { + digits: string; + select: string; + addAll: string; + deprecated: string; + dark: string; + updated: string; + index: string; + flag: string; + name: string; + code: string; + symbol: string; + amount: string; + action: string; + trend: string; + remove: string; + noRate: string; + already: string; + change: string; + chart: string; + ratesFailed: string; + blocks: string[]; +}; + +const zh: Messages = { + digits: "小數位數", + select: "選擇貨幣", + addAll: "添加全部", + deprecated: "顯示已廢棄的貨幣", + dark: "深色模式", + updated: "匯率更新時間", + index: "序號", + flag: "國旗", + name: "國家名稱", + code: "代碼", + symbol: "符號", + amount: "折算金額", + action: "操作", + trend: "趨勢", + remove: "移除", + noRate: "無匯率", + already: "貨幣已參與計算", + change: "變動(較上一個觀測日)", + chart: "圖表(近 30 個觀測日)", + ratesFailed: "匯率更新失敗,畫面仍用上次的資料", + blocks: ["不可以哦~", "基準貨幣要留著", "這個不能移除", "先換一個基準吧", "它正在當基準"], +}; + +const en: Messages = { + digits: "Decimal places", + select: "Select currency", + addAll: "Add all", + deprecated: "Show deprecated currencies", + dark: "Dark mode", + updated: "Rates updated", + index: "No.", + flag: "Flag", + name: "Name", + code: "Code", + symbol: "Symbol", + amount: "Amount", + action: "Action", + trend: "Trend", + remove: "Remove", + noRate: "No rate", + already: "Already in the calculation", + change: "Change (vs previous observation)", + chart: "Chart (last 30 observations)", + ratesFailed: "Couldn't update rates. Showing the last saved data.", + blocks: [ + "Not this one~", + "Keep the base currency", + "This one stays", + "Switch the base first", + "It's the base right now", + ], +}; + +export function resolveLocale(language: string): Locale { + return language.toLowerCase().startsWith("zh") ? "zh-Hant" : "en"; +} + +export function messages(locale: Locale): Messages { + return locale === "zh-Hant" ? zh : en; +} diff --git a/plugins/exchange-rates/src/main.ts b/plugins/exchange-rates/src/main.ts new file mode 100644 index 000000000..c0d23013c --- /dev/null +++ b/plugins/exchange-rates/src/main.ts @@ -0,0 +1,18 @@ +import { createApp } from "vue"; +import App from "./App.vue"; +import { installBrowserFx } from "./browser-fx"; +import { messages, resolveLocale } from "./i18n"; +import "./style.css"; + +if (import.meta.env.DEV) { + document.documentElement.classList.add("dev-host"); + void import("./dev-preview.css"); +} + +if (!window.fx) installBrowserFx(); + +const locale = resolveLocale(navigator.language || "en"); +document.documentElement.lang = locale; +document.title = messages(locale).select === "選擇貨幣" ? "匯率換算" : "Exchange rates"; + +createApp(App).mount("#app"); diff --git a/plugins/exchange-rates/src/style.css b/plugins/exchange-rates/src/style.css new file mode 100644 index 000000000..9af260986 --- /dev/null +++ b/plugins/exchange-rates/src/style.css @@ -0,0 +1,349 @@ +:root { + color-scheme: light dark; + --bg-app: transparent; + --text: #222; + --muted: #667; + --header: rgba(255, 255, 255, 0.72); + --row: rgba(255, 255, 255, 0.58); + --line: rgba(0, 0, 0, 0.08); + --menu: rgba(255, 255, 255, 0.96); + --hover: rgba(0, 0, 0, 0.06); + --input: rgba(255, 255, 255, 0.8); + --trend: #2f9e44; + --remove: #e6b325; + --remove-text: #2b2208; + --tip: #f15a22; + --badge: #1c1c1c; + --badge-text: #fff; + --up-bg: #d9f5e5; + --up-fg: #137a45; + --down-bg: #f8d6dc; + --down-fg: #b42333; + --line-chart: #3b6fd8; + --base-trend: rgba(20, 52, 120, 0.12); +} + +html, +body, +#app { + margin: 0; + min-height: 100%; + background: transparent; +} + +body { + color: var(--text); +} + +.app { + min-height: 100vh; + padding: 12px; + color: var(--text); + font: 14px/1.4 "Segoe UI", "Microsoft JhengHei", sans-serif; + background: var(--bg-app); +} + +.app.dark { + --text: #f2f2f2; + --muted: #b7b7b7; + --header: rgba(32, 32, 32, 0.92); + --row: rgba(48, 48, 48, 0.9); + --line: rgba(255, 255, 255, 0.08); + --menu: rgba(42, 42, 42, 0.98); + --hover: rgba(255, 255, 255, 0.08); + --input: rgba(28, 28, 28, 0.9); + --base-trend: rgba(10, 28, 72, 0.95); + color-scheme: dark; +} + +.toolbar { + display: flex; + flex-wrap: wrap; + gap: 14px; + align-items: center; + margin-bottom: 12px; +} + +.digits, +.check, +.updated { + display: flex; + gap: 8px; + align-items: center; +} + +.digits input { + width: 4.2rem; + padding: 4px 6px; + color: inherit; + background: var(--input); + border: 1px solid var(--line); + border-radius: 4px; +} + +.picker { + position: relative; + min-width: 220px; +} + +.picker input, +.amount input { + width: 100%; + box-sizing: border-box; + padding: 6px 8px; + color: inherit; + background: var(--input); + border: 1px solid var(--line); + border-radius: 4px; +} + +.menu { + position: absolute; + z-index: 20; + top: calc(100% + 4px); + left: 0; + width: 280px; + max-height: 280px; + margin: 0; + padding: 4px 0; + overflow: auto; + list-style: none; + background: var(--menu); + border-radius: 6px; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28); +} + +.menu li { + padding: 8px 12px; + cursor: pointer; +} + +.menu li:hover { + background: var(--hover); +} + +button { + font: inherit; + cursor: pointer; +} + +.icon-button { + padding: 2px 8px; + color: inherit; + background: transparent; + border: 0; +} + +table { + width: 100%; + margin-bottom: 14px; + border-collapse: collapse; +} + +.board { + table-layout: fixed; +} + +.col-index, +.col-flag, +.col-name, +.col-code, +.col-symbol { width: 4.55rem; } +.col-action { width: 5.5rem; } + +.board th:nth-child(-n + 5), +.board td:nth-child(-n + 5) { + white-space: nowrap; +} + +.board th:nth-child(3), +.board td:nth-child(3) { + overflow: hidden; + text-overflow: ellipsis; +} + +th, +td { + padding: 8px 10px; + text-align: left; + border-top: 1px solid var(--line); +} + +th { + background: var(--header); + border-top: 0; +} + +td { + background: var(--row); +} + +.num, +.amount { + text-align: right; + font-variant-numeric: tabular-nums; +} + +.amount button, +.amount input { + width: 100%; + padding: 4px 6px; + color: inherit; + text-align: right; + background: transparent; + border: 1px solid transparent; + border-radius: 4px; +} + +.amount input { + font-family: inherit; + font-size: 15px; +} + +.amount button:hover, +.amount input:focus { + border-color: var(--line); + outline: none; +} + +.flag { + display: block; + width: 28px; + height: 18px; + object-fit: cover; + border-radius: 2px; +} + +.flag-fallback { + color: var(--muted); + font-size: 12px; +} + +.drag-source { + cursor: grab; + user-select: none; + touch-action: none; +} + +.currency-row td { + transform: var(--shift, none); + transition: transform 180ms ease; +} + +.currency-row.dragging { + position: relative; + z-index: 4; +} + +.currency-row.dragging td { + position: relative; + z-index: 4; + background: var(--menu); + box-shadow: 0 10px 22px rgba(0, 0, 0, 0.28); + transition: none; + cursor: grabbing; +} + +.badge { + display: inline-block; + padding: 2px 7px; + color: var(--badge-text); + font-weight: 700; + background: var(--badge); + border-radius: 4px; +} + +.trend-button, +.remove-button { + display: inline-flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + min-width: 4.5rem; + padding: 4px 12px; + border: 0; + border-radius: 4px; +} + +.trend-button { + color: #fff; + background: var(--trend); +} + +.remove-button { + color: var(--remove-text); + background: var(--remove); +} + +.remove-wrap { + position: relative; + display: inline-flex; +} + +.block-tip { + position: absolute; + top: 50%; + right: calc(100% + 8px); + z-index: 5; + padding: 6px 10px; + color: #fff; + white-space: nowrap; + background: var(--tip); + border-radius: 6px; + transform: translateY(-50%); +} + +.toast { + position: fixed; + top: 18px; + left: 50%; + z-index: 50; + padding: 10px 16px; + color: #fff; + background: rgba(20, 20, 20, 0.92); + border-radius: 8px; + transform: translateX(-50%); +} + +.mask { + position: fixed; + inset: 0; + z-index: 30; + display: flex; + align-items: center; + justify-content: center; + padding: 28px; + background: rgba(0, 0, 0, 0.35); +} + +.trend-panel { + width: min(920px, 100%); + max-height: 100%; + overflow: auto; + background: var(--menu); + border-radius: 10px; +} + +.trend-panel .base-row td { + background: var(--base-trend); +} + +.pill { + display: inline-block; + padding: 2px 8px; + border-radius: 6px; +} + +.up { + color: var(--up-fg); + background: var(--up-bg); +} + +.down { + color: var(--down-fg); + background: var(--down-bg); +} + +.spark { + display: block; +} diff --git a/plugins/exchange-rates/src/types.ts b/plugins/exchange-rates/src/types.ts new file mode 100644 index 000000000..c72eb10c5 --- /dev/null +++ b/plugins/exchange-rates/src/types.ts @@ -0,0 +1,34 @@ +export type RateBook = { + date: string; + fetchedAt: number; + rates: Record; +}; + +export type CurrencyInfo = { + code: string; + deprecated: boolean; +}; + +export type SeriesPoint = { + date: string; + quote: string; + rate: string; +}; + +export type Settings = { + base: string; + amount: string; + digits: number; + dark: boolean; + darkLocked: boolean; + showDeprecated: boolean; + codes: string[]; +}; + +export type FxBridge = { + getItem(key: string): unknown; + setItem(key: string, value: unknown): void; + fetchRates(): Promise; + fetchCurrencies(): Promise; + fetchSeries(from: string, quotes: string[]): Promise; +}; diff --git a/plugins/exchange-rates/src/vite-env.d.ts b/plugins/exchange-rates/src/vite-env.d.ts new file mode 100644 index 000000000..a57f33efe --- /dev/null +++ b/plugins/exchange-rates/src/vite-env.d.ts @@ -0,0 +1,31 @@ +/// + +declare module "*.vue" { + import type { DefineComponent } from "vue"; + const component: DefineComponent; + export default component; +} + +declare module "../public/fx-parse.mjs" { + export function parseLatest(text: string): import("./types").RateBook; + export function parseCurrencies(currentText: string, allText: string): import("./types").CurrencyInfo[]; + export function parseSeries(text: string): import("./types").SeriesPoint[]; +} + +interface ZToolsHost { + isDarkColors(): boolean; + getThemeInfo(): { isDark?: boolean }; + onThemeChange(callback: (info: { isDark?: boolean }) => void): void; + onPluginEnter(callback: (payload: unknown) => void): void; + setExpendHeight(height: number): void; + showToast(message: string): void; + dbStorage?: { + getItem(key: string): unknown; + setItem(key: string, value: unknown): void; + }; +} + +interface Window { + fx?: import("./types").FxBridge; + ztools?: ZToolsHost; +} diff --git a/plugins/exchange-rates/tsconfig.json b/plugins/exchange-rates/tsconfig.json new file mode 100644 index 000000000..6cfb1be09 --- /dev/null +++ b/plugins/exchange-rates/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "noEmit": true, + "isolatedModules": true, + "skipLibCheck": true, + "lib": ["ES2022", "DOM"], + "useDefineForClassFields": true, + "types": ["vite/client"] + }, + "include": ["src"] +} diff --git a/plugins/exchange-rates/vite.config.ts b/plugins/exchange-rates/vite.config.ts new file mode 100644 index 000000000..60556e7f8 --- /dev/null +++ b/plugins/exchange-rates/vite.config.ts @@ -0,0 +1,26 @@ +import { mkdirSync, readFileSync, writeFileSync } from "node:fs"; +import { resolve } from "node:path"; +import { defineConfig, type Plugin } from "vite"; +import vue from "@vitejs/plugin-vue"; + +function emitDistPluginJson(): Plugin { + return { + name: "emit-dist-plugin-json", + closeBundle() { + const source = JSON.parse(readFileSync(resolve("plugin.json"), "utf8")) as Record; + const dist = { + ...source, + main: "index.html", + logo: "logo.png", + preload: "preload.js", + }; + mkdirSync(resolve("dist"), { recursive: true }); + writeFileSync(resolve("dist/plugin.json"), JSON.stringify(dist, null, 2)); + }, + }; +} + +export default defineConfig({ + base: "./", + plugins: [vue(), emitDistPluginJson()], +});