Commit 121480df authored by Domi's avatar Domi

i18n-tool.py

parent 2bc86acf
......@@ -9,12 +9,17 @@
"version": "0.0.0",
"dependencies": {
"@types/turndown": "^5.0.4",
"@vueuse/core": "^10.7.1",
"@vueuse/gesture": "^2.0.0-beta.1",
"buffer": "^6.0.3",
"file-type": "^18.7.0",
"lodash-es": "^4.17.21",
"mammoth": "^1.6.0",
"pdfjs-dist": "^4.0.269",
"tiktoken": "^1.0.11",
"turndown": "^7.1.2",
"vite-plugin-top-level-await": "^1.4.1",
"vite-plugin-wasm": "^3.3.0",
"vue": "^3.3.4",
"vue-i18n": "^9.7.0"
},
......@@ -31,7 +36,7 @@
"cross-env": "^7.0.3",
"npm-run-all2": "^6.1.1",
"postcss": "^8.4.31",
"tailwindcss": "^3.3.5",
"tailwindcss": "^3.4.1",
"typescript": "~5.2.0",
"vite": "^4.4.11",
"vitest": "^1.1.0",
......@@ -513,7 +518,6 @@
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"android"
......@@ -545,7 +549,6 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"android"
......@@ -561,7 +564,6 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
......@@ -577,7 +579,6 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
......@@ -593,7 +594,6 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
......@@ -609,7 +609,6 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
......@@ -625,7 +624,6 @@
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"linux"
......@@ -641,7 +639,6 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
......@@ -657,7 +654,6 @@
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"linux"
......@@ -673,7 +669,6 @@
"cpu": [
"loong64"
],
"dev": true,
"optional": true,
"os": [
"linux"
......@@ -689,7 +684,6 @@
"cpu": [
"mips64el"
],
"dev": true,
"optional": true,
"os": [
"linux"
......@@ -705,7 +699,6 @@
"cpu": [
"ppc64"
],
"dev": true,
"optional": true,
"os": [
"linux"
......@@ -721,7 +714,6 @@
"cpu": [
"riscv64"
],
"dev": true,
"optional": true,
"os": [
"linux"
......@@ -737,7 +729,6 @@
"cpu": [
"s390x"
],
"dev": true,
"optional": true,
"os": [
"linux"
......@@ -753,7 +744,6 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
......@@ -769,7 +759,6 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"netbsd"
......@@ -785,7 +774,6 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"openbsd"
......@@ -801,7 +789,6 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"sunos"
......@@ -817,7 +804,6 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
......@@ -833,7 +819,6 @@
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"win32"
......@@ -847,7 +832,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
......@@ -1108,6 +1092,22 @@
"node": ">= 8"
}
},
"node_modules/@rollup/plugin-virtual": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-3.0.2.tgz",
"integrity": "sha512-10monEYsBp3scM4/ND4LNH5Rxvh3e/cVeL3jWTgZ2SrQ+BmUoQcopVQvnaMcOnykb1VkxUFuDAN+0FnpTFRy2A==",
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
}
},
"node_modules/@rollup/pluginutils": {
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.5.tgz",
......@@ -1305,6 +1305,203 @@
"integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
"dev": true
},
"node_modules/@swc/core": {
"version": "1.3.102",
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.102.tgz",
"integrity": "sha512-OAjNLY/f6QWKSDzaM3bk31A+OYHu6cPa9P/rFIx8X5d24tHXUpRiiq6/PYI6SQRjUPlB72GjsjoEU8F+ALadHg==",
"hasInstallScript": true,
"dependencies": {
"@swc/counter": "^0.1.1",
"@swc/types": "^0.1.5"
},
"engines": {
"node": ">=10"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/swc"
},
"optionalDependencies": {
"@swc/core-darwin-arm64": "1.3.102",
"@swc/core-darwin-x64": "1.3.102",
"@swc/core-linux-arm-gnueabihf": "1.3.102",
"@swc/core-linux-arm64-gnu": "1.3.102",
"@swc/core-linux-arm64-musl": "1.3.102",
"@swc/core-linux-x64-gnu": "1.3.102",
"@swc/core-linux-x64-musl": "1.3.102",
"@swc/core-win32-arm64-msvc": "1.3.102",
"@swc/core-win32-ia32-msvc": "1.3.102",
"@swc/core-win32-x64-msvc": "1.3.102"
},
"peerDependencies": {
"@swc/helpers": "^0.5.0"
},
"peerDependenciesMeta": {
"@swc/helpers": {
"optional": true
}
}
},
"node_modules/@swc/core-darwin-arm64": {
"version": "1.3.102",
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.102.tgz",
"integrity": "sha512-CJDxA5Wd2cUMULj3bjx4GEoiYyyiyL8oIOu4Nhrs9X+tlg8DnkCm4nI57RJGP8Mf6BaXPIJkHX8yjcefK2RlDA==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-darwin-x64": {
"version": "1.3.102",
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.102.tgz",
"integrity": "sha512-X5akDkHwk6oAer49oER0qZMjNMkLH3IOZaV1m98uXIasAGyjo5WH1MKPeMLY1sY6V6TrufzwiSwD4ds571ytcg==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-linux-arm-gnueabihf": {
"version": "1.3.102",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.102.tgz",
"integrity": "sha512-kJH3XtZP9YQdjq/wYVBeFuiVQl4HaC4WwRrIxAHwe2OyvrwUI43dpW3LpxSggBnxXcVCXYWf36sTnv8S75o2Gw==",
"cpu": [
"arm"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-linux-arm64-gnu": {
"version": "1.3.102",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.102.tgz",
"integrity": "sha512-flQP2WDyCgO24WmKA1wjjTx+xfCmavUete2Kp6yrM+631IHLGnr17eu7rYJ/d4EnDBId/ytMyrnWbTVkaVrpbQ==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-linux-arm64-musl": {
"version": "1.3.102",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.102.tgz",
"integrity": "sha512-bQEQSnC44DyoIGLw1+fNXKVGoCHi7eJOHr8BdH0y1ooy9ArskMjwobBFae3GX4T1AfnrTaejyr0FvLYIb0Zkog==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-linux-x64-gnu": {
"version": "1.3.102",
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.102.tgz",
"integrity": "sha512-dFvnhpI478svQSxqISMt00MKTDS0e4YtIr+ioZDG/uJ/q+RpcNy3QI2KMm05Fsc8Y0d4krVtvCKWgfUMsJZXAg==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-linux-x64-musl": {
"version": "1.3.102",
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.102.tgz",
"integrity": "sha512-+a0M3CvjeIRNA/jTCzWEDh2V+mhKGvLreHOL7J97oULZy5yg4gf7h8lQX9J8t9QLbf6fsk+0F8bVH1Ie/PbXjA==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-win32-arm64-msvc": {
"version": "1.3.102",
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.102.tgz",
"integrity": "sha512-w76JWLjkZNOfkB25nqdWUNCbt0zJ41CnWrJPZ+LxEai3zAnb2YtgB/cCIrwxDebRuMgE9EJXRj7gDDaTEAMOOQ==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-win32-ia32-msvc": {
"version": "1.3.102",
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.102.tgz",
"integrity": "sha512-vlDb09HiGqKwz+2cxDS9T5/461ipUQBplvuhW+cCbzzGuPq8lll2xeyZU0N1E4Sz3MVdSPx1tJREuRvlQjrwNg==",
"cpu": [
"ia32"
],
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-win32-x64-msvc": {
"version": "1.3.102",
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.102.tgz",
"integrity": "sha512-E/jfSD7sShllxBwwgDPeXp1UxvIqehj/ShSUqq1pjR/IDRXngcRSXKJK92mJkNFY7suH6BcCWwzrxZgkO7sWmw==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/counter": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.2.tgz",
"integrity": "sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw=="
},
"node_modules/@swc/types": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.5.tgz",
"integrity": "sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw=="
},
"node_modules/@tokenizer/token": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
......@@ -1371,7 +1568,7 @@
"version": "18.18.9",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.9.tgz",
"integrity": "sha512-0f5klcuImLnG4Qreu9hPj/rEfFq6YRc5n2mAjSsH+ec/mJL+3voBH0+8T7o8RpFjH7ovc+TRsL/c7OYIQsPTfQ==",
"dev": true,
"devOptional": true,
"dependencies": {
"undici-types": "~5.26.4"
}
......@@ -1386,6 +1583,11 @@
"resolved": "https://registry.npmjs.org/@types/turndown/-/turndown-5.0.4.tgz",
"integrity": "sha512-28GI33lCCkU4SGH1GvjDhFgOVr+Tym4PXGBIU1buJUa6xQolniPArtUT+kv42RR2N9MsMLInkr904Aq+ESHBJg=="
},
"node_modules/@types/web-bluetooth": {
"version": "0.0.20",
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz",
"integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow=="
},
"node_modules/@vitejs/plugin-vue": {
"version": "4.4.1",
"dev": true,
......@@ -1715,6 +1917,134 @@
"dev": true,
"license": "MIT"
},
"node_modules/@vueuse/core": {
"version": "10.7.1",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.7.1.tgz",
"integrity": "sha512-74mWHlaesJSWGp1ihg76vAnfVq9NTv1YT0SYhAQ6zwFNdBkkP+CKKJmVOEHcdSnLXCXYiL5e7MaewblfiYLP7g==",
"dependencies": {
"@types/web-bluetooth": "^0.0.20",
"@vueuse/metadata": "10.7.1",
"@vueuse/shared": "10.7.1",
"vue-demi": ">=0.14.6"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/core/node_modules/vue-demi": {
"version": "0.14.6",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
"integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/@vueuse/gesture": {
"version": "2.0.0-beta.1",
"resolved": "https://registry.npmjs.org/@vueuse/gesture/-/gesture-2.0.0-beta.1.tgz",
"integrity": "sha512-HTLibLy3bh6TjRnDAbMAvHSsEmrkRituMj2x+mHwmp1EnM8A8CDRTfNJEr8d/hIairnPPp5Va2KWYVmyP/zvkA==",
"dependencies": {
"chokidar": "^3.5.2",
"consola": "^2.15.3",
"upath": "^2.0.1",
"vue-demi": "*"
},
"peerDependencies": {
"@vue/composition-api": "^1.4.1",
"vue": "^2.0.0 || >=3.0.0-rc.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/@vueuse/gesture/node_modules/vue-demi": {
"version": "0.14.6",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
"integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/@vueuse/metadata": {
"version": "10.7.1",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.7.1.tgz",
"integrity": "sha512-jX8MbX5UX067DYVsbtrmKn6eG6KMcXxLRLlurGkZku5ZYT3vxgBjui2zajvUZ18QLIjrgBkFRsu7CqTAg18QFw==",
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/shared": {
"version": "10.7.1",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.7.1.tgz",
"integrity": "sha512-v0jbRR31LSgRY/C5i5X279A/WQjD6/JsMzGa+eqt658oJ75IvQXAeONmwvEMrvJQKnRElq/frzBR7fhmWY5uLw==",
"dependencies": {
"vue-demi": ">=0.14.6"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/shared/node_modules/vue-demi": {
"version": "0.14.6",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
"integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/@xmldom/xmldom": {
"version": "0.8.10",
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
......@@ -1801,7 +2131,6 @@
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"dev": true,
"dependencies": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
......@@ -1915,7 +2244,6 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
"dev": true,
"engines": {
"node": ">=8"
}
......@@ -1937,7 +2265,6 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true,
"dependencies": {
"fill-range": "^7.0.1"
},
......@@ -2109,7 +2436,6 @@
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
"dev": true,
"funding": [
{
"type": "individual",
......@@ -2136,7 +2462,6 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"dependencies": {
"is-glob": "^4.0.1"
},
......@@ -2195,6 +2520,11 @@
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"devOptional": true
},
"node_modules/consola": {
"version": "2.15.3",
"resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz",
"integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw=="
},
"node_modules/console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
......@@ -2378,7 +2708,6 @@
},
"node_modules/esbuild": {
"version": "0.18.20",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
......@@ -2419,7 +2748,6 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"android"
......@@ -2621,7 +2949,6 @@
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true,
"dependencies": {
"to-regex-range": "^5.0.1"
},
......@@ -2682,7 +3009,6 @@
"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,
"optional": true,
"os": [
......@@ -2944,7 +3270,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dev": true,
"dependencies": {
"binary-extensions": "^2.0.0"
},
......@@ -2967,7 +3292,6 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
......@@ -2985,7 +3309,6 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"dependencies": {
"is-extglob": "^2.1.1"
},
......@@ -2997,7 +3320,6 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"engines": {
"node": ">=0.12.0"
}
......@@ -3578,7 +3900,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
......@@ -3845,7 +4166,6 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"engines": {
"node": ">=8.6"
},
......@@ -4138,7 +4458,6 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dev": true,
"dependencies": {
"picomatch": "^2.2.1"
},
......@@ -4190,7 +4509,6 @@
},
"node_modules/rollup": {
"version": "3.29.4",
"dev": true,
"license": "MIT",
"bin": {
"rollup": "dist/bin/rollup"
......@@ -4526,9 +4844,9 @@
"dev": true
},
"node_modules/tailwindcss": {
"version": "3.3.5",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.5.tgz",
"integrity": "sha512-5SEZU4J7pxZgSkv7FP1zY8i2TIAOooNZ1e/OGtxIEv6GltpoiXUqWvLy89+a10qYTB1N5Ifkuw9lqQkN9sscvA==",
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz",
"integrity": "sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==",
"dev": true,
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
......@@ -4606,6 +4924,11 @@
"node": ">=0.8"
}
},
"node_modules/tiktoken": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/tiktoken/-/tiktoken-1.0.11.tgz",
"integrity": "sha512-aMJcn9NGmb6zDXkCweJLnACyIyjdiYIk1odAfnCUvin7O1QsV1rQP1hatGDMhQovxkeSJhFeU7QuGkbDHGciDQ=="
},
"node_modules/tinybench": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.1.tgz",
......@@ -4642,7 +4965,6 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"dependencies": {
"is-number": "^7.0.0"
},
......@@ -4731,7 +5053,7 @@
},
"node_modules/undici-types": {
"version": "5.26.5",
"dev": true,
"devOptional": true,
"license": "MIT"
},
"node_modules/unplugin": {
......@@ -4746,6 +5068,15 @@
"webpack-virtual-modules": "^0.6.0"
}
},
"node_modules/upath": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz",
"integrity": "sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==",
"engines": {
"node": ">=4",
"yarn": "*"
}
},
"node_modules/update-browserslist-db": {
"version": "1.0.13",
"dev": true,
......@@ -4780,6 +5111,18 @@
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"node_modules/uuid": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/validate-npm-package-license": {
"version": "3.0.4",
"dev": true,
......@@ -4791,7 +5134,6 @@
},
"node_modules/vite": {
"version": "4.5.0",
"dev": true,
"license": "MIT",
"dependencies": {
"esbuild": "^0.18.10",
......@@ -5323,6 +5665,27 @@
}
}
},
"node_modules/vite-plugin-top-level-await": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/vite-plugin-top-level-await/-/vite-plugin-top-level-await-1.4.1.tgz",
"integrity": "sha512-hogbZ6yT7+AqBaV6lK9JRNvJDn4/IJvHLu6ET06arNfo0t2IsyCaon7el9Xa8OumH+ESuq//SDf8xscZFE0rWw==",
"dependencies": {
"@rollup/plugin-virtual": "^3.0.2",
"@swc/core": "^1.3.100",
"uuid": "^9.0.1"
},
"peerDependencies": {
"vite": ">=2.8"
}
},
"node_modules/vite-plugin-wasm": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/vite-plugin-wasm/-/vite-plugin-wasm-3.3.0.tgz",
"integrity": "sha512-tVhz6w+W9MVsOCHzxo6SSMSswCeIw4HTrXEi6qL3IRzATl83jl09JVO1djBqPSwfjgnpVHNLYcaMbaDX5WB/pg==",
"peerDependencies": {
"vite": "^2 || ^3 || ^4 || ^5"
}
},
"node_modules/vitest": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-1.1.0.tgz",
......
......@@ -5,11 +5,11 @@
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Anything Copilot</title>
<base href="http://localhost:3000">
<base href="http://localhost:3000" />
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/content/index.ts"></script>
<script type="module" src="/@vite/client"></script>
<script type="module" src="/src/pages/dev.ts"></script>
</body>
</html>
......@@ -92,7 +92,7 @@
input,
textarea {
color-scheme: dark;
color-scheme: light dark;
}
}
......
import {
MessageType,
ServiceFunc,
type ParseDocOptions,
type InvokeMessage,
} from "@/types"
import { MessageType, ServiceFunc, type ParseDocOptions } from "@/types"
import { waitMessage, tabUpdated } from "@/utils/ext"
import { offscreen } from "./offscreen"
......@@ -92,34 +87,35 @@ async function updateWindow({ windowId, windowInfo }: UpdatePipWinOption) {
await chrome.windows.update(windowId, windowInfo)
}
async function parseDoc(
options: ParseDocOptions,
sender: chrome.runtime.MessageSender
) {
const result = await offscreen.parseDoc(options)
chrome.tabs.sendMessage(sender.tab?.id!, {
// type: MessageType.parseDoc
})
}
async function handleInvokeRequest(
message: any,
sender: chrome.runtime.MessageSender
) {
const { key, func, args } = message as InvokeMessage
const { key, func, args } = message
let result = null
let error = null
try {
switch (func) {
case ServiceFunc.parseDoc:
result = await offscreen.parseDoc(args[0])
case ServiceFunc.calcTokens:
case ServiceFunc.tokenSlice:
result = await offscreen.invoke({
func,
args,
})
break
}
} catch (err) {
error = err
}
console.log("invoke response: ", result, error)
if (!sender.tab?.id) {
console.error("sender tab id is undefined", sender)
}
chrome.tabs.sendMessage(sender.tab?.id!, {
type: MessageType.invokeResponse,
key,
......@@ -129,7 +125,7 @@ async function handleInvokeRequest(
}
function handleMessage(message: any, sender: chrome.runtime.MessageSender) {
console.log("bg message: ", message, sender, Date.now())
console.log("[bg]: ", message.type, message, sender, Date.now())
switch (message?.type) {
case MessageType.bgOpenPip:
openPipBackground(message.url)
......@@ -152,7 +148,7 @@ function handleMessage(message: any, sender: chrome.runtime.MessageSender) {
case MessageType.setupOffscreenDocument:
return offscreen.setup()
case MessageType.fromOffscreen:
return offscreen.handleOffscreenMessage(message)
return offscreen.handleMessage(message)
case MessageType.invokeRequest:
handleInvokeRequest(message, sender)
break
......
import { MessageType, ServiceFunc, type ParseDocOptions } from "@/types"
import Invoke from "@/utils/Invoke"
let creating: Promise<void> | null // A global promise to avoid concurrency issues
......@@ -37,58 +38,35 @@ export async function setupOffscreenDocument(path: string) {
export const offscreenHtmlPath = "/src/pages/offscreen.html"
class Offscreen {
class Offscreen extends Invoke {
public readonly path: string
private pendingCallback: {
[key in string]: { resolve: (v: any) => void; reject: (e: any) => void }
}
constructor(path: string) {
super("offscreen")
this.path = path
this.pendingCallback = {}
}
public setup() {
return setupOffscreenDocument(this.path)
}
public handleOffscreenMessage(message: any) {
const { type, key, payload, success } = message
if (type === MessageType.fromOffscreen) {
const callbacks = this.pendingCallback[key]
if (callbacks) {
const callback = success != false ? callbacks.resolve : callbacks.reject
callback(payload)
}
delete this.pendingCallback[key]
}
}
private getReturnValue(key: string) {
const promise = new Promise((resolve, reject) => {
this.pendingCallback[key] = { resolve, reject }
})
return promise
}
private async executeTask(task: string, payload: any) {
public async send(req: any): Promise<{ key: string; response: any }> {
const key = this.key
await this.setup()
const key = crypto.randomUUID()
chrome.runtime.sendMessage({
const response = await chrome.runtime.sendMessage({
type: MessageType.toOffscreen,
key,
task,
payload,
...req,
})
return { key, response }
}
return key
public handleMessage(message: any): void {
const { type, key, payload, success } = message
if (type === MessageType.fromOffscreen) {
this.setReturnValue(key, success, payload)
}
}
public async parseDoc(options: ParseDocOptions) {
console.log("to offscreen parseDoc ", options)
const key = await this.executeTask(ServiceFunc.parseDoc, options)
return this.getReturnValue(key)
public setup() {
return setupOffscreenDocument(this.path)
}
}
......
......@@ -9,12 +9,12 @@ const props = defineProps<{
<div :class="['scrollbar relative overflow-auto', props.class]">
<div
v-if="fade == true"
class="fade sticky top-0 left-0 w-full h-4 z-50"
class="sticky top-0 left-0 w-full h-4 z-50 bg-gradient-to-b from-background to-transparent"
></div>
<slot></slot>
<div
v-if="fade == true"
class="fade sticky bottom-0 left-0 w-full h-4 z-50"
class="sticky bottom-0 left-0 w-full h-4 z-50 bg-gradient-to-t from-background to-transparent"
></div>
</div>
</template>
......@@ -30,17 +30,7 @@ const props = defineProps<{
}
.scrollbar:hover::-webkit-scrollbar-thumb {
border: 4px solid transparent;
background: rgba(var(--fg-rgb), 0.1);
background-clip: content-box;
}
.fade {
--fade-bg-color: var(--color-background);
}
.fade.top-0 {
background: linear-gradient(to bottom, var(--fade-bg-color), transparent);
}
.fade.bottom-0 {
background: linear-gradient(to bottom, transparent, var(--fade-bg-color));
@apply bg-foreground/10;
}
</style>
<script setup lang="ts">
import { onMounted, onUnmounted, reactive, ref } from "vue"
import { onMounted, onUnmounted, reactive, ref, watch } from "vue"
import IconNoteStackAdd from "@/components/icons/IconNoteStackAdd.vue"
import IconClose from "@/components/icons/IconClose.vue"
import { chatDocsPanel, docsAddon } from "@/store"
import ChatDocsPanel from "@/components/chatdocs/ChatDocsPanel.vue"
import { watchEffect } from "vue"
import { useI18n } from "@/utils/i18n"
const { t } = useI18n()
const logoUrl = chrome.runtime.getURL("/logo.svg")
const div = ref<HTMLDivElement>()
const chatDocsDiv = ref<HTMLDivElement>()
const position = reactive({
valid: false,
rect: new DOMRect(0, 0, 0, 0),
tx: 0,
ty: 0,
})
let timer = 0
watchEffect(() => {
const { valid, rect, tx, ty } = position
const div = chatDocsDiv.value
if (div && valid && chatDocsPanel.visible) {
div.style.top = rect.top + "px"
div.style.left = rect.left + "px"
div.style.transform = `translate(${tx}px, ${ty}px)`
}
})
function onDragOver(e: DragEvent) {
docsAddon.visible = true
clearTimeout(timer)
timer = window.setTimeout(() => {
docsAddon.visible = false
}, 180)
console.log(e.dataTransfer?.items.length, e.dataTransfer?.items[0]?.type)
timer = window.setTimeout(() => (docsAddon.visible = false), 180)
}
async function onDrop(e: DragEvent) {
......@@ -71,14 +88,57 @@ async function onDrop(e: DragEvent) {
console.log("types: ", types, items?.length)
}
function handlePointerMove(e: PointerEvent) {
const div = chatDocsDiv.value
if (e.buttons == 1 && div) {
if (!position.valid) {
const rect = div.getBoundingClientRect()
position.rect = rect
position.valid = true
div.style.top = rect.top + "px"
div.style.left = rect.left + "px"
div.style.transform = "translate(0px, 0px)"
}
position.tx += e.movementX
position.ty += e.movementY
// div.style.transform = `translate(${position.tx}px, ${position.ty}px)`
}
}
function adjustPosition() {
const div = chatDocsDiv.value
if (div) {
const rect = div.getBoundingClientRect()
const dx =
rect.left < 0
? -rect.left
: rect.right > innerWidth
? innerWidth - rect.right
: 0
const dy =
rect.top < 0
? -rect.top
: rect.bottom > innerHeight
? innerHeight - rect.bottom
: 0
position.tx += dx
position.ty += dy
// div.style.transform = `translate(${position.tx}px, ${position.ty}px)`
}
}
onMounted(() => {
const doc = div.value?.ownerDocument || document
doc.addEventListener("dragover", onDragOver, true)
doc.defaultView?.addEventListener("resize", adjustPosition)
})
onUnmounted(() => {
const doc = div.value?.ownerDocument || document
doc.removeEventListener("dragover", onDragOver, true)
doc.removeEventListener("resize", adjustPosition)
doc.defaultView?.removeEventListener("resize", adjustPosition)
})
</script>
......@@ -104,7 +164,7 @@ onUnmounted(() => {
<IconNoteStackAdd class="w-8 h-8" />
<div class="text-xl font-bold">Anything Copilot</div>
</div>
<p class="text-center text-sm mt-2">支持PDF、DOCX</p>
<p class="text-center text-sm mt-2">{{ t("chatDocs.supportFormat") }}</p>
<div :class="['absolute text-xs flex items-center bottom-2 right-2']">
<img :src="logoUrl" class="w-3 h-3" />
</div>
......@@ -113,12 +173,34 @@ onUnmounted(() => {
<div
v-if="chatDocsPanel.visible"
ref="chatDocsDiv"
:class="[
'fixed bottom-10 left-1/2 top-1/2 p-3 w-80 border rounded-lg z-[9999]',
'border-foreground/10 bg-background -translate-x-1/2 -translate-y-1/2',
'h-fit shadow-lg dark:border-2',
'fixed w-96 max-w-full h-fit border rounded-lg z-[9999]',
'border-foreground/10 bg-background shadow-lg dark:border-2',
{
'left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2': !position.valid,
},
]"
>
<div
class="flex items-center px-4 pt-4 pb-1 select-none"
@pointerdown="
(e) => e.buttons == 1 && (e.target as Element)?.setPointerCapture(e.pointerId)
"
@pointermove="handlePointerMove"
@pointerup="adjustPosition"
@pointercancel="adjustPosition"
>
<img :src="logoUrl" class="w-6 h-6" />
<span class="mx-2 text-xl font-bold">{{ t("chatDocsAddon") }}</span>
<button
aria-label="close"
class="ml-auto p-1 top-0 right-0 rounded-full hover:bg-rose-400/10"
@click="chatDocsPanel.visible = false"
>
<IconClose class="w-5 h-5" />
</button>
</div>
<ChatDocsPanel @close="chatDocsPanel.visible = false" />
</div>
</template>
......
<script setup lang="ts">
import { watch, computed, reactive, ref, onMounted } from "vue"
import { watch, computed, reactive, ref, onMounted, watchEffect } from "vue"
import { chatDocsPanel } from "@/store"
import IconClose from "@/components/icons/IconClose.vue"
import { contentService } from "@/utils/service"
import { convertBlobToBase64, semanticClip } from "@/utils/utils"
import ScrollView from "@/components/ScrollView.vue"
......@@ -14,6 +13,8 @@ import IconPause from "../icons/IconPause.vue"
import IconProgressActivity from "../icons/IconProgressActivity.vue"
import { sitesConfig } from "./chat"
import { query, dispatchInput, click, waitFor } from "@/utils/dom"
import { chatDocPrompt } from "@/utils/prompt"
import { useI18n } from "@/utils/i18n"
type Sheet = "" | "docSelect" | "promptTemplate"
......@@ -23,6 +24,7 @@ type SnippetItem = {
start: number
end: number
snippet: string
length: number
}
type Selector = {
......@@ -33,6 +35,7 @@ type Selector = {
defineEmits(["close"])
const { t } = useI18n()
const logoUrl = chrome.runtime.getURL("/logo.svg")
const div = ref<HTMLDivElement>()
const sheet = ref<Sheet>("")
......@@ -43,12 +46,17 @@ const sendTask = reactive({
})
const config = reactive({
prompt: `Here is some relevant reference information. Please refrain from summarizing or responding to specific content until I pose targeted questions. If you comprehend this instruction, kindly reply with "Okay, please continue."`,
maxInputLength: 3000,
prompt: chatDocPrompt,
maxInput: 3000,
maxInputType: "token" as "char" | "token",
maxRuns: 10,
selector: null as Selector | null,
})
const lenRate = reactive({
tokenRate: 4,
})
const docs = computed(() => {
const docs = Object.values(chatDocsPanel.docMap).filter(
(doc) => !doc.removed && doc.success
......@@ -57,10 +65,12 @@ const docs = computed(() => {
})
const currentMessage = computed(() => {
const { prompt, maxInputLength, maxRuns } = config
const { prompt, maxInput, maxInputType } = config
const snippets: SnippetItem[] = []
const rate = maxInputType == "token" ? lenRate.tokenRate : 1
const maxInputLength = maxInput * rate - prompt.length
for (let doc of docs.value) {
for (let i = 0; i < doc.contents.length; i++) {
const content = doc.contents[i]
......@@ -82,8 +92,7 @@ const currentMessage = computed(() => {
}
const meta = metaList.join("")
const maxDataLength =
maxInputLength - prompt.length - snippetsLength - meta.length - 100
const maxDataLength = maxInputLength - snippetsLength - meta.length - 100
let data = content.data.slice(content.sentLength)
data = semanticClip(data, maxDataLength)
......@@ -96,6 +105,7 @@ const currentMessage = computed(() => {
start: content.sentLength,
end: content.sentLength + data.length,
snippet: snippet,
length: snippet.length,
})
}
}
......@@ -111,6 +121,34 @@ const currentMessage = computed(() => {
}
})
watch(
[config, () => currentMessage.value],
async ([config, currentMessage]) => {
const { message } = currentMessage
const { maxInput, maxInputType } = config
console.log("token limit watch started", maxInputType, message.slice(0, 10))
if (maxInputType !== "token") return
if (!message) return
const tokenLength = await contentService.calcTokens(message)
const rate = (message.length / tokenLength) * 0.95
const exceedMaxInput = tokenLength > maxInput
if (exceedMaxInput) {
if (lenRate.tokenRate > rate) {
lenRate.tokenRate = rate
} else {
lenRate.tokenRate *= 0.95
}
} else if (lenRate.tokenRate / rate < 0.6) {
lenRate.tokenRate = rate
}
console.log("token limit watch: ", maxInput, tokenLength, lenRate.tokenRate)
}
)
const copied = ref(0)
watch(
() => chatDocsPanel.inputs,
async (inputs, old, onCleanup) => {
......@@ -206,7 +244,8 @@ onMounted(() => {
)
if (matchConfig) {
config.maxInputLength = matchConfig.inputLength
config.maxInput = matchConfig.maxInputToken || matchConfig.maxInputLength
config.maxInputType = matchConfig.maxInputToken ? "token" : "char"
config.selector = matchConfig.selector
}
......@@ -227,17 +266,86 @@ const removeItem = (key: string) => {
}
const handleCopyMessage = () => {
clearTimeout(copied.value)
copied.value = window.setTimeout(() => (copied.value = 0), 2000)
const message = currentMessage.value.message
navigator.clipboard.writeText(message)
}
const nextMessage = () => {
const len = async (text: string, type: "char" | "token") => {
if (type == "token") {
return contentService.calcTokens(text)
}
return text.length
}
// const setCurrent = async () => {
// const { prompt, maxInput, maxInputType, maxRuns } = config
// const snippets: SnippetItem[] = []
// const promptLength = await len(prompt, maxInputType)
// const maxInputLength = maxInput - promptLength
// for (let doc of docs.value) {
// for (let i = 0; i < doc.contents.length; i++) {
// const content = doc.contents[i]
// if (!content.selected || content.sentLength == content.data.length) {
// continue
// }
// const snippetsLength = snippets.reduce((a, c) => a + c.length, 0)
// if (snippets.length >= 1 && maxInputLength - snippetsLength < 600) {
// break
// }
// const metaList: string[] = []
// if (doc.kind == "file") {
// metaList.push(`file: ${doc.name}\n`)
// }
// if (doc.contents.length > 3) {
// metaList.push(`page: ${i + 1}\n`)
// }
// const meta = metaList.join("")
// const metaLength = await len(meta, maxInputType)
// const maxDataLength =
// maxInputLength - prompt.length - snippetsLength - metaLength - 100
// let data = content.data.slice(content.sentLength)
// data = await contentService.tokenSlice(content.data, maxDataLength)
// console.log('current data: ', data)
// data = semanticClip(data, data.length)
// const snippet = `\`\`\`\`md\n${meta}\n${data}\n\`\`\`\``
// const snippetLength = await len(snippet, maxInputType)
// snippets.push({
// key: doc.key,
// index: i,
// start: content.sentLength,
// end: content.sentLength + data.length,
// snippet: snippet,
// length: snippetLength,
// })
// }
// }
// const text = snippets.map((p) => p.snippet).join("\n\n")
// const message = text ? `${prompt}\n\n${text}` : ""
// const done = docs.value.length > 0 && snippets.length == 0
// currentMessage.value.done = done
// currentMessage.value.message = message
// currentMessage.value.snippets = snippets
// }
const nextMessage = async () => {
for (let item of currentMessage.value.snippets) {
const content = chatDocsPanel.docMap[item.key]?.contents[item.index]
if (content.sentLength < item.end) {
content.sentLength = item.end
}
}
// await setCurrent()
}
const autoSend = async () => {
......@@ -273,7 +381,7 @@ const autoSend = async () => {
await new Promise((r) => setTimeout(r, 600))
await waitFor(config.selector.wait, 1000 * 30)
await new Promise((r) => setTimeout(r, 200))
nextMessage()
await nextMessage()
if (currentMessage.value.done) {
sendTask.status = "done"
......@@ -295,25 +403,15 @@ const resetSent = () => {
</script>
<template>
<div ref="div" class="docs-panel">
<!-- Brand Header -->
<div class="flex items-center">
<img :src="logoUrl" class="w-6 h-6" />
<span class="mx-2 text-xl font-bold">PDF & Doc</span>
<button
aria-label="close"
class="ml-auto p-1 top-0 right-0 rounded-full hover:bg-rose-400/10"
@click="$emit('close')"
>
<IconClose class="w-5 h-5" />
</button>
</div>
<div ref="div" class="pb-3">
<div class="relative">
<!-- primary panel -->
<ScrollView fade class="max-h-[560px]">
<ScrollView fade class="max-h-[560px] px-4">
<div class="">
<div class="mb-4">
<div class="mb-2 text-base font-bold">Files</div>
<div class="mb-2 text-base font-bold">
{{ t("chatDocs.files") }}
</div>
<div class="flex flex-col gap-2">
<template v-for="(item, key) in chatDocsPanel.docMap">
<DocItem
......@@ -332,25 +430,31 @@ const resetSent = () => {
</div>
<div class="mb-4">
<div class="text-base font-bold">注入设置</div>
<div class="text-base font-bold">
{{ t("chatDocs.msgSettings") }}
</div>
<div
class="text-sm my-2 px-3 py-1 rounded-lg bg-[var(--color-background-soft)]"
>
<div class="flex items-center justify-between my-1">
<span>Prompt</span>
<span>{{ t("prompt") }}</span>
<button
class="py-1 flex items-center"
@click="sheet = 'promptTemplate'"
>
<span class="px-2">编辑 Prompt</span>
<span class="px-2">{{ t("chatDocs.editPrompt") }}</span>
<IconArrowRight />
</button>
</div>
<div class="flex items-center justify-between my-1">
<span>单次最大注入字符</span>
<span
>{{ t("chatDocs.maxLength") }} ({{
config.maxInputType == "token" ? "token" : "char"
}})</span
>
<input
v-model="config.maxInputLength"
v-model="config.maxInput"
class="border rounded px-2 py-1 w-20"
type="number"
min="1000"
......@@ -358,7 +462,7 @@ const resetSent = () => {
/>
</div>
<div class="flex items-center justify-between my-1">
<span>最大注入次数</span>
<span>{{ t("chatDocs.maxSendings") }}</span>
<input
v-model="config.maxRuns"
class="border rounded px-2 py-1 w-20"
......@@ -371,12 +475,17 @@ const resetSent = () => {
</div>
<div class="mb-4">
<div class="text-base font-bold">发送进度</div>
<div class="text-base font-bold">
{{ t("chatDocs.sendProgress") }}
</div>
<div
class="text-sm px-3 my-2 py-1 rounded-lg bg-[var(--color-background-soft)]"
>
<div class="progress relative w-full h-2 my-2 rounded-full">
<div
aria-label="progress"
class="relative w-full h-2 my-2 rounded-full bg-foreground/10"
>
<div
class="absolute h-full rounded-full transition-all bg-primary/30"
:style="{
......@@ -384,7 +493,12 @@ const resetSent = () => {
}"
></div>
<div
class="absolute h-full rounded-full transition-all bg-primary"
:class="[
'absolute h-full rounded-full transition-all bg-primary overflow-hidden',
{
running: sendTask.status == 'running',
},
]"
:style="{
width: `${progress.sentPrecent}%`,
}"
......@@ -393,9 +507,10 @@ const resetSent = () => {
<div class="my-2">
<div class="flex items-center">
<div v-if="!currentMessage.done">
发送消息 {{ currentMessage.message.length }} 字符
{{ t("message") }} {{ currentMessage.message.length }}
{{ t("char") }}
</div>
<div v-else>发送完成</div>
<div v-else>{{ t("chatDocs.sendCompleted") }}</div>
<span class="mx-auto"></span>
<div v-if="!currentMessage.done">
{{ progress.sent }} / {{ progress.total }}
......@@ -405,29 +520,28 @@ const resetSent = () => {
class="py-1 px-2 border rounded"
@click="resetSent"
>
重置
{{ t("reset") }}
</button>
</div>
</div>
<div v-if="!currentMessage.done" class="my-2 flex items-center">
<div class="mr-auto">消息内容</div>
<div class="mr-auto">{{ t("chatDocs.msgContent") }}</div>
<button
class="py-1 px-2 border ml-2 rounded"
@click="handleCopyMessage"
>
复制
{{ copied ? t("copied") : t("copy") }}
</button>
<button
class="py-1 px-2 border ml-2 rounded"
@click="nextMessage"
>
下一个
{{ t("next") }}
</button>
</div>
<div v-else class="my-2 flex items-center justify-between">
<div>你可以开始聊天了!</div>
<!-- <button>重置</button> -->
<div>{{ t("chatDocs.startChatting") }}</div>
</div>
</div>
</div>
......@@ -440,14 +554,13 @@ const resetSent = () => {
@click="togglePause"
>
<IconPause class="w-5 h-5" />
<span>暂停</span>
<span>{{ t("pause") }}</span>
</button>
<button
:disabled="sendTask.status !== '' || docs.length == 0"
:class="[
'font-bold flex items-center gap-1 px-3 py-1 bg-primary-300 ',
'hover:bg-primary-400 dark:bg-primary-800 dark:hover:bg-primary-700',
'disabled:hover:bg-primary-300 disabled:dark:hover:bg-primary-800',
'font-bold flex items-center gap-1 px-3 py-1 bg-primary-300 dark:bg-primary-800',
'enabled:hover:bg-primary-400 enabled:dark:hover:bg-primary-700',
]"
@click="autoSend"
>
......@@ -456,7 +569,7 @@ const resetSent = () => {
class="w-5 h-5 animate-spin"
/>
<IconPlayCircle v-else class="w-5 h-5" />
自动发送
{{ t("chatDocs.autoSending") }}
</button>
</div>
</div>
......@@ -468,31 +581,31 @@ const resetSent = () => {
v-if="sheet != ''"
class="absolute w-full h-full top-0 left-0 flex flex-col bg-background"
>
<div class="flex items-center pt-3">
<div class="flex items-center pt-3 px-4">
<button
@click="sheet = ''"
class="flex items-center"
aria-label="返回"
class="flex items-center max-w-full"
:aria-label="t('back')"
>
<IconArrowBack />
<IconArrowBack class="shrink-0" />
<span
v-if="sheet === 'docSelect'"
class="mx-2 text-base font-bold"
class="mx-2 text-base font-bold truncate min-w-0"
>{{ chatDocsPanel.docMap[currentDoc]?.name }}</span
>
<span
v-else-if="sheet === 'promptTemplate'"
class="mx-2 text-base font-bold"
>
Prompt模板
{{ t("promptTemplate") }}
</span>
</button>
</div>
<ScrollView fade v-if="sheet == 'docSelect'">
<p class="text-sm pb-2">选择与你想了解的主题更相关的内容</p>
<ScrollView fade v-if="sheet == 'docSelect'" class="px-4">
<p class="text-sm pb-2">{{ t("chatDocs.chooseContentRelevant") }}</p>
<input
class="w-full px-2 py-1 border"
placeholder="搜索"
:placeholder="t('search')"
type="text"
/>
<div class="grid grid-cols-3 gap-3 py-3">
......@@ -502,7 +615,8 @@ const resetSent = () => {
<div
:title="content.data"
:class="[
'w-full h-0 pb-[130%] border-2 cursor-pointer bg-background-soft',
'w-full h-0 pb-[130%] border-2 cursor-pointer',
'bg-background-soft hover:border-primary/50',
{
'border-primary': content.selected,
},
......@@ -513,7 +627,7 @@ const resetSent = () => {
</div>
</div>
</ScrollView>
<ScrollView fade v-else-if="sheet == 'promptTemplate'">
<ScrollView fade v-else-if="sheet == 'promptTemplate'" class="px-4">
<textarea
:class="[
'scrollbar border border-foreground/20 w-full h-36 p-2 bg-background-soft',
......@@ -522,8 +636,8 @@ const resetSent = () => {
v-model="config.prompt"
></textarea>
<div class="flex gap-2 justify-end my-2">
<button class="px-2">取消</button>
<button class="px-2">保存</button>
<button class="px-2">{{ t("cancel") }}</button>
<button class="px-2">{{ t("save") }}</button>
</div>
</ScrollView>
</div>
......@@ -539,14 +653,19 @@ const resetSent = () => {
*:hover {
@apply border-foreground/30;
}
.sheet {
background-color: var(--color-background);
}
.progress {
background-color: rgba(var(--fg-rgb), 0.1);
}
.progress .sent {
.running::before {
content: "";
@apply h-full w-full absolute bg-gradient-to-r from-transparent via-white/30 to-transparent to-25%;
animation: running 1s ease-in-out 0.2s infinite;
}
.progress .pending {
@keyframes running {
from {
transform: translate(-24px, 0);
}
to {
transform: translate(100%, 0);
}
}
</style>
......@@ -2,7 +2,9 @@
import IconNoteStackAdd from "@/components/icons/IconNoteStackAdd.vue"
import type { chatDocsPanel } from "@/store"
import { ref } from "vue"
import { useI18n } from "@/utils/i18n"
const { t } = useI18n()
const dragEnter = ref(false)
const emit = defineEmits({
......@@ -29,12 +31,15 @@ const handleFileInput = (e: Event) => {
for="anything-copilot-doc-input"
:class="[
'relative flex items-center justify-center gap-2 w-full h-14 ',
'rounded-lg border-2 bg-background-soft ',
dragEnter ? 'border-primary' : 'border-background-soft',
'px-4 rounded-lg border-2 bg-background-soft transition-all',
{
'border-primary scale-105': dragEnter,
'border-background-soft': !dragEnter,
},
]"
>
<IconNoteStackAdd />
<span>拖拽或点击选择文件</span>
<IconNoteStackAdd class="shrink-0" />
<span>{{ t("chatDocs.selectFile") }}</span>
<input
multiple
type="file"
......
......@@ -2,7 +2,7 @@ export const sitesConfig = [
{
host: "huggingface.co",
path: /^\/chat/,
inputLength: 8000, // 2048 token
maxInputLength: 8000, // 2048 token
selector: {
input: "form[tabindex] textarea",
send: 'form[tabindex] button[type="submit"]',
......@@ -12,7 +12,8 @@ export const sitesConfig = [
{
host: "chat.openai.com",
path: /^\//,
inputLength: 18000,
maxInputLength: 18000,
maxInputToken: 4096,
selector: {
input: "form textarea#prompt-textarea",
send: "form textarea ~ button",
......@@ -22,7 +23,7 @@ export const sitesConfig = [
{
host: "bard.google.com",
path: /^\/chat/,
inputLength: 4096,
maxInputLength: 4096,
selector: {
input: "input-area rich-textarea p",
send: "input-area div[class*=send] button[class*=send]",
......@@ -32,7 +33,7 @@ export const sitesConfig = [
{
host: "copilot.microsoft.com",
path: /^\//,
inputLength: 2048,
maxInputLength: 2048,
selector: {
input:
"cib-serp /deep/ cib-action-bar /deep/ cib-text-input /deep/ textarea",
......@@ -43,7 +44,7 @@ export const sitesConfig = [
{
host: "yiyan.baidu.com",
path: /^\//,
inputLength: 2000,
maxInputLength: 2000,
selector: {
input: "textarea:not(h1 ~ textarea)",
send: 'div > span:has(svg[width="240"])',
......
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
height="24"
viewBox="0 -960 960 960"
width="24"
fill="currentColor"
>
<path
d="M478-240q21 0 35.5-14.5T528-290q0-21-14.5-35.5T478-340q-21 0-35.5 14.5T428-290q0 21 14.5 35.5T478-240Zm-36-154h74q0-33 7.5-52t42.5-52q26-26 41-49.5t15-56.5q0-56-41-86t-97-30q-57 0-92.5 30T342-618l66 26q5-18 22.5-39t53.5-21q32 0 48 17.5t16 38.5q0 20-12 37.5T506-526q-44 39-54 59t-10 73Zm38 314q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"
/>
</svg>
</template>
import { mount, waitMountApp } from "./ui"
import { contentCss, pipLauncher, pipLoading, pipWindow } from "@/store"
import {
chatDocsPanel,
contentCss,
pipLauncher,
pipLoading,
pipWindow,
} from "@/store"
import { MessageType } from "@/types"
import Copilot from "./Copilot.vue"
import { waitMessage } from "@/utils/ext"
......@@ -16,7 +22,7 @@ function handleMessage(
sender: chrome.runtime.MessageSender,
sendResponse: (res: any) => void
) {
console.log(message, sender)
console.log("[Content]", message.type, message, sender)
switch (message?.type) {
case MessageType.pip:
dispatchContentEvent({
......@@ -45,6 +51,9 @@ function handleMessage(
case MessageType.invokeResponse:
contentService.handleMessage(message)
break
case MessageType.showChatDocs:
chatDocsPanel.visible = true
break
}
}
......
......@@ -6,5 +6,36 @@
"moveAside": "ቀስት ለማግኘት",
"close": "ዝጋ",
"refresh": "አስተካክል",
"protectedTabTips": "ይህ ገጽ በመሳሪያ መሳሪያ የተጠበቀ ነው"
"protectedTabTips": "ይህ ገጽ በመሳሪያ መሳሪያ የተጠበቀ ነው",
"prompt": "መረጃ",
"message": "መልእክት",
"char": "ቁምፊ",
"reset": "ዳግም ጀምር",
"copy": "ኮፒ",
"copied": "ተኮፒ ሆኗል",
"pause": "እቅፍ",
"back": "ተመለስ",
"search": "ፈልግ",
"promptTemplate": "ተመርጧል ታሪክ",
"cancel": "ሰርዝ",
"save": "አስቀምጥ",
"next": "ቀጣይ",
"chatDocsAddon": "ተንኮል ከ ተረጋጋይ ትምህር ጋር",
"chatDocs": {
"supportFormat": "Support PDF, DOCX",
"files": "Files/Text",
"selectFile": "ተመን ወደምለዋዋጥ ወደሚነካ ወደሚገኝ ስእሎች መቀነስ ይቻላል",
"msgSettings": "መልእክት ቅንዓት",
"editPrompt": "ማስቀመጥ ስለሚችል",
"maxLength": "የማከም ስልክ",
"maxSendings": "የመላክ ስልክ",
"sendProgress": "መላክ ሁኔታ",
"sendCompleted": "መላክ ተሰነባበት",
"msgContent": "መልእክት ይከናወናል",
"startChatting": "እንደሚሰማ መንገድ ተነስቶ ይጀምራል!",
"autoSending": "እንደሚቆጠር መላክ",
"chooseContentRelevant": "ከመረጡ የሚያሳውቁ ተግባራዎችን ለመረጡ ይችላሉ"
},
"newFeature": "አዲስ አማራ",
"chatDocsTips": "የ ChatGPT, Bard, MS Copilot ይጠቀሙ..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "تحريك جانباً",
"close": "إغلاق",
"refresh": "تحديث",
"protectedTabTips": "هذه الصفحة محمية بواسطة المتصفح"
"protectedTabTips": "هذه الصفحة محمية بواسطة المتصفح",
"prompt": "المطالبة",
"message": "رسالة",
"char": "حرف",
"reset": "إعادة تعيين",
"copy": "نسخ",
"copied": "تم النسخ",
"pause": "توقف",
"back": "العودة",
"search": "البحث",
"promptTemplate": "نموذج التنبيه",
"cancel": "إلغاء",
"save": "حفظ",
"next": "التالي",
"chatDocsAddon": "الدردشة مع المستندات",
"chatDocs": {
"supportFormat": "دعم PDF، DOCX",
"files": "ملفات/نص",
"selectFile": "اسحب أو انقر لاختيار ملف",
"msgSettings": "إعدادات الرسالة",
"editPrompt": "تحرير التلميح",
"maxLength": "الحد الأقصى للطول",
"maxSendings": "الحد الأقصى لعدد الإرسال",
"sendProgress": "تقدم الإرسال",
"sendCompleted": "تم الإرسال",
"msgContent": "محتوى الرسالة",
"startChatting": "يمكنك بدء الدردشة الآن!",
"autoSending": "الإرسال التلقائي",
"chooseContentRelevant": "اختر محتوى أكثر صلة بالموضوع الذي ترغب في التعلم عنه"
},
"newFeature": "ميزة جديدة",
"chatDocsTips": "دعم ChatGPT، Bard، MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Премести настрана",
"close": "Затвори",
"refresh": "Обнови",
"protectedTabTips": "Тази страница е защитена от браузъра"
"protectedTabTips": "Тази страница е защитена от браузъра",
"prompt": "Подкана",
"message": "Съобщение",
"char": "Знак",
"reset": "Нулиране",
"copy": "Копиране",
"copied": "Копирано",
"pause": "Пауза",
"back": "Назад",
"search": "Търсене",
"promptTemplate": "Шаблон за подсказка",
"cancel": "Отказ",
"save": "Запазване",
"next": "Следващ",
"chatDocsAddon": "Чат с документи",
"chatDocs": {
"supportFormat": "Поддръжка на PDF, DOCX",
"files": "Файлове/Текст",
"selectFile": "Плъзнете или кликнете, за да изберете файл",
"msgSettings": "Настройки за съобщения",
"editPrompt": "Редакция на подсказка",
"maxLength": "Максимална дължина",
"maxSendings": "Максимален брой изпращания",
"sendProgress": "Прогрес на изпращане",
"sendCompleted": "Изпращането завърши",
"msgContent": "Съдържание на съобщението",
"startChatting": "Вече можете да започнете чат!",
"autoSending": "Автоматично изпращане",
"chooseContentRelevant": "Изберете съдържание, свързано с темата, за която искате да научите повече"
},
"newFeature": "Нова функционалност",
"chatDocsTips": "Поддръжка на ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "পাশে সরান",
"close": "বন্ধ করুন",
"refresh": "পুনরায় লোড করুন",
"protectedTabTips": "এই পৃষ্ঠাটি ব্রাউজার দ্বারা সুরক্ষিত"
"protectedTabTips": "এই পৃষ্ঠাটি ব্রাউজার দ্বারা সুরক্ষিত",
"prompt": "প্রম্পট",
"message": "বার্তা",
"char": "অক্ষর",
"reset": "রিসেট",
"copy": "অনুলিপি",
"copied": "অনুলিপি করা হয়েছে",
"pause": "বিরতি",
"back": "পেছনে",
"search": "অনুসন্ধান",
"promptTemplate": "প্রম্পট টেমপ্লেট",
"cancel": "বাতিল",
"save": "সংরক্ষণ",
"next": "পরবর্তী",
"chatDocsAddon": "ডকুমেন্ট সহ চ্যাট",
"chatDocs": {
"supportFormat": "সাপোর্ট করে PDF, DOCX",
"files": "ফাইল/টেক্সট",
"selectFile": "ফাইল নির্বাচন করতে ড্র্যাগ করুন বা ক্লিক করুন",
"msgSettings": "মেসেজ সেটিংস",
"editPrompt": "প্রম্পট সম্পাদনা",
"maxLength": "সর্বাধিক দৈর্ঘ্য",
"maxSendings": "সর্বাধিক প্রেরণের সংখ্যা",
"sendProgress": "প্রেরণের অগ্রগতি",
"sendCompleted": "প্রেরণ সম্পন্ন",
"msgContent": "মেসেজের কনটেন্ট",
"startChatting": "আপনি এখন চ্যাট শুরু করতে পারেন!",
"autoSending": "অটো প্রেরণ",
"chooseContentRelevant": "আপনি যে বিষয়ে আরও জানতে চান তা সম্পর্কিত কনটেন্ট চয়ন করুন"
},
"newFeature": "নতুন বৈশিষ্ট্য",
"chatDocsTips": "সাপোর্ট ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Aparta",
"close": "Tanca",
"refresh": "Refresca",
"protectedTabTips": "Aquesta pàgina està protegida pel navegador"
"protectedTabTips": "Aquesta pàgina està protegida pel navegador",
"prompt": "Sol·licitud",
"message": "Missatge",
"char": "Caràcter",
"reset": "Restablir",
"copy": "Còpia",
"copied": "Copiat",
"pause": "Pausa",
"back": "Enrere",
"search": "Cerca",
"promptTemplate": "Plantilla d'indicacions",
"cancel": "Cancel·lar",
"save": "Desa",
"next": "Següent",
"chatDocsAddon": "Xateja amb Documents",
"chatDocs": {
"supportFormat": "Suporta PDF, DOCX",
"files": "Fitxers/Text",
"selectFile": "Arrossega o fes clic per seleccionar un fitxer",
"msgSettings": "Configuració del missatge",
"editPrompt": "Edita la indicació",
"maxLength": "Longitud màxima",
"maxSendings": "Nombre màxim d'enviaments",
"sendProgress": "Progrés de l'enviament",
"sendCompleted": "Enviament completat",
"msgContent": "Contingut del missatge",
"startChatting": "Pots començar a xatejar ara!",
"autoSending": "Enviament automàtic",
"chooseContentRelevant": "Trieu contingut més rellevant pel tema que voleu aprendre"
},
"newFeature": "Nova característica",
"chatDocsTips": "Suporta ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Přesunout stranou",
"close": "Zavřít",
"refresh": "Obnovit",
"protectedTabTips": "Tato stránka je chráněna prohlížečem"
"protectedTabTips": "Tato stránka je chráněna prohlížečem",
"prompt": "Výzva",
"message": "Zpráva",
"char": "Znak",
"reset": "Resetovat",
"copy": "Kopírovat",
"copied": "Zkopírováno",
"pause": "Pauza",
"back": "Zpět",
"search": "Hledat",
"promptTemplate": "Šablona výzvy",
"cancel": "Zrušit",
"save": "Uložit",
"next": "Další",
"chatDocsAddon": "Chat s dokumenty",
"chatDocs": {
"supportFormat": "Podpora formátů PDF, DOCX",
"files": "Soubory/Text",
"selectFile": "Přetáhněte nebo klepněte pro výběr souboru",
"msgSettings": "Nastavení zprávy",
"editPrompt": "Upravit upozornění",
"maxLength": "Maximální délka",
"maxSendings": "Maximální počet odeslání",
"sendProgress": "Průběh odesílání",
"sendCompleted": "Odesílání dokončeno",
"msgContent": "Obsah zprávy",
"startChatting": "Můžete začít chatovat nyní!",
"autoSending": "Automatické odesílání",
"chooseContentRelevant": "Vyberte obsah více relevantní k tématu, které chcete studovat"
},
"newFeature": "Nová funkce",
"chatDocsTips": "Podpora ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Flyt til side",
"close": "Luk",
"refresh": "Opdater",
"protectedTabTips": "Denne side er beskyttet af browseren"
"protectedTabTips": "Denne side er beskyttet af browseren",
"prompt": "Prompt",
"message": "Besked",
"char": "Tegn",
"reset": "Nulstil",
"copy": "Kopiér",
"copied": "Kopieret",
"pause": "Pause",
"back": "Tilbage",
"search": "Søg",
"promptTemplate": "Promptskabelon",
"cancel": "Annuller",
"save": "Gem",
"next": "Næste",
"chatDocsAddon": "Chat med Dokumenter",
"chatDocs": {
"supportFormat": "Understøtter PDF, DOCX",
"files": "Filer/Text",
"selectFile": "Træk eller klik for at vælge en fil",
"msgSettings": "Beskedindstillinger",
"editPrompt": "Rediger prompt",
"maxLength": "Maksimal længde",
"maxSendings": "Maksimal antal afsendelser",
"sendProgress": "Send fremskridt",
"sendCompleted": "Send fuldført",
"msgContent": "Beskedindhold",
"startChatting": "Du kan begynde at chatte nu!",
"autoSending": "Auto afsendelse",
"chooseContentRelevant": "Vælg indhold mere relevant for det emne, du ønsker at lære om"
},
"newFeature": "Ny funktion",
"chatDocsTips": "Understøtter ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Beiseite bewegen",
"close": "Schließen",
"refresh": "Aktualisieren",
"protectedTabTips": "Diese Seite ist durch den Browser geschützt"
"protectedTabTips": "Diese Seite ist durch den Browser geschützt",
"prompt": "Aufforderung",
"message": "Nachricht",
"char": "Zeichen",
"reset": "Zurücksetzen",
"copy": "Kopieren",
"copied": "Kopiert",
"pause": "Pause",
"back": "Zurück",
"search": "Suchen",
"promptTemplate": "Aufforderungsvorlage",
"cancel": "Abbrechen",
"save": "Speichern",
"next": "Weiter",
"chatDocsAddon": "Chat mit Dokumenten",
"chatDocs": {
"supportFormat": "Unterstützt PDF, DOCX",
"files": "Dateien/Text",
"selectFile": "Ziehen Sie die Datei hierhin oder klicken Sie, um eine Datei auszuwählen",
"msgSettings": "Nachrichteneinstellungen",
"editPrompt": "Prompt bearbeiten",
"maxLength": "Maximale Länge",
"maxSendings": "Maximale Anzahl der Sendungen",
"sendProgress": "Sendefortschritt",
"sendCompleted": "Senden abgeschlossen",
"msgContent": "Nachrichteninhalt",
"startChatting": "Sie können jetzt chatten!",
"autoSending": "Automatisches Senden",
"chooseContentRelevant": "Wählen Sie Inhalte, die zum gewünschten Thema passen"
},
"newFeature": "Neues Feature",
"chatDocsTips": "Unterstützt ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Μετακίνηση στην πλευρά",
"close": "Κλείσιμο",
"refresh": "Ανανέωση",
"protectedTabTips": "Αυτή η σελίδα προστατεύεται από τον περιηγητή"
"protectedTabTips": "Αυτή η σελίδα προστατεύεται από τον περιηγητή",
"prompt": "Προτροπή",
"message": "Μήνυμα",
"char": "Χαρακτήρας",
"reset": "Επαναφορά",
"copy": "Αντιγραφή",
"copied": "Αντιγράφηκε",
"pause": "Παύση",
"back": "Πίσω",
"search": "Αναζήτηση",
"promptTemplate": "Πρότυπο προτροπής",
"cancel": "Ακύρωση",
"save": "Αποθήκευση",
"next": "Επόμενο",
"chatDocsAddon": "Συνομιλία με Έγγραφα",
"chatDocs": {
"supportFormat": "Υποστήριξη PDF, DOCX",
"files": "Αρχεία/Κείμενο",
"selectFile": "Σύρετε ή κάντε κλικ για να επιλέξετε ένα αρχείο",
"msgSettings": "Ρυθμίσεις μηνύματος",
"editPrompt": "Επεξεργασία οδηγίας",
"maxLength": "Μέγιστο μήκος",
"maxSendings": "Μέγιστος αριθμός αποστολών",
"sendProgress": "Πρόοδος αποστολής",
"sendCompleted": "Η αποστολή ολοκληρώθηκε",
"msgContent": "Περιεχόμενο μηνύματος",
"startChatting": "Μπορείτε να αρχίσετε τη συνομιλία τώρα!",
"autoSending": "Αυτόματη αποστολή",
"chooseContentRelevant": "Επιλέξτε περιεχόμενο που σχετίζεται περισσότερο με το θέμα που θέλετε να μάθετε"
},
"newFeature": "Νέα δυνατότητα",
"chatDocsTips": "Υποστήριξη ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Move aside",
"close": "Close",
"refresh": "Refresh",
"protectedTabTips": "This page is protected by browser"
"protectedTabTips": "This page is protected by browser",
"prompt": "Prompt",
"message": "Message",
"char": "Char",
"reset": "Reset",
"copy": "Copy",
"copied": "Copied",
"pause": "Pause",
"back": "Back",
"search": "Search",
"promptTemplate": "Prompt Template",
"cancel": "Cancel",
"save": "Save",
"next": "Next",
"chatDocsAddon": "Chat with Docs",
"newFeature": "New Feature",
"chatDocsTips": "Support ChatGPT, Bard, MS Copilot...",
"chatDocs": {
"supportFormat": "Support PDF, DOCX",
"files": "Files/Text",
"selectFile": "Drag or select files",
"msgSettings": "Message Settings",
"editPrompt": "Edit Prompt",
"maxLength": "Max Length",
"maxSendings": "Max Sendings",
"sendProgress": "Send Progress",
"sendCompleted": "Send Completed",
"msgContent": "Message Content",
"startChatting": "You can start chatting now!",
"autoSending": "Auto Sending",
"chooseContentRelevant": "Choose content more relevant to the topic you want to learn about"
}
}
......@@ -6,5 +6,36 @@
"moveAside": "Mover a un lado",
"close": "Cerrar",
"refresh": "Actualizar",
"protectedTabTips": "Esta página está protegida por el navegador"
"protectedTabTips": "Esta página está protegida por el navegador",
"prompt": "Indicación",
"message": "Mensaje",
"char": "Carácter",
"reset": "Reiniciar",
"copy": "Copiar",
"copied": "Copiado",
"pause": "Pausa",
"back": "Atrás",
"search": "Buscar",
"promptTemplate": "Plantilla de aviso",
"cancel": "Cancelar",
"save": "Guardar",
"next": "Siguiente",
"chatDocsAddon": "Chat con Documentos",
"chatDocs": {
"supportFormat": "Soporte PDF, DOCX",
"files": "Archivos/Texto",
"selectFile": "Arrastra o haz clic para elegir un archivo",
"msgSettings": "Configuración de mensajes",
"editPrompt": "Editar Indicación",
"maxLength": "Longitud Máxima",
"maxSendings": "Máximo de Envíos",
"sendProgress": "Progreso de Envío",
"sendCompleted": "Envío Completado",
"msgContent": "Contenido del Mensaje",
"startChatting": "¡Puedes empezar a chatear ahora!",
"autoSending": "Envío Automático",
"chooseContentRelevant": "Elige contenido más relevante para el tema que deseas aprender"
},
"newFeature": "Nueva característica",
"chatDocsTips": "Compatibilidad con ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Mover a un lado",
"close": "Cerrar",
"refresh": "Refrescar",
"protectedTabTips": "Esta página está protegida por el navegador"
"protectedTabTips": "Esta página está protegida por el navegador",
"prompt": "Indicación",
"message": "Mensaje",
"char": "Carácter",
"reset": "Reiniciar",
"copy": "Copiar",
"copied": "Copiado",
"pause": "Pausa",
"back": "Atrás",
"search": "Buscar",
"promptTemplate": "Plantilla de aviso",
"cancel": "Cancelar",
"save": "Guardar",
"next": "Siguiente",
"chatDocsAddon": "Chat con Documentos",
"chatDocs": {
"supportFormat": "Soporte PDF, DOCX",
"files": "Archivos/Texto",
"selectFile": "Arrastra o haz clic para elegir un archivo",
"msgSettings": "Configuración de mensajes",
"editPrompt": "Editar Indicación",
"maxLength": "Longitud Máxima",
"maxSendings": "Máximo de Envíos",
"sendProgress": "Progreso de Envío",
"sendCompleted": "Envío Completado",
"msgContent": "Contenido del Mensaje",
"startChatting": "¡Puedes empezar a chatear ahora!",
"autoSending": "Envío Automático",
"chooseContentRelevant": "Elige contenido más relevante para el tema que deseas aprender"
},
"newFeature": "Nueva característica",
"chatDocsTips": "Soporte para ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Liiguta kõrvale",
"close": "Sulge",
"refresh": "Värskenda",
"protectedTabTips": "See lehekülg on kaitstud brauseri poolt"
"protectedTabTips": "See lehekülg on kaitstud brauseri poolt",
"prompt": "Käsk",
"message": "Sõnum",
"char": "Tähemärk",
"reset": "Lähtesta",
"copy": "Kopeeri",
"copied": "Kopeeritud",
"pause": "Paus",
"back": "Tagasi",
"search": "Otsi",
"promptTemplate": "Viibimall",
"cancel": "Tühista",
"save": "Salvesta",
"next": "Järgmine",
"chatDocsAddon": "Vestlus dokumentidega",
"chatDocs": {
"supportFormat": "Toetab PDF-i, DOCX-i",
"files": "Failid/Tekst",
"selectFile": "Lohista või klõpsa faili valimiseks",
"msgSettings": "Sõnumiseaded",
"editPrompt": "Muuda Viidet",
"maxLength": "Maksimaalne Pikkus",
"maxSendings": "Maksimaalsed Saadetised",
"sendProgress": "Saada Edusammud",
"sendCompleted": "Saadetud Lõpule",
"msgContent": "Sõnumi Sisu",
"startChatting": "Võid nüüd vestlust alustada!",
"autoSending": "Automaatne Saatmine",
"chooseContentRelevant": "Valige teema kohta rohkem seotud sisu"
},
"newFeature": "Uus funktsioon",
"chatDocsTips": "Toetab ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "جابجا شدن",
"close": "بستن",
"refresh": "تازه‌سازی",
"protectedTabTips": "این صفحه توسط مرورگر محافظت می‌شود"
"protectedTabTips": "این صفحه توسط مرورگر محافظت می‌شود",
"prompt": "درخواست",
"message": "پیام",
"char": "کاراکتر",
"reset": "بازنشانی",
"copy": "کپی",
"copied": "کپی شده",
"pause": "توقف",
"back": "بازگشت",
"search": "جستجو",
"promptTemplate": "الگوی هشدار",
"cancel": "لغو",
"save": "ذخیره",
"next": "بعدی",
"chatDocsAddon": "چت با اسناد",
"chatDocs": {
"supportFormat": "پشتیبانی از PDF، DOCX",
"files": "فایل‌ها/متن",
"selectFile": "فایل را بکشید یا برای انتخاب کلیک کنید",
"msgSettings": "تنظیمات پیام",
"editPrompt": "ویرایش هدایت",
"maxLength": "حداکثر طول",
"maxSendings": "حداکثر ارسال‌ها",
"sendProgress": "پیشرفت ارسال",
"sendCompleted": "ارسال کامل شد",
"msgContent": "محتوای پیام",
"startChatting": "اکنون می‌توانید چت را شروع کنید!",
"autoSending": "ارسال خودکار",
"chooseContentRelevant": "محتوای مرتبط با موضوعی که می‌خواهید درباره آن یاد بگیرید را انتخاب کنید"
},
"newFeature": "ویژگی جدید",
"chatDocsTips": "پشتیبانی از ChatGPT، Bard، MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Siirrä sivuun",
"close": "Sulje",
"refresh": "Päivitä",
"protectedTabTips": "Tämä sivu on suojattu selaimen toimesta"
"protectedTabTips": "Tämä sivu on suojattu selaimen toimesta",
"prompt": "Kehote",
"message": "Viesti",
"char": "Merkki",
"reset": "Nollaa",
"copy": "Kopioi",
"copied": "Kopioitu",
"pause": "Tauko",
"back": "Takaisin",
"search": "Haku",
"promptTemplate": "Ohjeiden malli",
"cancel": "Peruuta",
"save": "Tallenna",
"next": "Seuraava",
"chatDocsAddon": "Keskustele asiakirjojen kanssa",
"chatDocs": {
"supportFormat": "Tuki PDF, DOCX",
"files": "Tiedostot/Teksti",
"selectFile": "Raahaa tai klikkaa valitaksesi tiedosto",
"msgSettings": "Viestiasetukset",
"editPrompt": "Muokkaa Vihjetekstiä",
"maxLength": "Maksimipituus",
"maxSendings": "Maksimilähetykset",
"sendProgress": "Lähetys etenee",
"sendCompleted": "Lähetys valmis",
"msgContent": "Viestin Sisältö",
"startChatting": "Voit aloittaa keskustelun nyt!",
"autoSending": "Automaattilähetys",
"chooseContentRelevant": "Valitse aiheeseesi liittyvämpi sisältö"
},
"newFeature": "Uusi ominaisuus",
"chatDocsTips": "Tuki ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Ilipat sa tabi",
"close": "Isara",
"refresh": "I-refresh",
"protectedTabTips": "Protektado ng browser ang pahinang ito"
"protectedTabTips": "Protektado ng browser ang pahinang ito",
"prompt": "Prompt",
"message": "Mensahe",
"char": "Karakter",
"reset": "I-reset",
"copy": "Kopyahin",
"copied": "Nakopya",
"pause": "Pahinga",
"back": "Bumalik",
"search": "Maghanap",
"promptTemplate": "Padron ng Prompt",
"cancel": "Itigil",
"save": "I-save",
"next": "Susunod",
"chatDocsAddon": "Usapang may Docs",
"chatDocs": {
"supportFormat": "Suporta sa PDF, DOCX",
"files": "Mga File/Teksto",
"selectFile": "I-drag o i-click para pumili ng file",
"msgSettings": "Mga Setting ng Mensahe",
"editPrompt": "I-edit ang Prompt",
"maxLength": "Max na Habà",
"maxSendings": "Max na Pagsusugo",
"sendProgress": "Padala ng Progreso",
"sendCompleted": "Padala Natapos",
"msgContent": "Nilalaman ng Mensahe",
"startChatting": "Maaari ka nang magsimula ng kausap!",
"autoSending": "Auto Padala",
"chooseContentRelevant": "Pumili ng nilalaman na mas kaugnay sa paksa na nais mong malaman"
},
"newFeature": "Bagong Tampok",
"chatDocsTips": "Suporta sa ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Déplacer de côté",
"close": "Fermer",
"refresh": "Actualiser",
"protectedTabTips": "Cette page est protégée par le navigateur"
"protectedTabTips": "Cette page est protégée par le navigateur",
"prompt": "Invite",
"message": "Message",
"char": "Caractère",
"reset": "Réinitialiser",
"copy": "Copier",
"copied": "Copié",
"pause": "Pause",
"back": "Retour",
"search": "Rechercher",
"promptTemplate": "Modèle de suggestion",
"cancel": "Annuler",
"save": "Enregistrer",
"next": "Suivant",
"chatDocsAddon": "Discussion avec Docs",
"chatDocs": {
"supportFormat": "Prise en charge PDF, DOCX",
"files": "Fichiers/Texte",
"selectFile": "Faites glisser ou cliquez pour choisir un fichier",
"msgSettings": "Paramètres du message",
"editPrompt": "Éditer l'invite",
"maxLength": "Longueur maximale",
"maxSendings": "Nombre maximum d'envois",
"sendProgress": "Progression de l'envoi",
"sendCompleted": "Envoi terminé",
"msgContent": "Contenu du message",
"startChatting": "Vous pouvez commencer à discuter maintenant !",
"autoSending": "Envoi automatique",
"chooseContentRelevant": "Choisissez un contenu plus pertinent pour le sujet que vous souhaitez apprendre"
},
"newFeature": "Nouvelle fonctionnalité",
"chatDocsTips": "Prise en charge de ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "અપર ચાલો",
"close": "બંધ",
"refresh": "રિફ્રેશ",
"protectedTabTips": "આ પાનું બ્રાઉઝર દ્વારા સુરક્ષિત છે"
"protectedTabTips": "આ પાનું બ્રાઉઝર દ્વારા સુરક્ષિત છે",
"prompt": "પ્રોમ્પ્ટ",
"message": "સંદેશ",
"char": "અક્ષર",
"reset": "રીસેટ કરો",
"copy": "કૉપિ",
"copied": "કૉપિ થઈ ગયું",
"pause": "વિરામ",
"back": "પાછળ",
"search": "શોધો",
"promptTemplate": "પ્રોંપ્ટ ટેમ્પલેટ",
"cancel": "રદ કરો",
"save": "સાચવો",
"next": "આગામી",
"chatDocsAddon": "ડોક્યુમેન્ટ્સ સાથે ચેટ",
"chatDocs": {
"supportFormat": "પીડીએફ, ડોક્સ આધાર પર સપોર્ટ",
"files": "ફાઇલો/ટેક્સટ",
"selectFile": "ફાઇલ પસાર તથા પસંદ કરવાનું માટે ક્લિક કરો",
"msgSettings": "સંદેશ સેટિંગ્સ",
"editPrompt": "સૂચના સંપાદિત કરો",
"maxLength": "મહત્તમ લંબાઇ",
"maxSendings": "મહત્તમ મોકલવાની સંખ્યા",
"sendProgress": "મોકલવાનો પ્રગતિ",
"sendCompleted": "મોકલવું પૂર્ણ થયું",
"msgContent": "સંદેશ સારાંશ",
"startChatting": "તમે હવે ચેટિંગ શરૂ કરી શકો છો!",
"autoSending": "આપતી મોકલવું",
"chooseContentRelevant": "તમારા શીખવાના વિષય સાથે સંબંધિત કન્ટેન્ટ પસંદ કરો"
},
"newFeature": "નવું લક્ષણ",
"chatDocsTips": "સપોર્ટ ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "הזז בצד",
"close": "סגור",
"refresh": "רענן",
"protectedTabTips": "דף זה מוגן על ידי הדפדפן"
"protectedTabTips": "דף זה מוגן על ידי הדפדפן",
"prompt": "הפניה",
"message": "הודעה",
"char": "תו",
"reset": "איפוס",
"copy": "העתק",
"copied": "הועתק",
"pause": "השהייה",
"back": "חזור",
"search": "חיפוש",
"promptTemplate": "תבנית פנימה",
"cancel": "ביטול",
"save": "שמירה",
"next": "הבא",
"chatDocsAddon": "צ'אט עם מסמכים",
"chatDocs": {
"supportFormat": "תמיכה ב־PDF, DOCX",
"files": "קבצים/טקסט",
"selectFile": "גרור או לחץ לבחירת קובץ",
"msgSettings": "הגדרות הודעה",
"editPrompt": "ערוך הסבר",
"maxLength": "אורך מרבי",
"maxSendings": "מספר שליחות מרבי",
"sendProgress": "התקדמות בשליחה",
"sendCompleted": "שליחה הושלמה",
"msgContent": "תוכן ההודעה",
"startChatting": "אתה יכול להתחיל לשוחח כעת!",
"autoSending": "שליחה אוטומטית",
"chooseContentRelevant": "בחר תוכן הקשור יותר לנושא שברצונך ללמוד עליו"
},
"newFeature": "תכונה חדשה",
"chatDocsTips": "תמיכה ב-ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "दूर हटें",
"close": "बंद करें",
"refresh": "ताज़ा करें",
"protectedTabTips": "यह पृष्ठ ब्राउज़र द्वारा सुरक्षित है"
"protectedTabTips": "यह पृष्ठ ब्राउज़र द्वारा सुरक्षित है",
"prompt": "प्रॉम्प्ट",
"message": "संदेश",
"char": "अक्षर",
"reset": "रीसेट",
"copy": "कॉपी",
"copied": "कॉपी किया गया",
"pause": "विराम",
"back": "वापस",
"search": "खोज",
"promptTemplate": "पूर्वसूचना टेम्प्लेट",
"cancel": "रद्द करें",
"save": "सहेजें",
"next": "अगला",
"chatDocsAddon": "डॉक्यूमेंट्स के साथ चैट",
"chatDocs": {
"supportFormat": "PDF, DOCX का समर्थन करें",
"files": "फ़ाइलें/टेक्स्ट",
"selectFile": "फ़ाइल का चयन करने के लिए खींचें या क्लिक करें",
"msgSettings": "संदेश सेटिंग्स",
"editPrompt": "प्रम्पट संपादित करें",
"maxLength": "अधिकतम लंबाई",
"maxSendings": "अधिकतम भेजने की संख्या",
"sendProgress": "भेजने की प्रगति",
"sendCompleted": "भेजना पूरा हुआ",
"msgContent": "संदेश सामग्री",
"startChatting": "आप अब चैटिंग शुरू कर सकते हैं!",
"autoSending": "आत्म-भेजन",
"chooseContentRelevant": "उस विषय के बारे में सीखना जिस पर आप चर्चा करना चाहते हैं, उससे संबंधित सामग्री चुनें"
},
"newFeature": "नई सुविधा",
"chatDocsTips": "समर्थन ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Pomakni na stranu",
"close": "Zatvori",
"refresh": "Osvježi",
"protectedTabTips": "Ova stranica je zaštićena preglednikom"
"protectedTabTips": "Ova stranica je zaštićena preglednikom",
"prompt": "Poziv",
"message": "Poruka",
"char": "Znak",
"reset": "Resetiraj",
"copy": "Kopiraj",
"copied": "Kopirano",
"pause": "Pauza",
"back": "Natrag",
"search": "Pretraga",
"promptTemplate": "Predložak upita",
"cancel": "Odustani",
"save": "Spremi",
"next": "Sljedeće",
"chatDocsAddon": "Čavrljanje s dokumentima",
"chatDocs": {
"supportFormat": "Podržava PDF, DOCX",
"files": "Datoteke/Tekst",
"selectFile": "Povuci ili klikni za odabir datoteke",
"msgSettings": "Postavke poruke",
"editPrompt": "Uredi uputu",
"maxLength": "Maksimalna duljina",
"maxSendings": "Maksimalni broj slanja",
"sendProgress": "Slanje u tijeku",
"sendCompleted": "Slanje završeno",
"msgContent": "Sadržaj poruke",
"startChatting": "Možete početi razgovarati sada!",
"autoSending": "Automatsko slanje",
"chooseContentRelevant": "Odaberite sadržaj koji je relevantan za temu koju želite naučiti"
},
"newFeature": "Nova značajka",
"chatDocsTips": "Podrška za ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Elmozdít",
"close": "Bezárás",
"refresh": "Frissítés",
"protectedTabTips": "Ezt az oldalt a böngésző védi"
"protectedTabTips": "Ezt az oldalt a böngésző védi",
"prompt": "Felszólítás",
"message": "Üzenet",
"char": "Karakter",
"reset": "Visszaállítás",
"copy": "Másolás",
"copied": "Másolva",
"pause": "Szünet",
"back": "Vissza",
"search": "Keresés",
"promptTemplate": "Kérés sablon",
"cancel": "Mégse",
"save": "Mentés",
"next": "Következő",
"chatDocsAddon": "Csevegés dokumentumokkal",
"chatDocs": {
"supportFormat": "PDF, DOCX támogatás",
"files": "Fájlok/Szöveg",
"selectFile": "Húzza vagy kattintson a fájl kiválasztásához",
"msgSettings": "Üzenet beállítások",
"editPrompt": "Ugró ablak szerkesztése",
"maxLength": "Maximális hossz",
"maxSendings": "Maximális küldési szám",
"sendProgress": "Küldés folyamatban",
"sendCompleted": "Küldés befejeződött",
"msgContent": "Üzenet tartalom",
"startChatting": "Most kezdheti a beszélgetést!",
"autoSending": "Automatikus küldés",
"chooseContentRelevant": "Válassza ki a témához relevánsabb tartalmat, amiről szeretne tanulni"
},
"newFeature": "Új funkció",
"chatDocsTips": "Támogatja a ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Pindah ke samping",
"close": "Tutup",
"refresh": "Segarkan",
"protectedTabTips": "Halaman ini dilindungi oleh browser"
"protectedTabTips": "Halaman ini dilindungi oleh browser",
"prompt": "Prompt",
"message": "Pesan",
"char": "Karakter",
"reset": "Atur Ulang",
"copy": "Salin",
"copied": "Tersalin",
"pause": "Jeda",
"back": "Kembali",
"search": "Cari",
"promptTemplate": "Pola Petunjuk",
"cancel": "Batal",
"save": "Simpan",
"next": "Selanjutnya",
"chatDocsAddon": "Obrolan dengan Dokumen",
"chatDocs": {
"supportFormat": "Dukungan PDF, DOCX",
"files": "File/Teks",
"selectFile": "Seret atau klik untuk memilih file",
"msgSettings": "Pengaturan Pesan",
"editPrompt": "Edit Prompt",
"maxLength": "Panjang Maksimal",
"maxSendings": "Jumlah Pengiriman Maksimal",
"sendProgress": "Kirim Progres",
"sendCompleted": "Kirim Selesai",
"msgContent": "Konten Pesan",
"startChatting": "Anda bisa mulai chatting sekarang!",
"autoSending": "Pengiriman Otomatis",
"chooseContentRelevant": "Pilih konten yang lebih relevan dengan topik yang ingin Anda pelajari"
},
"newFeature": "Fitur Baru",
"chatDocsTips": "Dukungan ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Sposta da parte",
"close": "Chiudi",
"refresh": "Aggiorna",
"protectedTabTips": "Questa pagina è protetta dal browser"
"protectedTabTips": "Questa pagina è protetta dal browser",
"prompt": "Prompt",
"message": "Messaggio",
"char": "Carattere",
"reset": "Reimposta",
"copy": "Copia",
"copied": "Copiato",
"pause": "Pausa",
"back": "Indietro",
"search": "Cerca",
"promptTemplate": "Modello di promemoria",
"cancel": "Annulla",
"save": "Salva",
"next": "Avanti",
"chatDocsAddon": "Chat con Documenti",
"chatDocs": {
"supportFormat": "Supporto PDF, DOCX",
"files": "File/Testo",
"selectFile": "Trascina o clicca per scegliere un file",
"msgSettings": "Impostazioni messaggio",
"editPrompt": "Modifica Prompt",
"maxLength": "Lunghezza massima",
"maxSendings": "Invii massimi",
"sendProgress": "Invio in corso",
"sendCompleted": "Invio completato",
"msgContent": "Contenuto messaggio",
"startChatting": "Puoi iniziare a chattare adesso!",
"autoSending": "Invio automatico",
"chooseContentRelevant": "Scegli contenuti più pertinenti all'argomento che vuoi apprendere"
},
"newFeature": "Nuova funzionalità",
"chatDocsTips": "Supporta ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "一旦寄せる",
"close": "閉じる",
"refresh": "更新",
"protectedTabTips": "このページはブラウザによって保護されています"
"protectedTabTips": "このページはブラウザによって保護されています",
"prompt": "プロンプト",
"message": "メッセージ",
"char": "文字",
"reset": "リセット",
"copy": "コピー",
"copied": "コピー済み",
"pause": "一時停止",
"back": "戻る",
"search": "検索",
"promptTemplate": "プロンプトのテンプレート",
"cancel": "キャンセル",
"save": "保存",
"next": "次へ",
"chatDocsAddon": "ドキュメントとのチャット",
"chatDocs": {
"supportFormat": "PDF、DOCX 対応",
"files": "ファイル/テキスト",
"selectFile": "ファイルを選択するにはドラッグまたはクリック",
"msgSettings": "メッセージ設定",
"editPrompt": "プロンプトの編集",
"maxLength": "最大長",
"maxSendings": "最大送信回数",
"sendProgress": "送信進捗",
"sendCompleted": "送信完了",
"msgContent": "メッセージ内容",
"startChatting": "今すぐチャットを始めることができます!",
"autoSending": "自動送信",
"chooseContentRelevant": "学びたいトピックに関連するコンテンツを選択してください"
},
"newFeature": "新機能",
"chatDocsTips": "ChatGPT、Bard、MS Copilot のサポート..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "ಬೆಳಕು ನೀಡಿ",
"close": "ಮುಚ್ಚಿ",
"refresh": "ರಿಫ್ರೆಶ್",
"protectedTabTips": "ಈ ಪುಟವನ್ನು ಬ್ರೌಸರ್‌ ರಕ್ಷಿಸಿದೆ"
"protectedTabTips": "ಈ ಪುಟವನ್ನು ಬ್ರೌಸರ್‌ ರಕ್ಷಿಸಿದೆ",
"prompt": "ಪ್ರಾಂಪ್ಟ್",
"message": "ಸಂದೇಶ",
"char": "ಅಕ್ಷರ",
"reset": "ಮರುಹೊಂದಿಸಿ",
"copy": "ನಕಲಿಸಿ",
"copied": "ನಕಲಿಸಲಾಗಿದೆ",
"pause": "ವಿರಾಮ",
"back": "ಹಿಂತಿರುಗಿ",
"search": "ಹುಡುಕು",
"promptTemplate": "ಪ್ರಾಂಪ್ಟ್ ಟೆಂಪ್ಲೇಟ್",
"cancel": "ರದ್ದು ಮಾಡು",
"save": "ಉಳಿಸು",
"next": "ಮುಂದುವರಿಸು",
"chatDocsAddon": "ಡಾಕ್ಸ್ ಸಹ ಚಾಟ್",
"chatDocs": {
"supportFormat": "PDF, DOCX ಬೆಂಬಲ",
"files": "ಕಡತ/ಟೆಕ್ಸ್ಟ್",
"selectFile": "ಫೈಲ್ ಆಯ್ಕೆಮಾಡಲು ಎಳ್ಳಿಗೆ ಅಥವಾ ಕ್ಲಿಕ್ ಮಾಡಿ",
"msgSettings": "ಸಂದೇಶ ಸೆಟ್ಟಿಂಗ್ಗಳು",
"editPrompt": "ಸೂಚನೆ ಸಂಪಾದಿಸಿ",
"maxLength": "ಗರಿಷ್ಠ ಉದ್ದ",
"maxSendings": "ಗರಿಷ್ಠ ಕಳುಹಿಸುವ ಸಂಖ್ಯೆ",
"sendProgress": "ಕಳುಹಿಸುತ್ತಿದೆ ಪ್ರೋಗ್ರೆಸ್",
"sendCompleted": "ಕಳುಹಿಸಲಾಗಿದೆ",
"msgContent": "ಸಂದೇಶ ವಿಷಯಾಂತರ",
"startChatting": "ನೀವು ಈಗ ಚಾಟಿಂಗ್ ಆರಂಭಿಸಬಹುದು!",
"autoSending": "ಸ್ವಯಂ ಕಳುಹಿಸುತ್ತಿದೆ",
"chooseContentRelevant": "ನೀವು ಕಲಿಯಬಯಸುವ ವಿಷಯಕ್ಕೆ ಹೆಚ್ಚಿನ ಸಂಬಂಧಪಟ್ಟ ವಿಷಯಗಳನ್ನು ಆರಿಸಿ"
},
"newFeature": "ಹೊಸ ವಿಶೇಷವನ್ನು",
"chatDocsTips": "ChatGPT, Bard, MS Copilot ಅನ್ನು ಬೆಂಬಲಿಸುತ್ತದೆ..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "옆으로 이동",
"close": "닫기",
"refresh": "새로고침",
"protectedTabTips": "이 페이지는 브라우저에 의해 보호됩니다"
"protectedTabTips": "이 페이지는 브라우저에 의해 보호됩니다",
"prompt": "프롬프트",
"message": "메시지",
"char": "문자",
"reset": "재설정",
"copy": "복사",
"copied": "복사됨",
"pause": "일시정지",
"back": "뒤로",
"search": "검색",
"promptTemplate": "프롬프트 템플릿",
"cancel": "취소",
"save": "저장",
"next": "다음",
"chatDocsAddon": "문서와 채팅",
"chatDocs": {
"supportFormat": "PDF, DOCX 지원",
"files": "파일/텍스트",
"selectFile": "파일 선택하려면 끌거나 클릭하세요",
"msgSettings": "메시지 설정",
"editPrompt": "프롬프트 편집",
"maxLength": "최대 길이",
"maxSendings": "최대 전송 횟수",
"sendProgress": "전송 진행",
"sendCompleted": "전송 완료",
"msgContent": "메시지 내용",
"startChatting": "이제 채팅을 시작할 수 있습니다!",
"autoSending": "자동 전송",
"chooseContentRelevant": "학습하고 싶은 주제와 관련된 콘텐츠를 선택하세요"
},
"newFeature": "새로운 기능",
"chatDocsTips": "ChatGPT, Bard, MS Copilot 지원..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Nustumti šalin",
"close": "Uždaryti",
"refresh": "Atnaujinti",
"protectedTabTips": "Šis puslapis apsaugotas naršyklės"
"protectedTabTips": "Šis puslapis apsaugotas naršyklės",
"prompt": "Raginimas",
"message": "Žinutė",
"char": "Simbolis",
"reset": "Atstatyti",
"copy": "Kopijuoti",
"copied": "Nukopijuota",
"pause": "Pauzė",
"back": "Atgal",
"search": "Ieškoti",
"promptTemplate": "Užklausos šablonas",
"cancel": "Atšaukti",
"save": "Išsaugoti",
"next": "Kitas",
"chatDocsAddon": "Pokalbis su Dokumentais",
"chatDocs": {
"supportFormat": "Palaikomi PDF, DOCX",
"files": "Failai/Tekstas",
"selectFile": "Vilkite arba spustelėkite, norėdami pasirinkti failą",
"msgSettings": "Žinutės nustatymai",
"editPrompt": "Redaguoti užklausą",
"maxLength": "Maksimalus ilgis",
"maxSendings": "Maksimalus siuntimų skaičius",
"sendProgress": "Siuntimo eiga",
"sendCompleted": "Siuntimas baigtas",
"msgContent": "Žinutės turinys",
"startChatting": "Dabar galite pradėti pokalbį!",
"autoSending": "Automatinis siuntimas",
"chooseContentRelevant": "Pasirinkite turinį, kuris yra labiau susijęs su jumis dominančia tema"
},
"newFeature": "Nauja funkcija",
"chatDocsTips": "Palaiko ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Pagriezt malā",
"close": "Aizvērt",
"refresh": "Atsvaidzināt",
"protectedTabTips": "Šī lapa ir aizsargāta ar pārlūkprogrammu"
"protectedTabTips": "Šī lapa ir aizsargāta ar pārlūkprogrammu",
"prompt": "Uzaicinājums",
"message": "Ziņojums",
"char": "Rakstzīme",
"reset": "Atiestatīt",
"copy": "Kopēt",
"copied": "Nokopēts",
"pause": "Pauze",
"back": "Atpakaļ",
"search": "Meklēt",
"promptTemplate": "Piedāvājuma veidne",
"cancel": "Atcelt",
"save": "Saglabāt",
"next": "Nākamais",
"chatDocsAddon": "Čats ar Dokumentiem",
"chatDocs": {
"supportFormat": "Atbalsta PDF, DOCX",
"files": "Faili/Teksts",
"selectFile": "Velciet vai noklikšķiniet, lai izvēlētos failu",
"msgSettings": "Ziņojuma iestatījumi",
"editPrompt": "Rediģēt Uzvedības norādi",
"maxLength": "Maksimālais garums",
"maxSendings": "Maksimālais nosūtījumu skaits",
"sendProgress": "Nosūtīšanas progress",
"sendCompleted": "Nosūtīšana pabeigta",
"msgContent": "Ziņojuma saturs",
"startChatting": "Jūs varat sākt čatot tagad!",
"autoSending": "Automātiska sūtīšana",
"chooseContentRelevant": "Izvēlieties saturu, kas ir saistīts ar tēmu, par kuru vēlaties uzzināt"
},
"newFeature": "Jauna funkcija",
"chatDocsTips": "Atbalsta ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "വലത്തരിക്കുക",
"close": "അടുത്തവെക്കുക",
"refresh": "പുതുക്കുക",
"protectedTabTips": "ഈ പേജ് ബ്രൗസർ സംരക്ഷിക്കുന്നു"
"protectedTabTips": "ഈ പേജ് ബ്രൗസർ സംരക്ഷിക്കുന്നു",
"prompt": "പ്രോംപ്റ്റ്",
"message": "സന്ദേശം",
"char": "അക്ഷരം",
"reset": "പുനഃസജ്ജമാക്കുക",
"copy": "പകർത്തുക",
"copied": "പകർത്തി",
"pause": "ഇടവേള",
"back": "പിന്നിലേക്ക്",
"search": "തിരയുക",
"promptTemplate": "പ്രോംപ്റ്റ് ടെമ്പ്ലേറ്റ്",
"cancel": "റദ്ദാക്കുക",
"save": "സേവ്",
"next": "അടുത്തത്",
"chatDocsAddon": "ഡോക്യുമെന്റുകൾ സഹ ചാറ്റ്",
"chatDocs": {
"supportFormat": "പി.ഡി.എഫ്, ഡോക്സ് പിന്തുണച്ചാണ്",
"files": "കടുത്ത/എഴുത്ത്",
"selectFile": "ഫയൽ തിരഞ്ഞെടുക്കുന്നതിന് ഇങ്ങനെ അല്ലെങ്കിൽ ക്ലിക്കുചെയ്യുക",
"msgSettings": "സന്ദേശ ക്രമീകരണങ്ങൾ",
"editPrompt": "പ്രോംപ്റ്റ് തിരുത്തുക",
"maxLength": "പരമാവധി നീളം",
"maxSendings": "പരമാവധി അയയ്ക്കൽകൾ",
"sendProgress": "അയയ്ക്കൽ പുരോഗതി",
"sendCompleted": "അയയ്ക്കല്‍ പൂർത്തമായി",
"msgContent": "സന്ദേശ ഉള്ളടക്കം",
"startChatting": "നിന്ന് നിന്നേക്ക് ചാറ്റിംഗ് ആരംഭിക്കാം!",
"autoSending": "ഓട്ടോ അയയ്ക്കൽ",
"chooseContentRelevant": "നിങ്ങളുടെ അറിവിനായി കരുതോട്ട വിഷയത്തിനു കൂടുതൽ ബന്ധമായ ഉള്ളടക്കം തിരഞ്ഞെടുക്കുക"
},
"newFeature": "പുതിയ സവിശേഷത",
"chatDocsTips": "ChatGPT, Bard, MS Copilot പിന്തുണയ്ക്കുന്നു..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "पाठवा",
"close": "बंद करा",
"refresh": "ताज्या करा",
"protectedTabTips": "हे पृष्ठ ब्राउझरने संरक्षित केले आहे"
"protectedTabTips": "हे पृष्ठ ब्राउझरने संरक्षित केले आहे",
"prompt": "प्रॉम्प्ट",
"message": "संदेश",
"char": "अक्षर",
"reset": "रीसेट करा",
"copy": "कॉपी",
"copied": "कॉपी झाले",
"pause": "विराम",
"back": "मागे",
"search": "शोध",
"promptTemplate": "सूचना टेम्प्लेट",
"cancel": "रद्द करा",
"save": "सेव्ह करा",
"next": "पुढे",
"chatDocsAddon": "दस्तऐवजांसह चॅट",
"chatDocs": {
"supportFormat": "पीडीएफ, डॉक्स समर्थन",
"files": "फाइलें/टेक्स्ट",
"selectFile": "फाइल निवडण्यासाठी ड्रॅग किंवा क्लिक करा",
"msgSettings": "संदेश सेटिंग्ज",
"editPrompt": "प्रॉम्प्ट संपादित करा",
"maxLength": "अधिकतम लांबी",
"maxSendings": "अधिकतम पाठवण्यांची संख्या",
"sendProgress": "पाठवण्याची प्रगती",
"sendCompleted": "पाठवणे संपले",
"msgContent": "संदेश सामग्री",
"startChatting": "तुम्ही आता गप्पा सुरू करू शकता!",
"autoSending": "स्वत: पाठवणे",
"chooseContentRelevant": "तुम्हाला ओळखायचं विषयसंबंधित आशय निवडा"
},
"newFeature": "नवीन सुविधा",
"chatDocsTips": "समर्थन ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Bersisih",
"close": "Tutup",
"refresh": "Muat semula",
"protectedTabTips": "Halaman ini dilindungi oleh pelayar"
"protectedTabTips": "Halaman ini dilindungi oleh pelayar",
"prompt": "Arahan",
"message": "Mesej",
"char": "Aksara",
"reset": "Tetap Semula",
"copy": "Salin",
"copied": "Telah Disalin",
"pause": "Jeda",
"back": "Kembali",
"search": "Cari",
"promptTemplate": "Templat Pesanan",
"cancel": "Batal",
"save": "Simpan",
"next": "Seterusnya",
"chatDocsAddon": "Berbual dengan Dokumen",
"chatDocs": {
"supportFormat": "Sokongan PDF, DOCX",
"files": "Fail/Teks",
"selectFile": "Seret atau klik untuk memilih fail",
"msgSettings": "Tetapan Mesej",
"editPrompt": "Edit Prompt",
"maxLength": "Panjang Maksimum",
"maxSendings": "Penghantaran Maksimum",
"sendProgress": "Hantar Kemajuan",
"sendCompleted": "Hantar Selesai",
"msgContent": "Kandungan Mesej",
"startChatting": "Anda boleh mula berbual sekarang!",
"autoSending": "Penghantaran Automatik",
"chooseContentRelevant": "Pilih kandungan yang lebih berkaitan dengan topik yang anda ingin ketahui"
},
"newFeature": "Ciri Baru",
"chatDocsTips": "Sokongan ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Opzij zetten",
"close": "Sluiten",
"refresh": "Vernieuwen",
"protectedTabTips": "Deze pagina is beschermd door de browser"
"protectedTabTips": "Deze pagina is beschermd door de browser",
"prompt": "Prompt",
"message": "Bericht",
"char": "Karakter",
"reset": "Resetten",
"copy": "Kopiëren",
"copied": "Gekopieerd",
"pause": "Pauze",
"back": "Terug",
"search": "Zoeken",
"promptTemplate": "Prompt sjabloon",
"cancel": "Annuleren",
"save": "Opslaan",
"next": "Volgende",
"chatDocsAddon": "Chatten met Documenten",
"chatDocs": {
"supportFormat": "Ondersteunt PDF, DOCX",
"files": "Bestanden/Tekst",
"selectFile": "Sleep of klik om een bestand te kiezen",
"msgSettings": "Berichtinstellingen",
"editPrompt": "Prompt bewerken",
"maxLength": "Maximale lengte",
"maxSendings": "Maximale verzendingen",
"sendProgress": "Verzenden Voortgang",
"sendCompleted": "Verzenden Voltooid",
"msgContent": "Berichtinhoud",
"startChatting": "Je kunt nu beginnen met chatten!",
"autoSending": "Automatisch verzenden",
"chooseContentRelevant": "Kies inhoud die relevanter is voor het onderwerp dat je wilt leren"
},
"newFeature": "Nieuwe functie",
"chatDocsTips": "Ondersteuning voor ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Flytt til side",
"close": "Lukk",
"refresh": "Oppdater",
"protectedTabTips": "Denne siden er beskyttet av nettleseren"
"protectedTabTips": "Denne siden er beskyttet av nettleseren",
"prompt": "Kommando",
"message": "Melding",
"char": "Tegn",
"reset": "Tilbakestill",
"copy": "Kopier",
"copied": "Kopiert",
"pause": "Pause",
"back": "Tilbake",
"search": "Søk",
"promptTemplate": "Prompt Mal",
"cancel": "Avbryt",
"save": "Lagre",
"next": "Neste",
"chatDocsAddon": "Chat med Dokumenter",
"chatDocs": {
"supportFormat": "Støtter PDF, DOCX",
"files": "Filer/Tekst",
"selectFile": "Dra eller klikk for å velge en fil",
"msgSettings": "Meldingsinnstillinger",
"editPrompt": "Rediger Prompt",
"maxLength": "Maks Lengde",
"maxSendings": "Maks Sendings",
"sendProgress": "Send Fremskritt",
"sendCompleted": "Send Fullført",
"msgContent": "Meldingsinnhold",
"startChatting": "Du kan begynne å chatte nå!",
"autoSending": "Auto Sending",
"chooseContentRelevant": "Velg innhold som er mer relevant for emnet du vil lære om"
},
"newFeature": "Ny funksjon",
"chatDocsTips": "Støtte for ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Przesuń na bok",
"close": "Zamknij",
"refresh": "Odśwież",
"protectedTabTips": "Ta strona jest chroniona przez przeglądarkę"
"protectedTabTips": "Ta strona jest chroniona przez przeglądarkę",
"prompt": "Monit",
"message": "Wiadomość",
"char": "Znak",
"reset": "Resetuj",
"copy": "Kopiuj",
"copied": "Skopiowane",
"pause": "Pauza",
"back": "Wstecz",
"search": "Szukaj",
"promptTemplate": "Szablon Zapytania",
"cancel": "Anuluj",
"save": "Zapisz",
"next": "Następny",
"chatDocsAddon": "Czat z Dokumentami",
"chatDocs": {
"supportFormat": "Obsługa PDF, DOCX",
"files": "Pliki/Tekst",
"selectFile": "Przeciągnij lub kliknij, aby wybrać plik",
"msgSettings": "Ustawienia Wiadomości",
"editPrompt": "Edytuj Podpowiedź",
"maxLength": "Maksymalna Długość",
"maxSendings": "Maksymalna Liczba Wysyłek",
"sendProgress": "Stan Wysyłki",
"sendCompleted": "Wysyłka Zakończona",
"msgContent": "Treść Wiadomości",
"startChatting": "Możesz teraz zacząć rozmawiać!",
"autoSending": "Automatyczne Wysyłanie",
"chooseContentRelevant": "Wybierz treść bardziej związana z tematem, który chcesz się dowiedzieć"
},
"newFeature": "Nowa funkcja",
"chatDocsTips": "Wsparcie dla ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Mover para o lado",
"close": "Fechar",
"refresh": "Atualizar",
"protectedTabTips": "Esta página está protegida pelo navegador"
"protectedTabTips": "Esta página está protegida pelo navegador",
"prompt": "Prompt",
"message": "Mensagem",
"char": "Caráter",
"reset": "Redefinir",
"copy": "Copiar",
"copied": "Copiado",
"pause": "Pausa",
"back": "Voltar",
"search": "Buscar",
"promptTemplate": "Modelo de Prompt",
"cancel": "Cancelar",
"save": "Salvar",
"next": "Próximo",
"chatDocsAddon": "Conversar com Documentos",
"chatDocs": {
"supportFormat": "Suporte para PDF, DOCX",
"files": "Arquivos/Texto",
"selectFile": "Arraste ou clique para escolher um arquivo",
"msgSettings": "Configurações de Mensagem",
"editPrompt": "Editar Prompt",
"maxLength": "Comprimento Máximo",
"maxSendings": "Máximo de Envios",
"sendProgress": "Progresso de Envio",
"sendCompleted": "Envio Concluído",
"msgContent": "Conteúdo da Mensagem",
"startChatting": "Você pode começar a conversar agora!",
"autoSending": "Envio Automático",
"chooseContentRelevant": "Escolha conteúdo mais relevante para o tópico que você deseja aprender"
},
"newFeature": "Nova Funcionalidade",
"chatDocsTips": "Suporte para ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Mover para o lado",
"close": "Fechar",
"refresh": "Atualizar",
"protectedTabTips": "Esta página está protegida pelo navegador"
"protectedTabTips": "Esta página está protegida pelo navegador",
"prompt": "Prompt",
"message": "Mensagem",
"char": "Caráter",
"reset": "Redefinir",
"copy": "Copiar",
"copied": "Copiado",
"pause": "Pausa",
"back": "Voltar",
"search": "Pesquisar",
"promptTemplate": "Modelo de Prompt",
"cancel": "Cancelar",
"save": "Guardar",
"next": "Próximo",
"chatDocsAddon": "Conversar com Documentos",
"chatDocs": {
"supportFormat": "Suporte para PDF, DOCX",
"files": "Ficheiros/Texto",
"selectFile": "Arraste ou clique para escolher um ficheiro",
"msgSettings": "Configurações da Mensagem",
"editPrompt": "Editar Prompt",
"maxLength": "Comprimento Máximo",
"maxSendings": "Máximo de Envios",
"sendProgress": "Progresso de Envio",
"sendCompleted": "Envio Concluído",
"msgContent": "Conteúdo da Mensagem",
"startChatting": "Pode começar a conversar agora!",
"autoSending": "Envio Automático",
"chooseContentRelevant": "Escolha conteúdo mais relevante para o tópico que deseja aprender"
},
"newFeature": "Nova funcionalidade",
"chatDocsTips": "Suporte a ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Mută în lateral",
"close": "Închide",
"refresh": "Reîmprospătează",
"protectedTabTips": "Această pagină este protejată de browser"
"protectedTabTips": "Această pagină este protejată de browser",
"prompt": "Prompt",
"message": "Mesaj",
"char": "Caracter",
"reset": "Resetează",
"copy": "Copiază",
"copied": "Copiat",
"pause": "Pauză",
"back": "Înapoi",
"search": "Caută",
"promptTemplate": "Șablon Prompt",
"cancel": "Anulare",
"save": "Salvare",
"next": "Următorul",
"chatDocsAddon": "Chat cu Documente",
"chatDocs": {
"supportFormat": "Suport PDF, DOCX",
"files": "Fișiere/Text",
"selectFile": "Trage sau dă clic pentru a alege un fișier",
"msgSettings": "Setări Mesaj",
"editPrompt": "Editează Sfat",
"maxLength": "Lungime Maximă",
"maxSendings": "Număr Maxim de Trimiteri",
"sendProgress": "Progres Trimitere",
"sendCompleted": "Trimitere Completată",
"msgContent": "Conținut Mesaj",
"startChatting": "Puteți începe să discutați acum!",
"autoSending": "Trimitere Automată",
"chooseContentRelevant": "Alegeți conținut mai relevant pentru subiectul pe care doriți să îl învățați"
},
"newFeature": "Caracteristică nouă",
"chatDocsTips": "Suport pentru ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Убрать в сторону",
"close": "Закрыть",
"refresh": "Обновить",
"protectedTabTips": "Эта страница защищена браузером"
"protectedTabTips": "Эта страница защищена браузером",
"prompt": "Приглашение",
"message": "Сообщение",
"char": "Символ",
"reset": "Сброс",
"copy": "Копировать",
"copied": "Скопировано",
"pause": "Пауза",
"back": "Назад",
"search": "Поиск",
"promptTemplate": "Шаблон подсказки",
"cancel": "Отмена",
"save": "Сохранить",
"next": "Далее",
"chatDocsAddon": "Чат с документами",
"chatDocs": {
"supportFormat": "Поддержка PDF, DOCX",
"files": "Файлы/Текст",
"selectFile": "Перетащите или кликните, чтобы выбрать файл",
"msgSettings": "Настройки Сообщения",
"editPrompt": "Редактировать Подсказку",
"maxLength": "Максимальная Длина",
"maxSendings": "Максимальное Количество Отправок",
"sendProgress": "Прогресс Отправки",
"sendCompleted": "Отправка Завершена",
"msgContent": "Содержание Сообщения",
"startChatting": "Теперь вы можете начать чат!",
"autoSending": "Автоматическая Отправка",
"chooseContentRelevant": "Выберите более релевантный контент по теме, которую вы хотите изучить"
},
"newFeature": "Новая функция",
"chatDocsTips": "Поддержка ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Presunúť bokom",
"close": "Zatvoriť",
"refresh": "Obnoviť",
"protectedTabTips": "Táto stránka je chránená prehliadačom"
"protectedTabTips": "Táto stránka je chránená prehliadačom",
"prompt": "Prompt",
"message": "Správa",
"char": "Znak",
"reset": "Resetovať",
"copy": "Kopírovať",
"copied": "Skopírované",
"pause": "Pauza",
"back": "Späť",
"search": "Hľadať",
"promptTemplate": "Šablóna Pokynu",
"cancel": "Zrušiť",
"save": "Uložiť",
"next": "Ďalej",
"chatDocsAddon": "Chat s Dokumentmi",
"chatDocs": {
"supportFormat": "Podpora pre PDF, DOCX",
"files": "Súbory/Text",
"selectFile": "Potiahnite alebo kliknite na výber súboru",
"msgSettings": "Nastavenia Správy",
"editPrompt": "Upraviť Prompt",
"maxLength": "Maximálna Dĺžka",
"maxSendings": "Maximálny Počet Odoslaní",
"sendProgress": "Stav Odosielania",
"sendCompleted": "Odoslanie Dokončené",
"msgContent": "Obsah Správy",
"startChatting": "Teraz môžete začať chýbať!",
"autoSending": "Automatické Odosielanie",
"chooseContentRelevant": "Vyberte obsah, ktorý je viac relevantný pre tému, ktorú chcete študovať"
},
"newFeature": "Nová funkcia",
"chatDocsTips": "Podpora ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Premakni na stran",
"close": "Zapri",
"refresh": "Osveži",
"protectedTabTips": "Ta stran je zaščitena z brskalnikom"
"protectedTabTips": "Ta stran je zaščitena z brskalnikom",
"prompt": "Prompt",
"message": "Sporočilo",
"char": "Znak",
"reset": "Ponastavi",
"copy": "Kopiraj",
"copied": "Kopirano",
"pause": "Pavza",
"back": "Nazaj",
"search": "Iskanje",
"promptTemplate": "Predloga Zahteve",
"cancel": "Prekliči",
"save": "Shrani",
"next": "Naprej",
"chatDocsAddon": "Klepet z Dokumenti",
"chatDocs": {
"supportFormat": "Podpora za PDF, DOCX",
"files": "Datoteke/Besedilo",
"selectFile": "Povleci ali klikni za izbiro datoteke",
"msgSettings": "Nastavitve Sporočila",
"editPrompt": "Uredi Vprašanje",
"maxLength": "Največja Dolžina",
"maxSendings": "Največje Pošiljanje",
"sendProgress": "Napredek Pošiljanja",
"sendCompleted": "Pošiljanje Končano",
"msgContent": "Vsebina Sporočila",
"startChatting": "Lahko začnete klepetati zdaj!",
"autoSending": "Avtomatsko Pošiljanje",
"chooseContentRelevant": "Izberite vsebino, ki je bolj relevantna za temo, ki se je želite naučiti"
},
"newFeature": "Nova funkcionalnost",
"chatDocsTips": "Podpora za ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Pomeri na stranu",
"close": "Zatvori",
"refresh": "Osveži",
"protectedTabTips": "Ова страница је заштићена прегледачем"
"protectedTabTips": "Ова страница је заштићена прегледачем",
"prompt": "Prompt",
"message": "Poruka",
"char": "Karakter",
"reset": "Resetuj",
"copy": "Kopiraj",
"copied": "Kopirano",
"pause": "Pauza",
"back": "Nazad",
"search": "Pretraga",
"promptTemplate": "Šablon Upita",
"cancel": "Otkaži",
"save": "Sačuvaj",
"next": "Sledeće",
"chatDocsAddon": "Ćaskanje sa Dokumentima",
"chatDocs": {
"supportFormat": "Podrška za PDF, DOCX",
"files": "Fajlovi/Tekst",
"selectFile": "Prevuci ili klikni da izabereš fajl",
"msgSettings": "Podešavanja Poruke",
"editPrompt": "Uredi Prompt",
"maxLength": "Maksimalna Dužina",
"maxSendings": "Maksimalan Broj Slanja",
"sendProgress": "Progres Slanja",
"sendCompleted": "Slanje Završeno",
"msgContent": "Sadržaj Poruke",
"startChatting": "Možete početi sa četovanjem sada!",
"autoSending": "Automatsko Slanje",
"chooseContentRelevant": "Izaberite sadržaj koji je relevantniji za temu koju želite naučiti"
},
"newFeature": "Nova funkcionalnost",
"chatDocsTips": "Podrška za ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Flytta åt sidan",
"close": "Stäng",
"refresh": "Uppdatera",
"protectedTabTips": "Denna sida skyddas av webbläsaren"
"protectedTabTips": "Denna sida skyddas av webbläsaren",
"prompt": "Prompt",
"message": "Meddelande",
"char": "Tecken",
"reset": "Återställ",
"copy": "Kopiera",
"copied": "Kopierat",
"pause": "Pausa",
"back": "Tillbaka",
"search": "Sök",
"promptTemplate": "Promptmall",
"cancel": "Avbryt",
"save": "Spara",
"next": "Nästa",
"chatDocsAddon": "Chatta med Dokument",
"chatDocs": {
"supportFormat": "Stöd för PDF, DOCX",
"files": "Filer/Text",
"selectFile": "Dra eller klicka för att välja en fil",
"msgSettings": "Meddelandeinställningar",
"editPrompt": "Redigera Prompt",
"maxLength": "Max längd",
"maxSendings": "Max sändningar",
"sendProgress": "Sändningsframsteg",
"sendCompleted": "Sändning slutförd",
"msgContent": "Meddelandeinnehåll",
"startChatting": "Du kan börja chatta nu!",
"autoSending": "Automatisk sändning",
"chooseContentRelevant": "Välj innehåll som är mer relevant för det ämne du vill lära dig om"
},
"newFeature": "Ny funktion",
"chatDocsTips": "Stöd för ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Hama kando",
"close": "Funga",
"refresh": "Sasisha",
"protectedTabTips": "Ukurasa huu umelindwa na kivinjari"
"protectedTabTips": "Ukurasa huu umelindwa na kivinjari",
"prompt": "Prompt",
"message": "Ujumbe",
"char": "Herufi",
"reset": "Weka Upya",
"copy": "Nakili",
"copied": "Imenakiliwa",
"pause": "Sitisha",
"back": "Nyuma",
"search": "Tafuta",
"promptTemplate": "Kiolezo cha Utatuzi",
"cancel": "Ghairi",
"save": "Hifadhi",
"next": "Ifuatayo",
"chatDocsAddon": "Ongea na Nyaraka",
"chatDocs": {
"supportFormat": "Support PDF, DOCX",
"files": "Files/Text",
"selectFile": "Drag au bonyeza kuchagua faili",
"msgSettings": "Mipangilio ya Ujumbe",
"editPrompt": "Hariri Prompt",
"maxLength": "Urefu Maksimumu",
"maxSendings": "Idadi Kubwa ya Kutuma",
"sendProgress": "Maendeleo ya Kutuma",
"sendCompleted": "Kutuma Kumekamilika",
"msgContent": "Yaliyomo ya Ujumbe",
"startChatting": "Unaweza kuanza kuchat sasa!",
"autoSending": "Kutuma Kiotomatiki",
"chooseContentRelevant": "Chagua yaliyomo inayohusiana zaidi na mada unayotaka kujifunza kuhusu"
},
"newFeature": "Kipengele Kipya",
"chatDocsTips": "Msaada wa ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "பக்கத்திற்கு நீக்கு",
"close": "மூடு",
"refresh": "புதுப்பிக்க",
"protectedTabTips": "இந்த பக்கம் உலாவியால் பாதுகாக்கப்படுகிறது"
"protectedTabTips": "இந்த பக்கம் உலாவியால் பாதுகாக்கப்படுகிறது",
"prompt": "Prompt",
"message": "செய்தி",
"char": "எழுத்து",
"reset": "மீட்டமை",
"copy": "நகல்",
"copied": "நகலிடப்பட்டது",
"pause": "இடைநிறுத்து",
"back": "பின்பற்று",
"search": "தேடு",
"promptTemplate": "உதவி வார்ப்பு",
"cancel": "ரத்துசெய்",
"save": "சேமிக்க",
"next": "அடுத்து",
"chatDocsAddon": "ஆவணங்களுடன் உரை",
"chatDocs": {
"supportFormat": "பிடிஎஃப், டாக்ஸ் ஆதரித்துள்ளது",
"files": "கோப்புகள்/உரை",
"selectFile": "கோப்பை தந்து அல்லது கிளிக் செய்வதற்கு எழுதி",
"msgSettings": "செய்தி அமைப்புகள்",
"editPrompt": "எடிட் ப்ராம்ப்ட்",
"maxLength": "அதிக நீளம்",
"maxSendings": "அதிக அனுப்புதல்கள்",
"sendProgress": "அனுப்புதல் முன்னேற்றம்",
"sendCompleted": "அனுப்பல் முடிந்தது",
"msgContent": "செய்தி உள்ளடக்கம்",
"startChatting": "நீங்கள் இப்போது உரையாடல் ஆரம்பிக்கலாம்!",
"autoSending": "தானாக அனுப்புதல்",
"chooseContentRelevant": "நீங்கள் அறிந்திருக்க விரும்பும் பகுதிக்கு உரையாடல் தேர்ந்தெடுக்கவும்"
},
"newFeature": "புதிய அம்சம்",
"chatDocsTips": "ChatGPT, Bard, MS Copilot க்கு ஆதரவு..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "చేరుకుందండి",
"close": "మూసివేయి",
"refresh": "తాజాకరించండి",
"protectedTabTips": "ఈ పేజీని బ్రౌజర్ రక్షించింది"
"protectedTabTips": "ఈ పేజీని బ్రౌజర్ రక్షించింది",
"prompt": "Prompt",
"message": "సందేశం",
"char": "అక్షరం",
"reset": "రీసెట్",
"copy": "కాపీ",
"copied": "కాపీ చేయబడింది",
"pause": "విరామం",
"back": "వెనక్కి",
"search": "వెతికి చూడు",
"promptTemplate": "ప్రాంప్ట్ మ్యాటింపు",
"cancel": "రద్దు చేయి",
"save": "భద్రపరచు",
"next": "తరువాత",
"chatDocsAddon": "డాక్యుమెంట్స్తో చాట్",
"chatDocs": {
"supportFormat": "యొక్క మద్దతు PDF, DOCX",
"files": "ఫైళ్ళు/వచనం",
"selectFile": "ఫైల్ ఎంచుకోవడానికి అథవా నొక్కండా క్లిక్ చేయడానికి లాగండి",
"msgSettings": "సందేశం సెట్టింగ్స్",
"editPrompt": "సవరించండి ప్రాంప్ట్",
"maxLength": "అత్యధిక పొడవు",
"maxSendings": "అత్యంత పంపిణీలు",
"sendProgress": "పంపిణీ ప్రోగ్రెస్",
"sendCompleted": "పంపిణీ పూర్తి",
"msgContent": "సందేశ కంటెంట్",
"startChatting": "మీరు ఇప్పటికే చాటింగ్ ప్రారంభించవచ్చు!",
"autoSending": "స్వీయం పంపిణీ",
"chooseContentRelevant": "మీరు కలిగిన విషయానికి అనుసంధానం కలిగిన కంటెంట్ ఎంచుకోండి"
},
"newFeature": "కొత్త లక్షణం",
"chatDocsTips": "మద్దతు ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "เลื่อนข้างหลัง",
"close": "ปิด",
"refresh": "รีเฟรช",
"protectedTabTips": "หน้านี้ได้รับการป้องกันโดยเบราว์เซอร์"
"protectedTabTips": "หน้านี้ได้รับการป้องกันโดยเบราว์เซอร์",
"prompt": "Prompt",
"message": "ข้อความ",
"char": "ตัวอักษร",
"reset": "รีเซ็ต",
"copy": "คัดลอก",
"copied": "คัดลอกแล้ว",
"pause": "หยุดชั่วคราว",
"back": "กลับ",
"search": "ค้นหา",
"promptTemplate": "แม่แบบโปรโมต",
"cancel": "ยกเลิก",
"save": "บันทึก",
"next": "ถัดไป",
"chatDocsAddon": "พูดคุยกับเอกสาร",
"chatDocs": {
"supportFormat": "รองรับ PDF, DOCX",
"files": "ไฟล์/ข้อความ",
"selectFile": "ลากรูปหรือคลิกเพื่อเลือกไฟล์",
"msgSettings": "ตั้งค่าข้อความ",
"editPrompt": "แก้ไข Prompt",
"maxLength": "ความยาวสูงสุด",
"maxSendings": "จำนวนส่งสูงสุด",
"sendProgress": "ความคืบหน้าในการส่ง",
"sendCompleted": "ส่งเรียบร้อย",
"msgContent": "เนื้อหาข้อความ",
"startChatting": "คุณสามารถเริ่มสนทนาได้แล้ว!",
"autoSending": "การส่งอัตโนมัติ",
"chooseContentRelevant": "เลือกเนื้อหาที่เกี่ยวข้องมากขึ้นกับหัวข้อที่คุณต้องการเรียนรู้"
},
"newFeature": "คุณลักษณะใหม่",
"chatDocsTips": "สนับสนุน ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Kenara Taşı",
"close": "Kapat",
"refresh": "Yenile",
"protectedTabTips": "Bu sayfa tarayıcı tarafından korunmaktadır"
"protectedTabTips": "Bu sayfa tarayıcı tarafından korunmaktadır",
"prompt": "Prompt",
"message": "Mesaj",
"char": "Karakter",
"reset": "Sıfırla",
"copy": "Kopyala",
"copied": "Kopyalandı",
"pause": "Duraklat",
"back": "Geri",
"search": "Ara",
"promptTemplate": "İstem Şablonu",
"cancel": "İptal",
"save": "Kaydet",
"next": "İleri",
"chatDocsAddon": "Belgelerle Sohbet",
"chatDocs": {
"supportFormat": "PDF, DOCX Desteği",
"files": "Dosyalar/Metin",
"selectFile": "Bir dosya seçmek için sürükleyin veya tıklayın",
"msgSettings": "Mesaj Ayarları",
"editPrompt": "Prompt'u Düzenle",
"maxLength": "Maksimum Uzunluk",
"maxSendings": "Maksimum Gönderim",
"sendProgress": "Gönderme İlerlemesi",
"sendCompleted": "Gönderme Tamamlandı",
"msgContent": "Mesaj İçeriği",
"startChatting": "Şimdi sohbet etmeye başlayabilirsiniz!",
"autoSending": "Otomatik Gönderim",
"chooseContentRelevant": "Öğrenmek istediğiniz konuyla daha ilgili içerik seçin"
},
"newFeature": "Yeni Özellik",
"chatDocsTips": "ChatGPT, Bard, MS Copilot Desteği..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Відкрити сторонній",
"close": "Закрити",
"refresh": "Оновити",
"protectedTabTips": "Ця сторінка захищена браузером"
"protectedTabTips": "Ця сторінка захищена браузером",
"prompt": "Запит",
"message": "Повідомлення",
"char": "Символ",
"reset": "Скинути",
"copy": "Копіювати",
"copied": "Скопійовано",
"pause": "Пауза",
"back": "Назад",
"search": "Пошук",
"promptTemplate": "Шаблон підказки",
"cancel": "Скасувати",
"save": "Зберегти",
"next": "Далі",
"chatDocsAddon": "Чат з Документами",
"chatDocs": {
"supportFormat": "Підтримка PDF, DOCX",
"files": "Файли/Текст",
"selectFile": "Перетягніть або клацніть, щоб вибрати файл",
"msgSettings": "Налаштування повідомлення",
"editPrompt": "Редагувати Prompt",
"maxLength": "Максимальна довжина",
"maxSendings": "Максимальна кількість відправлень",
"sendProgress": "Прогрес відправлення",
"sendCompleted": "Відправлення завершено",
"msgContent": "Зміст повідомлення",
"startChatting": "Ви можете почати спілкування зараз!",
"autoSending": "Автоматичне відправлення",
"chooseContentRelevant": "Виберіть вміст, який більше відповідає темі, яку ви хочете вивчити"
},
"newFeature": "Нова функція",
"chatDocsTips": "Підтримка ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "Di chuyển sang một bên",
"close": "Đóng",
"refresh": "Làm mới",
"protectedTabTips": "Trang này được bảo vệ bởi trình duyệt"
"protectedTabTips": "Trang này được bảo vệ bởi trình duyệt",
"prompt": "Prompt",
"message": "Thông điệp",
"char": "Ký tự",
"reset": "Đặt lại",
"copy": "Sao chép",
"copied": "Đã sao chép",
"pause": "Tạm dừng",
"back": "Quay lại",
"search": "Tìm kiếm",
"promptTemplate": "Mẫu Hướng dẫn",
"cancel": "Hủy",
"save": "Lưu",
"next": "Tiếp theo",
"chatDocsAddon": "Trò chuyện với Tài liệu",
"chatDocs": {
"supportFormat": "Hỗ trợ PDF, DOCX",
"files": "Tệp/Chữ",
"selectFile": "Kéo hoặc nhấp để chọn tệp",
"msgSettings": "Cài đặt Tin nhắn",
"editPrompt": "Chỉnh sửa Prompt",
"maxLength": "Độ dài tối đa",
"maxSendings": "Số lần gửi tối đa",
"sendProgress": "Tiến trình Gửi",
"sendCompleted": "Gửi hoàn tất",
"msgContent": "Nội dung Tin nhắn",
"startChatting": "Bạn có thể bắt đầu trò chuyện ngay bây giờ!",
"autoSending": "Tự động Gửi",
"chooseContentRelevant": "Chọn nội dung liên quan hơn đến chủ đề bạn muốn tìm hiểu"
},
"newFeature": "Tính năng Mới",
"chatDocsTips": "Hỗ trợ ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "移到旁边",
"close": "关闭",
"refresh": "刷新",
"protectedTabTips": "当前页面受浏览器保护"
"protectedTabTips": "当前页面受浏览器保护",
"prompt": "Prompt",
"message": "消息",
"char": "字符",
"reset": "重置",
"copy": "复制",
"copied": "已复制",
"pause": "暂停",
"back": "返回",
"search": "搜索",
"promptTemplate": "Prompt模板",
"cancel": "取消",
"save": "保存",
"next": "下一个",
"chatDocsAddon": "读取文档",
"newFeature": "新功能",
"chatDocsTips": "支持 ChatGPT, Bard, MS Copilot...",
"chatDocs": {
"supportFormat": "支持PDF、DOCX",
"files": "文件/文本",
"selectFile": "拖拽或选择文件",
"msgSettings": "消息设置",
"editPrompt": "编辑 Prompt",
"maxLength": "最大长度",
"maxSendings": "最大发送次数",
"sendProgress": "发送进度",
"sendCompleted": "发送完成",
"msgContent": "消息内容",
"startChatting": "你可以开始聊天了!",
"autoSending": "自动发送",
"chooseContentRelevant": "选择与你想了解的主题更相关的内容"
}
}
\ No newline at end of file
......@@ -6,5 +6,36 @@
"moveAside": "移到旁邊",
"close": "關閉",
"refresh": "刷新",
"protectedTabTips": "此頁面受到瀏覽器保護"
"protectedTabTips": "此頁面受到瀏覽器保護",
"prompt": "Prompt",
"message": "訊息",
"char": "字元",
"reset": "重設",
"copy": "複製",
"copied": "已複製",
"pause": "暫停",
"back": "返回",
"search": "搜尋",
"promptTemplate": "提示模板",
"cancel": "取消",
"save": "保存",
"next": "下一步",
"chatDocsAddon": "與文件聊天",
"chatDocs": {
"supportFormat": "支持 PDF、DOCX",
"files": "文件/文本",
"selectFile": "拖拉或點擊以選擇文件",
"msgSettings": "消息設置",
"editPrompt": "編輯提示",
"maxLength": "最大長度",
"maxSendings": "最大發送次數",
"sendProgress": "發送進度",
"sendCompleted": "發送完成",
"msgContent": "消息內容",
"startChatting": "你現在可以開始聊天了!",
"autoSending": "自動發送",
"chooseContentRelevant": "選擇與你想了解的主題更相關的內容"
},
"newFeature": "新功能",
"chatDocsTips": "支援 ChatGPT, Bard, MS Copilot..."
}
\ No newline at end of file
......@@ -5,12 +5,12 @@ const contentCss = "/assets/index.css"
const manifest = {
manifest_version: 3,
// maximum of 45 characters
name: "__MSG_name__",
name: "AAA __MSG_name__",
// edge 12 characters
// short_name: "__MSG_short_name__",
// no more than 132 characters
description: "__MSG_description__",
version: "1.1.2",
version: "1.2.0",
action: {
default_icon: {
16: "logo.png",
......@@ -64,11 +64,11 @@ const manifest = {
matches: ["<all_urls>"],
},
],
content_security_policy: __DEV__
? {
extension_pages: `script-src 'self' http://localhost:3000;`,
}
: undefined,
content_security_policy: {
extension_pages: __DEV__
? `script-src 'self' http://localhost:3000 'wasm-unsafe-eval';`
: `script-src 'self' 'wasm-unsafe-eval'`,
},
}
export default manifest
......@@ -2,12 +2,17 @@
import { ref, onMounted, onUnmounted, computed, reactive, watch } from "vue"
import { emptyTab, checkContent, getStoreUrl } from "@/utils/ext"
import { items, pipWindow } from "@/store"
import { MessageType } from "@/types"
// import { sitesConfig as chatDocsSites } from "@/components/chatdocs/chat"
import PipWindowActions from "@/components/popup/PipWindowActions.vue"
import IconThumbUp from "@/components/icons/IconThumbUp.vue"
import IconThumbDown from "@/components/icons/IconThumbDown.vue"
import IconGithub from "@/components/icons/IconGithub.vue"
import IconDiscord from "@/components/icons/IconDiscord.vue"
import IconXLogo from "@/components/icons/IconXLogo.vue"
import IconNoteStack from "@/components/icons/IconNoteStack.vue"
import IconHelp from "@/components/icons/IconHelp.vue"
import { useI18n } from "@/utils/i18n"
const { t } = useI18n()
......@@ -16,13 +21,25 @@ const activeTab = ref<chrome.tabs.Tab>(emptyTab)
const manifest = reactive(chrome.runtime.getManifest())
const avaiable = ref(false)
const handleLocalChange = (changes: {
[key: string]: chrome.storage.StorageChange
}) => {
if (changes.pipWindowId) {
pipWindow.id = changes.pipWindowId.newValue
}
}
const host = computed({
get: () => {
if (!activeTab.value.url) return ""
const u = new URL(activeTab.value.url)
return u.host
},
set: () => {},
})
// const chatDocs = computed(() => {
// const url = activeTab.value.url
// if (url) {
// const u = new URL(url)
// return chatDocsSites.some(
// (site) => site.host == u.host && site.path.test(u.pathname)
// )
// }
// return false
// })
onMounted(() => {
chrome.tabs.query({ active: true, currentWindow: true }).then((tabs) => {
......@@ -49,14 +66,13 @@ onUnmounted(() => {
chrome.storage.local.onChanged.removeListener(handleLocalChange)
})
const host = computed({
get: () => {
if (!activeTab.value.url) return ""
const u = new URL(activeTab.value.url)
return u.host
},
set: () => {},
})
const handleLocalChange = (changes: {
[key: string]: chrome.storage.StorageChange
}) => {
if (changes.pipWindowId) {
pipWindow.id = changes.pipWindowId.newValue
}
}
async function handleWriteHtml() {
const tabs = await chrome.tabs.query({ active: true, currentWindow: true })
......@@ -93,10 +109,19 @@ function fivestar() {
),
"_blank"
}
function showChatDocs() {
const tabId = activeTab.value.id
if (tabId) {
chrome.tabs.sendMessage(tabId, {
type: MessageType.showChatDocs,
})
}
}
</script>
<template>
<main class="w-[300px] p-4 mx-auto">
<main class="w-[300px] p-4 mx-auto bg-background">
<div class="flex">
<div class="mr-auto">
<span class="font-bold opacity-50">Anything Copilot</span>
......@@ -148,6 +173,20 @@ function fivestar() {
{{ t("protectedTabTips") }}
</div>
<div class="mt-6">
<div class="my-3 flex items-center">
<span class="mr-1">{{ t("newFeature") }}🎉</span>
</div>
<button class="flex items-center" @click="showChatDocs">
<IconNoteStack class="size-9" />
<div class="mx-2 text-left">
<div class="text-sm">{{ t("chatDocsAddon") }}</div>
<div class="text-xs">{{ t("chatDocsTips") }}</div>
</div>
</button>
</div>
<div class="text-sm mt-6">{{ t("other") }}</div>
<button
v-for="item of items"
......
import "@/content/index"
// import "@/pages/popup"
import * as pdfjs from "pdfjs-dist"
import { parseContent } from "@/utils/pdf"
import { MimeType } from "@/utils/file"
import { convertToHtml, images } from "mammoth"
import TurndownService from "turndown"
import { MessageType, ServiceFunc } from "@/types"
// import { fileTypeFromBlob } from "file-type"
import type { ParseDocOptions } from "@/types"
import { MessageType, ServiceFunc, type ParseDocOptions } from "@/types"
import { Tiktoken } from "tiktoken/lite"
import cl100k_base from "tiktoken/encoders/cl100k_base.json"
pdfjs.GlobalWorkerOptions.workerSrc = "/js/pdf.worker.js"
......@@ -41,6 +42,16 @@ async function parseDocx(file: File) {
return [markdown]
}
async function parseText(file: File) {
const reader = new FileReader()
reader.readAsText(file)
return new Promise<string>((resolve) => {
reader.onload = () => {
resolve(reader.result as string)
}
})
}
async function parseDoc({ type, size, url, filename }: ParseDocOptions) {
const res = await fetch(url)
const blob = await res.blob()
......@@ -48,32 +59,61 @@ async function parseDoc({ type, size, url, filename }: ParseDocOptions) {
const file = new File([blob], filename, { type })
let contents: string[] = []
switch (type) {
case "application/pdf":
if (type === MimeType.pdf) {
contents = await parsePdf(file)
break
case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
} else if (type == MimeType.docx) {
contents = await parseDocx(file)
break
case "application/msword":
break
} else if (type === MimeType.doc) {
// not supported
} else if (/^text\//.test(type)) {
const text = await parseText(file)
contents = [text]
}
return contents
}
async function calcTokens(text: string) {
const encoding = new Tiktoken(
cl100k_base.bpe_ranks,
cl100k_base.special_tokens,
cl100k_base.pat_str
)
const tokens = encoding.encode(text)
const length = tokens.length
encoding.free()
return length
}
async function tokenSlice(text: string, length: number) {
const encoding = new Tiktoken(
cl100k_base.bpe_ranks,
cl100k_base.special_tokens,
cl100k_base.pat_str
)
const tokens = encoding.encode(text).slice(0, length)
const value = new TextDecoder().decode(encoding.decode(tokens))
encoding.free()
return value
}
async function handleMessage(
message: any,
sender: chrome.runtime.MessageSender
) {
if (message?.type === MessageType.toOffscreen) {
console.log("offscreen message: ", message, sender)
const { func, args } = message
let taskPromise: Promise<any> | null = null
switch (message?.task) {
switch (func) {
case ServiceFunc.parseDoc:
taskPromise = parseDoc(message.payload)
taskPromise = parseDoc(...(args as [any]))
break
case ServiceFunc.calcTokens:
taskPromise = calcTokens(...(args as [any]))
break
case ServiceFunc.tokenSlice:
taskPromise = tokenSlice(...(args as [any, any]))
break
}
......
......@@ -15,20 +15,13 @@ export enum MessageType {
fromOffscreen = "from-offscreen",
invokeRequest = "invoke-request",
invokeResponse = "invoke-Response",
showChatDocs = "show-chat-docs",
}
export enum ServiceFunc {
parseDoc = "parse-doc",
}
export interface InvokeRequest {
func: string
args: any[]
}
export interface InvokeMessage extends InvokeRequest {
type: MessageType
key: string
calcTokens = "calc-tokens",
tokenSlice = "token-slice",
}
export type ParseDocOptions = {
......
......@@ -3,25 +3,46 @@ type CallbackItem = {
reject: (e: any) => void
}
interface InvokeReq {
func: string
args: any[]
}
abstract class Invoke {
private pendingCallback: Record<string, CallbackItem>
private count: number
private name: string
private uniqueId: string
constructor(name: string) {
this.name = name
this.uniqueId = `${Math.round(Math.random() * 1e6)}`
this.pendingCallback = {}
this.count = 0
}
protected get key() {
return `${this.name}-${this.count++}`
return `${this.name}-${this.uniqueId}-${this.count++}`
}
protected getReturnValue(key: string) {
const promise = new Promise((resolve, reject) => {
protected getReturnValue(key: string, req: InvokeReq, timeout?: number) {
let timer: any
const promise = new Promise<any>((resolve, reject) => {
this.pendingCallback[key] = { resolve, reject }
if (timeout) {
timer = setTimeout(
() =>
reject(`"${this.name}" invoke timeout: ${req.func} key: ${key}`),
timeout
)
}
})
promise.finally(() => {
delete this.pendingCallback[key]
timer && clearTimeout(timer)
})
return promise
}
......@@ -30,18 +51,18 @@ abstract class Invoke {
if (callback) {
const fn = success != false ? callback.resolve : callback.reject
fn(payload)
delete this.pendingCallback[key]
} else {
console.error(`unknown invoke callback message: ${key}`)
console.log(this.pendingCallback)
}
}
abstract send(req: any): Promise<{ key: string; response: any }>
abstract handleMessage(message: any): void
abstract send(req: InvokeReq): Promise<{ key: string; response: any }>
abstract handleMessage(message: InvokeReq): void
public async invoke(req: any) {
public async invoke<T = any>(req: InvokeReq, timeout = 20000): Promise<T> {
const { key } = await this.send(req)
const result = await this.getReturnValue(key)
delete this.pendingCallback[key]
return result
return this.getReturnValue(key, req, timeout)
}
}
......
export enum MimeType {
pdf = "application/pdf",
docx = "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
doc = "application/msword",
}
import { createI18n, useI18n as vueUseI18n } from "vue-i18n"
import messages from "@intlify/unplugin-vue-i18n/messages"
import type EnMessage from "@/locales/en.json"
import type ZhMessage from "@/locales/zh-CN.json"
type MessageSchema = typeof EnMessage
type MessageSchema = typeof EnMessage & typeof ZhMessage
export function getLocale() {
if (__DEV__) {
return "ja"
}
const language = chrome.i18n.getUILanguage()
let code = language
if (["en-AU", "en-GB", "en-US"].includes(code)) {
......
export const chatDocPrompt = `Here is some relevant reference information. Please refrain from summarizing or responding to specific content until I pose targeted questions. If you comprehend this instruction, kindly reply with "Okay, please continue."`
import {
MessageType,
type InvokeRequest,
type ParseDocOptions,
ServiceFunc,
} from "@/types"
import { MessageType, ServiceFunc, type ParseDocOptions } from "@/types"
import Invoke from "./Invoke"
class Service extends Invoke {
......@@ -25,16 +20,26 @@ class Service extends Invoke {
}
}
public async invoke(req: InvokeRequest): Promise<any> {
return super.invoke(req)
}
public parseDoc(options: ParseDocOptions): Promise<string[]> {
return this.invoke({
func: ServiceFunc.parseDoc,
args: [options],
})
}
public calcTokens(text: string): Promise<number> {
return this.invoke({
func: ServiceFunc.calcTokens,
args: [text],
})
}
public tokenSlice(text: string, length: number): Promise<string> {
return this.invoke({
func: ServiceFunc.tokenSlice,
args: [text, length],
})
}
}
const contentService = new Service("content")
......
......@@ -2,18 +2,43 @@
module.exports = {
content: ["./src/**/*.{vue,js,ts,jsx,tsx}"],
theme: {
borderRadius: {
none: "0px",
sm: "2px",
DEFAULT: "4px",
md: "6px",
lg: "8px",
xl: "12px",
"2xl": "16px",
"3xl": "24px",
full: "9999px",
},
fontSize: {
xs: "12px",
sm: "14px",
base: "16px",
lg: "18px",
xl: "20px",
"2xl": "24px",
"3xl": "30px",
"4xl": "36px",
"5xl": "48px",
"6xl": "60px",
"7xl": "72px",
// xs: "12px",
// sm: "14px",
// base: "16px",
// lg: "18px",
// xl: "20px",
// "2xl": "24px",
// "3xl": "30px",
// "4xl": "36px",
// "5xl": "48px",
// "6xl": "60px",
// "7xl": "72px",
xs: ["12px", { lineHeight: "16px" }],
sm: ["14px", { lineHeight: "20px" }],
base: ["16px", { lineHeight: "24px" }],
lg: ["18.px", { lineHeight: "28px" }],
xl: ["20px", { lineHeight: "28px" }],
"2xl": ["24px", { lineHeight: "32px" }],
"3xl": ["30px", { lineHeight: "36px" }],
"4xl": ["36px", { lineHeight: "40px" }],
"5xl": ["48x", { lineHeight: "1" }],
"6xl": ["60px", { lineHeight: "1" }],
"7xl": ["72px", { lineHeight: "1" }],
"8xl": ["96px", { lineHeight: "1" }],
"9xl": ["128px", { lineHeight: "1" }],
},
spacing: {
px: "1px",
......
import click
from os import path
from os import path, listdir
import json
@click.group()
@click.option('--d', default='src/locales', help="locales directory")
@click.option('-d', default='src/locales', help="locales directory path")
@click.option('--filename', default='messages.json', help="locale message filename")
@click.pass_context
def cli(ctx, d):
def cli(ctx, d: str, filename: str):
locales_dir = path.realpath(path.join(d))
dir_items = listdir(locales_dir)
def get_path(p: str):
msg_path = path.join(locales_dir,p)
return path.join(msg_path, filename) if path.isdir(msg_path) else msg_path
items = { path.splitext(i)[0]:get_path(i) for i in dir_items}
ctx.obj['locales_dir'] = locales_dir
ctx.obj['items'] = items
# extract the locale
@cli.command()
@click.option('--new', default=['en', 'zh-CN'], multiple=True, help="new language")
@click.option('--old', default='zh-TW', help="old language")
@click.option('--o', default='-', help="output")
@click.option('-k','--keep', default=['en', 'zh-CN'], multiple=True, help="keep language")
@click.option('-r', '--ref', default='ja', help="diff reference language")
@click.option('-e','--empty', default=True, help="output empty language")
@click.option('-o', default='-', help="output")
@click.option('-l', default=9999, type=int, help="keys limit")
@click.pass_context
def extract(ctx, new, old, o=''):
locales_dir = ctx.obj['locales_dir']
new_msgs = {
code: json.load(
open(path.join(locales_dir, code + '.json'), 'r', encoding='utf8')
)
for code in new
def extract(ctx, keep, ref, empty=True, o='-', l=9999):
items = ctx.obj['items']
msgs = {
code: json.load(open(items[code], 'r', encoding='utf8'))
for code in items.keys()
}
old_msg = json.load(
open(path.join(locales_dir, old + '.json'), 'r', encoding='utf8')
)
ref_msg = json.load(open(items[ref], 'r', encoding='utf8'))
new_keys = {
code: [key for key in new_msgs[code].keys() if key not in old_msg.keys()]
for code in new
code: [key for key in msgs[code].keys() if key not in ref_msg.keys()]
for code in items.keys()
}
new_data = {
code: {key: new_msgs[code][key] for key in new_keys[code]}
for code in new
code: {key: msgs[code][key] for key in new_keys[code][0:l]}
for code in items.keys() if code in keep or (empty and len(new_keys[code]) == 0)
}
print(json.dumps(new_data, ensure_ascii=False))
print(json.dumps(new_data, ensure_ascii=False, indent=4))
@cli.command()
@click.option('--t', default='', help='')
@click.option('-t', default='', help='')
@click.pass_context
def update(ctx, t):
locales_dir = ctx.obj['locales_dir']
......@@ -71,8 +84,7 @@ def update(ctx, t):
line_data = json.loads(line)
code = line_data['code']
content = line_data['content']
content = json.loads(content) if type(
content) == str else content
content = json.loads(content) if type(content) == str else content
update_msg(code, content)
if t.endswith('.json'):
......
......@@ -5,10 +5,11 @@ import { defineConfig } from "vite"
import vue from "@vitejs/plugin-vue"
import vueJsx from "@vitejs/plugin-vue-jsx"
import vueI18n from "@intlify/unplugin-vue-i18n/vite"
import wasm from "vite-plugin-wasm"
import topLevelAwait from "vite-plugin-top-level-await"
import manifest from "./src/manifest"
import makeManifest from "./utils/manifest-plugin"
/// <reference types="vitest" />
// https://vitejs.dev/config/
......@@ -30,6 +31,8 @@ export default defineConfig({
),
}),
makeManifest(manifest, { isDev: false }),
wasm(),
topLevelAwait(),
],
resolve: {
alias: {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment