From 5614e423039f8b3f8b1c7bb9a807614673d1a52c Mon Sep 17 00:00:00 2001 From: Victor Savinov Date: Sat, 22 Jan 2022 05:58:12 +0300 Subject: [PATCH] v0.5 --- README.md | 2 +- _locales/am/messages.json | 53 + _locales/ar/messages.json | 53 + _locales/bg/messages.json | 53 + _locales/bn/messages.json | 53 + _locales/ca/messages.json | 53 + _locales/cs/messages.json | 53 + _locales/da/messages.json | 53 + _locales/de/messages.json | 53 + _locales/el/messages.json | 53 + _locales/en/messages.json | 53 + _locales/es/messages.json | 53 + _locales/et/messages.json | 53 + _locales/fa/messages.json | 53 + _locales/fi/messages.json | 53 + _locales/fil/messages.json | 53 + _locales/fr/messages.json | 53 + _locales/gu/messages.json | 53 + _locales/he/messages.json | 53 + _locales/hi/messages.json | 53 + _locales/hin/messages.json | 41 + _locales/hr/messages.json | 53 + _locales/hu/messages.json | 53 + _locales/id/messages.json | 53 + _locales/it/messages.json | 53 + _locales/ja/messages.json | 53 + _locales/kn/messages.json | 53 + _locales/ko/messages.json | 53 + _locales/lt/messages.json | 53 + _locales/lv/messages.json | 53 + _locales/ml/messages.json | 53 + _locales/mr/messages.json | 53 + _locales/ms/messages.json | 53 + _locales/nb_NO/messages.json | 41 + _locales/nl/messages.json | 53 + _locales/no/messages.json | 53 + _locales/pl/messages.json | 53 + _locales/pt_BR/messages.json | 53 + _locales/pt_PT/messages.json | 53 + _locales/ro/messages.json | 53 + _locales/ru/messages.json | 53 + _locales/sk/messages.json | 53 + _locales/sl/messages.json | 53 + _locales/sr/messages.json | 53 + _locales/sv/messages.json | 53 + _locales/sw/messages.json | 53 + _locales/ta/messages.json | 53 + _locales/te/messages.json | 53 + _locales/th/messages.json | 53 + _locales/tr/messages.json | 53 + _locales/uk/messages.json | 53 + _locales/vi/messages.json | 53 + _locales/zh_CN/messages.json | 53 + _locales/zh_TW/messages.json | 53 + background.js | 43 + content-script.js | 910 ++++++++++ content-styles.css | 13 + icons/128.png | Bin 0 -> 6569 bytes icons/16.png | Bin 0 -> 637 bytes icons/32.png | Bin 0 -> 1283 bytes icons/48.png | Bin 0 -> 2000 bytes manifest.json | 39 + py/locale.py | 208 +++ ui/fonts/OpenSans-Medium.ttf | Bin 0 -> 129948 bytes ui/fonts/OpenSans-Regular.ttf | Bin 0 -> 129796 bytes ui/options.html | 37 + ui/popup.html | 37 + ui/satus/satus.css | 1664 +++++++++++++++++ ui/satus/satus.js | 3226 +++++++++++++++++++++++++++++++++ ui/script.js | 479 +++++ ui/styles.css | 94 + 71 files changed, 9536 insertions(+), 1 deletion(-) create mode 100644 _locales/am/messages.json create mode 100644 _locales/ar/messages.json create mode 100644 _locales/bg/messages.json create mode 100644 _locales/bn/messages.json create mode 100644 _locales/ca/messages.json create mode 100644 _locales/cs/messages.json create mode 100644 _locales/da/messages.json create mode 100644 _locales/de/messages.json create mode 100644 _locales/el/messages.json create mode 100644 _locales/en/messages.json create mode 100644 _locales/es/messages.json create mode 100644 _locales/et/messages.json create mode 100644 _locales/fa/messages.json create mode 100644 _locales/fi/messages.json create mode 100644 _locales/fil/messages.json create mode 100644 _locales/fr/messages.json create mode 100644 _locales/gu/messages.json create mode 100644 _locales/he/messages.json create mode 100644 _locales/hi/messages.json create mode 100644 _locales/hin/messages.json create mode 100644 _locales/hr/messages.json create mode 100644 _locales/hu/messages.json create mode 100644 _locales/id/messages.json create mode 100644 _locales/it/messages.json create mode 100644 _locales/ja/messages.json create mode 100644 _locales/kn/messages.json create mode 100644 _locales/ko/messages.json create mode 100644 _locales/lt/messages.json create mode 100644 _locales/lv/messages.json create mode 100644 _locales/ml/messages.json create mode 100644 _locales/mr/messages.json create mode 100644 _locales/ms/messages.json create mode 100644 _locales/nb_NO/messages.json create mode 100644 _locales/nl/messages.json create mode 100644 _locales/no/messages.json create mode 100644 _locales/pl/messages.json create mode 100644 _locales/pt_BR/messages.json create mode 100644 _locales/pt_PT/messages.json create mode 100644 _locales/ro/messages.json create mode 100644 _locales/ru/messages.json create mode 100644 _locales/sk/messages.json create mode 100644 _locales/sl/messages.json create mode 100644 _locales/sr/messages.json create mode 100644 _locales/sv/messages.json create mode 100644 _locales/sw/messages.json create mode 100644 _locales/ta/messages.json create mode 100644 _locales/te/messages.json create mode 100644 _locales/th/messages.json create mode 100644 _locales/tr/messages.json create mode 100644 _locales/uk/messages.json create mode 100644 _locales/vi/messages.json create mode 100644 _locales/zh_CN/messages.json create mode 100644 _locales/zh_TW/messages.json create mode 100644 background.js create mode 100644 content-script.js create mode 100644 content-styles.css create mode 100644 icons/128.png create mode 100644 icons/16.png create mode 100644 icons/32.png create mode 100644 icons/48.png create mode 100644 manifest.json create mode 100644 py/locale.py create mode 100644 ui/fonts/OpenSans-Medium.ttf create mode 100644 ui/fonts/OpenSans-Regular.ttf create mode 100644 ui/options.html create mode 100644 ui/popup.html create mode 100644 ui/satus/satus.css create mode 100644 ui/satus/satus.js create mode 100644 ui/script.js create mode 100644 ui/styles.css diff --git a/README.md b/README.md index fe821a5..1ffef9b 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# auto-scroll \ No newline at end of file +# Auto Scroll \ No newline at end of file diff --git a/_locales/am/messages.json b/_locales/am/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/am/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/ar/messages.json b/_locales/ar/messages.json new file mode 100644 index 0000000..96b6b0d --- /dev/null +++ b/_locales/ar/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "إلغاء" + }, + "description": { + "message": "أفضل أداة إطار حسب بإطار. تعمل على جميع المواقع! حرك مؤشر الفأرة على الفيديو و إستعمل مفاتيح الأسهم لتبديل بين الإطارات." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "إعادة تعيين" + }, + "save": { + "message": "حفظ" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/bg/messages.json b/_locales/bg/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/bg/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/bn/messages.json b/_locales/bn/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/bn/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/ca/messages.json b/_locales/ca/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/ca/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/cs/messages.json b/_locales/cs/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/cs/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/da/messages.json b/_locales/da/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/da/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/de/messages.json b/_locales/de/messages.json new file mode 100644 index 0000000..25cbc60 --- /dev/null +++ b/_locales/de/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Das beste Frame-by-Frame-Tool. Funktioniert mit allen Websites! Bewegen Sie den Mauszeiger über das Video und verwenden Sie die Pfeiltasten der Tastatur, um die Frames zu wechseln." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/el/messages.json b/_locales/el/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/el/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/en/messages.json b/_locales/en/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/en/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/es/messages.json b/_locales/es/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/es/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/et/messages.json b/_locales/et/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/et/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/fa/messages.json b/_locales/fa/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/fa/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/fi/messages.json b/_locales/fi/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/fi/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/fil/messages.json b/_locales/fil/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/fil/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/fr/messages.json b/_locales/fr/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/fr/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/gu/messages.json b/_locales/gu/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/gu/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/he/messages.json b/_locales/he/messages.json new file mode 100644 index 0000000..4be85ef --- /dev/null +++ b/_locales/he/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "האם אתה בטוח שברצונך לייצא את המידע?" + }, + "areYouSureYouWantToImportTheData": { + "message": "האם אתה בטוח שברצונך לייבא את המידע?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "ביטול" + }, + "description": { + "message": "הכלי הטוב ביותר למעבר בין חלוניות (פריימים). עובד עם כל האתרים! יש להזיז את סמן העכבר על גבי סרטון ולהשתמש במקשי החיצים למעבר בין פריימים." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "ייצוא" + }, + "import": { + "message": "ייבוא" + }, + "language": { + "message": "שפה" + }, + "light": { + "message": "בהיר" + }, + "ok": { + "message": "אישור" + }, + "reset": { + "message": "איפוס" + }, + "save": { + "message": "שמירה" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "משהו השתבש. יש לנסות לטעון את העמוד מחדש." + }, + "theme": { + "message": "ערכת נושא" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/hi/messages.json b/_locales/hi/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/hi/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/hin/messages.json b/_locales/hin/messages.json new file mode 100644 index 0000000..528455c --- /dev/null +++ b/_locales/hin/messages.json @@ -0,0 +1,41 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/hr/messages.json b/_locales/hr/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/hr/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/hu/messages.json b/_locales/hu/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/hu/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/id/messages.json b/_locales/id/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/id/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/it/messages.json b/_locales/it/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/it/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/ja/messages.json b/_locales/ja/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/ja/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/kn/messages.json b/_locales/kn/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/kn/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/ko/messages.json b/_locales/ko/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/ko/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/lt/messages.json b/_locales/lt/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/lt/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/lv/messages.json b/_locales/lv/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/lv/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/ml/messages.json b/_locales/ml/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/ml/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/mr/messages.json b/_locales/mr/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/mr/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/ms/messages.json b/_locales/ms/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/ms/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/nb_NO/messages.json b/_locales/nb_NO/messages.json new file mode 100644 index 0000000..528455c --- /dev/null +++ b/_locales/nb_NO/messages.json @@ -0,0 +1,41 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/nl/messages.json b/_locales/nl/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/nl/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/no/messages.json b/_locales/no/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/no/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/pl/messages.json b/_locales/pl/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/pl/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/pt_BR/messages.json b/_locales/pt_BR/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/pt_BR/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/pt_PT/messages.json b/_locales/pt_PT/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/pt_PT/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/ro/messages.json b/_locales/ro/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/ro/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/ru/messages.json b/_locales/ru/messages.json new file mode 100644 index 0000000..b1566b6 --- /dev/null +++ b/_locales/ru/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Вы действительно хотите экспортировать данные?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Вы действительно хотите испортировать данные?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Отмена" + }, + "description": { + "message": "Лучшее Frame By Frame расширение. Работает со всеми веб-сайтами! Наведите курсор на видео, затем используйте клавиатуру, чтобы выбрать нужный кадр." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Экспорт" + }, + "import": { + "message": "Импортировать" + }, + "language": { + "message": "Язык" + }, + "light": { + "message": "Светлая" + }, + "ok": { + "message": "Ок" + }, + "reset": { + "message": "Сброс" + }, + "save": { + "message": "Сохранить" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Что-то пошло не так. Попробуйте перезагрузить страницу." + }, + "theme": { + "message": "Тема" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/sk/messages.json b/_locales/sk/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/sk/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/sl/messages.json b/_locales/sl/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/sl/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/sr/messages.json b/_locales/sr/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/sr/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/sv/messages.json b/_locales/sv/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/sv/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/sw/messages.json b/_locales/sw/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/sw/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/ta/messages.json b/_locales/ta/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/ta/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/te/messages.json b/_locales/te/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/te/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/th/messages.json b/_locales/th/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/th/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/tr/messages.json b/_locales/tr/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/tr/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/uk/messages.json b/_locales/uk/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/uk/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/vi/messages.json b/_locales/vi/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/vi/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/zh_CN/messages.json b/_locales/zh_CN/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/zh_CN/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/_locales/zh_TW/messages.json b/_locales/zh_TW/messages.json new file mode 100644 index 0000000..b40df4c --- /dev/null +++ b/_locales/zh_TW/messages.json @@ -0,0 +1,53 @@ +{ + "areYouSureYouWantToExportTheData": { + "message": "Are you sure you want to export the data?" + }, + "areYouSureYouWantToImportTheData": { + "message": "Are you sure you want to import the data?" + }, + "autoScrollActivation": { + "message": "\"Auto scroll\" activation" + }, + "black": { + "message": "Black" + }, + "cancel": { + "message": "Cancel" + }, + "description": { + "message": "Best Frame By Frame Tool. Works with all websites! Move your mouse cursor over video and use keyboard arrows to switch frames." + }, + "dragDropActivation": { + "message": "\"Drag & Drop\" activation" + }, + "export": { + "message": "Export" + }, + "import": { + "message": "Import" + }, + "language": { + "message": "Language" + }, + "light": { + "message": "Light" + }, + "ok": { + "message": "Ok" + }, + "reset": { + "message": "Reset" + }, + "save": { + "message": "Save" + }, + "somethingWentWrongTryReloadingThePage": { + "message": "Something went wrong. Try reloading the page." + }, + "theme": { + "message": "Theme" + }, + "touchscreenActivation": { + "message": "\"Touchscreen\" activation" + } +} \ No newline at end of file diff --git a/background.js b/background.js new file mode 100644 index 0000000..2426298 --- /dev/null +++ b/background.js @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------- +>>> BACKGROUND +----------------------------------------------------------------- +# Listeners + # On Install + # Message +---------------------------------------------------------------*/ + +/*--------------------------------------------------------------- +# LISTENERS +---------------------------------------------------------------*/ + +/*--------------------------------------------------------------- +# ON INSTALL +---------------------------------------------------------------*/ + +chrome.runtime.onInstalled.addListener(function(event){ + if(event.reason === 'install') { + chrome.storage.local.set({ + auto_scroll: { + middle: true + } + }); + } +}); + + +/*--------------------------------------------------------------- +# MESSAGE +---------------------------------------------------------------*/ + +chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) { + if (message === 'get-tab-url') { + var response = { + url: new URL(sender.tab.url).hostname, + id: sender.tab.id + }; + + sendResponse(response); + + return response; + } +}); \ No newline at end of file diff --git a/content-script.js b/content-script.js new file mode 100644 index 0000000..28cbcc8 --- /dev/null +++ b/content-script.js @@ -0,0 +1,910 @@ +/*-------------------------------------------------------------- +>>> CONTENT SCRIPT +---------------------------------------------------------------- +# Global variable +# Message + # Listener + # Sent +# Storage + # Get + # Set + # Import + # On changed +# Find container +# Cursor + # Set + # Reset +# Features + # Auto + # Drag & Drop +# Initialization +--------------------------------------------------------------*/ + +/*-------------------------------------------------------------- +# GLOBAL VARIABLE +--------------------------------------------------------------*/ + +var extension = { + hostname: location.hostname, + request: null, + animationRequest: null +}; + + + + + + + + +/*-------------------------------------------------------------- +# MESSAGE +--------------------------------------------------------------*/ + +extension.message = {}; + + +/*-------------------------------------------------------------- +# LISTENER +--------------------------------------------------------------*/ + +extension.message.listener = function (callback) { + chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) { + if (message === 'init') { + if (window === window.top) { + sendResponse(extension.hostname); + } + } + }); +}; + + +/*-------------------------------------------------------------- +# SENT +--------------------------------------------------------------*/ + +extension.message.sent = function (message, callback) { + chrome.runtime.sendMessage(message, callback); +}; + + + + + + + + +/*-------------------------------------------------------------- +# STORAGE +--------------------------------------------------------------*/ + +extension.storage = { + items: {} +}; + + +/*-------------------------------------------------------------- +# GET +--------------------------------------------------------------*/ + +extension.storage.get = function (key) { + return this.items[key]; +}; + + +/*-------------------------------------------------------------- +# SET +--------------------------------------------------------------*/ + +extension.storage.set = function (key, value) { + var object = {}; + + object[key] = value; + + this.items[key] = value; + + chrome.storage.local.set(object); +}; + + +/*-------------------------------------------------------------- +# IMPORT +--------------------------------------------------------------*/ + +extension.storage.import = function (callback) { + chrome.storage.local.get(function (items) { + extension.storage.items = items; + + document.removeEventListener('storage-import', callback); + document.addEventListener('storage-import', callback); + + document.dispatchEvent(new CustomEvent('storage-import')); + }); +}; + + +/*-------------------------------------------------------------- +# ON CHANGED +--------------------------------------------------------------*/ + +extension.storage.onchanged = function (callback) { + chrome.storage.onChanged.addListener(function (changes) { + for (var key in changes) { + var value = changes[key].newValue; + + extension.storage.items[key] = value; + + document.removeEventListener('storage-change', callback); + document.addEventListener('storage-change', callback); + + document.dispatchEvent(new CustomEvent('storage-import'), { + detail: { + key, + value + } + }); + } + }); +}; + + + + + + + + +/*-------------------------------------------------------------- +# EVENTS +--------------------------------------------------------------*/ + +extension.events = { + data: { + alt: false, + ctrl: false, + shift: false, + keys: {} + }, + keyboard: {}, + mouse: {} +}; + + +/*-------------------------------------------------------------- +# CREATE +--------------------------------------------------------------*/ + +extension.events.create = function (target) { + for (var type in this[target]) { + document.addEventListener(type, this[target][type], true); + } +}; + + +/*-------------------------------------------------------------- +# REMOVE +--------------------------------------------------------------*/ + +extension.events.remove = function (target) { + for (var type in this[target]) { + document.removeEventListener(type, this[target][type]); + } +}; + + +/*-------------------------------------------------------------- +# CHECK ACTIVE ELEMENT +--------------------------------------------------------------*/ + +extension.events.checkActiveElement = function () { + if ( + event.target.isContentEditable || + [ + 'EMBED', + 'INPUT', + 'OBJECT', + 'TEXTAREA', + 'IFRAME' + ].includes((document.activeElement || {}).tagName) + ) { + return true; + } +}; + + +/*-------------------------------------------------------------- +# FEATURES +--------------------------------------------------------------*/ + +extension.events.features = {}; + + +/*-------------------------------------------------------------- +# HANDLER +--------------------------------------------------------------*/ + +extension.events.handler = function () { + var prevent = false; + + for (var key in extension.events.features) { + var shortcut = extension.storage.items[key]; + + if (shortcut) { + var same_keys = true; + + if ( + (extension.events.data.alt === shortcut.alt || shortcut.hasOwnProperty('alt') === false) && + (extension.events.data.ctrl === shortcut.ctrl || shortcut.hasOwnProperty('ctrl') === false) && + (extension.events.data.shift === shortcut.shift || shortcut.hasOwnProperty('shift') === false) && + (extension.events.data.click === shortcut.click || shortcut.hasOwnProperty('click') === false) && + (extension.events.data.middle === shortcut.middle || shortcut.hasOwnProperty('middle') === false) && + (extension.events.data.context === shortcut.context || shortcut.hasOwnProperty('context') === false) + ) { + if (shortcut.keys) { + for (var code in extension.events.data.keys) { + if (!shortcut.keys[code]) { + same_keys = false; + } + } + + for (var code in shortcut.keys) { + if (!extension.events.data.keys[code]) { + same_keys = false; + } + } + } + + if (same_keys === true) { + cancelAnimationFrame(extension.animationRequest); + + extension.events.features[key](); + + prevent = true; + } + } + } + } + + return prevent; +}; + + +/*-------------------------------------------------------------- +# KEYBOARD +--------------------------------------------------------------*/ + +extension.events.keyboard.keydown = function (event) { + if (extension.events.checkActiveElement()) { + return false; + } + + if (event.code === 'AltLeft' || event.code === 'AltRight') { + extension.events.data.alt = true; + } else if (event.code === 'ControlLeft' || event.code === 'ControlRight') { + extension.events.data.ctrl = true; + } else if (event.code === 'ShiftLeft' || event.code === 'ShiftRight') { + extension.events.data.shift = true; + } else { + extension.events.data.keys[event.keyCode] = true; + } + + extension.events.data.wheel = 0; + extension.events.data.click = false; + extension.events.data.middle = false; + extension.events.data.context = false; + + if (extension.events.handler()) { + event.preventDefault(); + event.stopPropagation(); + + return false; + } +}; + +extension.events.keyboard.keyup = function (event) { + if (extension.events.checkActiveElement()) { + return false; + } + + if (event.code === 'AltLeft' || event.code === 'AltRight') { + extension.events.data.alt = false; + } else if (event.code === 'ControlLeft' || event.code === 'ControlRight') { + extension.events.data.ctrl = false; + } else if (event.code === 'ShiftLeft' || event.code === 'ShiftRight') { + extension.events.data.shift = false; + } else { + delete extension.events.data.keys[event.keyCode]; + } + + extension.events.data.wheel = 0; + extension.events.data.click = false; + extension.events.data.middle = false; + extension.events.data.context = false; +}; + + +/*-------------------------------------------------------------- +# MOUSE +--------------------------------------------------------------*/ + +extension.events.mouse.mousemove = function (event) { + extension.cursor.x = event.clientX; + extension.cursor.y = event.clientY; + extension.cursor.target = event.target; +}; + +extension.events.mouse.mousedown = function (event) { + if ( + extension.events.data.click && event.button === 0 || + extension.events.data.middle && event.button === 1 + ) { + extension.events.data = { + alt: false, + ctrl: false, + shift: false, + keys: {} + }; + } + + extension.events.data.click = false; + extension.events.data.middle = false; + extension.events.data.context = false; + + if (event.button === 0) { + extension.events.data.click = true; + } else if (event.button === 1) { + extension.events.data.middle = true; + } + + if (extension.events.handler()) { + event.preventDefault(); + event.stopPropagation(); + + extension.mousedown = true; + + return false; + } +}; + +extension.events.mouse.mouseup = function (event) { + if (extension.events.data.context) { + extension.events.data = { + alt: false, + ctrl: false, + shift: false, + keys: {} + }; + } + + extension.events.data.context = true; + extension.events.data.middle = false; + extension.events.data.click = false; + + if (extension.mousedown === true) { + event.preventDefault(); + event.stopPropagation(); + + extension.mousedown = false; + + return false; + } +}; + + + + + + + +/*-------------------------------------------------------------- +# FIND CONTAINER +--------------------------------------------------------------*/ + +extension.findContainer = function (target) { + if (target.isContentEditable !== true) { + var style = getComputedStyle(target); + + while ( + target.parentNode !== document && + ((style.overflowX !== 'auto' && style.overflowX !== 'scroll') || target.scrollWidth <= target.clientWidth) && + ((style.overflowY !== 'auto' && style.overflowY !== 'scroll') || target.scrollHeight <= target.clientHeight) + ) { + target = target.parentNode; + + style = getComputedStyle(target); + } + + if ( + document.scrollingElement && + (target === document.documentElement || target === document.body) + ) { + target = document.scrollingElement; + } + + extension.target = target; + } +}; + + + + + + + + +/*-------------------------------------------------------------- +# CURSOR +--------------------------------------------------------------*/ + +extension.cursor = { + x: 0, + y: 0, + target: document.documentElement +}; + + +/*-------------------------------------------------------------- +# SET +--------------------------------------------------------------*/ + +extension.cursor.set = function (type) { + document.documentElement.dataset.autoScrollCursor = type; +}; + + +/*-------------------------------------------------------------- +# RESET +--------------------------------------------------------------*/ + +extension.cursor.reset = function () { + delete document.documentElement.dataset.autoScrollCursor; +}; + + + + + + + + +/*-------------------------------------------------------------- +# FEATURES +--------------------------------------------------------------*/ + +/*-------------------------------------------------------------- +# AUTO +--------------------------------------------------------------*/ + +extension.autoMode = { + sensitivity: 10, + mousedown: { + x: 0, + y: 0 + }, + offset: { + x: 0, + y: 0 + } +}; + + +/*-------------------------------------------------------------- +# START +--------------------------------------------------------------*/ + +extension.events.features.auto_scroll = function (event) { + var data = extension.storage.items['auto_scroll']; + + if (data) { + addEventListener('mousemove', extension.autoMode.check, true); + + if ( + data.click || + data.middle || + data.context + ) { + addEventListener('mouseup', extension.autoMode.end, true); + } else { + addEventListener('keyup', extension.autoMode.end, true); + } + } +}; + + +/*-------------------------------------------------------------- +# CHECK +--------------------------------------------------------------*/ + +extension.autoMode.check = function (event) { + var x = Math.abs(extension.autoMode.mousedown.x - event.clientX), + y = Math.abs(extension.autoMode.mousedown.y - event.clientY); + + if (x > 5 || y > 5) { + extension.cursor.set('all-scroll'); + + extension.autoMode.mousedown.x = event.clientX; + extension.autoMode.mousedown.y = event.clientY; + + extension.findContainer(event.target); + extension.autoMode.move(event); + extension.autoMode.scroll(); + + addEventListener('mousemove', extension.autoMode.move, true); + removeEventListener('mousemove', extension.autoMode.check, true); + } +}; + + +/*-------------------------------------------------------------- +# MOVE +--------------------------------------------------------------*/ + +extension.autoMode.move = function (event) { + var x = event.clientX - extension.autoMode.mousedown.x, + y = event.clientY - extension.autoMode.mousedown.y; + + x = x / 100 * extension.autoMode.sensitivity; + y = y / 100 * extension.autoMode.sensitivity; + + extension.autoMode.offset.x = x; + extension.autoMode.offset.y = y; +}; + + +/*-------------------------------------------------------------- +# SCROLL +--------------------------------------------------------------*/ + +extension.autoMode.scroll = function () { + var target = extension.target, + x = target.scrollLeft + extension.autoMode.offset.x, + y = target.scrollTop + extension.autoMode.offset.y; + + if (target.scroll) { + target.scroll(x, y); + } else { + target.scrollLeft = x; + target.scrollTop = y; + } + + extension.request = requestAnimationFrame(extension.autoMode.scroll); +}; + + +/*-------------------------------------------------------------- +# END +--------------------------------------------------------------*/ + +extension.autoMode.end = function (event) { + cancelAnimationFrame(extension.request); + + extension.cursor.reset(); + + removeEventListener('mousemove', extension.autoMode.check, true); + removeEventListener('mousemove', extension.autoMode.move, true); + removeEventListener('mouseup', extension.autoMode.end, true); +}; + + + + + + + + +/*-------------------------------------------------------------- +# DRAG & DROP +--------------------------------------------------------------*/ + +extension.dragAndDrop = { + mousedown: { + x: 0, + y: 0 + }, + offset: { + x: 0, + y: 0 + }, + scroll: { + x: 0, + y: 0 + } +}; + + +/*-------------------------------------------------------------- +# START +--------------------------------------------------------------*/ + +extension.events.features.drag_and_drop = function (event) { + var data = extension.storage.items['drag_and_drop']; + + if (data) { + extension.cursor.set('all-scroll'); + + extension.dragAndDrop.mousedown.x = extension.cursor.x; + extension.dragAndDrop.mousedown.y = extension.cursor.y; + + extension.findContainer(extension.cursor.target); + + extension.dragAndDrop.scroll.x = extension.target.scrollLeft; + extension.dragAndDrop.scroll.y = extension.target.scrollTop; + + extension.dragAndDrop.move(event); + extension.dragAndDrop.scroll(); + + addEventListener('mousemove', extension.dragAndDrop.move, true); + + if ( + data.click || + data.middle || + data.context + ) { + addEventListener('mouseup', extension.dragAndDrop.end, true); + } else { + addEventListener('keyup', extension.dragAndDrop.end, true); + } + } +}; + + +/*-------------------------------------------------------------- +# MOVE +--------------------------------------------------------------*/ + +extension.dragAndDrop.move = function (event) { + extension.dragAndDrop.offset.x = extension.cursor.x - extension.dragAndDrop.mousedown.x; + extension.dragAndDrop.offset.y = extension.cursor.y - extension.dragAndDrop.mousedown.y; +}; + + +/*-------------------------------------------------------------- +# SCROLL +--------------------------------------------------------------*/ + +extension.dragAndDrop.scroll = function () { + var target = extension.target, + x = extension.dragAndDrop.scroll.x - extension.dragAndDrop.offset.x, + y = extension.dragAndDrop.scroll.y - extension.dragAndDrop.offset.y; + + if (target.scroll) { + target.scroll(x, y); + } else { + target.scrollLeft = x; + target.scrollTop = y; + } + + extension.request = requestAnimationFrame(extension.dragAndDrop.scroll); +}; + + +/*-------------------------------------------------------------- +# END +--------------------------------------------------------------*/ + +extension.dragAndDrop.end = function (event) { + cancelAnimationFrame(extension.request); + + extension.cursor.reset(); + + removeEventListener('mousemove', extension.dragAndDrop.move, true); + removeEventListener('mouseup', extension.dragAndDrop.end, true); +}; + + + + + + + + +/*-------------------------------------------------------------- +# TOUCHSCREEN +--------------------------------------------------------------*/ + +extension.touchscreen = { + mousedown: { + x: 0, + y: 0 + }, + offset: { + x: 0, + y: 0 + }, + scroll: { + x: 0, + y: 0 + }, + momentum: { + time: 0, + x: 0, + y: 0, + speedX: 0, + speedY: 0 + } +}; + + +/*-------------------------------------------------------------- +# START +--------------------------------------------------------------*/ + +extension.events.features.touchscreen = function (event) { + var data = extension.storage.items['touchscreen']; + + if (data) { + extension.cursor.set('all-scroll'); + + extension.touchscreen.mousedown.x = extension.cursor.x; + extension.touchscreen.mousedown.y = extension.cursor.y; + + extension.findContainer(extension.cursor.target); + + extension.touchscreen.scroll.x = extension.target.scrollLeft; + extension.touchscreen.scroll.y = extension.target.scrollTop; + + extension.touchscreen.move(event); + extension.touchscreen.scroll(); + + addEventListener('mousemove', extension.touchscreen.move, true); + + if ( + data.click || + data.middle || + data.context + ) { + addEventListener('mouseup', extension.touchscreen.end, true); + } else { + addEventListener('keyup', extension.touchscreen.end, true); + } + } +}; + + +/*-------------------------------------------------------------- +# MOVE +--------------------------------------------------------------*/ + +extension.touchscreen.move = function (event) { + var now = performance.now(); + + extension.touchscreen.offset.x = extension.cursor.x - extension.touchscreen.mousedown.x; + extension.touchscreen.offset.y = extension.cursor.y - extension.touchscreen.mousedown.y; + + if (now - extension.touchscreen.momentum.time > 150) { + extension.touchscreen.momentum.x = extension.cursor.x; + extension.touchscreen.momentum.y = extension.cursor.y; + + extension.touchscreen.momentum.time = now; + } +}; + + +/*-------------------------------------------------------------- +# SCROLL +--------------------------------------------------------------*/ + +extension.touchscreen.scroll = function () { + var target = extension.target, + x = extension.touchscreen.scroll.x - extension.touchscreen.offset.x, + y = extension.touchscreen.scroll.y - extension.touchscreen.offset.y; + + target.scrollLeft = x; + target.scrollTop = y; + + extension.request = requestAnimationFrame(extension.touchscreen.scroll); +}; + +extension.touchscreen.animation = function () { + var momentum = extension.touchscreen.momentum; + + if (momentum.speedX !== 0 || momentum.speedY !== 0) { + var target = extension.target; + + if (momentum.speedX > 0) { + momentum.speedX--; + } else if (momentum.speedX < 0) { + momentum.speedX++; + } + + if (momentum.speedY > 0) { + momentum.speedY--; + } else if (momentum.speedY < 0) { + momentum.speedY++; + } + + target.scrollLeft -= momentum.speedX; + target.scrollTop -= momentum.speedY; + + extension.animationRequest = requestAnimationFrame(extension.touchscreen.animation); + } +}; + + +/*-------------------------------------------------------------- +# END +--------------------------------------------------------------*/ + +extension.touchscreen.end = function (event) { + extension.touchscreen.momentum.speedX = Math.min(Math.max(Math.floor((extension.cursor.x - extension.touchscreen.momentum.x) / 10), -40), 40); + extension.touchscreen.momentum.speedY = Math.min(Math.max(Math.floor((extension.cursor.y - extension.touchscreen.momentum.y) / 10), -40), 40); + + console.log(extension.touchscreen.momentum.speedX, extension.touchscreen.momentum.speedY); + + cancelAnimationFrame(extension.request); + + extension.touchscreen.animation(); + + extension.cursor.reset(); + + removeEventListener('mousemove', extension.touchscreen.move, true); + removeEventListener('mouseup', extension.touchscreen.end, true); +}; + + + + + + + + +/*-------------------------------------------------------------- +# ACTIVATION +--------------------------------------------------------------*/ + +/*-------------------------------------------------------------- +# ENABLE +--------------------------------------------------------------*/ + +extension.enable = function () { + extension.events.create('mouse'); + extension.events.create('keyboard'); +}; + +/*-------------------------------------------------------------- +# DISABLE +--------------------------------------------------------------*/ + +extension.disable = function () { + extension.events.remove('mouse'); + extension.events.remove('keyboard'); +}; + + + + + + + + +/*-------------------------------------------------------------- +# INITIALIZATION +--------------------------------------------------------------*/ + +extension.storage.onchanged(function (key, value) { + if (key === 'domains') { + if (value[extension.hostname] !== false) { + extension.enable(); + } else { + extension.disable(); + } + } +}); + +chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) { + if (message === 'init') { + if (window === window.top) { + sendResponse(extension.hostname); + } + } +}); + +chrome.runtime.sendMessage('get-tab-url', function (response) { + extension.hostname = response.url; + + extension.storage.import(function () { + if (!extension.storage.items.domains || extension.storage.items.domains[extension.hostname] !== false) { + extension.enable(); + } + }); +}); \ No newline at end of file diff --git a/content-styles.css b/content-styles.css new file mode 100644 index 0000000..1b26b2c --- /dev/null +++ b/content-styles.css @@ -0,0 +1,13 @@ +/*-------------------------------------------------------------- +>>> CONTENT STYLES +--------------------------------------------------------------*/ + +html[data-auto-scroll-cursor=all-scroll], +html[data-auto-scroll-cursor=all-scroll] * { + cursor: all-scroll !important +} + +html[data-auto-scroll-cursor=grabbing], +html[data-auto-scroll-cursor=grabbing] * { + cursor: grabbing !important +} \ No newline at end of file diff --git a/icons/128.png b/icons/128.png new file mode 100644 index 0000000000000000000000000000000000000000..2f7fb3b605931ea4f3931f5aa597f610b963ac41 GIT binary patch literal 6569 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 bT=4$@R)mv=uZ=Z700000NkvXXu0mjfEF7E? literal 0 HcmV?d00001 diff --git a/icons/16.png b/icons/16.png new file mode 100644 index 0000000000000000000000000000000000000000..2e2b3a960ca8a56b055ab43ea9adea8bd6b0f936 GIT binary patch literal 637 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" + ], + "run_at": "document_start" + } + ], + "permissions": [ + "storage" + ], + "offline_enabled": true +} \ No newline at end of file diff --git a/py/locale.py b/py/locale.py new file mode 100644 index 0000000..7d846d5 --- /dev/null +++ b/py/locale.py @@ -0,0 +1,208 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# -------------------------------------------------------------- +# >>> TABLE OF CONTENTS: +# -------------------------------------------------------------- +# 1.0 Import modules +# 2.0 Lower camel case +# 3.0 Get list of files +# 4.0 Add item +# 5.0 Remove item +# 6.0 Decode +# 7.0 Add locales +# 8.0 Initialization +# -------------------------------------------------------------- + +# -------------------------------------------------------------- +# 1.0 IMPORT MODULES +# -------------------------------------------------------------- + +import io +import json +import os +import pathlib +import re +import sys + + +# -------------------------------------------------------------- +# 2.0 LOWER CAMEL CASE +# -------------------------------------------------------------- + +def lowerCamelCase(string): + string = re.sub(r"(-|_)+", ' ', string).title() + string = re.sub(r"[^a-zA-Z0-9]", '', string) + + return string[0].lower() + string[1:] + + +# -------------------------------------------------------------- +# 3.0 GET LIST OF FILES +# -------------------------------------------------------------- + +def getListOfFiles(dirName): + allFiles = list() + + for entry in os.listdir(dirName): + fullPath = os.path.join(dirName, entry) + + if not os.path.isdir(fullPath): + allFiles.append(fullPath) + + for entry in os.listdir(dirName): + fullPath = os.path.join(dirName, entry) + + if os.path.isdir(fullPath): + allFiles = allFiles + getListOfFiles(fullPath) + + return allFiles + + +# -------------------------------------------------------------- +# 4.0 ADD ITEM +# -------------------------------------------------------------- + +def addItem(allFiles): + message = input('Enter your message: ') + camelized_message = lowerCamelCase(message) + + for keyFile in allFiles: + with open(keyFile, 'r+') as json_file: + data = json.load(json_file) + + if (camelized_message in data) == False: + data[camelized_message] = {'message': message} + + json_file.seek(0) + json.dump(data, json_file, ensure_ascii=False, indent=4, + sort_keys=True) + json_file.truncate() + + +# -------------------------------------------------------------- +# 5.0 REMOVE ITEM +# -------------------------------------------------------------- + +def removeItem(allFiles): + key = input('Enter your key (lowerCamelCase): ') + + for keyFile in allFiles: + with open(keyFile, 'r+') as json_file: + data = json.load(json_file) + + if key in data: + del data[key] + + json_file.seek(0) + json.dump(data, json_file, ensure_ascii=False, indent=4, + sort_keys=True) + json_file.truncate() + + +# -------------------------------------------------------------- +# 6.0 DECODE +# -------------------------------------------------------------- + +def decodeCharacters(allFiles): + for keyFile in allFiles: + with open(keyFile, 'r+') as json_file: + data = json.load(json_file) + + json_file.seek(0) + json.dump(data, json_file, ensure_ascii=False, indent=4, + sort_keys=True) + json_file.truncate() + + +# -------------------------------------------------------------- +# 7.0 ADD LOCALES +# -------------------------------------------------------------- + +def addLocales(): + locales = [ + 'am', + 'ar', + 'bg', + 'bn', + 'ca', + 'cs', + 'da', + 'de', + 'el', + 'en', + 'es', + 'et', + 'fa', + 'fi', + 'fil', + 'fr', + 'gu', + 'he', + 'hi', + 'hin', + 'hr', + 'hu', + 'id', + 'it', + 'ja', + 'kn', + 'ko', + 'lt', + 'lv', + 'ml', + 'mr', + 'ms', + 'nb_NO', + 'nl', + 'no', + 'pl', + 'pt_BR', + 'pt_PT', + 'ro', + 'ru', + 'sk', + 'sl', + 'sr', + 'sv', + 'sw', + 'ta', + 'te', + 'th', + 'tr', + 'uk', + 'vi', + 'zh_CN', + 'zh_TW' + ] + + for locale in locales: + if not os.path.exists('../_locales/' + locale): + pathlib.Path('../_locales/' + locale).mkdir(parents=True, + exist_ok=True) + + file = io.open('../_locales/' + locale + '/messages.json', + mode='w', encoding='utf-8') + + file.write('{}') + + file.close() + + print(locale) + + +# -------------------------------------------------------------- +# 8.0 INITIALIZATION +# -------------------------------------------------------------- + +allFiles = getListOfFiles('../_locales/') + +for arg in sys.argv: + if arg == '-add': + addItem(allFiles) + elif arg == '-remove': + removeItem(allFiles) + elif arg == '-decode': + decodeCharacters(allFiles) + elif arg == '-generate': + addLocales() \ No newline at end of file diff --git a/ui/fonts/OpenSans-Medium.ttf b/ui/fonts/OpenSans-Medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..6b4191859b38e4e461b63e93356a3ec8af7c13fd GIT binary patch literal 129948 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 z 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 OWT8tj2@v7&_x}O&vJE`| literal 0 HcmV?d00001 diff --git a/ui/fonts/OpenSans-Regular.ttf b/ui/fonts/OpenSans-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3a29f26497950810af1f58a52625552a2fa07a4a GIT binary patch literal 129796 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 G#`%ArKbQCb literal 0 HcmV?d00001 diff --git a/ui/options.html b/ui/options.html new file mode 100644 index 0000000..7d98a9f --- /dev/null +++ b/ui/options.html @@ -0,0 +1,37 @@ + + + + + + Auto Scroll + + + + + + + + + + \ No newline at end of file diff --git a/ui/popup.html b/ui/popup.html new file mode 100644 index 0000000..e5af895 --- /dev/null +++ b/ui/popup.html @@ -0,0 +1,37 @@ + + + + + + Frame By Frame + + + + + + + + + + \ No newline at end of file diff --git a/ui/satus/satus.css b/ui/satus/satus.css new file mode 100644 index 0000000..3836772 --- /dev/null +++ b/ui/satus/satus.css @@ -0,0 +1,1664 @@ + +/*-------------------------------------------------------------- +>>> THEMES: +---------------------------------------------------------------- +# Default +# Dark +# Black +--------------------------------------------------------------*/ + +/*-------------------------------------------------------------- +# DEFAULT +--------------------------------------------------------------*/ + +body { + --satus-contrast: 0, 0, 0; + --satus-primary: #f6b465; + --satus-hover: rgba(var(--satus-contrast), .04); + + --satus-alert-error-background: #fde6e6; + --satus-alert-error-border: #ecd7d7; + --satus-alert-error-color: #ad5f5f; + + --satus-checkbox--background: rgb(90, 90, 73, .08); + --satus-checkbox--border: rgb(90, 90, 73, .16); + --satus-checkbox--mark: #fff; + + --satus-divider: rgba(var(--satus-contrast),.1); + + --satus-header-background: #fff; + --satus-header-border: rgba(var(--satus-contrast),.1); + --satus-header-text: #8f8f8f; + + --satus-layers-background: #f6f5f4; + --satus-layers-text: #8f8f8f; + + --satus-modal-background: #f6f6f4; + --satus-modal-border: rgba(var(--satus-contrast), .1); + --satus-modal-text: #8f8f8f; + + --satus-section-card-background: #fff; + --satus-section-card-border: rgba(var(--satus-contrast),.1); + + --satus-select-background: #f6f6f4; + --satus-select-text: #8f8f8f; + + --satus-switch-background: rgba(var(--satus-contrast),.08); + --satus-switch-track: #e0e0e0; + --satus-switch-track--active: var(--satus-primary); + --satus-switch-thumb: #fff; + + --satus-tabs-background: #e8e8e3; + --satus-tabs-foreground: #fff; + --satus-tabs-border: rgba(var(--satus-contrast), .1); + + --satus-text-field--background: #e8e8e3; + --satus-text-field--border: #d6d6cd; + --satus-text-field--text: #8f8f8f; + + + --satus-tooltip: rgba(var(--satus-contrast),.4); + --satus-sortable-ghost: rgba(var(--satus-contrast), .80); + --satus-sortable-background: rgba(var(--satus-contrast), .08); + --satus-sortable-text: currentColor; +} + + +/*-------------------------------------------------------------- +# DARK +--------------------------------------------------------------*/ + +body[data-theme=dark] { + --satus-contrast: 255, 255, 255; + --satus-primary: #8f8f8f; + --satus-switch-background: rgba(var(--satus-contrast),.08); + --satus-header-background: #1f1f1f; + --satus-header-border: rgba(var(--satus-contrast),.08); + --satus-header-text: #ccc; + --satus-layers-background: #000; + --satus-layers-text: #ccc; + --satus-section-card-background: #1e1e1e; + --satus-section-card-border: rgba(var(--satus-contrast),.08); + --satus-modal-background: #212121; + --satus-modal-border: rgba(var(--satus-contrast),.08); + --satus-modal-text: #ccc; + --satus-hover: rgba(var(--satus-contrast), .05); + --satus-text-field--background: #333333; + --satus-text-field--border: #525252; + --satus-text-field--text: #ccc; + --satus-switch-track: #111; + --satus-switch-track--active: var(--satus-primary); + --satus-switch-thumb: #ddd; + --satus-tooltip: rgba(var(--satus-contrast),.4); + --satus-sortable-ghost: rgba(var(--satus-contrast), .8); + --satus-sortable-background: rgba(var(--satus-contrast), .1); + --satus-sortable-text: #fff; + --satus-divider: rgba(var(--satus-contrast),.08); + --satus-tabs-background: #111; + --satus-tabs-foreground: #2e2e2e; + --satus-tabs-border: #2f2f2f; + --satus-checkbox--background: rgb(var(--satus-contrast), .08); + --satus-checkbox--border: #2f2f2f; + --satus-checkbox--mark: #fff; + --satus-alert-error-background: #501616; + --satus-alert-error-border: #6f1f1f; + --satus-alert-error-color: #cf7777; +} + + +/*-------------------------------------------------------------- +# BLACK +--------------------------------------------------------------*/ + +body[data-theme=black] { + --satus-contrast: 255, 255, 255; + --satus-primary: #8f8f8f; + --satus-switch-background: rgba(var(--satus-contrast),.08); + --satus-header-background: #000; + --satus-header-border: rgba(var(--satus-contrast),.16); + --satus-header-text: #ccc; + --satus-layers-background: #000; + --satus-layers-text: #ccc; + --satus-section-card-background: #000; + --satus-section-card-border: rgba(var(--satus-contrast),.16); + --satus-modal-background: #000; + --satus-modal-border: rgba(var(--satus-contrast),.16); + --satus-modal-text: #ccc; + --satus-hover: rgba(var(--satus-contrast), .05); + --satus-text-field--background: #333333; + --satus-text-field--border: #525252; + --satus-text-field--text: #ccc; + --satus-switch-track: rgba(var(--satus-contrast),.16); + --satus-switch-track--active: var(--satus-primary); + --satus-switch-thumb: #ddd; + --satus-tooltip: rgba(var(--satus-contrast),.4); + --satus-sortable-ghost: rgba(var(--satus-contrast), .8); + --satus-sortable-background: rgba(var(--satus-contrast), .1); + --satus-sortable-text: #fff; + --satus-divider: rgba(var(--satus-contrast),.08); + --satus-tabs-background: #111; + --satus-tabs-foreground: #2e2e2e; + --satus-tabs-border: #2f2f2f; + --satus-checkbox--background: rgb(var(--satus-contrast), .08); + --satus-checkbox--border: #2f2f2f; + --satus-checkbox--mark: #fff; + --satus-alert-error-background: #501616; + --satus-alert-error-border: #6f1f1f; + --satus-alert-error-color: #cf7777; +} +/*-------------------------------------------------------------- +>>> ELEMENTS: +---------------------------------------------------------------- +# Reset +# Attributes + # Hidden +--------------------------------------------------------------*/ + +/*-------------------------------------------------------------- +# RESET +--------------------------------------------------------------*/ + +:where([class^=satus]:not(iframe, canvas, img, svg, video, svg *, symbol *)) { + display: revert; + all: unset; +} + +:where([class^=satus]:not(iframe, canvas, img, svg, video, svg *, symbol *)) { + box-sizing: border-box; +} + + +/*-------------------------------------------------------------- +# ATTRIBUTES +--------------------------------------------------------------*/ + +/*-------------------------------------------------------------- +# HIDDEN +--------------------------------------------------------------*/ + +[class^=satus][hidden] { + display: none; +} +/*-------------------------------------------------------------- +>>> PLUVIAM +--------------------------------------------------------------*/ + +.satus-pluviam { + position: absolute; + transform: scale(0); + animation-name: pluviam; + animation-duration: 1000ms; + opacity: var(--satus-pluviam-opacity, .08); + border-radius: 50%; + background: var(--satus-pluviam-background, #000); + animation-fill-mode: forwards; +} + +@keyframes pluviam { + 0% { + transform: scale(0); + opacity: var(--satus-pluviam-opacity, .08); + } + 70% { + transform: scale(.8); + opacity: var(--satus-pluviam-opacity, .08); + } + 100% { + transform: scale(1); + opacity: 0; + } +} +/*-------------------------------------------------------------- +>>> SORTABLE +--------------------------------------------------------------*/ + +.satus-sortable__chosen { + color: var(--satus-sortable-text) !important; + background-color: var(--satus-sortable-background) !important; +} + +.satus-sortable__ghost { + position: fixed !important; + z-index: 999 !important; + top: 0 !important; + left: 0 !important; + pointer-events: none !important; + box-shadow: 0 1px 3px rgb(0, 0, 0, .2), 0 4px 8px rgb(0, 0, 0, .1), inset 0 0 0 1px rgb(0, 0, 0, .16); + will-change: transform !important; + opacity: .8 !important; +} +/*-------------------------------------------------------------- +>>> CONTEXT MENU +--------------------------------------------------------------*/ + +.satus-modal--contextmenu .satus-modal__scrim { + background: none; + backdrop-filter: none; + animation: none; + visibility: visible; + opacity: 1; + transform: none; +} + +.satus-modal--contextmenu .satus-modal__surface { + position: absolute; + margin: 0; + box-sizing: border-box; + min-width: 200px; + max-width: 200px; + padding: 4px 0; + border-radius: 4px; + box-shadow: none; + animation: none; + visibility: visible; + opacity: 1; + transform: none; +} + +.satus-modal--contextmenu .satus-modal__surface > * { + +} + +.satus-modal--contextmenu .satus-modal__surface>* { + display: flex; + height: 32px; + padding: 0 16px; + align-items: center; +} + +.satus-modal--contextmenu .satus-modal__surface .satus-button svg { + width: 20px; + height: 18px; + margin: 0 14px 0 0; + opacity: .75; + fill: none; + stroke: var(--satus-primary); + flex: 0 0 20px; +} + +.satus-modal--contextmenu .satus-modal__surface .satus-button .satus-span { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} +/*-------------------------------------------------------------- +>>> BASE +--------------------------------------------------------------*/ + +.satus-base { + display: flex; + flex-direction: column; + width: 100%; + height: 100% +} +/**/ + +.satus-aside { + color: var(--satus-aside-text); + background: var(--satus-aside-background); + box-sizing: border-box; +} +/*-------------------------------------------------------------- +>>> RADIO +--------------------------------------------------------------*/ +/*-------------------------------------------------------------- +>>> CHECKBOX +--------------------------------------------------------------*/ + +.satus-checkbox { + position: relative; + font: inherit; + display: flex; + color: inherit; + border: none; + background: transparent; + appearance: none; + align-items: center; + justify-content: flex-start; +} + +.satus-checkbox:hover { + cursor: pointer; + background-color: var(--satus-hover); +} + +.satus-checkbox:focus { + outline: none; +} + +.satus-checkbox__content { + display: block; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} + +.satus-checkbox::before { + display: flex; + min-width: 16px; + width: 16px; + height: 16px; + margin: 0 12px 0 0; + content: ''; + border: 1px solid var(--satus-checkbox--border); + border-radius: 6px; + background: var(--satus-checkbox--background); + align-items: center; + justify-content: center; +} + +.satus-checkbox[data-value=true]::before { + background: var(--satus-primary); +} + +.satus-checkbox[data-value=true]::after { + position: absolute; + top: 20px; + left: 20px; + width: 8px; + height: 4px; + content: ''; + transform: rotate(-45deg); + border: 2px solid var(--satus-checkbox--mark); + border-top: none; + border-right: none; +} +/*-------------------------------------------------------------- +>>> SELECT +--------------------------------------------------------------*/ + +.satus-select { + position: relative; + display: flex; + cursor: pointer; + align-items: center; + justify-content: space-between; +} + +.satus-select:hover { + background-color: var(--satus-hover); +} + +.satus-select>span:nth-child(2) { + display: flex; + align-items: center; +} + +.satus-select>span:nth-child(2)>svg { + width: 20px; + height: 18px; + margin: 0 14px 0 0; + opacity: .75; +} + +.satus-select>span:nth-child(3) { + margin-left: 16px; + text-align: right; + opacity: .75; +} + +.satus-select select { + font: inherit; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + margin: 0; + padding: inherit; + opacity: 0; + border: none; + outline: none; + appearance: none; + z-index: 1; +} + +.satus-select option { + color: var(--satus-select-text); + background: var(--satus-select-background); +} +/*-------------------------------------------------------------- +>>> SHORTCUT: +---------------------------------------------------------------- +# +--------------------------------------------------------------*/ + +.satus-shortcut { + justify-content: space-between; +} + +.satus-shortcut__value { + font-size: 11px; + display: flex; + text-transform: uppercase; + align-items: center; +} + +.satus-shortcut__actions { + display: flex; + justify-content: flex-end; +} + +.satus-shortcut__actions .satus-button { + height: 32px; + margin: 8px 4px 0; + border-radius: 8px; + background: rgba(0, 0, 0, .15); +} + +.satus-shortcut__actions .satus-button:hover { + background: rgba(0, 0, 0, .25); +} + +.satus-shortcut__primary { + display: flex; + box-sizing: border-box; + width: 100%; + height: 68px; + padding: 16px; + background: rgba(0, 0, 0, .16); + align-items: center; +} + +.satus-shortcut__key { + display: flex; + box-sizing: border-box; + min-width: 32px; + height: 32px; + padding: 4px 8px; + border-radius: 4px; + background: #fff; + box-shadow: 0 1px 3px rgba(0, 0, 0, .15), inset 0 -3px 0 rgba(0, 0, 0, .1); + align-items: center; + justify-content: center; +} + +.satus-shortcut__value>.satus-shortcut__key { + font-size: 14px; + min-width: 24px; + height: 24px; +} + +.satus-shortcut__plus { + position: relative; + width: 12px; + height: 12px; + margin: 8px; +} + +.satus-shortcut__plus::before { + position: absolute; + top: 0; + left: 5px; + width: 2px; + height: 12px; + content: ''; + background-color: #aaa; +} + +.satus-shortcut__plus::after { + position: absolute; + top: 5px; + left: 0; + width: 12px; + height: 2px; + content: ''; + background-color: #aaa; +} + +.satus-shortcut__mouse { + position: relative; + display: flex; + width: 28px; + height: 36px; + border-radius: 50%; + border-top-left-radius: 12px; + border-top-right-radius: 12px; + background: #fff; + box-shadow: 0 1px 3px rgba(0, 0, 0, .15), inset 0 -3px 0 rgba(0, 0, 0, .1); +} + +.satus-shortcut__value>.satus-shortcut__mouse { + width: 22px; + height: 28px; +} + +.satus-shortcut__mouse>div { + position: absolute; + top: 0; + left: calc(50% - 1px); + width: 2px; + height: 11px; + border-radius: 2px; + background: #ccc; +} + +.satus-shortcut__mouse::before { + position: absolute; + top: -16%; + right: 14%; + width: 2px; + height: 60%; + content: ''; + background: #f96754; +} + +.satus-shortcut__mouse.false::before { + top: -6%; +} + +.satus-shortcut__mouse.false::after { + position: absolute; + top: -20%; + right: calc(14% - 4px); + width: 0; + height: 0; + content: ''; + border-right: 5px solid transparent; + border-bottom: 8px solid #f96754; + border-left: 5px solid transparent; +} + +.satus-shortcut__mouse.true::after { + position: absolute; + top: 40%; + right: calc(14% - 4px); + width: 0; + height: 0; + content: ''; + border-top: 8px solid #f96754; + border-right: 5px solid transparent; + border-left: 5px solid transparent; +} + +.satus-shortcut__mouse.click::before { + position: absolute; + top: 0; + left: -1px; + width: 10px; + height: 10px; + content: ''; + border-radius: 50%; + background: #f96754; +} + +.satus-shortcut__mouse.middle::before { + position: absolute; + top: 0; + left: 50%; + width: 10px; + height: 10px; + content: ''; + border-radius: 50%; + background: #f96754; + z-index: 1; + transform: translateX(-50%); +} + +.satus-shortcut__mouse.context::before { + position: absolute; + top: 0; + left: 15px; + width: 10px; + height: 10px; + content: ''; + border-radius: 50%; + background: #f96754; +} + +.satus-section_shortcut { + width: 100%; + margin: 8px 0 0; + justify-content: flex-end; +} + +.satus-button_shortcut { + font-weight: 500; + overflow: hidden; + height: 28px; + min-height: 28px; + margin-right: 2px; + padding: 4px 8px; + text-transform: uppercase; + color: #f96754; + border-radius: 4px; +} +/*-------------------------------------------------------------- +>>> SWITCH +---------------------------------------------------------------- +# Container +# Track +# Thumb +--------------------------------------------------------------*/ + + +/*-------------------------------------------------------------- +# CONTAINER +--------------------------------------------------------------*/ + +.satus-switch { + font: inherit; + display: flex; + transition: background-color 75ms; + color: inherit; + border: none; + outline: none; + background-color: transparent; + justify-content: space-between; + align-items: center; +} + +.satus-switch:hover { + cursor: pointer; +} + +.satus-switch__content { + display: flex; + align-items: center; +} + +.satus-switch__content>svg { + width: 20px; + height: 18px; + margin: 0 14px 0 0; + opacity: .75; +} + + +/*-------------------------------------------------------------- +# TRACK +--------------------------------------------------------------*/ + +.satus-switch>i { + width: 32px; + height: 18px; + transition: background-color 150ms; + border-radius: 18px; + background-color: var(--satus-switch-track); + flex: 0 0 32px; +} + +.satus-section--card .satus-switch>i { + margin-left: 16px; +} + +.satus-switch[data-value='true']>i { + background-color: var(--satus-switch-track--active); +} + + +/*-------------------------------------------------------------- +# THUMB +--------------------------------------------------------------*/ + +.satus-switch>i::before { + display: block; + width: 14px; + height: 14px; + margin: 2px; + content: ''; + transition: transform 150ms cubic-bezier(.4, 0, .2, 1); + border-radius: 50%; + background-color: var(--satus-switch-thumb); + will-change: transform; +} + +.satus-switch[data-value='true']>i::before { + transform: translateX(14px); +} +/*-------------------------------------------------------------- +>>> LAYERS +--------------------------------------------------------------*/ + +.satus-layers { + position: relative; + overflow: hidden; + color: var(--satus-layers-text); + background: var(--satus-layers-background); + flex: 1; +} + +.satus-layer { + position: absolute; + top: 0; + left: 0; + display: flex; + overflow-y: auto; + flex-direction: column; + box-sizing: border-box; + width: 100%; + height: 100%; + padding: 0 12px; + align-content: center; +} +/*-------------------------------------------------------------- +# INPUT +--------------------------------------------------------------*/ + +.satus-input[type=text], +.satus-input[type=password] { + font: inherit; + box-sizing: border-box; + width: 100%; + margin: 0; + padding: 6px 8px; + color: var(--satus-text-field--text, inherit); + border: none; + outline: none; + background: none; + appearance: none; + font-size: 16px; + margin: 8px 0; + border: 1px solid var(--satus-text-field--border); + border-radius: 4px; + background-color: var(--satus-text-field--background); +} +/*-------------------------------------------------------------- +>>> MENUBAR +--------------------------------------------------------------*/ + +.satus-menubar { + display: flex; +} + +.satus-menubar, +.satus-menubar ul { + margin: 0; + padding: 0; + list-style: none; + color: var(--satus-menubar-text); + background: var(--satus-menubar-background); +} + +.satus-menubar li { + position: relative; +} + +.satus-menubar li:focus, +.satus-menubar li:hover { + background: var(--satus-menubar-hover); +} + +.satus-menubar>li ul { + position: absolute; + min-width: 126px; +} + +.satus-menubar>li>ul ul { + top: 0; + left: 100%; +} + +.satus-menubar li>ul { + position: absolute; + display: none; +} + +.satus-menubar li>*:not(ul):focus+ul, +.satus-menubar li>*:not(ul):hover+ul, +.satus-menubar li>ul:hover { + display: block; +} + +.satus-menubar li> :not(ul) { + font-size: 14px; + display: flex; + width: 100%; + height: 32px; + align-items: center; +} +/*-------------------------------------------------------------- +# MAIN +--------------------------------------------------------------*/ + +.satus-main { + color: var(--satus-main-text); + background: var(--satus-main-background); + overflow-y: auto; + box-sizing: border-box; +} +/*-------------------------------------------------------------- +# SCROLLBAR +--------------------------------------------------------------*/ + +::-webkit-scrollbar { + width: 4px; +} + +::-webkit-scrollbar:hover { + width: 8px; +} + +::-webkit-scrollbar-thumb { + background: rgba(var(--satus-contrast), .3); +} +/*-------------------------------------------------------------- +>>> TEXTAREA +--------------------------------------------------------------*/ + +.satus-textarea { + position: relative; + display: flex; + overflow: hidden; + color: var(--satus-textarea-color, inherit); + background: var(--satus-textarea-background); +} + +.satus-textarea textarea { + font-size: inherit; + line-height: 1.2; + overflow: auto; + width: 100%; + height: 100%; + padding: 0; + resize: none; + white-space: pre; + word-break: break-all; + color: inherit; + border: none; + outline: none; + background: transparent; + overflow-wrap: normal; +} + +.satus-textarea__line-number { + padding: 0 16px 0 8px; + opacity: .5; +} + +.satus-textarea__line-number>span { + font-size: inherit; + line-height: 1.2; + display: block; + width: 100%; + text-align: right; +} +/*-------------------------------------------------------------- +>>> DIVIDER +--------------------------------------------------------------*/ + +.satus-divider { + height: 1px; + margin: 16px 0 12px; + background: var(--satus-divider); +} +/*-------------------------------------------------------------- +>>> TEXT FIELD +--------------------------------------------------------------*/ + +.satus-text-field { + position: relative; + padding: 0 16px; + background-color: var(--satus-text-field--background); + border-radius: 8px; + color: var(--satus-text-field--text); + overflow: hidden; + display: flex; +} + +.satus-text-field__pre { + display: flex; + position: relative; + height: 100%; + margin: 0; + padding: 0; + overflow: hidden; + align-items: center; + flex: 1; +} + +.satus-text-field__input { + font: inherit; + position: absolute; + top: 0; + left: 0; + width: 100%; + min-width: 0; + max-width: none; + height: 100%; + min-height: 0; + max-height: none; + margin: 0; + padding: 0; + opacity: 0; + border: none; + appearance: none; + z-index: 9; +} + +.satus-text-field__hidden-text { + position: absolute; + pointer-events: none; + opacity: 0; +} + +.satus-text-field__text { + position: absolute; + top: 0; + left: 0; + display: flex; + height: 100%; + margin: 0; + align-items: center; +} + +.satus-text-field__cursor { + position: absolute; + top: 6px; + left: 0; + display: none; + width: 2px; + height: 25px; + animation: blink 1s step-end 8; + background: #fa0; +} + +.satus-text-field__selection { + position: absolute; + top: 5px; + left: 0; + display: none; + width: 0; + height: 25px; + border: 1px solid rgba(255, 255, 255, .2); + border-radius: 3px; + background: rgba(255, 255, 255, .1); +} + +.satus-text-field__input:focus + * + * + * + .satus-text-field__cursor, +.satus-text-field__selection:not([disabled]) { + display: block; +} + +@keyframes blink { + from, + to { + opacity: 1; + } + 50% { + opacity: 0; + } +} + + +/*-------------------------------------------------------------- +# SYNTAX HIGHLIGHTING +--------------------------------------------------------------*/ + +.satus-text-field__text>.group { + color: #47ff47; + background-color: rgb(71, 255, 71, .16); +} + +.satus-text-field__text>.character-class { + color: #ffc247; + background-color: rgb(255, 170, 0, .16); +} + +.satus-text-field__text>.quantifier { + color: #47c2ff; + background-color: rgb(71, 194, 255, .16); +} + +.satus-text-field__text>.anchor { + color: #47c2ff; + background-color: rgb(71, 194, 255, .16); +} + +.satus-text-field__text>.metasequence { + color: #47ff47; + background-color: rgb(71, 255, 71, .16); +} + +.satus-text-field__text>.text { + color: #c4c4d4; + background-color: rgb(196, 196, 212, .16); +} +/*-------------------------------------------------------------- +>>> TABS +--------------------------------------------------------------*/ + +.satus-tabs { + display: flex; + height: 26px !important; +} + +.satus-tabs__content { + position: relative; + overflow: hidden; + width: 100%; + height: 100%; + border: 2px solid var(--satus-tabs-background); + border-radius: 4px; + background: var(--satus-tabs-background); + display: flex; +} + +.satus-tabs__selection { + position: absolute; + z-index: 0; + top: 0; + left: 0; + height: 100%; + transition: left .25s; + border-radius: 4px; + background: var(--satus-tabs-foreground); + box-sizing: border-box; + border: 1px solid var(--satus-tabs-border); +} + +.satus-tabs__button { + font: inherit; + position: relative; + z-index: 1; + overflow: hidden; + height: 100%; + padding: 0 4px; + white-space: nowrap; + text-overflow: ellipsis; + color: inherit; + border: none; + background: transparent; + flex: 1; + text-align: center; +} + +.satus-tabs__button:hover { + cursor: pointer; +} +/*-------------------------------------------------------------- +>>> ALERT +--------------------------------------------------------------*/ + +.satus-alert { + display: flex; + box-sizing: border-box; + min-height: 48px; + margin: 8px 0 0; + padding: 8px 16px; + border-radius: 8px; + align-items: center; +} + +.satus-alert--error { + color: var(--satus-alert-error-color); + border: 1px solid var(--satus-alert-error-border); + background: var(--satus-alert-error-background); +} +/*-------------------------------------------------------------- +>>> SLIDER +--------------------------------------------------------------*/ + +.satus-slider { + box-sizing: border-box; + width: 100%; + padding: 8px 16px 0; + outline: none; +} + +.satus-slider__container { + position: relative; + display: block; + width: 100%; + height: 32px; +} + +.satus-slider__track { + position: absolute; + top: 50%; + left: 0; + width: 100%; + height: 2px; + transform: translateY(-50%); +} + +.satus-slider__track::before { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + content: ''; + opacity: .24; + background: var(--satus-primary); +} + +.satus-slider__handle:focus::after { + position: absolute; + top: -2px; + left: 50%; + display: block; + padding: 1px 4px; + content: attr(data-value); + transform: translate(-50%, -100%); + color: #fff; + border-radius: 4px; + background: var(--satus-primary); +} + +.satus-slider__track-fill { + position: absolute; + top: 0; + left: 0; + height: 100%; + background: var(--satus-primary); +} + +.satus-slider__handle { + position: absolute; + top: 50%; + left: 0; + width: 10px; + height: 10px; + transform: translate(-50%, -50%); + border-radius: 50%; + background: var(--satus-primary); +} + +.satus-slider__handle::before { + position: absolute; + top: 50%; + left: 50%; + width: 1px; + height: 1px; + content: ''; + transition: .2s; + transform: translate(-50%, -50%) scale(1); + opacity: 0; + border-radius: 50%; + background: var(--satus-primary); +} + +.satus-slider:focus .satus-slider__handle::before { + transform: translate(-50%, -50%) scale(26); + opacity: .24; +} +/*-------------------------------------------------------------- +>>> COLOR PICKER: +---------------------------------------------------------------- +# Button +# Modal +--------------------------------------------------------------*/ + + +/*-------------------------------------------------------------- +# BUTTON +--------------------------------------------------------------*/ + +.satus-color-picker { + font-size: inherit; + position: relative; + display: flex; + box-sizing: border-box; + margin: 0; + cursor: pointer; + color: inherit; + border: none; + outline: none; + background-color: var(--satus-theme-button); + justify-content: space-between; + -webkit-tap-highlight-color: transparent; + align-items: center; + -webkit-appearance: none; +} + +.satus-color-picker__value { + width: 22px; + height: 22px; + border: 2px solid rgba(0, 0, 0, .16); + border-radius: 50%; + background: #fff; +} + + +/*-------------------------------------------------------------- +# MODAL +--------------------------------------------------------------*/ + +.satus-modal--color-picker { + position: relative; +} + +.satus-modal--color-picker .satus-modal__surface { + padding-top: 0; +} + +.satus-color-picker__palette { + position: relative; + overflow: hidden; + width: 100%; + height: 256px; + background-color: #f00; +} + +.satus-color-picker__palette:before { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + content: ''; + background-image: linear-gradient(0deg, black, transparent), linear-gradient(90deg, white, transparent); +} + +.satus-color-picker__cursor { + position: absolute; + width: 5px; + height: 5px; + transform: translate(-50%, -50%); + pointer-events: none; + border: 1px solid #fff; + border-radius: 50%; + box-shadow: 0 0 0 1px #000; +} + +.satus-modal--color-picker .satus-modal__surface .satus-section--color { + margin: 8px 16px 0; + align-items: center; +} + +.satus-color-picker__color { + width: 32px; + height: 32px; + margin: 0 16px 0 0; + border: 2px solid rgba(0, 0, 0, .16); + border-radius: 50%; + background: #f00; +} + +.satus-slider.satus-color-picker__hue { + padding: 0; + flex: 1; +} + +.satus-color-picker__hue .satus-slider__track { + height: 16px; + border-radius: 4px; + background-image: linear-gradient(90deg, #f00, #ff2a00, #f50, #ff7f00, #fa0, #ffd400, #ff0, #d4ff00, #af0, #80ff00, #5f0, #2bff00, #0f0, #00ff2b, #0f5, #00ff80, #0fa, #00ffd5, #0ff, #00d4ff, #0af, #007fff, #05f, #002bff, #00f, #2a00ff, #50f, #7f00ff, #a0f, #d400ff, #f0f, #ff00d4, #f0a, #ff0080, #f05, #ff002b, #f00); +} + +.satus-color-picker__hue .satus-slider__handle { + width: 16px; + height: 16px; + background: #fff; + box-shadow: 0 0 4px rgb(0, 0, 0, .64); +} + +.satus-color-picker__hue::before, +.satus-color-picker__hue .satus-slider__track-fill, +.satus-color-picker__hue .satus-slider__handle:focus::after { + display: none; +} +/*-------------------------------------------------------------- +>>> SECTION: +---------------------------------------------------------------- +# Align +# Card +--------------------------------------------------------------*/ + +.satus-section { + display: flex; + box-sizing: border-box; + flex-wrap: wrap; +} + + +/*-------------------------------------------------------------- +# ALIGN +--------------------------------------------------------------*/ + +.satus-section--align-start { + align-items: center; + justify-content: flex-start; +} + +.satus-section--align-end { + align-items: center; + justify-content: flex-end; +} + +.satus-section--space-between { + align-items: center; + justify-content: space-between; +} + +.satus-section--column { + flex-direction: column; +} + + +/*-------------------------------------------------------------- +# CARD +--------------------------------------------------------------*/ + +.satus-section--card { + flex-direction: column; + box-sizing: border-box; + width: 100%; + max-width: 900px; + margin: 8px auto; + padding: 8px 0; + color: var(--satus-section-card-text); + border: 1px solid var(--satus-section-card-border); + border-radius: 8px; + background: var(--satus-section-card-background); + justify-content: stretch; +} + +.satus-section--label { + width: 100%; + max-width: 900px; + margin: 8px auto; +} + +.satus-section--card>*:not(.satus-button) { + box-sizing: border-box; + min-height: 48px; + padding: 0 16px; + text-align: left; +} + +.satus-section--card>.satus-switch, +.satus-section--card>.satus-select, +.satus-section--card>.satus-radio { + display: flex; + justify-content: space-between; + align-items: center; +} + +.satus-section--card>.satus-button:hover, +.satus-section--card>.satus-switch:hover, +.satus-section--card>.satus-select:hover, +.satus-section--card>.satus-slider:hover, +.satus-section--card>.satus-radio:hover { + background-color: var(--satus-hover); +} + +.satus-section--card>.satus-button { + width: 100%; + padding: 0 16px; +} + +.satus-section--card>.satus-button>svg { + width: 20px; + margin: 2px 16px 0 0; + color: var(--satus-primary); +} + +.satus-section--card>.satus-span { + display: flex; + align-items: center; +} +/*-------------------------------------------------------------- +>>> LIST: +--------------------------------------------------------------*/ + +.satus-list { + list-style: none; + margin: 0; +} + +.satus-list__item { + display: flex; + align-items: center; + justify-content: space-between; + min-height: 48px; +} + +.satus-list__item>*:last-child { + text-align: right; +} +/*-------------------------------------------------------------- +>>> HEADER +--------------------------------------------------------------*/ + +.satus-header { + z-index: 1; + display: flex; + box-sizing: border-box; + height: 56px; + padding: 0 12px; + color: var(--satus-header-text); + background: var(--satus-header-background); + border-bottom: 1px solid var(--satus-header-border); + box-shadow: 0 0 3px rgb(0, 0, 0, .1); + align-items: center; + justify-content: space-between; +} + +.satus-header .satus-button { + width: 40px; + min-width: 40px; + height: 40px; + padding: 8px; + color: inherit; + border-radius: 50%; +} + +.satus-header .satus-section--align-start>* { + margin-right: 8px; +} + +.satus-header .satus-span--title { + font-size: 15px; + font-weight: 500; + overflow: hidden; + white-space: nowrap; + letter-spacing: .0125em; + text-overflow: ellipsis; + flex: 1; +} +/*-------------------------------------------------------------- +# BUTTON +--------------------------------------------------------------*/ + +.satus-button { + font: inherit; + position: relative; + display: flex; + overflow: hidden; + height: 48px; + margin: 0; + padding: 8px; + text-align: left; + color: var(--satus-button-text, inherit); + border: none; + background: var(--satus-button-background, transparent); + appearance: none; + align-items: center; +} + +.satus-button:hover { + cursor: pointer; + background-color: var(--satus-hover); +} + +.satus-button[hidden] { + display: none; +} + +.satus-button>svg { + min-width: 20px; +} + +.satus-button>.satus-span--label { + display: block; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} +/*-------------------------------------------------------------- +>>> MODAL +--------------------------------------------------------------*/ + +.satus-modal { + position: absolute; + z-index: 100; + top: 0; + left: 0; + display: flex; + width: 100%; + height: 100vh; + justify-content: center; + align-items: center; +} + +.satus-modal__scrim { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + animation: modalFadeIn 150ms linear forwards; + opacity: 0; + background: rgba(0, 0, 0, .16); + backdrop-filter: blur(8px); +} + +.satus-modal__surface { + display: flex; + overflow-y: auto; + flex-direction: column; + width: 95%; + min-width: 240px; + max-width: 560px; + max-height: 80%; + margin: 0 16px; + padding: 12px 16px; + transform: scale(.8); + animation: modalZoomIn 150ms linear forwards; + animation-delay: 20ms; + opacity: 0; + color: var(--satus-modal-text); + border-radius: 6px; + background-color: var(--satus-modal-background); + border: 1px solid var(--satus-modal-border); + box-shadow: 0 2px 6px rgb(0, 0, 0, .15); + box-sizing: border-box; +} + +.satus-modal__surface .satus-section--actions { + display: flex; + width: 100%; + margin: 8px 0 0; + padding: 0; + justify-content: flex-end; + align-items: center; +} + +.satus-modal__surface .satus-section--actions .satus-button { + font-weight: 500; + height: 32px; + margin-left: 8px; + padding: 0 8px; + letter-spacing: .5px; + color: var(--satus-primary); + border-radius: 4px; +} + +.satus-modal__surface .satus-section--actions .satus-button:hover { + background: rgba(var(--satus-contrast), .075); +} + +.satus-modal--closing .satus-modal__scrim { + animation: modalFadeOut 70ms linear forwards; +} + +.satus-modal--closing .satus-modal__surface { + animation: modalZoomOut 70ms linear forwards; +} + +.satus-modal--vertical .satus-modal__surface { + position: absolute; + top: 8px; + right: 8px; + left: auto; + min-width: 200px; + max-width: 200px; + margin: 0; + padding: 8px 0; + transform-origin: right top; +} + +.satus-modal--vertical .satus-modal__surface>.satus-button, +.satus-modal--vertical .satus-modal__surface>.satus-switch, +.satus-modal--vertical .satus-modal__surface>.satus-select { + height: 36px; + padding: 0 16px; +} + +.satus-modal--vertical .satus-modal__surface>.satus-tabs { + padding: 0 12px; +} + +.satus-modal--vertical .satus-modal__surface>.satus-span { + font-size: 13px; + font-weight: 500; + margin: 6px 0; + padding: 0 12px; +} + +.satus-modal--vertical .satus-modal__surface>.satus-button:hover, +.satus-modal--vertical .satus-modal__surface>.satus-switch:hover, +.satus-modal--vertical .satus-modal__surface>.satus-select:hover { + background-color: var(--satus-hover); +} + +.satus-modal--vertical .satus-button svg { + width: 20px; + height: 18px; + margin: 0 14px 0 0; + opacity: .75; + flex: 0 0 20px; +} + +.satus-modal--vertical .satus-button .satus-span { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + + +/*-------------------------------------------------------------- +# ANIMATIONS +--------------------------------------------------------------*/ + +@keyframes modalFadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +@keyframes modalFadeOut { + from { + opacity: 1; + } + to { + opacity: 0; + } +} + +@keyframes modalZoomIn { + from { + transform: scale(.8); + opacity: 0; + } + to { + transform: scale(1); + opacity: 1; + } +} + +@keyframes modalZoomOut { + from { + transform: scale(1); + opacity: 1; + } + to { + transform: scale(.8); + opacity: 0; + } +} \ No newline at end of file diff --git a/ui/satus/satus.js b/ui/satus/satus.js new file mode 100644 index 0000000..8ec0e8a --- /dev/null +++ b/ui/satus/satus.js @@ -0,0 +1,3226 @@ + +/*-------------------------------------------------------------- +>>> CORE: +---------------------------------------------------------------- +# Global variable +# Functions +# Render +--------------------------------------------------------------*/ + +/*-------------------------------------------------------------- +# GLOBAL VARIABLE +--------------------------------------------------------------*/ + +var satus = { + components: {}, + events: {}, + locale: { + strings: {} + }, + storage: { + attributes: {}, + data: {} + } +}; + + +/*-------------------------------------------------------------- +# FUNCTIONS +--------------------------------------------------------------*/ + +/*-------------------------------------------------------------- +# APPEND +--------------------------------------------------------------*/ + +satus.append = function (element, container) { + (container || document.body).appendChild(element); +}; + + +/*-------------------------------------------------------------- +# ANIMATION DURATION +--------------------------------------------------------------*/ + +satus.getAnimationDuration = function (element) { + return Number(window.getComputedStyle(element).getPropertyValue('animation-duration').replace(/[^0-9.]/g, '')) * 1000; +}; + + +/*-------------------------------------------------------------- +# APPEND +--------------------------------------------------------------*/ + +satus.attr = function (element, attributes) { + if (attributes) { + for (var key in attributes) { + if (element.is_svg) { + element.setAttributeNS(null, key, attributes[key]); + } else { + var value = attributes[key]; + + if (['placeholder', 'title'].indexOf(key) !== -1) { + value = satus.locale.get(value); + } + + element.setAttribute(key, value); + } + } + } +}; + +satus.elementIndex = function (element) { + return Array.prototype.slice.call(element.parentNode.children).indexOf(element); +}; + + +/*-------------------------------------------------------------- +# DATA +--------------------------------------------------------------*/ + +satus.data = function (element, data) { + if (data) { + for (var key in data) { + element.dataset[key] = data[key]; + } + } +}; + + +/*-------------------------------------------------------------- +# PROPERTIES +--------------------------------------------------------------*/ + +satus.properties = function (element, properties) { + if (properties) { + for (var key in properties) { + element[key] = properties[key]; + } + } +}; + + +/*-------------------------------------------------------------- +# CAMELIZE +--------------------------------------------------------------*/ + +satus.camelize = function (string) { + var result = ''; + + for (var i = 0, l = string.length; i < l; i++) { + var character = string[i]; + + if (character === '-') { + i++; + + result += string[i].toUpperCase(); + } else { + result += character; + } + } + + return result; +}; + + +/*-------------------------------------------------------------- +# SNAKELIZE +--------------------------------------------------------------*/ + +satus.snakelize = function (string) { + return string.replace(/([A-Z])/g, '-$1').toLowerCase(); +}; + + +/*-------------------------------------------------------------- +# CLASS +--------------------------------------------------------------*/ + +satus.class = function (element, string) { + if (string) { + element.className += ' ' + string; + } +}; + + +/*-------------------------------------------------------------- +# EMPTY +--------------------------------------------------------------*/ + +satus.empty = function (element, exclude = []) { + for (var i = element.childNodes.length - 1; i > -1; i--) { + var child = element.childNodes[i]; + + if (exclude.indexOf(child) === -1) { + child.remove(); + } + } +}; + + +/*-------------------------------------------------------------- +# EVENTS +--------------------------------------------------------------*/ + +Object.defineProperty(satus.events, 'add', { + value: function (type, listener) { + if (this.hasOwnProperty(type) === false) { + this[type] = []; + } + + this[type].push(listener); + } +}); + + +/*-------------------------------------------------------------- +# ISSET +--------------------------------------------------------------*/ + +satus.isset = function (variable) { + if (variable === null || variable === undefined) { + return false; + } + + return true; +}; + + +/*-------------------------------------------------------------- +# FETCH +--------------------------------------------------------------*/ + +satus.fetch = function (url, success, error) { + fetch(url).then(function (response) { + if (response.ok) { + response.json().then(success); + } else { + error(); + } + }).catch(function () { + error(success); + }); +}; + + +/*-------------------------------------------------------------- +# AJAX +--------------------------------------------------------------*/ + +satus.ajax = function (url, success, error) { + var xhr = new XMLHttpRequest(); + + xhr.onload = function () { + success(this.response); + }; + xhr.onerror = function () { + error(success); + }; + + xhr.open('GET', url, true); + xhr.send(); +}; + + +/*-------------------------------------------------------------- +# STORAGE +--------------------------------------------------------------*/ + +/*-------------------------------------------------------------- +# GET +--------------------------------------------------------------*/ + +satus.storage.get = function (name) { + var target = satus.storage.data; + + if (typeof name !== 'string') { + return; + } + + name = name.split('/').filter(function (value) { + return value != ''; + }); + + for (var i = 0, l = name.length; i < l; i++) { + if (satus.isset(target[name[i]])) { + target = target[name[i]]; + } else { + return undefined; + } + } + + return target; +}; + + +/*-------------------------------------------------------------- +# SET +--------------------------------------------------------------*/ + +satus.storage.set = function (name, value, callback) { + var items = {}, + target = satus.storage.data; + + if (typeof name !== 'string') { + return; + } + + name = name.split('/').filter(function (value) { + return value != ''; + }); + + for (var i = 0, l = name.length; i < l; i++) { + var item = name[i]; + + if (i < l - 1) { + + if (target[item]) { + target = target[item]; + } else { + target[item] = {}; + + target = target[item]; + } + } else { + target[item] = value; + } + } + + for (var key in this.data) { + if (typeof this.data[key] !== 'function') { + items[key] = this.data[key]; + } + } + + if (satus.storage.attributes[name]) { + document.body.setAttribute('data-' + name, value); + } + + chrome.storage.local.set(items, callback); +}; + + +/*-------------------------------------------------------------- +# REMOVE +--------------------------------------------------------------*/ + +satus.storage.remove = function (name) { + delete this.data[name]; + + chrome.storage.local.remove(name); +}; + + +/*-------------------------------------------------------------- +# IMPORT +--------------------------------------------------------------*/ + +satus.storage.import = function (keys, callback) { + if (typeof keys === 'function') { + callback = keys; + + keys = undefined; + } + + chrome.storage.local.get(keys, function (items) { + for (var key in items) { + if (satus.storage.attributes[key]) { + document.body.setAttribute('data-' + key, items[key]); + } + + satus.storage.data[key] = items[key]; + } + + if (callback) { + callback(items); + } + }); +}; + + +/*-------------------------------------------------------------- +# CLEAR +--------------------------------------------------------------*/ + +satus.storage.clear = function (callback) { + this.data = {}; + + chrome.storage.local.clear(callback); +}; + + +/*-------------------------------------------------------------- +# LOCALIZATION +--------------------------------------------------------------*/ + +/*-------------------------------------------------------------- +# GET +--------------------------------------------------------------*/ + +satus.locale.get = function (string) { + return this.strings[string] || string; +}; + + +/*-------------------------------------------------------------- +# IMPORT +--------------------------------------------------------------*/ + +satus.locale.import = function (code, path, callback) { + var language = code || window.navigator.language; + + if (language.indexOf('en') === 0) { + language = 'en'; + } + + if (!path) { + path = '_locales/'; + } + + satus.fetch(chrome.runtime.getURL(path + language + '/messages.json'), function (response) { + for (var key in response) { + satus.locale.strings[key] = response[key].message; + } + + callback(); + }, function (success) { + satus.fetch(chrome.runtime.getURL(path + 'en/messages.json'), success, function () { + success(); + }); + }); +}; + + +/*-------------------------------------------------------------- +# ON +--------------------------------------------------------------*/ + +satus.on = function (element, events) { + if (this.isset(events) && typeof events === 'object') { + for (var selector in events) { + var type = typeof events[selector]; + + if (selector === 'selectionchange') { + element = document; + } + + if (type === 'function') { + element.addEventListener(selector, events[selector]); + } else if (type === 'object') { + element.addEventListener(selector, function (event) { + this.skeleton.on[event.type].parent = this.skeleton; + + if (this.skeleton.on[event.type].component !== 'modal' && this.base && this.base.layers) { + this.base.layers.open(this.skeleton.on[event.type]); + } else { + satus.render(this.skeleton.on[event.type], this.base); + } + }); + } else if (type === 'string') { + element.addEventListener(selector, function () { + var match = this.skeleton.on[event.type].match(/(["'`].+["'`]|[^.()]+)/g), + target = this.base; + + for (var i = 0, l = match.length; i < l; i++) { + var key = match[i]; + + if (target.skeleton[key]) { + target = target.skeleton[key]; + } else { + if (typeof target[key] === 'function') { + target[key](); + } else { + target = target[key]; + } + } + + if (target.rendered) { + target = target.rendered; + } + } + }); + } + } + } +}; + + +/*-------------------------------------------------------------- +# STYLE +--------------------------------------------------------------*/ + +satus.style = function (component, object) { + for (var key in object) { + component.style[key] = object[key]; + } +}; + + +/*-------------------------------------------------------------- +# SEARCH +--------------------------------------------------------------*/ + +satus.search = function (query, object, callback) { + var elements = ['switch', 'select', 'slider', 'shortcut', 'radio', 'color-picker'], + threads = 0, + results = {}; + + query = query.toLowerCase(); + + function parse(items, parent) { + threads++; + + for (var key in items) { + if (key !== 'rendered' && key !== 'base' && key !== 'parent') { + var item = items[key]; + + if (elements.indexOf(item.component) !== -1 && key.indexOf(query) !== -1) { + results[key] = Object.assign({}, item); + } + + if (typeof item === 'object') { + parse(item, items); + } + } + } + + threads--; + + if (threads === 0) { + callback(results); + } + } + + parse(object); +}; + + +/*-------------------------------------------------------------- +# PARENTS +--------------------------------------------------------------*/ + +satus.parents = function (object, components_only) { + function parse(items, parent) { + for (var key in items) { + if (key !== 'rendered' && key !== 'base' && key !== 'parent') { + var item = items[key]; + + if (components_only !== true || item.component) { + item.parent = items; + } + + if (typeof item === 'object' && item.component !== 'shortcut') { + parse(item, items); + } + } + } + } + + parse(object); +}; + + +/*-------------------------------------------------------------- +# TEXT +--------------------------------------------------------------*/ + +satus.text = function (component, value) { + if (typeof value === 'function') { + value = value(); + } + + if (value) { + component.appendChild(document.createTextNode(this.locale.get(value))); + } +}; + + +/*-------------------------------------------------------------- +# DECRYPTION +--------------------------------------------------------------*/ + +satus.decrypt = async function (text, password) { + var iv = text.slice(0, 24).match(/.{2}/g).map(byte => parseInt(byte, 16)), + algorithm = { + name: 'AES-GCM', + iv: new Uint8Array(iv) + }; + + try { + var data = new TextDecoder().decode(await crypto.subtle.decrypt( + algorithm, + await crypto.subtle.importKey( + 'raw', + await crypto.subtle.digest('SHA-256', new TextEncoder().encode(password)), + algorithm, + false, ['decrypt'] + ), + new Uint8Array(atob(text.slice(24)).match(/[\s\S]/g).map(ch => ch.charCodeAt(0))) + )); + } catch (err) { + return false; + } + + return data; +}; + + +/*-------------------------------------------------------------- +# ENCRYPTION +--------------------------------------------------------------*/ + +satus.encrypt = async function (text, password) { + var iv = crypto.getRandomValues(new Uint8Array(12)), + algorithm = { + name: 'AES-GCM', + iv: iv + }; + + return Array.from(iv).map(b => ('00' + b.toString(16)).slice(-2)).join('') + btoa(Array.from(new Uint8Array(await crypto.subtle.encrypt( + algorithm, + await crypto.subtle.importKey('raw', await crypto.subtle.digest('SHA-256', new TextEncoder().encode(password)), algorithm, false, ['encrypt']), + new TextEncoder().encode(text) + ))).map(byte => String.fromCharCode(byte)).join('')); +}; + + +/*-------------------------------------------------------------- +# IS +--------------------------------------------------------------*/ + +satus.isArray = function (array) { + if (Array.isArray(array)) { + return true; + } else { + return false; + } +}; + +satus.isNumber = function (number) { + if (typeof number === 'number' && isNaN(number) === false) { + return true; + } else { + return false; + } +}; + + +/*-------------------------------------------------------------- +# INDEX OF +--------------------------------------------------------------*/ + +satus.indexOf = function (child, parent) { + var index = 0; + + if (satus.isArray(parent)) { + index = parent.indexOf(child); + } else { + while ((child = child.previousElementSibling)) { + index++; + } + } + + return index; +}; + + +/*-------------------------------------------------------------- +# TO INDEX +--------------------------------------------------------------*/ + +satus.toIndex = function (index, child, parent) { + if (satus.isArray(parent)) { + parent.splice(index, 0, parent.splice(satus.indexOf(child, parent), 1)[0]) + } +}; + + +/*-------------------------------------------------------------- +# CLONE +--------------------------------------------------------------*/ + +satus.clone = function (item) { + var clone = item.cloneNode(true), + parent_css = window.getComputedStyle(item.parentNode), + css = window.getComputedStyle(item), + style = ''; + + for (var i = 0, l = css.length; i < l; i++) { + var property = css[i], + value = css.getPropertyValue(property); + + if (property === 'background-color') { + value = parent_css.getPropertyValue('background-color'); + } + + if (['box-shadow', 'left', 'top', 'bottom', 'right', 'opacity'].indexOf(property) === -1) { + style += property + ':' + value + ';'; + } + } + + + clone.setAttribute('style', style); + + return clone; +}; + + +/*-------------------------------------------------------------- +# REMOVE +--------------------------------------------------------------*/ + +satus.remove = function (child, parent) { + if (satus.isArray(parent)) { + parent.splice(satus.indexOf(child, parent), 1); + } +}; + + +/*-------------------------------------------------------------- +# RENDER +--------------------------------------------------------------*/ + +satus.render = function (skeleton, container, skip, property) { + var component; + + if (skeleton.hasOwnProperty('component') && skip !== true) { + var name = skeleton.component, + camelized_name = this.camelize(name); + + if (skeleton.on && skeleton.on.beforerender) { + skeleton.on.beforerender(skeleton); + } + + if (this.components[camelized_name]) { + component = this.components[camelized_name](skeleton); + + if (this.isset(component.inner) === false) { + component.inner = component; + } + } else if (name === 'svg' || container && container.is_svg) { + component = document.createElementNS('http://www.w3.org/2000/svg', name); + + component.is_svg = true; + + component.inner = component; + } else { + component = document.createElement(skeleton.component); + + component.inner = component; + } + + if (component.inner.hasOwnProperty('base') === false && container) { + component.inner.base = container.base; + } + + if (component.inner.base && name === 'layers') { + component.inner.base.layers = component; + } + + skeleton.rendered = component; + component.skeleton = skeleton; + + component.className = (component.className + ' satus-' + skeleton.component).trim(); + + if (skeleton.variant) { + component.className += ' satus-' + skeleton.component + '--' + skeleton.variant; + } + + this.append(component, container); + + container = component.inner || component; + + this.class(component, skeleton.class); + this.style(component, skeleton.style); + this.attr(component, skeleton.attr); + this.data(component, skeleton.data); + this.properties(component, skeleton.properties); + this.on(component, skeleton.on); + this.text(container, skeleton.text); + + if (component.hasOwnProperty('storage') === false && skeleton.storage !== false) { + component.storage = skeleton.storage || property || false; + } + + if (component.hasOwnProperty('storageValue') === false) { + if (component.storage !== false) { + component.storageValue = satus.storage.get(component.storage); + } + + if (skeleton.hasOwnProperty('value') && component.storageValue === undefined) { + component.storageValue = skeleton.value; + } + } + + component.storageChange = function () { + if (this.storage) { + var key = this.storage; + + if (typeof key === 'function') { + key = key(); + } + + satus.storage.set(key, this.storageValue); + } + + this.dispatchEvent(new CustomEvent('change')); + }; + + component.dispatchEvent(new CustomEvent('render')); + + if (skeleton.autofocus === true) { + component.focus(); + } + + if (this.events.hasOwnProperty('render')) { + for (var i = 0, l = this.events['render'].length; i < l; i++) { + this.events['render'][i](component, skeleton); + } + } + } + + if (!component || component.render_children !== false) { + for (var key in skeleton) { + if (key !== 'parent' && skeleton[key] && skeleton[key].hasOwnProperty('component')) { + skeleton[key].parent = skeleton; + + this.render(skeleton[key], container, false, key); + } + } + } + + return component; +}; +/*-------------------------------------------------------------- +>>> COLOR: +---------------------------------------------------------------- +# RGB to HSL +# HUE to RGB +# HSL to RGB +--------------------------------------------------------------*/ + +satus.color = {}; + + +/*-------------------------------------------------------------- +# RGB TO HSL +--------------------------------------------------------------*/ + +satus.color.rgbToHsl = function (array) { + var r = array[0] / 255, + g = array[1] / 255, + b = array[2] / 255, + min = Math.min(r, g, b), + max = Math.max(r, g, b), + h = 0, + s = 0, + l = (min + max) / 2; + + if (min === max) { + h = 0; + s = 0; + } else { + var delta = max - min; + + s = l <= 0.5 ? delta / (max + min) : delta / (2 - max - min); + + if (max === r) { + h = (g - b) / delta + (g < b ? 6 : 0); + } else if (max === g) { + h = (b - r) / delta + 2; + } else if (max === b) { + h = (r - g) / delta + 4; + } + + h /= 6; + } + + h *= 360; + s *= 100; + l *= 100; + + if (array.length === 3) { + return [h, s, l]; + } else { + return [h, s, l, array[3]]; + } +}; + + +/*-------------------------------------------------------------- +# HUE TO RGB +--------------------------------------------------------------*/ + +satus.color.hueToRgb = function (array) { + var t1 = array[0], + t2 = array[1], + hue = array[2]; + + if (hue < 0) { + hue += 6; + } + + if (hue >= 6) { + hue -= 6; + } + + if (hue < 1) { + return (t2 - t1) * hue + t1; + } else if (hue < 3) { + return t2; + } else if (hue < 4) { + return (t2 - t1) * (4 - hue) + t1; + } else { + return t1; + } +}; + + +/*-------------------------------------------------------------- +# HSL TO RGB +--------------------------------------------------------------*/ + +satus.color.hslToRgb = function (array) { + var h = array[0] / 360, + s = array[1] / 100, + l = array[2] / 100, + r, g, b; + + if (s == 0) { + r = g = b = l; + } else { + var hue2rgb = function hue2rgb(p, q, t) { + if (t < 0) t += 1; + if (t > 1) t -= 1; + if (t < 1 / 6) return p + (q - p) * 6 * t; + if (t < 1 / 2) return q; + if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; + return p; + } + + var q = l < 0.5 ? l * (1 + s) : l + s - l * s; + var p = 2 * l - q; + r = hue2rgb(p, q, h + 1 / 3); + g = hue2rgb(p, q, h); + b = hue2rgb(p, q, h - 1 / 3); + } + + return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; +}; +/*-------------------------------------------------------------- +>>> PLUVIAM +--------------------------------------------------------------*/ + +satus.events.add('render', function (component, skeleton) { + if (skeleton.pluviam === true) { + function createPluviam(event) { + var pluviam = document.createElement('span'), + rect = this.getBoundingClientRect(), + x = event.clientX - rect.left, + y = event.clientY - rect.top, + diameter = Math.sqrt(Math.pow(rect.width * 2, 2) + Math.pow(rect.height * 2, 2)); + + pluviam.className = 'satus-pluviam'; + + pluviam.style.left = x - diameter / 2 + 'px'; + pluviam.style.top = y - diameter / 2 + 'px'; + pluviam.style.width = diameter + 'px'; + pluviam.style.height = diameter + 'px'; + + this.appendChild(pluviam); + + setTimeout(function () { + pluviam.remove(); + }, 1000); + } + + component.addEventListener('mousedown', createPluviam); + component.addEventListener('mouseover', createPluviam); + } +}); +/*-------------------------------------------------------------- +>>> EXTENSION STORAGE +--------------------------------------------------------------*/ +/*-------------------------------------------------------------- +>>> INDEXEDDB: +---------------------------------------------------------------- +# Global variable +# Methods + # Open + # Get + # Get by key + # Set + # Clear + # Delete + # Search +--------------------------------------------------------------*/ + +/*-------------------------------------------------------------- +# GLOBAL VARIABLE +--------------------------------------------------------------*/ + +satus.indexeddb = { + request: null +}; + + +/*-------------------------------------------------------------- +# METHODS +--------------------------------------------------------------*/ + +/*-------------------------------------------------------------- +# OPEN +---------------------------------------------------------------- +satus.indexeddb.open('rootCellar', { + fruits: { + indexes: [ + 'id', + 'name', + 'amount', + ... + ], + keyOptions: { + keyPath: 'id', + autoIncrement: true + } + }, + ... +}, function () { ... }); +--------------------------------------------------------------*/ + +satus.indexeddb.open = function (name, objects, callback) { + var request = indexedDB.open(name); + + request.onerror = function (event) { + callback(); + }; + + request.onblocked = function(event) { + satus.indexeddb.open(callback); + }; + + request.onsuccess = function (event) { + satus.indexeddb.request = this.result; + + callback(); + }; + + request.onupgradeneeded = function (event) { + satus.indexeddb.request = this.result; + + for (var key in objects) { + var object = objects[key]; + + if (!this.result.objectStoreNames.contains(key)) { + var object_store = this.result.createObjectStore(key, object.keyOptions); + + for (var i = 0, l = object.indexes.length; i < l; i++) { + var name = object.indexes[i]; + + object_store.createIndex(name, name); + } + } + } + + this.result.onversionchange = function (event) { + satus.indexeddb.close(); + + satus.indexeddb.open(callback); + }; + }; +}; + + +/*-------------------------------------------------------------- +# GET +---------------------------------------------------------------- +satus.indexeddb.get({ + fruits: { + direction: 'next', + index: 'name', + offset: 0, + limit: 100 + }, + ... +}, function (result) { ... }); +--------------------------------------------------------------*/ + +satus.indexeddb.get = function (items, callback) { + var queue = [], + results = {}; + + for (var key in items) { + var item = items[key]; + + queue.push({ + name: key, + direction: item.direction, + index: item.index, + offset: item.offset + }); + } + + function handle() { + var item = queue[0], + transaction = satus.indexeddb.request.transaction(item.name, 'readonly'), + object_store = transaction.objectStore(item.name), + object_result = [], + offset = item.offset || 0, + limit = item.limit || 100; + + if (item.index) { + object_store = object_store.index(item.index); + } + + results[item.name] = object_result; + + object_store.openCursor(null, item.direction).onsuccess = function(event) { + var cursor = event.target.result; + + if (cursor) { + if (item.offset > 0) { + cursor.advance(item.offset); + + item.offset = 0; + } else if (object_result.length < limit) { + object_result.push(cursor.value); + + cursor.continue(); + } + } else { + object_store.count().onsuccess = function(event) { + object_result.fullLength = event.target.result; + + queue.shift(); + + if (queue.length === 0) { + callback(results); + } else { + handle(); + } + }; + } + }; + } + + handle(); +}; + + +/*-------------------------------------------------------------- +# GET BY KEY +---------------------------------------------------------------- +satus.indexeddb.getByKey({ + fruits: [1], + ... +}, function (result) { ... }); +--------------------------------------------------------------*/ + +satus.indexeddb.getByKey = function (items, callback) { + var queue = [], + results = {}; + + for (var name in items) { + queue.push({ + name: name, + keys: items[name] + }); + } + + function handle() { + var item = queue[0], + transaction = satus.indexeddb.request.transaction(item.name, 'readonly'), + object_store = transaction.objectStore(item.name), + object_result = []; + + results[item.name] = object_result; + + for (var i = 0, l = item.keys.length; i < l; i++) { + var key = item.keys[i]; + + object_store.get(key).onsuccess = function(event) { + var result = event.target.result; + + if (result) { + object_result.push(result); + } + + object_store.count().onsuccess = function(event) { + object_result.fullLength = event.target.result; + + queue.shift(); + + if (queue.length === 0) { + callback(results); + } else { + handle(); + } + }; + }; + } + } + + handle(); +}; + + +/*-------------------------------------------------------------- +# SET +---------------------------------------------------------------- +satus.indexeddb.set({ + fruits: [ + { name: 'apple', amount: 500 }, + ... + ], + ... +}, function () { ... }); +--------------------------------------------------------------*/ + +satus.indexeddb.set = function (items, callback) { + var threads = 0; + + for (var name in items) { + var item = items[name], + transaction = this.request.transaction(name, 'readwrite'), + object_store = transaction.objectStore(name); + + for (var i = 0, l = item.length; i < l; i++) { + var request = object_store.put(item[i]); + + threads++; + + request.onsuccess = function () { + threads--; + + if (callback && threads === 0) { + callback(); + } + }; + + request.onerror = function () { + threads--; + + if (callback && threads === 0) { + callback(); + } + }; + } + } +}; + + +/*-------------------------------------------------------------- +# CLEAR +---------------------------------------------------------------- +satus.indexeddb.clear(['fruits'], function (result) { ... }); +--------------------------------------------------------------*/ + +satus.indexeddb.clear = function (items) { + if (typeof items === 'string') { + items = [items]; + } + + for (var i = 0, l = items.length; i < l; i++) { + var name = items[i], + transaction = satus.indexeddb.request.transaction(name, 'readwrite'), + object_store = transaction.objectStore(name); + + object_store.clear(); + } +}; + + +/*-------------------------------------------------------------- +# DELETE +---------------------------------------------------------------- +satus.indexeddb.delete({ + fruits: { + name: [ + 'apple' + ] + } +}); +--------------------------------------------------------------*/ + +satus.indexeddb.delete = function (stores, callback) { + var queue = []; + + for (var name in stores) { + var store = stores[name]; + + for (var index in store) { + queue.push({ + object_store_name: name, + index_name: index, + keys: store[index] + }); + } + } + + function handle() { + var item = queue[0], + transaction = satus.indexeddb.request.transaction(item.object_store_name, 'readwrite'), + object_store = transaction.objectStore(item.object_store_name), + object_result = []; + + if (item.index_name) { + object_store = object_store.index(item.index_name); + } + + object_store.openCursor(null, item.direction).onsuccess = function(event) { + var cursor = event.target.result; + + if (cursor) { + cursor.delete(); + } + + queue.shift(); + + if (queue.length === 0) { + callback(); + } else { + handle(); + } + }; + } + + handle(); +}; + + +/*-------------------------------------------------------------- +# SEARCH +---------------------------------------------------------------- +satus.indexeddb.search({ + fruits: { + query: 'apple', // or function () { ... } + direction: 'next', + index: 'name', + offset: 0, + limit: 0 + }, + ... +}, function () { ... }); +--------------------------------------------------------------*/ + +satus.indexeddb.search = function (items, callback) { + var queue = [], + results = {}; + + for (var key in items) { + var item = items[key]; + + queue.push({ + name: key, + direction: item.direction, + index: item.index, + offset: item.offset + }); + } + + function handle() { + var item = queue[0], + transaction = satus.indexeddb.request.transaction(item.name, 'readonly'), + object_store = transaction.objectStore(item.name), + object_result = [], + offset = item.offset || 0, + limit = item.limit || 100; + + if (item.index) { + object_store = object_store.index(item.index); + } + + results[item.name] = object_result; + + object_store.openCursor(null, item.direction).onsuccess = function(event) { + var cursor = event.target.result; + + if (cursor) { + if (item.offset > 0) { + cursor.advance(item.offset); + + item.offset = 0; + } else if (limit && object_result.length < limit) { + object_result.push(cursor.value); + + cursor.continue(); + } + } else { + object_store.count().onsuccess = function(event) { + object_result.fullLength = event.target.result; + + queue.shift(); + + if (queue.length === 0) { + callback(results); + } else { + handle(); + } + }; + } + }; + } + + handle(); +}; +/*-------------------------------------------------------------- +>>> SORTABLE +--------------------------------------------------------------*/ + +satus.events.add('render', function (component, skeleton) { + if (skeleton.sortable === true) { + component.addEventListener('mousedown', function (event) { + if (event.button !== 0) { + return false; + } + + var component = this, + rect = this.getBoundingClientRect(), + x = event.clientX, + y = event.clientY, + offset_x = event.clientX - rect.left, + offset_y = event.clientY - rect.top, + ghost = satus.clone(this), + children = this.parentNode.children, + appended = false; + + ghost.classList.add('satus-sortable__ghost'); + + function mousemove(event) { + if (appended === false && (Math.abs(event.clientX - x) > 4 || Math.abs(event.clientY - y) > 4)) { + appended = true; + + component.classList.add('satus-sortable__chosen'); + + component.parentNode.appendChild(ghost); + } + + ghost.style.transform = 'translate(' + (event.clientX - offset_x) + 'px, ' + (event.clientY - offset_y) + 'px)'; + } + + function mouseup(event) { + component.classList.remove('satus-sortable__chosen'); + ghost.remove(); + + window.removeEventListener('mousemove', mousemove, true); + window.removeEventListener('mouseup', mouseup, true); + + for (var i = 0, l = children.length; i < l; i++) { + var child = children[i]; + + if (child !== component) { + child.removeEventListener('mouseover', siblingMouseOver); + } + } + + component.dispatchEvent(new CustomEvent('sort')); + + event.stopPropagation(); + + return false; + } + + window.addEventListener('mousemove', mousemove, { + passive: true, + capture: true + }); + + window.addEventListener('mouseup', mouseup, { + passive: true, + capture: true + }); + + function siblingMouseOver(event) { + var target = event.target, + parent = target.parentNode, + y = event.layerY / (target.offsetHeight / 100); + + if (y < 50 && target.previousSibling !== component || y >= 50 && target.nextSibling === component) { + parent.insertBefore(component, target); + } else { + parent.insertBefore(component, target.nextSibling); + } + } + + for (var i = 0, l = children.length; i < l; i++) { + var child = children[i]; + + if (child !== component) { + child.addEventListener('mouseover', siblingMouseOver); + } + } + + event.stopPropagation(); + event.preventDefault(); + + return false; + }); + } +}); +/*-------------------------------------------------------------- +>>> USER +--------------------------------------------------------------*/ + +satus.user = function () { + /*-------------------------------------------------------------- + 1.0 VARIABLES + --------------------------------------------------------------*/ + + var user_agent = navigator.userAgent, + random_cookie = 'ta{t`nX6cMXK,Wsc', + video = document.createElement('video'), + video_formats = { + ogg: 'video/ogg; codecs="theora"', + h264: 'video/mp4; codecs="avc1.42E01E"', + webm: 'video/webm; codecs="vp8, vorbis"', + vp9: 'video/webm; codecs="vp9"', + hls: 'application/x-mpegURL; codecs="avc1.42E01E"' + }, + audio = document.createElement('audio'), + audio_formats = { + mp3: 'audio/mpeg', + mp4: 'audio/mp4', + aif: 'audio/x-aiff' + }, + cvs = document.createElement('canvas'), + ctx = cvs.getContext('webgl'), + data = { + browser: { + audio: null, + cookies: null, + flash: null, + java: null, + languages: null, + name: null, + platform: null, + version: null, + video: null, + webgl: null + }, + os: { + name: null, + type: null + }, + device: { + connection: { + type: null, + speed: null + }, + cores: null, + gpu: null, + max_touch_points: null, + ram: null, + screen: null, + touch: null + } + }; + + + /*-------------------------------------------------------------- + 2.0 SOFTWARE + --------------------------------------------------------------*/ + + /*-------------------------------------------------------------- + 2.1.0 OS + --------------------------------------------------------------*/ + + /*-------------------------------------------------------------- + 2.1.1 NAME + --------------------------------------------------------------*/ + + if (navigator.appVersion.indexOf('Win') !== -1) { + if (navigator.appVersion.match(/(Windows 10.0|Windows NT 10.0)/)) { + data.os.name = 'Windows 10'; + } else if (navigator.appVersion.match(/(Windows 8.1|Windows NT 6.3)/)) { + data.os.name = 'Windows 8.1'; + } else if (navigator.appVersion.match(/(Windows 8|Windows NT 6.2)/)) { + data.os.name = 'Windows 8'; + } else if (navigator.appVersion.match(/(Windows 7|Windows NT 6.1)/)) { + data.os.name = 'Windows 7'; + } else if (navigator.appVersion.match(/(Windows NT 6.0)/)) { + data.os.name = 'Windows Vista'; + } else if (navigator.appVersion.match(/(Windows NT 5.1|Windows XP)/)) { + data.os.name = 'Windows XP'; + } else { + data.os.name = 'Windows'; + } + } else if (navigator.appVersion.indexOf('(iPhone|iPad|iPod)') !== -1) { + data.os.name = 'iOS'; + } else if (navigator.appVersion.indexOf('Mac') !== -1) { + data.os.name = 'macOS'; + } else if (navigator.appVersion.indexOf('Android') !== -1) { + data.os.name = 'Android'; + } else if (navigator.appVersion.indexOf('OpenBSD') !== -1) { + data.os.name = 'OpenBSD'; + } else if (navigator.appVersion.indexOf('SunOS') !== -1) { + data.os.name = 'SunOS'; + } else if (navigator.appVersion.indexOf('Linux') !== -1) { + data.os.name = 'Linux'; + } else if (navigator.appVersion.indexOf('X11') !== -1) { + data.os.name = 'UNIX'; + } + + /*-------------------------------------------------------------- + 2.1.2 TYPE + --------------------------------------------------------------*/ + + if (navigator.appVersion.match(/(Win64|x64|x86_64|WOW64)/)) { + data.os.type = '64-bit'; + } else { + data.os.type = '32-bit'; + } + + + /*-------------------------------------------------------------- + 2.2.0 BROWSER + --------------------------------------------------------------*/ + + /*-------------------------------------------------------------- + 2.2.1 NAME + --------------------------------------------------------------*/ + + if (user_agent.indexOf('Opera') !== -1) { + data.browser.name = 'Opera'; + } else if (user_agent.indexOf('Vivaldi') !== -1) { + data.browser.name = 'Vivaldi'; + } else if (user_agent.indexOf('Edge') !== -1) { + data.browser.name = 'Edge'; + } else if (user_agent.indexOf('Chrome') !== -1) { + data.browser.name = 'Chrome'; + } else if (user_agent.indexOf('Safari') !== -1) { + data.browser.name = 'Safari'; + } else if (user_agent.indexOf('Firefox') !== -1) { + data.browser.name = 'Firefox'; + } else if (user_agent.indexOf('MSIE') !== -1) { + data.browser.name = 'IE'; + } + + + /*-------------------------------------------------------------- + 2.2.2 VERSION + --------------------------------------------------------------*/ + + var browser_version = user_agent.match(new RegExp(data.browser.name + '/([0-9.]+)')); + + if (browser_version[1]) { + data.browser.version = browser_version[1]; + } + + + /*-------------------------------------------------------------- + 2.2.3 PLATFORM + --------------------------------------------------------------*/ + + data.browser.platform = navigator.platform || null; + + + /*-------------------------------------------------------------- + 2.2.4 LANGUAGES + --------------------------------------------------------------*/ + + data.browser.languages = navigator.languages || null; + + + /*-------------------------------------------------------------- + 2.2.5 COOKIES + --------------------------------------------------------------*/ + + if (document.cookie) { + document.cookie = random_cookie; + + if (document.cookie.indexOf(random_cookie) !== -1) { + data.browser.cookies = true; + } + } + + + /*-------------------------------------------------------------- + 2.2.6 FLASH + --------------------------------------------------------------*/ + + try { + if (new ActiveXObject('ShockwaveFlash.ShockwaveFlash')) { + data.browser.flash = true; + } + } catch (e) { + if (navigator.mimeTypes['application/x-shockwave-flash']) { + data.browser.flash = true; + } + } + + + /*-------------------------------------------------------------- + 2.2.7 JAVA + --------------------------------------------------------------*/ + + if (typeof navigator.javaEnabled === 'function' && navigator.javaEnabled()) { + data.browser.java = true; + } + + + /*-------------------------------------------------------------- + 2.2.8 VIDEO FORMATS + --------------------------------------------------------------*/ + + if (typeof video.canPlayType === 'function') { + data.browser.video = {}; + + for (var i in video_formats) { + var can_play_type = video.canPlayType(video_formats[i]); + + if (can_play_type === '') { + data.browser.video[i] = false; + } else { + data.browser.video[i] = can_play_type; + } + } + } + + + /*-------------------------------------------------------------- + 2.2.9 AUDIO FORMATS + --------------------------------------------------------------*/ + + if (typeof audio.canPlayType === 'function') { + data.browser.audio = {}; + + for (var i in audio_formats) { + var can_play_type = audio.canPlayType(audio_formats[i]); + + if (can_play_type == '') { + data.browser.audio[i] = false; + } else { + data.browser.audio[i] = can_play_type; + } + } + } + + + /*-------------------------------------------------------------- + 2.2.10 WEBGL + --------------------------------------------------------------*/ + + if (ctx && ctx instanceof WebGLRenderingContext) { + data.browser.webgl = true; + } + + + /*-------------------------------------------------------------- + 3.0 HARDWARE + --------------------------------------------------------------*/ + + /*-------------------------------------------------------------- + 3.1 SCREEN + --------------------------------------------------------------*/ + + if (screen) { + data.device.screen = screen.width + 'x' + screen.height; + } + + + /*-------------------------------------------------------------- + 3.2 RAM + --------------------------------------------------------------*/ + + if ('deviceMemory' in navigator) { + data.device.ram = navigator.deviceMemory + ' GB'; + } + + + /*-------------------------------------------------------------- + 3.3 GPU + --------------------------------------------------------------*/ + + if ( + ctx && + ctx instanceof WebGLRenderingContext && + 'getParameter' in ctx && + 'getExtension' in ctx + ) { + var info = ctx.getExtension('WEBGL_debug_renderer_info'); + + if (info) { + data.device.gpu = ctx.getParameter(info.UNMASKED_RENDERER_WEBGL); + } + } + + + /*-------------------------------------------------------------- + 3.4 CORES + --------------------------------------------------------------*/ + + if (navigator.hardwareConcurrency) { + data.device.cores = navigator.hardwareConcurrency; + } + + + /*-------------------------------------------------------------- + 3.5 TOUCH + --------------------------------------------------------------*/ + + if ( + window.hasOwnProperty('ontouchstart') || + window.DocumentTouch && document instanceof window.DocumentTouch || + navigator.maxTouchPoints > 0 || + window.navigator.msMaxTouchPoints > 0 + ) { + data.device.touch = true; + data.device.max_touch_points = navigator.maxTouchPoints; + } + + + /*-------------------------------------------------------------- + 3.6 CONNECTION + --------------------------------------------------------------*/ + + if (typeof navigator.connection === 'object') { + data.device.connection.type = navigator.connection.effectiveType || null; + + if (navigator.connection.downlink) { + data.device.connection.speed = navigator.connection.downlink + ' Mbps'; + } + } + + + /*-------------------------------------------------------------- + 4.0 CLEARING + --------------------------------------------------------------*/ + + video.remove(); + audio.remove(); + cvs.remove(); + + + return data; +}; +/*-------------------------------------------------------------- +>>> UUID +--------------------------------------------------------------*/ + +satus.uuid = function () { + return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, function (match) { + return (match ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> match / 4).toString(16) + }); +}; +/*-------------------------------------------------------------- +>>> CONTEXT MENU +--------------------------------------------------------------*/ + +satus.events.add('render', function (component, skeleton) { + if (skeleton.contextMenu) { + component.addEventListener('contextmenu', function (event) { + var x = event.clientX, + y = event.clientY, + modal = satus.render({ + component: 'modal', + variant: 'contextmenu', + parent: this.skeleton + }); + + if (window.innerWidth - x < 200) { + x = window.innerWidth - 200; + } + + modal.inner.style.left = x + 'px'; + modal.inner.style.top = y + 'px'; + + satus.render(this.skeleton.contextMenu, modal.inner); + + event.preventDefault(); + event.stopPropagation(); + + return false; + }); + } +}); +/*-------------------------------------------------------------- +>>> BASE +--------------------------------------------------------------*/ + +satus.components.base = function (skeleton) { + var component = document.createElement('div'); + + component.base = component; + + return component; +}; +/*-------------------------------------------------------------- +>>> RADIO +--------------------------------------------------------------*/ + +satus.components.radio = function (skeleton) { + var component = document.createElement('label'), + content = document.createElement('span'), + radio = document.createElement('input'); + + component.inner = content; + + radio.type = 'radio'; + + if (skeleton.group) { + component.storage = skeleton.group; + radio.name = skeleton.group; + } + + if (skeleton.value) { + radio.value = skeleton.value; + } + + component.addEventListener('render', function () { + this.storageValue = satus.storage.get(this.storage); + + if (satus.isset(this.storageValue)) { + radio.checked = this.storageValue === skeleton.value; + } else if (skeleton.checked) { + radio.checked = true; + } + }); + + radio.addEventListener('change', function () { + component.storageValue = this.value; + component.storageChange(); + }); + + component.appendChild(content); + component.appendChild(radio); + + return component; +}; +/*-------------------------------------------------------------- +>>> CHECKBOX +--------------------------------------------------------------*/ + +satus.components.checkbox = function (skeleton) { + var component = document.createElement('button'), + content = document.createElement('span'); + + component.inner = content; + + content.className = 'satus-checkbox__content'; + + component.appendChild(content); + + component.addEventListener('click', function () { + if (this.dataset.value === 'true') { + this.storageValue = false; + this.dataset.value = 'false'; + } else { + this.storageValue = true; + this.dataset.value = 'true'; + } + + this.storageChange(); + }); + + component.addEventListener('render', function () { + this.dataset.value = this.storageValue; + }); + + return component; +}; +/*-------------------------------------------------------------- +>>> SELECT +--------------------------------------------------------------*/ + +satus.components.select = function (skeleton) { + var component = document.createElement('div'), + component_content = document.createElement('span'), + component_value = document.createElement('span'), + component_select = document.createElement('select'); + + for (var i = 0, l = skeleton.options.length; i < l; i++) { + var option = document.createElement('option'); + + option.value = skeleton.options[i].value; + + satus.text(option, skeleton.options[i].text); + + component_select.appendChild(option); + } + + component.inner = component_content; + component.select = component_select; + + Object.defineProperty(component, 'value', { + get() { + return this.select.value; + }, + set(value) { + this.select.value = value; + } + }); + + component.render = function () { + var value_element = this.children[2]; + + satus.empty(value_element); + + satus.text(value_element, this.select.options[this.select.selectedIndex].text); + + this.dataset.value = this.value; + }; + + component.addEventListener('render', function () { + this.value = this.storageValue || this.skeleton.options[0].value; + + this.render(); + }); + + component_select.addEventListener('change', function () { + var component = this.parentNode; + + component.storageValue = this.value; + + component.storageChange(); + + component.render(); + }); + + component.appendChild(component_select); + component.appendChild(component_content); + component.appendChild(component_value); + + return component; +}; +/*-------------------------------------------------------------- +>>> SHORTCUT +--------------------------------------------------------------*/ + +satus.components.shortcut = function (skeleton) { + var component = document.createElement('button'), + content = document.createElement('span'), + value = document.createElement('div'); + + component.inner = content; + + component.className = 'satus-button'; + value.className = 'satus-shortcut__value'; + + component.render = function (parent) { + var self = this, + parent = parent || self.primary, + children = parent.children; + + satus.empty(parent); + + function createElement(name) { + var element = document.createElement('div'); + + element.className = 'satus-shortcut__' + name; + + parent.appendChild(element); + + return element; + } + + if (this.data.alt) { + createElement('key').textContent = 'Alt'; + } + + if (this.data.ctrl) { + if (children.length && children[children.length - 1].className.indexOf('plus') === -1) { + createElement('plus'); + } + + createElement('key').textContent = 'Ctrl'; + } + + if (this.data.shift) { + if (children.length && children[children.length - 1].className.indexOf('plus') === -1) { + createElement('plus'); + } + + createElement('key').textContent = 'Shift'; + } + + for (var code in this.data.keys) { + var key = this.data.keys[code].key, + arrows = ['ArrowUp', 'ArrowRight', 'ArrowDown', 'ArrowLeft'], + index = arrows.indexOf(key); + + if (children.length && children[children.length - 1].className.indexOf('plus') === -1) { + createElement('plus'); + } + + if (index !== -1) { + createElement('key').textContent = ['↑', '→', '↓', '←'][index]; + } else if (key === ' ') { + createElement('key').textContent = '␣'; + } else if (key) { + createElement('key').textContent = key.toUpperCase(); + } + } + + if (this.data.wheel) { + if (children.length && children[children.length - 1].className.indexOf('plus') === -1) { + createElement('plus'); + } + + var mouse = createElement('mouse'), + div = document.createElement('div'); + + mouse.appendChild(div); + + mouse.className += ' ' + (this.data.wheel > 0); + } + + if (this.data.click) { + if (children.length && children[children.length - 1].className.indexOf('plus') === -1) { + createElement('plus'); + } + + var mouse = createElement('mouse'), + div = document.createElement('div'); + + mouse.appendChild(div); + + mouse.className += ' click'; + } + + if (this.data.middle) { + if (children.length && children[children.length - 1].className.indexOf('plus') === -1) { + createElement('plus'); + } + + var mouse = createElement('mouse'), + div = document.createElement('div'); + + mouse.appendChild(div); + + mouse.className += ' middle'; + } + + if (this.data.context) { + if (children.length && children[children.length - 1].className.indexOf('plus') === -1) { + createElement('plus'); + } + + var mouse = createElement('mouse'), + div = document.createElement('div'); + + mouse.appendChild(div); + + mouse.className += ' context'; + } + }; + + component.valueElement = value; + + component.appendChild(content); + component.appendChild(value); + + component.keydown = function (event) { + event.preventDefault(); + event.stopPropagation(); + + component.data = { + alt: event.altKey, + ctrl: event.ctrlKey, + shift: event.shiftKey, + keys: {} + }; + + if (['control', 'alt', 'altgraph', 'shift'].indexOf(event.key.toLowerCase()) === -1) { + component.data.keys[event.keyCode] = { + code: event.code, + key: event.key + }; + } + + component.data.wheel = 0; + + component.render(); + + return false; + }; + + if (skeleton.wheel !== false) { + component.mousewheel = function (event) { + event.stopPropagation(); + + if ( + ( + component.data.wheel === 0 && + ( + Object.keys(component.data.keys).length === 0 && + component.data.alt === false && + component.data.ctrl === false && + component.data.shift === false + ) + ) || + component.data.wheel < 0 && event.deltaY > 0 || + component.data.wheel > 0 && event.deltaY < 0) { + component.data = { + alt: false, + ctrl: false, + shift: false, + keys: {} + }; + } + + component.data.wheel = event.deltaY < 0 ? -1 : 1; + + component.render(); + + return false; + }; + } + + component.addEventListener('render', function () { + this.data = this.storageValue || { + alt: false, + ctrl: false, + shift: false, + keys: {}, + wheel: 0 + }; + + this.render(this.valueElement); + }); + + component.addEventListener('click', function () { + satus.render({ + component: 'modal', + properties: { + parent: this + }, + on: { + close: function () { + window.removeEventListener('keydown', component.keydown); + window.removeEventListener('wheel', component.mousewheel); + } + }, + + primary: { + component: 'div', + class: 'satus-shortcut__primary', + on: { + render: function () { + component.primary = this; + + if (component.skeleton.mouseButtons === true) { + this.addEventListener('mousedown', function (event) { + if ( + component.data.click && event.button === 0 || + component.data.middle && event.button === 1 + ) { + component.data = { + alt: false, + ctrl: false, + shift: false, + keys: {} + }; + } + + component.data.click = false; + component.data.middle = false; + component.data.context = false; + + if (event.button === 0) { + component.data.click = true; + + component.render(); + } else if (event.button === 1) { + component.data.middle = true; + + component.render(); + } + }); + + this.addEventListener('contextmenu', function (event) { + event.preventDefault(); + event.stopPropagation(); + + if (component.data.context) { + component.data = { + alt: false, + ctrl: false, + shift: false, + keys: {} + }; + } + + component.data.context = true; + component.data.middle = false; + component.data.click = false; + + component.render(); + + return false; + }); + } + + component.render(); + } + } + }, + actions: { + component: 'section', + variant: 'actions', + + reset: { + component: 'button', + text: 'reset', + on: { + click: function () { + var component = this.parentNode.parentNode.parentNode.parent; + + component.data = component.skeleton.value || {}; + + component.render(component.valueElement); + + satus.storage.remove(component.storage); + + this.parentNode.parentNode.parentNode.close(); + + window.removeEventListener('keydown', component.keydown); + window.removeEventListener('wheel', component.mousewheel); + } + } + }, + cancel: { + component: 'button', + text: 'cancel', + on: { + click: function () { + component.data = satus.storage.get(component.storage) || component.skeleton.value || {}; + + component.render(component.valueElement); + + this.parentNode.parentNode.parentNode.close(); + + window.removeEventListener('keydown', component.keydown); + window.removeEventListener('wheel', component.mousewheel); + } + } + }, + save: { + component: 'button', + text: 'save', + on: { + click: function () { + component.storageValue = component.data; + + component.storageChange(); + + component.render(component.valueElement); + + this.parentNode.parentNode.parentNode.close(); + + window.removeEventListener('keydown', component.keydown); + window.removeEventListener('wheel', component.mousewheel); + } + } + } + } + }); + + window.addEventListener('keydown', this.keydown); + window.addEventListener('wheel', this.mousewheel); + }); + + return component; +}; +/*-------------------------------------------------------------- +>>> SWITCH +--------------------------------------------------------------*/ + +satus.components.switch = function (skeleton) { + var component = document.createElement('button'), + component_content = document.createElement('span'), + component_thumb = document.createElement('i'); + + component.inner = component_content; + + component_content.className = 'satus-switch__content'; + + component.addEventListener('click', function () { + if (this.dataset.value === 'true') { + this.storageValue = false; + this.dataset.value = 'false'; + } else { + this.storageValue = true; + this.dataset.value = 'true'; + } + + this.storageChange(); + }); + + component.addEventListener('render', function () { + this.dataset.value = this.storageValue; + }); + + component.appendChild(component_content); + component.appendChild(component_thumb); + + return component; +}; +/*-------------------------------------------------------------- +>>> LAYERS +--------------------------------------------------------------*/ + +satus.components.layers = function (skeleton) { + var component = document.createElement('div'); + + component.path = [skeleton]; + + component.back = function () { + if (this.path.length > 1) { + this.path.pop(); + + this.open(); + } + }; + + component.open = function (skeleton) { + var layer = document.createElement('div'); + + if (skeleton) { + this.path.push(skeleton); + } else { + skeleton = this.path[this.path.length - 1]; + } + + layer.className = 'satus-layer'; + + layer.skeleton = skeleton; + layer.base = this.base; + + satus.render(skeleton, layer, skeleton.component === 'layers'); + + satus.empty(this); + + this.appendChild(layer); + + this.dispatchEvent(new Event('open')); + }; + + component.update = function () { + var layer = this.querySelector('.satus-layer'); + + satus.empty(layer); + + satus.render(layer.skeleton, layer); + }; + + component.render_children = false; + + component.addEventListener('render', function () { + this.open(); + }); + + return component; +}; +/*-------------------------------------------------------------- +>>> INPUT +--------------------------------------------------------------*/ + +satus.components.input = function (skeleton) { + var component = document.createElement('input'); + + if (skeleton.attr) { + var key = skeleton.attr.name || skeleton.storage, + value; + + if (satus.isset(satus.storage.get(key))) { + value = satus.storage.get(key); + } else { + value = skeleton.value; + } + + if (skeleton.attr.type === 'radio') { + component.checked = value === skeleton.attr.value || skeleton.value; + } else if (satus.isset(value)) { + component.value = value; + } + + component.addEventListener('change', function () { + var key = this.skeleton.attr.name || this.skeleton.storage; + + satus.storage.set(key, this.value); + }); + } else { + var key = skeleton.name || skeleton.storage, + value; + + component.type = skeleton.type; + + if (satus.isset(satus.storage.get(key))) { + value = satus.storage.get(key); + } else { + value = skeleton.value; + } + + if (skeleton.type === 'radio') { + component.checked = value === skeleton.value || skeleton.value; + } else if (satus.isset(value)) { + component.value = value; + } + + component.addEventListener('change', function () { + var key = this.skeleton.name || this.skeleton.storage; + + satus.storage.set(key, this.value); + }); + } + + return component; +}; +/*-------------------------------------------------------------- +>>> MENUBAR +--------------------------------------------------------------*/ + +satus.components.menubar = function (skeleton) { + function createList(items) { + var ul = document.createElement('ul'); + + for (var key in items) { + var item = items[key], + li = document.createElement('li'); + + satus.render(item, li); + + if (item.items) { + li.appendChild(createList(item.items)); + } + + ul.appendChild(li); + } + + return ul; + } + + return createList(skeleton.items); +}; +/*-------------------------------------------------------------- +>>> TEXTAREA +--------------------------------------------------------------*/ + +satus.components.textarea = function (skeleton) { + var component = document.createElement('div'), + line_number = document.createElement('div'), + textarea = document.createElement('textarea'); + + line_number.className = 'satus-textarea__line-number'; + + component.line_number = line_number; + component.textarea = textarea; + + Object.defineProperty(component, 'value', { + get() { + return this.textarea.value; + }, + set(value) { + this.textarea.value = value; + + this.line_number.update(); + } + }); + + line_number.update = function () { + var count = this.parentNode.textarea.value.split('\n').length; + + if (count !== this.children.length) { + satus.empty(this); + + for (var i = 1; i <= count; i++) { + var span = document.createElement('span'); + + span.textContent = i; + + this.appendChild(span); + } + } + }; + + textarea.addEventListener('input', function () { + this.parentNode.line_number.update(); + }); + + textarea.addEventListener('selectionchange', function () { + this.parentNode.line_number.update(); + }); + + textarea.addEventListener('scroll', function () { + this.parentNode.line_number.style.transform = 'translateY(-' + this.scrollTop + 'px)'; + + this.parentNode.line_number.update(); + }); + + component.appendChild(line_number); + component.appendChild(textarea); + + line_number.update(1); + + return component; +}; +/*-------------------------------------------------------------- +>>> DIVIDER +--------------------------------------------------------------*/ + +satus.components.divider = function () { + var component = document.createElement('div'); + + return component; +}; +/*-------------------------------------------------------------- +>>> TEXT FIELD +--------------------------------------------------------------*/ + +satus.components.textField = function (skeleton) { + var component = document.createElement('div'), + pre = document.createElement('pre'), + input = document.createElement('textarea'), + hidden_text = document.createElement('span'), + text = document.createElement('span'), + selection = document.createElement('div'), + cursor = document.createElement('div'); + + input.className = 'satus-text-field__input'; + pre.className = 'satus-text-field__pre'; + hidden_text.className = 'satus-text-field__hidden-text'; + text.className = 'satus-text-field__text'; + selection.className = 'satus-text-field__selection'; + cursor.className = 'satus-text-field__cursor'; + + component.inputElement = input; + component.textElement = text; + component.languages = { + regex: function (component) { + var regex_token = /\[\^?]?(?:[^\\\]]+|\\[\S\s]?)*]?|\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9][0-9]*|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|c[A-Za-z]|[\S\s]?)|\((?:\?[:=!]?)?|(?:[?*+]|\{[0-9]+(?:,[0-9]*)?\})\??|[^.?*+^${[()|\\]+|./g, + char_class_token = /[^\\-]+|-|\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|c[A-Za-z]|[\S\s]?)/g, + char_class_parts = /^(\[\^?)(]?(?:[^\\\]]+|\\[\S\s]?)*)(]?)$/, + quantifier = /^(?:[?*+]|\{[0-9]+(?:,[0-9]*)?\})\??$/, + matches = component.inputElement.value.match(regex_token); + + function create(type, string) { + var span = document.createElement('span'); + + span.className = type; + span.textContent = string; + + component.textElement.appendChild(span); + } + + for (var i = 0, l = matches.length; i < l; i++) { + var match = matches[i]; + + if (match[0] === '[') { + create('character-class', match); + } else if (match[0] === '(') { + create('group', match); + } else if (match[0] === ')') { + create('group', match); + } else if (match[0] === '\\' || match === '^') { + create('anchor', match); + } else if (quantifier.test(match)) { + create('quantifier', match); + } else if (match === '|' || match === '.') { + create('metasequence', match); + } else { + create('text', match); + } + } + } + }; + component._syntax = skeleton.syntax; + + Object.defineProperty(component, 'value', { + get: function () { + return this.inputElement.value; + }, + set: function (value) { + var input = this.inputElement; + + input.value = value; + + input.updateValue(); + input.updateCursor(); + } + }); + + Object.defineProperty(component, 'syntax', { + get: function () { + return this._syntax; + }, + set: function (value) { + var input = this.inputElement; + + this._syntax = value; + + input.updateValue(); + input.updateCursor(); + } + }); + + input.rows = skeleton.rows || 1; + input.autocapitalize = 'none'; + input.autocomplete = 'off'; + input.autocorrect = 'off'; + input.spellcheck = false; + input.autofocus = true; + input.textElement = text; + input.hiddenTextElement = hidden_text; + input.selectionElement = selection; + input.cursorElement = cursor; + + input.updateValue = function () { + var component = this.parentNode.parentNode; + + for (var i = this.textElement.childNodes.length - 1; i > -1; i--) { + this.textElement.childNodes[i].remove(); + } + + if (this.value.length > 0) { + if (component.languages[component._syntax]) { + component.languages[component._syntax](component); + } else { + this.textElement.textContent = this.value; + } + } + }; + + input.updateCursor = function () { + var cursor = this.cursorElement, + selection = this.selectionElement, + hidden_text = this.hiddenTextElement, + start = this.selectionStart, + end = this.selectionEnd; + + cursor.style.animation = 'none'; + + if (start === end) { + selection.setAttribute('disabled', ''); + } else { + selection.removeAttribute('disabled'); + + hidden_text.textContent = this.value.substring(0, start); + + selection.style.left = hidden_text.offsetWidth - this.scrollLeft + 'px'; + + hidden_text.textContent = this.value.substring(start, end); + + selection.style.width = hidden_text.offsetWidth + 'px'; + } + + if (this.selectionDirection === 'forward') { + hidden_text.textContent = this.value.substring(0, end); + } else { + hidden_text.textContent = this.value.substring(0, start); + } + + cursor.style.left = hidden_text.offsetWidth - this.scrollLeft + 'px'; + + cursor.style.animation = ''; + + hidden_text.textContent = ''; + }; + + input.addEventListener('keydown', function () { + var self = this; + + setTimeout(function () { + var component = self.parentNode.parentNode; + + component.storageValue = self.value; + component.storageChange(); + + self.updateValue(); + self.updateCursor(); + }); + }); + + input.addEventListener('scroll', function (event) { + this.textElement.style.left = -this.scrollLeft + 'px'; + }); + + document.addEventListener('selectionchange', function () { + input.updateCursor(); + }); + + selection.setAttribute('disabled', ''); + + pre.appendChild(input); + pre.appendChild(hidden_text); + pre.appendChild(text); + pre.appendChild(selection); + pre.appendChild(cursor); + component.appendChild(pre); + + component.addEventListener('render', function () { + input.value = this.storageValue; + + this.inputElement.updateValue(); + this.inputElement.updateCursor(); + }); + + return component; +}; +/*-------------------------------------------------------------- +>>> TABS +--------------------------------------------------------------*/ + +satus.components.tabs = function (skeleton) { + var component = document.createElement('div'), + content = document.createElement('div'), + selection = document.createElement('div'); + + content.className = 'satus-tabs__content'; + selection.className = 'satus-tabs__selection'; + selection.style.width = 100 / skeleton.items.length + '%'; + + content.appendChild(selection); + + component.selection = selection; + + for (var i = 0, l = skeleton.items.length; i < l; i++) { + var item = skeleton.items[i], + button = document.createElement('button'); + + button.className = 'satus-tabs__button'; + button.value = item; + button.style.width = 100 / l + '%'; + + satus.text(button, item); + + button.addEventListener('click', function () { + var component = this.parentNode.parentNode; + + component.selection.style.left = 100 / (this.parentNode.children.length - 1) * (satus.indexOf(this) - 1) + '%'; + + component.storageValue = this.value; + component.storageChange(); + }); + + if (skeleton.value === item) { + selection.style.left = i * 50 + '%'; + } + + content.appendChild(button); + } + + component.appendChild(content); + + component.addEventListener('render', function () { + var index = satus.indexOf(this.storageValue, this.skeleton.items); + + if (index === -1) { + index = 0; + } + + this.selection.style.left = 100 / this.skeleton.items.length * index + '%'; + }); + + return component; +}; +/*-------------------------------------------------------------- +>>> ALERT +--------------------------------------------------------------*/ + +satus.components.alert = function (skeleton) { + var component = document.createElement('div'); + + return component; +}; +/*-------------------------------------------------------------- +>>> SLIDER +--------------------------------------------------------------*/ + +satus.components.slider = function (skeleton) { + var component = document.createElement('div'), + content = document.createElement('div'), + container = document.createElement('div'), + track = document.createElement('div'), + track_fill = document.createElement('div'); + + container.className = 'satus-slider__container'; + track.className = 'satus-slider__track'; + track_fill.className = 'satus-slider__track-fill'; + + component.min = skeleton.min || 0; + component.max = skeleton.max || 1; + component.step = (skeleton.step || 1); + component.percent = 100 / ((component.max - component.min) / component.step); + component.precision = String(component.step).replace(/[0-9]./, '').length; + + component.container = container; + component.track = track_fill; + component.handles = []; + component.inner = content; + + component.toPercent = function (number) { + return number / this.step * this.percent + '%'; + }; + + component.createHandle = function (index) { + var handle = document.createElement('div'); + + handle.className = 'satus-slider__handle'; + handle.handleIndex = index; + handle.tabIndex = 0; + + this.handles.push(handle); + + this.container.appendChild(handle); + }; + + component.update = function () { + if (this.values.length > 1) { + var min = Math.min.apply(null, this.values) - this.min, + max = Math.max.apply(null, this.values) - this.min; + + this.track.style.left = this.toPercent(min); + this.track.style.width = this.toPercent(max - min); + + for (var i = 0, l = this.handles.length; i < l; i++) { + var handle = this.handles[i], + value = this.values[i]; + + handle.style.left = this.toPercent(value - this.min); + handle.dataset.value = value; + } + } else { + var value = this.values[0]; + + this.track.style.width = this.toPercent(value - this.min); + this.handles[0].style.left = this.toPercent(value - this.min); + this.handles[0].dataset.value = value; + } + }; + + component.appendChild(content); + track.appendChild(track_fill); + container.appendChild(track); + component.appendChild(container); + + component.addEventListener('keydown', function (event) { + var code = event.keyCode; + + console.log(code); + }); + + component.addEventListener('render', function () { + var value = this.storageValue; + + if (satus.isArray(value)) { + this.values = value; + } else if (satus.isNumber(value)) { + this.values = [value]; + } else { + this.values = this.skeleton.values || [satus.isset(this.skeleton.value) ? this.skeleton.value : 1]; + } + + for (var i = 0, l = this.values.length; i < l; i++) { + this.createHandle(i); + } + + this.update(); + }); + + container.addEventListener('mousedown', function (event) { + if (event.button === 0) { + var component = this.parentNode, + rect = this.getBoundingClientRect(), + cursor_x = event.clientX - rect.left, + percent = cursor_x / rect.width * 100, + steps = percent / component.percent * component.step + component.min, + closest_value = component.values.indexOf(component.values.reduce(function(previous, current, index) { + return Math.abs(current - steps) < Math.abs(previous - steps) ? current : previous; + })), + handle_index = component.handles[closest_value].handleIndex; + + setTimeout(function () { + component.handles[closest_value].focus(); + }); + + function update(event) { + var cursor_x = Math.min(Math.max(event.clientX - rect.left, 0), rect.width), + percent = cursor_x / rect.width * 100, + value = percent / component.percent * component.step + component.min; + + value = (Math.round(value / component.step) * component.step); + + value = Number(value.toFixed(component.precision)); + + if (component.values[handle_index] !== value) { + component.values[handle_index] = value; + + component.storageValue = component.values.length === 1 ? component.values[0] : component.values; + component.value = component.storageValue; + + component.storageChange(); + } + + component.update(); + } + + function mousemove(event) { + update(event); + } + + function mouseup(event) { + window.removeEventListener('mousemove', mousemove); + window.removeEventListener('mouseup', mouseup); + }; + + window.addEventListener('mousemove', mousemove); + window.addEventListener('mouseup', mouseup); + + update(event); + + return true; + } + }); + + return component; +}; +/*-------------------------------------------------------------- +>>> COLOR PICKER +--------------------------------------------------------------*/ + +satus.components.colorPicker = function (skeleton) { + var component = document.createElement('button'), + component_label = document.createElement('span'), + component_value = document.createElement('span'); + + component.inner = component_label; + component.valueElement = component_value; + + component.className = 'satus-button'; + component_value.className = 'satus-color-picker__value'; + + component.appendChild(component_label); + component.appendChild(component_value); + + component.addEventListener('click', function () { + var rgb = this.rgb, + hsl = satus.color.rgbToHsl(rgb), + s = hsl[1] / 100, + l = hsl[2] / 100; + + s *= l < .5 ? l : 1 - l; + + var v = l + s; + + s = 2 * s / (l + s); + + satus.render({ + component: 'modal', + variant: 'color-picker', + value: hsl, + parent: this, + + palette: { + component: 'div', + class: 'satus-color-picker__palette', + style: { + 'backgroundColor': 'hsl(' + hsl[0] + 'deg, 100%, 50%)' + }, + on: { + mousedown: function () { + var palette = this, + rect = this.getBoundingClientRect(), + cursor = this.children[0]; + + function mousemove(event) { + var hsl = palette.skeleton.parent.value, + x = event.clientX - rect.left, + y = event.clientY - rect.top, + s; + + x = Math.min(Math.max(x, 0), rect.width) / (rect.width / 100); + y = Math.min(Math.max(y, 0), rect.height) / (rect.height / 100); + + var v = 100 - y, + l = (2 - x / 100) * v / 2; + + hsl[1] = x * v / (l < 50 ? l * 2 : 200 - l * 2); + hsl[2] = l; + + cursor.style.left = x + '%'; + cursor.style.top = y + '%'; + + palette.nextSibling.children[0].style.backgroundColor = 'hsl(' + hsl[0] + 'deg,' + hsl[1] + '%, ' + hsl[2] + '%)'; + + event.preventDefault(); + } + + function mouseup() { + window.removeEventListener('mousemove', mousemove); + window.removeEventListener('mouseup', mouseup); + } + + window.addEventListener('mousemove', mousemove); + window.addEventListener('mouseup', mouseup); + } + }, + + cursor: { + component: 'div', + class: 'satus-color-picker__cursor', + style: { + 'left': s * 100 + '%', + 'top': 100 - v * 100 + '%' + } + } + }, + section: { + component: 'section', + variant: 'color', + + color: { + component: 'div', + class: 'satus-color-picker__color', + style: { + 'backgroundColor': 'rgb(' + this.rgb.join(',') + ')' + } + }, + hue: { + component: 'slider', + class: 'satus-color-picker__hue', + storage: false, + value: hsl[0], + max: 360, + on: { + change: function () { + var modal = this.skeleton.parent.parent, + hsl = modal.value; + + hsl[0] = this.values[0]; + + this.previousSibling.style.backgroundColor = 'hsl(' + hsl[0] + 'deg,' + hsl[1] + '%, ' + hsl[2] + '%)'; + this.parentNode.previousSibling.style.backgroundColor = 'hsl(' + hsl[0] + 'deg, 100%, 50%)'; + } + } + } + }, + actions: { + component: 'section', + variant: 'actions', + + reset: { + component: 'button', + text: 'reset', + on: { + click: function () { + var modal = this.skeleton.parent.parent, + component = modal.parent; + + component.rgb = component.skeleton.value; + + component.storageValue = component.rgb; + component.storageChange(); + + component.valueElement.style.backgroundColor = 'rgb(' + component.rgb.join(',') + ')'; + + modal.rendered.close(); + } + } + }, + cancel: { + component: 'button', + text: 'cancel', + on: { + click: function () { + this.skeleton.parent.parent.rendered.close(); + } + } + }, + ok: { + component: 'button', + text: 'OK', + on: { + click: function () { + var modal = this.skeleton.parent.parent, + component = modal.parent; + + component.rgb = satus.color.hslToRgb(modal.value); + + component.storageValue = component.rgb; + component.storageChange(); + + component.valueElement.style.backgroundColor = 'rgb(' + component.rgb.join(',') + ')'; + + modal.rendered.close(); + } + } + } + } + }); + }); + + component.addEventListener('render', function () { + component.rgb = this.storageValue || [0, 100, 50]; + + component_value.style.backgroundColor = 'rgb(' + component.rgb.join(',') + ')'; + }); + + return component; +}; +/*-------------------------------------------------------------- +>>> LIST +--------------------------------------------------------------*/ + +satus.components.list = function (skeleton) { + var ul = document.createElement('ul'); + + for (var i = 0, l = skeleton.items.length; i < l; i++) { + var li = document.createElement('li'), + item = skeleton.items[i]; + + li.className = 'satus-list__item'; + + for (var j = 0, k = item.length; j < k; j++) { + var child = item[j]; + + if (typeof child === 'string') { + var span = document.createElement('span'); + + span.textContent = satus.locale.get(child); + + li.appendChild(span); + } else { + satus.render(child, li); + } + } + + ul.appendChild(li); + } + + return ul; +}; +/*-------------------------------------------------------------- +>>> MODAL +--------------------------------------------------------------*/ + +satus.components.modal = function (skeleton) { + var component = document.createElement('div'), + scrim = document.createElement('div'), + surface = document.createElement('div'); + + component.inner = surface; + + scrim.className = 'satus-modal__scrim'; + surface.className = 'satus-modal__surface'; + + component.close = function () { + var component = this, + component_surface = this.children[1]; + + this.classList.add('satus-modal--closing'); + + setTimeout(function () { + component.remove(); + + component.dispatchEvent(new CustomEvent('close')); + }, satus.getAnimationDuration(component_surface)); + }; + + scrim.addEventListener('click', function () { + this.parentNode.close(); + }); + + component.appendChild(scrim); + component.appendChild(surface); + + return component; +}; \ No newline at end of file diff --git a/ui/script.js b/ui/script.js new file mode 100644 index 0000000..d05015a --- /dev/null +++ b/ui/script.js @@ -0,0 +1,479 @@ +/*-------------------------------------------------------------- +>>> POPUP: +---------------------------------------------------------------- +# Skeleton +# Functions +# Initialization +--------------------------------------------------------------*/ + +/*-------------------------------------------------------------- +# SKELETON +--------------------------------------------------------------*/ + +var skeleton = { + component: 'base', + + header: { + component: 'header', + + section_1: { + component: 'section', + variant: 'align-start', + + back: { + component: 'button', + attr: { + 'hidden': 'true' + }, + on: { + click: 'layers.back' + }, + + svg: { + component: 'svg', + attr: { + 'viewBox': '0 0 24 24', + 'fill': 'none', + 'stroke-width': '1.5', + 'stroke': 'currentColor' + }, + + path: { + component: 'path', + attr: { + 'd': 'M14 18l-6-6 6-6' + } + } + } + }, + title: { + component: 'span', + variant: 'title' + } + }, + section_2: { + component: 'section', + variant: 'align-end', + + menu: { + component: 'button', + on: { + click: { + component: 'modal', + variant: 'vertical', + + label: { + component: 'span', + text: 'theme' + }, + theme: { + component: 'tabs', + items: [ + 'light', + 'black' + ], + value: 'light' + }, + divider: { + component: 'divider' + }, + language: { + component: 'select', + on: { + change: function (name, value) { + var self = this; + + satus.ajax('_locales/' + this.querySelector('select').value + '/messages.json', function (response) { + response = JSON.parse(response); + + for (var key in response) { + satus.locale.strings[key] = response[key].message; + } + + self.base.skeleton.header.section_1.title.rendered.textContent = satus.locale.get('languages'); + + self.base.skeleton.layers.rendered.update(); + }); + } + }, + options: [{ + value: 'en', + text: 'English' + }, + { + value: 'he', + text: 'עברית' + }, { + value: 'ru', + text: 'Русский' + }, { + value: 'de', + text: 'Deutsch' + }, { + value: 'ar', + text: 'العربية' + }], + + svg: { + component: 'svg', + attr: { + 'viewBox': '0 0 24 24', + 'fill': 'currentColor' + }, + + path: { + component: 'path', + attr: { + 'd': 'M12.9 15l-2.6-2.4c1.8-2 3-4.2 3.8-6.6H17V4h-7V2H8v2H1v2h11.2c-.7 2-1.8 3.8-3.2 5.3-1-1-1.7-2.1-2.3-3.3h-2c.7 1.6 1.7 3.2 3 4.6l-5.1 5L4 19l5-5 3.1 3.1.8-2zm5.6-5h-2L12 22h2l1.1-3H20l1.1 3h2l-4.5-12zm-2.6 7l1.6-4.3 1.6 4.3H16z' + } + } + }, + label: { + component: 'span', + text: 'language' + } + }, + export: { + component: 'button', + on: { + click: function () { + if (location.href.indexOf('/options.html?action=export') !== -1) { + exportData(); + } else { + chrome.tabs.create({ + url: 'ui/options.html?action=export' + }); + } + } + }, + + svg: { + component: 'svg', + attr: { + 'viewBox': '0 0 24 24', + 'fill': 'none', + 'stroke': 'currentColor', + 'stroke-linecap': 'round', + 'stroke-linejoin': 'round', + 'stroke-width': '2' + }, + + path: { + component: 'path', + attr: { + 'd': 'M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M17 8l-5-5-5 5M12 3v12' + } + } + }, + label: { + component: 'span', + text: 'export' + } + }, + import: { + component: 'button', + on: { + click: function () { + if (location.href.indexOf('/options.html?action=import') !== -1) { + importData(); + } else { + chrome.tabs.create({ + url: 'ui/options.html?action=import' + }); + } + } + }, + + svg: { + component: 'svg', + attr: { + 'viewBox': '0 0 24 24', + 'fill': 'none', + 'stroke': 'currentColor', + 'stroke-linecap': 'round', + 'stroke-linejoin': 'round', + 'stroke-width': '2' + }, + + path: { + component: 'path', + attr: { + 'd': 'M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3' + } + } + }, + label: { + component: 'span', + text: 'import' + } + } + } + }, + + svg: { + component: 'svg', + attr: { + 'viewBox': '0 0 24 24', + 'fill': 'currentColor' + }, + + circle_1: { + component: 'circle', + attr: { + 'cx': '12', + 'cy': '5.25', + 'r': '1' + } + }, + circle_2: { + component: 'circle', + attr: { + 'cx': '12', + 'cy': '12', + 'r': '1' + } + }, + circle_3: { + component: 'circle', + attr: { + 'cx': '12', + 'cy': '18.75', + 'r': '1' + } + } + } + } + } + }, + layers: { + component: 'layers', + on: { + open: function () { + var skeleton = this.path[this.path.length - 1], + parent = skeleton.parent, + section = this.base.skeleton.header.section_1, + is_home = this.path.length <= 1, + title = 'Auto Scroll'; + + if (parent) { + if (parent.label) { + title = parent.label.text; + } else if (parent.text) { + title = parent.text; + } + } + + section.back.rendered.hidden = is_home; + section.title.rendered.innerText = satus.locale.get(title); + } + }, + + toolbar: {}, + + section: { + component: 'section', + class: 'satus-section--card', + + auto_scroll: { + component: 'shortcut', + text: 'autoScrollActivation', + mouseButtons: true, + wheel: false + }, + drag_and_drop: { + component: 'shortcut', + text: 'dragDropActivation', + mouseButtons: true, + wheel: false + }, + touchscreen: { + component: 'shortcut', + text: 'touchscreenActivation', + mouseButtons: true, + wheel: false + } + }, + + made_with_love: { + component: 'a', + class: 'made-with-love', + attr: { + target: '_blank', + href: 'https://chrome.google.com/webstore/detail/improve-youtube-open-sour/bnomihfieiccainjcjblhegjgglakjdd' + }, + properties: { + innerHTML: 'Made with by ImprovedTube' + } + } + } +}; + + +/*-------------------------------------------------------------- +# FUNCTIONS +--------------------------------------------------------------*/ + +function exportData() { + if (location.href.indexOf('action=export') !== -1) { + var blob; + + try { + blob = new Blob([JSON.stringify(satus.storage.data)], { + type: 'application/json;charset=utf-8' + }); + } catch (error) { + return modalError(error); + } + + satus.render({ + component: 'modal', + + label: { + component: 'span', + text: 'areYouSureYouWantToExportTheData' + }, + actions: { + component: 'section', + variant: 'actions', + + ok: { + component: 'button', + text: 'ok', + on: { + click: function () { + try { + chrome.permissions.request({ + permissions: ['downloads'] + }, function (granted) { + if (granted) { + chrome.downloads.download({ + url: URL.createObjectURL(blob), + filename: 'auto-scroll.txt', + saveAs: true + }, function () { + setTimeout(function () { + close(); + }, 1000); + }); + } + }); + } catch (error) { + return modalError(error); + } + + this.parentNode.parentNode.parentNode.close(); + } + } + }, + cancel: { + component: 'button', + text: 'cancel', + on: { + click: function () { + this.parentNode.parentNode.parentNode.close(); + } + } + } + } + }); + } +} + +function importData() { + if (location.href.indexOf('action=import') !== -1) { + satus.render({ + component: 'modal', + + label: { + component: 'span', + text: 'areYouSureYouWantToImportTheData' + }, + actions: { + component: 'section', + variant: 'actions', + + ok: { + component: 'button', + text: 'ok', + on: { + click: function () { + var input = document.createElement('input'); + + input.type = 'file'; + + input.addEventListener('change', function () { + var file_reader = new FileReader(); + + file_reader.onload = function () { + var data = JSON.parse(this.result); + + for (var key in data) { + satus.storage.set(key, data[key]); + } + + close(); + }; + + file_reader.readAsText(this.files[0]); + }); + + input.click(); + + this.parentNode.parentNode.parentNode.close(); + } + } + }, + cancel: { + component: 'button', + text: 'cancel', + on: { + click: function () { + this.parentNode.parentNode.parentNode.close(); + } + } + } + } + }); + } +} + + +/*-------------------------------------------------------------- +# INITIALIZATION +--------------------------------------------------------------*/ + +satus.storage.attributes = { + theme: true +}; + +satus.storage.import(function (items) { + satus.locale.import(items.language, '../_locales/', function () { + chrome.tabs.query({ + active: true, + currentWindow: true + }, function (tabs) { + chrome.tabs.sendMessage(tabs[0].id, 'init', function (response) { + if (!response) { + skeleton.layers.toolbar = { + component: 'alert', + text: 'somethingWentWrongTryReloadingThePage', + variant: 'error' + }; + } else { + skeleton.layers.toolbar = { + component: 'switch', + class: 'satus-switch--domain', + text: response, + storage: 'domains/' + response, + value: true + }; + } + + satus.render(skeleton); + }); + }); + + exportData(); + importData(); + }); +}); \ No newline at end of file diff --git a/ui/styles.css b/ui/styles.css new file mode 100644 index 0000000..02e5b9a --- /dev/null +++ b/ui/styles.css @@ -0,0 +1,94 @@ +/*-------------------------------------------------------------- +>>> POPUP: +---------------------------------------------------------------- +# Body +# Made with love +--------------------------------------------------------------*/ + +/*-------------------------------------------------------------- +# BODY +--------------------------------------------------------------*/ + + + + + + + + + + + + + + + + +.satus-switch--domain { + width: 100%; + margin: 8px 0 0; + height: 48px; + padding: 0 16px; + transition: 150ms; + color: #fff; + border: 1px solid rgb(246, 180, 101, .4); + border-radius: 8px; + background-color: rgb(246, 180, 101, .5); +} + +.satus-switch--domain[data-value='true'] .satus-switch__thumb { + background-color: #375a6c; +} + +.satus-switch--domain:focus, +.satus-switch--domain:hover { + color: #899ea9; + border-color: #2a4350; + background-color: #233843; +} + +.satus-alert { + width: 100%; + margin: 8px 0 0; +} + +.satus-section--label { + font-size: 14px; + font-weight: 600; +} + + +/*-------------------------------------------------------------- +# MADE WITH LOVE +--------------------------------------------------------------*/ + +.made-with-love { + font-size: 13px; + font-weight: 600; + position: absolute; + bottom: 16px; + left: 50%; + width: 100%; + height: auto; + min-height: auto; + padding: 0; + cursor: pointer; + transition: 150ms; + transform: translateX(-50%); + text-align: center; + text-decoration: none; + color: inherit; + justify-content: center; +} + +.made-with-love svg { + position: relative; + top: 4px; + width: 16px; + height: 16px; + fill: #f00; +} + +.made-with-love span { + margin: 0 0 0 4px; +} \ No newline at end of file