diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..87f7f1f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,19 @@
+### ApacheCordova ###
+# Apache Cordova generated files and directories
+bin/*
+!/plugins
+!/plugins/android.json
+!/plugins/fetch.json
+plugins/*
+platforms/*
+
+/www/*
+node_modules/*
+/node_modules/*
+www/index.js
+js/**/*.js
+js/**/*.js.map
+.env
+
+#idea-ide
+/.idea/*
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..a55e7a1
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 103dbef..94a25f7 100755
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -2,12 +2,5 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 0000000..fd29596
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,2 @@
+# OS X
+.DS_Store
diff --git a/bin/afterUpdate.sh b/bin/afterUpdate.sh
deleted file mode 100755
index b31ff4b..0000000
--- a/bin/afterUpdate.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-
-cd $(dirname "$0")/..
-
-sourceDir=dist/public/*
-jsSourceDir=dist/js/
-scssSourdeDir=pwa/scss/
-
-rm -rf src/scss/lib
-
-mkdir -p src/js/lib/
-mkdir -p src/scss/lib/
-
-for d in "vendor/ainias/pwa"*/; do
-
- find $d$jsSourceDir -name '*.js' -exec cp -r '{}' src/js/lib/ \;
- find $d$scssSourdeDir -name '*.scss' -exec cp -r '{}' src/scss/lib/ \;
- cp -r -R $d$sourceDir public/
-done
-
-node bin/concatTranslator.js
-node bin/createImportScss.js
-
-bin/build.sh
\ No newline at end of file
diff --git a/bin/build.js b/bin/build.js
deleted file mode 100755
index f7b35de..0000000
--- a/bin/build.js
+++ /dev/null
@@ -1,91 +0,0 @@
-const shouldIncludeSourcemap = (process.argv.length >= 3 && process.argv[2] === "2");
-
-const shouldMangleAndTranspile = shouldIncludeSourcemap || (process.argv.length >= 3 && process.argv[2] === "1");
-// const shouldMangleAndTranspile = (process.argv.wordLength >= 3 && process.argv[2] === "1"); || true;
-
-const rollup = require('rollup');
-const fs = require('fs');
-
-var uglifyJs = null;
-var babel = null;
-var regenerator = null;
-
-if (shouldMangleAndTranspile) {
- uglifyJs = require('uglify-es');
- babel = require('babel-core');
- regenerator = require('regenerator');
-}
-let uglifyOptions = {
- ecma: "es6",
- mangle: {
- // ecma:"es6",
- properties: {
- keep_quoted: true,
- builtins: false,
- reserved: require('../node_modules/uglify-es/tools/domprops')
- },
- // toplevel: true
- },
- output: {
- beautify: true
- }
-};
-
-let uglifyOptions2 = {
- mangle: {toplevel: true}, compress: {
- keep_fargs: false,
- toplevel: true,
- dead_code: true,
- unused: true,
- passes: 1,
-
- },
-};
-
-let babelOptions = {
- compact: true,
- minified: true,
- presets: ['env'],
- // sourceMaps:"inline",
- // plugins: ["regenerator-runtime"]
-};
-
-let regeneratorOptions = {
- includeRuntime: true,
- // sourceMaps:"inline",
-};
-
-if (shouldIncludeSourcemap){
- uglifyOptions["sourceMap"] = {url: "inline"};
- uglifyOptions2["sourceMap"] = {url: "inline", content: "inline"};
- babelOptions["sourceMaps"] = "inline";
- regeneratorOptions["sourceMaps"] = "inline";
-}
-
-const options = require('../rollup.config');
-const outputOptions = options.output;
-options.output = null;
-const inputOptions = options;
-
-async function build() {
- const bundle = await rollup.rollup(inputOptions);
- for (let i = 0, n = outputOptions.length; i < n; i++) {
- let {code, map} = await bundle.generate(outputOptions[i]);
- if (shouldMangleAndTranspile) {
-
- const uglifyRes = uglifyJs.minify(code, uglifyOptions);
- code = uglifyRes.code;
- // fs.writeFileSync('transpiled.js', code);
- const babelRes = babel.transform(code, babelOptions);
- code = babelRes.code;
- code = regenerator.compile(code, regeneratorOptions).code;
-
-
- const uglifyRes2 = uglifyJs.minify(code, uglifyOptions2);
- code = uglifyRes2.code;
- }
- fs.writeFileSync(outputOptions[i].file, code);
- }
-}
-
-build();
\ No newline at end of file
diff --git a/bin/build.sh b/bin/build.sh
deleted file mode 100755
index 303bef1..0000000
--- a/bin/build.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/usr/bin/env bash
-
-cd $(dirname "$0")/..
-npm run build
\ No newline at end of file
diff --git a/bin/concatTranslator.js b/bin/concatTranslator.js
deleted file mode 100755
index 73aa6a9..0000000
--- a/bin/concatTranslator.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const moduleDirs = ['src/module', 'vendor/ainias'];
-const outputDir = 'public/js/lang';
-
-const fs = require('fs');
-var translations = {};
-
-var currentLangs = [];
-for (var i = 2, n = process.argv.length; i < n; i++)
-{
- currentLangs.push(process.argv[i].split(".")[0]);
-}
-
-for (var i = 0, n = moduleDirs.length; i < n; i++) {
- var currentModuleDir = moduleDirs[i];
- var files = fs.readdirSync(currentModuleDir);
- files.forEach(file => {
- if (fs.existsSync(currentModuleDir + "/" + file + "/pwa/translations")) {
- var translationFiles = fs.readdirSync(currentModuleDir + "/" + file + "/pwa/translations");
- translationFiles.forEach(translationFile => {
- var language = translationFile.split('.')[0];
- if (currentLangs.length > 0 && currentLangs.indexOf(language) === -1)
- {
- return;
- }
- if (typeof translations[language] === 'undefined') {
- translations[language] = {};
- }
- var res = fs.readFileSync(currentModuleDir + "/" + file + "/pwa/translations/" + translationFile, 'utf8');
- var currentTranslations = JSON.parse(res);
- for (var key in currentTranslations) {
- translations[language][key] = currentTranslations[key];
- }
- });
- }
- });
-}
-
-for (var lang in translations)
-{
- // console.log(translations[lang]);
- var langTranslations = JSON.stringify(translations[lang]);
- fs.writeFile(outputDir+"/"+lang+".json", langTranslations, err => {
- if (err){
- throw err;
- }
- });
-}
\ No newline at end of file
diff --git a/bin/createImportScss.js b/bin/createImportScss.js
deleted file mode 100644
index e633189..0000000
--- a/bin/createImportScss.js
+++ /dev/null
@@ -1,59 +0,0 @@
-const dir = "src/scss/lib";
-const outputDir = "src/scss";
-
-const fs = require('fs');
-
-var settingsToImportString = "";
-var filesToImportString = "";
-
-var files = fs.readdirSync(dir);
-files.forEach(file => {
- let newFileName = file;
- if (!fs.lstatSync(dir + "/" + file).isDirectory()) {
-
- if (!file.startsWith("_")) {
- newFileName = "_" + newFileName;
- }
- if (file.endsWith("settings.scss") || file.endsWith("Settings.scss")){
- settingsToImportString += '@import "lib/' + newFileName + '";\n';
- }
- else{
- filesToImportString += '@import "lib/' + newFileName + '";\n';
- }
- fs.readFile(dir + "/" + file, 'utf8',function (err, data) {
- if (err) {
- return console.log(err);
- }
- // console.log(data.match(/@import "\.\.\//g));
- var result = data.replace(/@import "\.\.\//g, '@import "../../');
- result = result.replace(/@import "[a-zA-z].*[\n\r]/g, "");
- result = result.replace(/@import '\.\.\//g, "@import '../../");
- result = result.replace(/@import '[a-zA-z].*[\n\r]/g, "");
- // var result = data;
- // console.log(result);
-
- fs.unlink(dir + "/" + file, function (err) {
- if (err) return console.log(err);
- fs.writeFile(dir + "/" + newFileName, result, 'utf8', function (err) {
- if (err) return console.log(err);
- });
- });
- });
- }
-});
-
-fs.writeFile(outputDir + "/_defaultSettings.scss", settingsToImportString, err => {
- if (err) {
- throw err;
- }
-});
-
-// var newFileContent = settingsToImportString;
-var newFileContent = '@import "settings";\n';
-newFileContent += filesToImportString;
-
-fs.writeFile(outputDir + "/_imports.scss", newFileContent, err => {
- if (err) {
- throw err;
- }
-});
\ No newline at end of file
diff --git a/bin/localLink.sh b/bin/localLink.sh
deleted file mode 100755
index f95ebd8..0000000
--- a/bin/localLink.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/env bash
-
-cd $(dirname "$0")/..
-rm -rf /var/www/pwa/wordRotator/vendor/ainias/$2
-ln -s $1 /var/www/pwa/wordRotator/vendor/ainias/$2
diff --git a/bin/newModule b/bin/newModule
deleted file mode 100755
index 3b75c86..0000000
Binary files a/bin/newModule and /dev/null differ
diff --git a/bin/test.sh b/bin/test.sh
deleted file mode 100644
index 67d6ad1..0000000
--- a/bin/test.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env bash
-
-cd $(dirname "$0")/..
-
-testcafe firefox test/test.testcafe.js --debug-on-fail
-#node bin/testcafe.js;
\ No newline at end of file
diff --git a/bin/testcafe.js b/bin/testcafe.js
deleted file mode 100644
index 35385e0..0000000
--- a/bin/testcafe.js
+++ /dev/null
@@ -1,25 +0,0 @@
-'use strict';
-
-const createTestCafe = require('testcafe');
-const selfSignedSertificate = require('openssl-self-signed-certificate');
-let runner = null;
-
-const sslOptions = {
- key: selfSignedSertificate.key,
- cert: selfSignedSertificate.cert
-};
-
-createTestCafe('192.168.0.51', 5000, 5001, sslOptions).then(async testcafe => {
- runner = testcafe.createRunner();
-
- let remoteConnection = await testcafe.createBrowserConnection();
- console.log(remoteConnection.url);
-
- remoteConnection.once('ready', () => {
- console.log("testing...");
- return runner.src('test/test.testcafe.js').browsers(remoteConnection).run({debugOnFail: true}).then(failedCount => {
- testcafe.close();
- });
- });
-});
-
diff --git a/composer.json b/composer.json
deleted file mode 100755
index eb363b7..0000000
--- a/composer.json
+++ /dev/null
@@ -1,95 +0,0 @@
-{
- "name": "zendframework/skeleton-application",
- "description": "Skeleton Application for Zend Framework zend-mvc applications",
- "type": "project",
- "license": "BSD-3-Clause",
- "keywords": [
- "framework",
- "mvc",
- "zf2"
- ],
- "homepage": "http://framework.zend.com/",
- "minimum-stability": "dev",
- "prefer-stable": true,
- "require": {
- "php": "^7.0",
- "zendframework/zend-component-installer": "^1.0 || ^0.7 || ^1.0.0-dev@dev",
- "zendframework/zend-mvc": "^3.0.1",
- "zfcampus/zf-development-mode": "^3.0",
- "zendframework/zend-mvc-form": "^1.0",
- "zendframework/zend-json": "^3.0",
- "zendframework/zend-log": "^2.9",
- "zendframework/zend-mvc-console": "^1.1.10",
- "zendframework/zend-mvc-i18n": "^1.0",
- "zendframework/zend-mvc-plugins": "^1.0.1",
- "zendframework/zend-psr7bridge": "^0.2.2",
- "zendframework/zend-session": "^2.7.1",
- "zendframework/zend-servicemanager-di": "^1.0",
- "zendframework/zend-navigation": "^2.8",
- "zendframework/zend-modulemanager": "^2.7",
- "zendframework/zend-servicemanager": "^3.1",
- "zendframework/zend-mvc-plugin-flashmessenger": "^1.0",
- "zendframework/zend-mail": "^2.7",
- "zendframework/zend-permissions-acl": "^2.6",
- "ccampbell/chromephp": "^4.1",
- "doctrine/doctrine-module": "*",
- "doctrine/doctrine-orm-module": "^1.1",
-
- "ainias/pwa-zf-user-management": "dev-es6 as 0.0.10",
- "ainias/pwa-zf-cronjob":"dev-es6 as 0.0.10",
- "ainias/pwa-zf-code-management":"dev-es6 as 0.0.10",
- "ainias/pwa-zf-core":"dev-es6 as 0.0.10",
- "ainias/pwa-zf-contact": "dev-master as 0.0.10",
- "ainias/pwa-lib": "dev-es6 as 0.0.10",
- "ainias/pwa-assets": "dev-es6 as 0.0.10",
- "ext-json": "*"
- },
- "autoload": {
- "psr-4": {
- "Application\\": "src/module/Application/src/"
- }
- },
- "autoload-dev": {
- "psr-4": {}
- },
- "extra": [],
- "scripts": {
- "development-disable": "zf-development-mode disable",
- "development-enable": "zf-development-mode enable",
- "development-status": "zf-development-mode status",
- "serve": "php -S 0.0.0.0:8080 -t public/ public/index.php",
- "post-update-cmd": "./bin/afterUpdate.sh"
- },
- "require-dev": {
- },
- "repositories": [
- {
- "type": "vcs",
- "url": "silas.link:pwaContact"
- },
- {
- "type": "vcs",
- "url": "silas.link:pwaCore"
- },
- {
- "type":"vcs",
- "url":"silas.link:pwaLib"
- },
- {
- "type": "vcs",
- "url": "silas.link:pwaCronjob"
- },
- {
- "type":"vcs",
- "url":"silas.link:pwaCodeManagement"
- },
- {
- "type": "vcs",
- "url": "silas.link:pwaUserManagement"
- },
- {
- "type":"vcs",
- "url":"silas.link:pwaAssets"
- }
- ]
-}
diff --git a/config.xml b/config.xml
new file mode 100644
index 0000000..852344f
--- /dev/null
+++ b/config.xml
@@ -0,0 +1,39 @@
+
+
+ WordRotator
+
+ A word-game
+
+
+ Silas Günther
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/application.config.php b/config/application.config.php
deleted file mode 100755
index 8320e9e..0000000
--- a/config/application.config.php
+++ /dev/null
@@ -1,68 +0,0 @@
- require __DIR__ . '/modules.config.php',
-
- // These are various options for the listeners attached to the ModuleManager
- 'module_listener_options' => [
- // This should be an array of paths in which modules reside.
- // If a string key is provided, the listener will consider that a module
- // namespace, the value of that key the specific path to that module's
- // Module class.
- 'module_paths' => [
- './src/module',
- './vendor',
- ],
-
- // An array of paths from which to glob configuration files after
- // modules are loaded. These effectively override configuration
- // provided by modules themselves. Paths may use GLOB_BRACE notation.
- 'config_glob_paths' => [
- realpath(__DIR__) . '/autoload/{,*.}global.php',
- realpath(__DIR__) . '/autoload/local.php',
- ],
-
- // Whether or not to enable a configuration cache.
- // If enabled, the merged configuration will be cached and used in
- // subsequent requests.
- 'config_cache_enabled' => true,
-
- // The key used to create the configuration cache file name.
- 'config_cache_key' => 'application.config.cache',
-
- // Whether or not to enable a module class map cache.
- // If enabled, creates a module class map cache which will be used
- // by in future requests, to reduce the autoloading process.
- 'module_map_cache_enabled' => true,
-
- // The key used to create the class map cache file name.
- 'module_map_cache_key' => 'application.module.cache',
-
- // The path in which to cache merged configuration.
- 'cache_dir' => 'data/cache/',
-
- // Whether or not to enable modules dependency checking.
- // Enabled by default, prevents usage of modules that depend on other modules
- // that weren't loaded.
- // 'check_dependencies' => true,
- ],
-
- // Used to create an own service manager. May contain one or more child arrays.
- //'service_listener_options' => [
- // [
- // 'service_manager' => $stringServiceManagerName,
- // 'config_key' => $stringConfigKey,
- // 'interface' => $stringOptionalInterface,
- // 'method' => $stringRequiredMethodName,
- // ],
- // ],
-
- // Initial configuration with which to seed the ServiceManager.
- // Should be compatible with Zend\ServiceManager\Config.
- // 'service_manager' => [],
-];
diff --git a/config/autoload/beta.local.php b/config/autoload/beta.local.php
deleted file mode 100644
index 920ed4b..0000000
--- a/config/autoload/beta.local.php
+++ /dev/null
@@ -1,57 +0,0 @@
- [
- 'connection' => array(
- 'default' => array(
- 'params' => [
- 'user' => 'silas',
- 'password' => 'AbGonWigogNulfAyp',
- 'host' => '127.0.0.1',
- 'dbname' => 'silas_beta_wordRotator',
- 'driverOptions' => array(
- PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
- ),
- 'useStrict' => true,
- ],
- ),
- ),
- ],
- 'mailEinstellungen' => array(
- 'options' => array(
- 'name' => 'WordRotator - Beta',
- 'host' => 'eltanin.uberspace.de',
- 'port' => '587',
- 'connection_class' => 'plain', // plain oder login
- 'connection_config' => array(
- 'username' => 'silas',
- 'password' => 'l$?%usN\\Oj\\/l0VQ%IF',
- 'ssl' => 'tls',
- ),
- ),
- 'sender' => 'beta@silas.link',
- ),
-
- "contact" => [
- "prefix" => "[WR]",
- "contact-email" => "beta@silas.link",
- "contact-name" => "Admin",
- ],
-
- 'systemvariablen' => array(
- 'passwordHash' => 'hencxkgj',
- 'websiteName' => 'WordRotator - Beta',
- 'maxAgeOfUserCodes' => 2 //In Tagen
- ),
-];
diff --git a/config/autoload/global.php b/config/autoload/global.php
deleted file mode 100755
index 7363390..0000000
--- a/config/autoload/global.php
+++ /dev/null
@@ -1,69 +0,0 @@
- array(
- 'driver' => 'Pdo',
- 'driver_options' => array(
- PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
- ),
- 'charset' => "UTF8",
- ),
-
- 'appVariables' => [
- ],
-
- 'doctrine' => array(
- 'driver' => array(
- 'entities' => array(
- 'class' => \Doctrine\ORM\Mapping\Driver\AnnotationDriver::class,
- 'cache' => 'array',
- ),
- ),
- ),
-
- 'session_config' => array(
- 'options' => array(
- 'name' => 'silasLinkId',
- 'cookie_httponly' => true,
- ),
-// 'storage' => 'Zend\Session\Storage\SessionArrayStorage',
-// 'validators' =>
- ),
- 'session_storage' => array(
- 'type' => Session\Storage\SessionArrayStorage::class,
- ),
- 'session_validators' => array(
- 'Zend\Session\Validator\RemoteAddr',
- 'Zend\Session\Validator\HttpUserAgent',
- ),
-
- 'session' => [
- 'config' => [
- 'class' => Session\Config\SessionConfig::class,
- 'options' => [
- 'name' => 'myapp',
- ],
- ],
- 'storage' => Session\Storage\SessionArrayStorage::class,
- 'validators' => [
-// Session\Validator\RemoteAddr::class,
-// Session\Validator\HttpUserAgent::class,
- ],
- ],
-
- "userManager" => [
- "canRegister" => false
- ],
-];
diff --git a/config/autoload/local.php b/config/autoload/local.php
deleted file mode 100755
index 025f072..0000000
--- a/config/autoload/local.php
+++ /dev/null
@@ -1,72 +0,0 @@
- [
- 'connection' => array(
- 'default' => array(
- 'params' => [
- 'user' => 'root',
- 'password' => '123456',
- 'host' => '127.0.0.1',
- 'dbname' => 'silas_wordRotator',
- 'driverOptions' => array(
- PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
- ),
- 'useStrict' => true,
- 'charset' => 'utf8'
- ],
- ),
- ),
- ],
- 'mailEinstellungen' => array(
- 'options' => array(
- 'name' => 'Stories',
- 'host' => 'eltanin.uberspace.de',
- 'port' => '587',
- 'connection_class' => 'plain', // plain oder login
- 'connection_config' => array(
- 'username' => 'silas',
- 'password' => 'l$?%usN\\Oj\\/l0VQ%IF',
- 'ssl' => 'tls',
- ),
- ),
- 'sender' => 'local@silas.link',
- ),
-
- "contact" => [
- "prefix" => "[WR]",
- "contact-email" => "wordrotator@silas.link",
- "contact-name" => "Admin",
- ],
-
- 'systemVariables' => array(
- 'passwordHash' => '123',
- 'websiteName' => '',
- 'maxAgeOfUserCodes' => 2 //In Tagen
- ),
- 'view_manager' => [
- 'display_exceptions' => true,
- ],
- "userManager" => [
- "canRegister" => true
- ],
-];
diff --git a/config/autoload/prod.local.php b/config/autoload/prod.local.php
deleted file mode 100755
index 1f09614..0000000
--- a/config/autoload/prod.local.php
+++ /dev/null
@@ -1,57 +0,0 @@
- [
- 'connection' => array(
- 'default' => array(
- 'params' => [
- 'user' => 'silas',
- 'password' => 'AbGonWigogNulfAyp',
- 'host' => '127.0.0.1',
- 'dbname' => 'silas_WordRotator',
- 'driverOptions' => array(
- PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
- ),
- 'useStrict' => true,
- ],
- ),
- ),
- ],
- 'mailEinstellungen' => array(
- 'options' => array(
- 'name' => 'WordRotator',
- 'host' => 'eltanin.uberspace.de',
- 'port' => '587',
- 'connection_class' => 'plain', // plain oder login
- 'connection_config' => array(
- 'username' => 'silas',
- 'password' => 'l$?%usN\\Oj\\/l0VQ%IF',
- 'ssl' => 'tls',
- ),
- ),
- 'sender' => 'wordRotator@silas.link',
- ),
-
- "contact" => [
- "prefix" => "[WR]",
- "contact-email" => "wordrotator@silas.link",
- "contact-name" => "Admin",
- ],
-
- 'systemvariablen' => array(
- 'passwordHash' => 'kxykgdgkhxyfbgxhjipab-lmk 'WordRotator',
- 'maxAgeOfUserCodes' => 2 //In Tagen
- ),
-];
diff --git a/config/autoload/test.local.php b/config/autoload/test.local.php
deleted file mode 100644
index e5ed5c4..0000000
--- a/config/autoload/test.local.php
+++ /dev/null
@@ -1,51 +0,0 @@
- [
- 'connection' => array(
- 'default' => array(
- 'params' => [
- 'user' => 'root',
- 'password' => '123456',
- 'host' => '127.0.0.1',
- 'dbname' => 'silas_beta_wordRotator',
- 'driverOptions' => array(
- PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
- ),
- 'useStrict' => true,
- ],
- ),
- ),
- ],
- 'mailEinstellungen' => array(
- 'options' => array(
- 'name' => 'test.wordrotator',
- 'host' => 'eltanin.uberspace.de',
- 'port' => '587',
- 'connection_class' => 'plain', // plain oder login
- 'connection_config' => array(
- 'username' => 'silas',
- 'password' => 'l$?%usN\\Oj\\/l0VQ%IF',
- 'ssl' => 'tls',
- ),
- ),
- 'sender' => 'test.framework@silas.link',
- ),
- "contact" => [
- "prefix" => "[WR]",
- "contact-email" => "local@silas.link",
- "contact-name" => "Admin",
- ],
-
- 'systemVariables' => array(
- 'passwordHash' => 'sdvsdg',
- 'websiteName' => 'Test.WordRotator',
- 'maxAgeOfUserCodes' => 2 //In Tagen
- ),
- 'view_manager' => [
- 'display_exceptions' => true,
- ],
- "userManager" => [
- "canRegister" => true
- ],
-];
\ No newline at end of file
diff --git a/config/autoload/zend-developer-tools.local-development.php b/config/autoload/zend-developer-tools.local-development.php
deleted file mode 100755
index 843978d..0000000
--- a/config/autoload/zend-developer-tools.local-development.php
+++ /dev/null
@@ -1,159 +0,0 @@
- [
- /**
- * General Profiler settings
- */
- 'profiler' => [
- /**
- * Enables or disables the profiler.
- *
- * Expects: bool
- * Default: true
- */
- 'enabled' => true,
-
- /**
- * Enables or disables the strict mode. If the strict mode is enabled, any error will throw an exception,
- * otherwise all errors will be added to the report (and shown in the toolbar).
- *
- * Expects: bool
- * Default: true
- */
- 'strict' => true,
-
- /**
- * If enabled, the profiler tries to flush the content before the it starts collecting data. This option
- * will be ignored if the Toolbar is enabled.
- *
- * Note: The flush listener listens to the MvcEvent::EVENT_FINISH event with a priority of -9400. You have
- * to disable this function if you wish to modify the output with a lower priority.
- *
- * Expects: bool
- * Default: false
- */
- 'flush_early' => false,
-
- /**
- * The cache directory is used in the version check and for every storage type that writes to the disk.
- * Note: The default value assumes that the current working directory is the application root.
- *
- * Expects: string
- * Default: 'data/cache'
- */
- 'cache_dir' => 'data/cache',
-
- /**
- * If a matches is defined, the profiler will be disabled if the request does not match the pattern.
- *
- * Example: 'matcher' => array('ip' => '127.0.0.1')
- * OR
- * 'matcher' => array('url' => array('path' => '/admin')
- * Note: The matcher is not implemented yet!
- */
- 'matcher' => [],
-
- /**
- * Contains a list with all collector the profiler should run. Zend Developer Tools ships with
- * 'db' (Zend\Db), 'time', 'event', 'memory', 'exception', 'request' and 'mail' (Zend\Mail). If you wish to
- * disable a default collector, simply set the value to null or false.
- *
- * Example: 'collectors' => array('db' => null)
- * Expects: array
- */
- 'collectors' => [],
- ],
- 'events' => [
- /**
- * Set to true to enable event-level logging for collectors that will support it. This enables a wildcard
- * listener onto the shared event manager that will allow profiling of user-defined events as well as the
- * built-in ZF events.
- *
- * Expects: bool
- * Default: false
- */
- 'enabled' => true,
-
- /**
- * Contains a list with all event-level collectors that should run. Zend Developer Tools ships with 'time'
- * and 'memory'. If you wish to disable a default collector, simply set the value to null or false.
- *
- * Example: 'collectors' => array('memory' => null)
- * Expects: array
- */
- 'collectors' => [],
-
- /**
- * Contains event identifiers used with the event listener. Zend Developer Tools defaults to listen to all
- * events. If you wish to disable the default all-inclusive identifier, simply set the value to null or
- * false.
- *
- * Example: 'identifiers' => array('all' => null, 'dispatchable' => 'Zend\Stdlib\DispatchableInterface')
- * Expects: array
- */
- 'identifiers' => [],
- ],
- /**
- * General Toolbar settings
- */
- 'toolbar' => [
- /**
- * Enables or disables the Toolbar.
- *
- * Expects: bool
- * Default: false
- */
- 'enabled' => true,
-
- /**
- * If enabled, every empty collector will be hidden.
- *
- * Expects: bool
- * Default: false
- */
- 'auto_hide' => false,
-
- /**
- * The Toolbar position.
- *
- * Expects: string ('bottom' or 'top')
- * Default: bottom
- */
- 'position' => 'bottom',
-
- /**
- * If enabled, the Toolbar will check if your current Zend Framework version is up-to-date.
- * Note: The check will only occur once every hour.
- *
- * Expects: bool
- * Default: false
- */
- 'version_check' => false,
-
- /**
- * Contains a list with all collector toolbar templates. The name of the array key must be same as the name
- * of the collector.
- *
- * Example: 'profiler' => array(
- * 'collectors' => array(
- * // My_Collector_Example::getName() -> mycollector
- * 'MyCollector' => 'My_Collector_Example',
- * )
- * ),
- * 'toolbar' => array(
- * 'entries' => array(
- * 'mycollector' => 'example/toolbar/my-collector',
- * )
- * ),
- * Expects: array
- */
- 'entries' => [],
- ],
- ],
-];
diff --git a/config/development.config.php b/config/development.config.php
deleted file mode 100755
index 27302ee..0000000
--- a/config/development.config.php
+++ /dev/null
@@ -1,15 +0,0 @@
- [
-// 'ZendDeveloperTools',
-// 'ZendDeveloperToolsTime',
- ],
- // Configuration overrides during development mode
- 'module_listener_options' => [
- 'config_glob_paths' => [realpath(__DIR__) . '/autoload/{,*.}{global,local}-development.php'],
- 'config_cache_enabled' => false,
- 'module_map_cache_enabled' => false,
- ],
-];
diff --git a/config/modules.config.php b/config/modules.config.php
deleted file mode 100755
index f6823e2..0000000
--- a/config/modules.config.php
+++ /dev/null
@@ -1,37 +0,0 @@
-= 9",
+ "android >= 4.4",
+ "ios >= 7"
+ ]
+}
\ No newline at end of file
diff --git a/postcss.config.js b/postcss.config.js
deleted file mode 100755
index 57fd842..0000000
--- a/postcss.config.js
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = {
- plugins: [
- require('autoprefixer')({}),
- require('cssnano')({reduceIdents:false, zindex:false})
- ]
-};
diff --git a/public/.htaccess b/public/.htaccess
deleted file mode 100755
index c2e1a8e..0000000
--- a/public/.htaccess
+++ /dev/null
@@ -1,51 +0,0 @@
-RewriteEngine On
-
-RewriteCond %{HTTPS} !=on
-RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
-
-RewriteRule ^\.htaccess$ - [F]
-# The following rule tells Apache that if the requested filename
-# exists, simply serve it.
-RewriteCond %{REQUEST_FILENAME} -s [OR]
-RewriteCond %{REQUEST_FILENAME} -l [OR]
-RewriteCond %{REQUEST_FILENAME} -d
-RewriteRule ^.*$ - [L]
-# The following rewrites all other queries to index.php. The
-# condition ensures that if you are using Apache aliases to do
-# mass virtual hosting or installed the project in a subdirectory,
-# the base path will be prepended to allow proper resolution of
-# the index.php file; it will work in non-aliased environments
-# as well, providing a safe, one-size fits all solution.
-#RewriteCond %{REQUEST_URI}::$1 ^/((data|cached)/.*)::\2$
-#RewriteRule ^(.*)$ %{ENV:BASE}/data.php [L]
-
-RewriteCond %{REQUEST_URI}::$1 ^(/?.*)/((data|cached)/.*)::\2$
-RewriteRule ^(.*) - [E=BASE:%1]
-RewriteCond %{REQUEST_URI}::$1 ^(/?.*)/((data|cached)/.*)::\2$
-RewriteRule ^(.*)$ %{ENV:BASE}/data.php [L]
-
-RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
-RewriteRule ^(.*) - [E=BASE:%1]
-RewriteRule ^(.*)$ %{ENV:BASE}/index.html [L]
-
-Options -Indexes
-
-
- AddType application/x-javascript .js
- AddType text/css .css
-
-
- SetOutputFilter DEFLATE
-
- SetEnvIfNoCase Request_URI \.(?:rar|zip)$ no-gzip dont-vary
- SetEnvIfNoCase Request_URI \.(?:gif|jpg|png)$ no-gzip dont-vary
- SetEnvIfNoCase Request_URI \.(?:avi|mov|mp4)$ no-gzip dont-vary
- SetEnvIfNoCase Request_URI \.mp3$ no-gzip dont-vary
- BrowserMatch ^Mozilla/4 gzip-only-text/html
- BrowserMatch ^Mozilla/4\.0[678] no-gzip
- BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
-
-
- Header append Vary User-Agent env=!dont-vary
-
-
diff --git a/public/core/html/load.html b/public/core/html/load.html
deleted file mode 100755
index f230103..0000000
--- a/public/core/html/load.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/core/html/settings.html b/public/core/html/settings.html
deleted file mode 100755
index c529cb0..0000000
--- a/public/core/html/settings.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/core/html/smartList.html b/public/core/html/smartList.html
deleted file mode 100755
index 7ae785a..0000000
--- a/public/core/html/smartList.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/css/foundation.css b/public/css/foundation.css
deleted file mode 100644
index f579e52..0000000
--- a/public/css/foundation.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@charset "UTF-8";
-/*! normalize-scss | MIT/GPLv2 License | bit.ly/normalize-scss */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure{display:block}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}main{display:block}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:inherit;font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}input{overflow:visible}[type=checkbox],[type=radio]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{-webkit-box-sizing:border-box;box-sizing:border-box;display:table;padding:0;color:inherit;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}details{display:block}summary{display:list-item}menu{display:block}canvas{display:inline-block}[hidden],template{display:none}.foundation-mq{font-family:"small=0em&smedium=25em&medium=40em&large=64em&xlarge=75em&xxlarge=90em"}html{-webkit-box-sizing:border-box;box-sizing:border-box;font-size:100%}*,:after,:before{-webkit-box-sizing:inherit;box-sizing:inherit}body{margin:0;padding:0;background:#fefefe;font-family:Helvetica Neue,Helvetica,Roboto,Arial,sans-serif;font-weight:400;line-height:1.5;color:#0a0a0a;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}img{display:inline-block;vertical-align:middle;max-width:100%;height:auto;-ms-interpolation-mode:bicubic}textarea{height:auto;min-height:50px;border-radius:0}select{-webkit-box-sizing:border-box;box-sizing:border-box;width:100%}.map_canvas embed,.map_canvas img,.map_canvas object,.mqa-display embed,.mqa-display img,.mqa-display object{max-width:none!important}button{padding:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:0;border-radius:0;background:transparent;line-height:1;cursor:auto}[data-whatinput=mouse] button{outline:0}pre{overflow:auto}button,input,optgroup,select,textarea{font-family:inherit}.is-visible{display:block!important}.hide,.is-hidden{display:none!important}.invisible{visibility:hidden}@media screen and (max-width:24.9375em){.hide-for-small-only{display:none!important}}@media screen and (max-width:0em),screen and (min-width:25em){.show-for-small-only{display:none!important}}@media screen and (min-width:25em){.hide-for-smedium{display:none!important}}@media screen and (max-width:24.9375em){.show-for-smedium{display:none!important}}@media screen and (min-width:25em) and (max-width:39.9375em){.hide-for-smedium-only{display:none!important}}@media screen and (max-width:24.9375em),screen and (min-width:40em){.show-for-smedium-only{display:none!important}}@media print,screen and (min-width:40em){.hide-for-medium{display:none!important}}@media screen and (max-width:39.9375em){.show-for-medium{display:none!important}}@media screen and (min-width:40em) and (max-width:63.9375em){.hide-for-medium-only{display:none!important}}@media screen and (max-width:39.9375em),screen and (min-width:64em){.show-for-medium-only{display:none!important}}@media print,screen and (min-width:64em){.hide-for-large{display:none!important}}@media screen and (max-width:63.9375em){.show-for-large{display:none!important}}@media screen and (min-width:64em) and (max-width:74.9375em){.hide-for-large-only{display:none!important}}@media screen and (max-width:63.9375em),screen and (min-width:75em){.show-for-large-only{display:none!important}}.show-for-sr,.show-on-focus{position:absolute!important;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;-webkit-clip-path:inset(50%);clip-path:inset(50%);border:0}.show-on-focus:active,.show-on-focus:focus{position:static!important;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal;-webkit-clip-path:none;clip-path:none}.hide-for-portrait,.show-for-landscape{display:block!important}@media screen and (orientation:landscape){.hide-for-portrait,.show-for-landscape{display:block!important}}@media screen and (orientation:portrait){.hide-for-portrait,.show-for-landscape{display:none!important}}.hide-for-landscape,.show-for-portrait{display:none!important}@media screen and (orientation:landscape){.hide-for-landscape,.show-for-portrait{display:none!important}}@media screen and (orientation:portrait){.hide-for-landscape,.show-for-portrait{display:block!important}}.row{max-width:75rem;margin-right:auto;margin-left:auto}.row:after,.row:before{display:table;content:" "}.row:after{clear:both}.row.collapse>.column,.row.collapse>.columns{padding-right:0;padding-left:0}.row .row{margin-right:-.625rem;margin-left:-.625rem}@media screen and (min-width:25em){.row .row{margin-right:-.625rem;margin-left:-.625rem}}@media print,screen and (min-width:40em){.row .row{margin-right:-.9375rem;margin-left:-.9375rem}}@media print,screen and (min-width:64em){.row .row{margin-right:-.9375rem;margin-left:-.9375rem}}.row .row.collapse{margin-right:0;margin-left:0}.row.expanded{max-width:none}.row.expanded .row{margin-right:auto;margin-left:auto}.row:not(.expanded) .row{max-width:none}.row.gutter-small>.column,.row.gutter-small>.columns{padding-right:.625rem;padding-left:.625rem}.row.gutter-medium>.column,.row.gutter-medium>.columns{padding-right:.9375rem;padding-left:.9375rem}.column,.columns{width:100%;float:left;padding-right:.625rem;padding-left:.625rem}@media print,screen and (min-width:40em){.column,.columns{padding-right:.9375rem;padding-left:.9375rem}}.column:last-child:not(:first-child),.columns:last-child:not(:first-child){float:right}.column.end:last-child:last-child,.end.columns:last-child:last-child{float:left}.column.row.row,.row.row.columns{float:none}.row .column.row.row,.row .row.row.columns{margin-right:0;margin-left:0;padding-right:0;padding-left:0}.small-1{width:8.3333333333%}.small-push-1{position:relative;left:8.3333333333%}.small-pull-1{position:relative;left:-8.3333333333%}.small-offset-0{margin-left:0}.small-2{width:16.6666666667%}.small-push-2{position:relative;left:16.6666666667%}.small-pull-2{position:relative;left:-16.6666666667%}.small-offset-1{margin-left:8.3333333333%}.small-3{width:25%}.small-push-3{position:relative;left:25%}.small-pull-3{position:relative;left:-25%}.small-offset-2{margin-left:16.6666666667%}.small-4{width:33.3333333333%}.small-push-4{position:relative;left:33.3333333333%}.small-pull-4{position:relative;left:-33.3333333333%}.small-offset-3{margin-left:25%}.small-5{width:41.6666666667%}.small-push-5{position:relative;left:41.6666666667%}.small-pull-5{position:relative;left:-41.6666666667%}.small-offset-4{margin-left:33.3333333333%}.small-6{width:50%}.small-push-6{position:relative;left:50%}.small-pull-6{position:relative;left:-50%}.small-offset-5{margin-left:41.6666666667%}.small-7{width:58.3333333333%}.small-push-7{position:relative;left:58.3333333333%}.small-pull-7{position:relative;left:-58.3333333333%}.small-offset-6{margin-left:50%}.small-8{width:66.6666666667%}.small-push-8{position:relative;left:66.6666666667%}.small-pull-8{position:relative;left:-66.6666666667%}.small-offset-7{margin-left:58.3333333333%}.small-9{width:75%}.small-push-9{position:relative;left:75%}.small-pull-9{position:relative;left:-75%}.small-offset-8{margin-left:66.6666666667%}.small-10{width:83.3333333333%}.small-push-10{position:relative;left:83.3333333333%}.small-pull-10{position:relative;left:-83.3333333333%}.small-offset-9{margin-left:75%}.small-11{width:91.6666666667%}.small-push-11{position:relative;left:91.6666666667%}.small-pull-11{position:relative;left:-91.6666666667%}.small-offset-10{margin-left:83.3333333333%}.small-12{width:100%}.small-offset-11{margin-left:91.6666666667%}.small-up-1>.column,.small-up-1>.columns{float:left;width:100%}.small-up-1>.column:nth-of-type(1n),.small-up-1>.columns:nth-of-type(1n){clear:none}.small-up-1>.column:nth-of-type(1n+1),.small-up-1>.columns:nth-of-type(1n+1){clear:both}.small-up-1>.column:last-child,.small-up-1>.columns:last-child{float:left}.small-up-2>.column,.small-up-2>.columns{float:left;width:50%}.small-up-2>.column:nth-of-type(1n),.small-up-2>.columns:nth-of-type(1n){clear:none}.small-up-2>.column:nth-of-type(odd),.small-up-2>.columns:nth-of-type(odd){clear:both}.small-up-2>.column:last-child,.small-up-2>.columns:last-child{float:left}.small-up-3>.column,.small-up-3>.columns{float:left;width:33.3333333333%}.small-up-3>.column:nth-of-type(1n),.small-up-3>.columns:nth-of-type(1n){clear:none}.small-up-3>.column:nth-of-type(3n+1),.small-up-3>.columns:nth-of-type(3n+1){clear:both}.small-up-3>.column:last-child,.small-up-3>.columns:last-child{float:left}.small-up-4>.column,.small-up-4>.columns{float:left;width:25%}.small-up-4>.column:nth-of-type(1n),.small-up-4>.columns:nth-of-type(1n){clear:none}.small-up-4>.column:nth-of-type(4n+1),.small-up-4>.columns:nth-of-type(4n+1){clear:both}.small-up-4>.column:last-child,.small-up-4>.columns:last-child{float:left}.small-up-5>.column,.small-up-5>.columns{float:left;width:20%}.small-up-5>.column:nth-of-type(1n),.small-up-5>.columns:nth-of-type(1n){clear:none}.small-up-5>.column:nth-of-type(5n+1),.small-up-5>.columns:nth-of-type(5n+1){clear:both}.small-up-5>.column:last-child,.small-up-5>.columns:last-child{float:left}.small-up-6>.column,.small-up-6>.columns{float:left;width:16.6666666667%}.small-up-6>.column:nth-of-type(1n),.small-up-6>.columns:nth-of-type(1n){clear:none}.small-up-6>.column:nth-of-type(6n+1),.small-up-6>.columns:nth-of-type(6n+1){clear:both}.small-up-6>.column:last-child,.small-up-6>.columns:last-child{float:left}.small-up-7>.column,.small-up-7>.columns{float:left;width:14.2857142857%}.small-up-7>.column:nth-of-type(1n),.small-up-7>.columns:nth-of-type(1n){clear:none}.small-up-7>.column:nth-of-type(7n+1),.small-up-7>.columns:nth-of-type(7n+1){clear:both}.small-up-7>.column:last-child,.small-up-7>.columns:last-child{float:left}.small-up-8>.column,.small-up-8>.columns{float:left;width:12.5%}.small-up-8>.column:nth-of-type(1n),.small-up-8>.columns:nth-of-type(1n){clear:none}.small-up-8>.column:nth-of-type(8n+1),.small-up-8>.columns:nth-of-type(8n+1){clear:both}.small-up-8>.column:last-child,.small-up-8>.columns:last-child{float:left}.small-collapse>.column,.small-collapse>.columns{padding-right:0;padding-left:0}.expanded.row .small-collapse.row,.small-collapse .row{margin-right:0;margin-left:0}.small-uncollapse>.column,.small-uncollapse>.columns{padding-right:.625rem;padding-left:.625rem}.small-centered{margin-right:auto;margin-left:auto}.small-centered,.small-centered:last-child:not(:first-child){float:none;clear:both}.small-pull-0,.small-push-0,.small-uncentered{position:static;float:left;margin-right:0;margin-left:0}@media screen and (min-width:25em){.smedium-1{width:8.3333333333%}.smedium-push-1{position:relative;left:8.3333333333%}.smedium-pull-1{position:relative;left:-8.3333333333%}.smedium-offset-0{margin-left:0}.smedium-2{width:16.6666666667%}.smedium-push-2{position:relative;left:16.6666666667%}.smedium-pull-2{position:relative;left:-16.6666666667%}.smedium-offset-1{margin-left:8.3333333333%}.smedium-3{width:25%}.smedium-push-3{position:relative;left:25%}.smedium-pull-3{position:relative;left:-25%}.smedium-offset-2{margin-left:16.6666666667%}.smedium-4{width:33.3333333333%}.smedium-push-4{position:relative;left:33.3333333333%}.smedium-pull-4{position:relative;left:-33.3333333333%}.smedium-offset-3{margin-left:25%}.smedium-5{width:41.6666666667%}.smedium-push-5{position:relative;left:41.6666666667%}.smedium-pull-5{position:relative;left:-41.6666666667%}.smedium-offset-4{margin-left:33.3333333333%}.smedium-6{width:50%}.smedium-push-6{position:relative;left:50%}.smedium-pull-6{position:relative;left:-50%}.smedium-offset-5{margin-left:41.6666666667%}.smedium-7{width:58.3333333333%}.smedium-push-7{position:relative;left:58.3333333333%}.smedium-pull-7{position:relative;left:-58.3333333333%}.smedium-offset-6{margin-left:50%}.smedium-8{width:66.6666666667%}.smedium-push-8{position:relative;left:66.6666666667%}.smedium-pull-8{position:relative;left:-66.6666666667%}.smedium-offset-7{margin-left:58.3333333333%}.smedium-9{width:75%}.smedium-push-9{position:relative;left:75%}.smedium-pull-9{position:relative;left:-75%}.smedium-offset-8{margin-left:66.6666666667%}.smedium-10{width:83.3333333333%}.smedium-push-10{position:relative;left:83.3333333333%}.smedium-pull-10{position:relative;left:-83.3333333333%}.smedium-offset-9{margin-left:75%}.smedium-11{width:91.6666666667%}.smedium-push-11{position:relative;left:91.6666666667%}.smedium-pull-11{position:relative;left:-91.6666666667%}.smedium-offset-10{margin-left:83.3333333333%}.smedium-12{width:100%}.smedium-offset-11{margin-left:91.6666666667%}.smedium-up-1>.column,.smedium-up-1>.columns{float:left;width:100%}.smedium-up-1>.column:nth-of-type(1n),.smedium-up-1>.columns:nth-of-type(1n){clear:none}.smedium-up-1>.column:nth-of-type(1n+1),.smedium-up-1>.columns:nth-of-type(1n+1){clear:both}.smedium-up-1>.column:last-child,.smedium-up-1>.columns:last-child{float:left}.smedium-up-2>.column,.smedium-up-2>.columns{float:left;width:50%}.smedium-up-2>.column:nth-of-type(1n),.smedium-up-2>.columns:nth-of-type(1n){clear:none}.smedium-up-2>.column:nth-of-type(odd),.smedium-up-2>.columns:nth-of-type(odd){clear:both}.smedium-up-2>.column:last-child,.smedium-up-2>.columns:last-child{float:left}.smedium-up-3>.column,.smedium-up-3>.columns{float:left;width:33.3333333333%}.smedium-up-3>.column:nth-of-type(1n),.smedium-up-3>.columns:nth-of-type(1n){clear:none}.smedium-up-3>.column:nth-of-type(3n+1),.smedium-up-3>.columns:nth-of-type(3n+1){clear:both}.smedium-up-3>.column:last-child,.smedium-up-3>.columns:last-child{float:left}.smedium-up-4>.column,.smedium-up-4>.columns{float:left;width:25%}.smedium-up-4>.column:nth-of-type(1n),.smedium-up-4>.columns:nth-of-type(1n){clear:none}.smedium-up-4>.column:nth-of-type(4n+1),.smedium-up-4>.columns:nth-of-type(4n+1){clear:both}.smedium-up-4>.column:last-child,.smedium-up-4>.columns:last-child{float:left}.smedium-up-5>.column,.smedium-up-5>.columns{float:left;width:20%}.smedium-up-5>.column:nth-of-type(1n),.smedium-up-5>.columns:nth-of-type(1n){clear:none}.smedium-up-5>.column:nth-of-type(5n+1),.smedium-up-5>.columns:nth-of-type(5n+1){clear:both}.smedium-up-5>.column:last-child,.smedium-up-5>.columns:last-child{float:left}.smedium-up-6>.column,.smedium-up-6>.columns{float:left;width:16.6666666667%}.smedium-up-6>.column:nth-of-type(1n),.smedium-up-6>.columns:nth-of-type(1n){clear:none}.smedium-up-6>.column:nth-of-type(6n+1),.smedium-up-6>.columns:nth-of-type(6n+1){clear:both}.smedium-up-6>.column:last-child,.smedium-up-6>.columns:last-child{float:left}.smedium-up-7>.column,.smedium-up-7>.columns{float:left;width:14.2857142857%}.smedium-up-7>.column:nth-of-type(1n),.smedium-up-7>.columns:nth-of-type(1n){clear:none}.smedium-up-7>.column:nth-of-type(7n+1),.smedium-up-7>.columns:nth-of-type(7n+1){clear:both}.smedium-up-7>.column:last-child,.smedium-up-7>.columns:last-child{float:left}.smedium-up-8>.column,.smedium-up-8>.columns{float:left;width:12.5%}.smedium-up-8>.column:nth-of-type(1n),.smedium-up-8>.columns:nth-of-type(1n){clear:none}.smedium-up-8>.column:nth-of-type(8n+1),.smedium-up-8>.columns:nth-of-type(8n+1){clear:both}.smedium-up-8>.column:last-child,.smedium-up-8>.columns:last-child{float:left}.smedium-collapse>.column,.smedium-collapse>.columns{padding-right:0;padding-left:0}.expanded.row .smedium-collapse.row,.smedium-collapse .row{margin-right:0;margin-left:0}.smedium-uncollapse>.column,.smedium-uncollapse>.columns{padding-right:.625rem;padding-left:.625rem}.smedium-centered{margin-right:auto;margin-left:auto}.smedium-centered,.smedium-centered:last-child:not(:first-child){float:none;clear:both}.smedium-pull-0,.smedium-push-0,.smedium-uncentered{position:static;float:left;margin-right:0;margin-left:0}}@media print,screen and (min-width:40em){.medium-1{width:8.3333333333%}.medium-push-1{position:relative;left:8.3333333333%}.medium-pull-1{position:relative;left:-8.3333333333%}.medium-offset-0{margin-left:0}.medium-2{width:16.6666666667%}.medium-push-2{position:relative;left:16.6666666667%}.medium-pull-2{position:relative;left:-16.6666666667%}.medium-offset-1{margin-left:8.3333333333%}.medium-3{width:25%}.medium-push-3{position:relative;left:25%}.medium-pull-3{position:relative;left:-25%}.medium-offset-2{margin-left:16.6666666667%}.medium-4{width:33.3333333333%}.medium-push-4{position:relative;left:33.3333333333%}.medium-pull-4{position:relative;left:-33.3333333333%}.medium-offset-3{margin-left:25%}.medium-5{width:41.6666666667%}.medium-push-5{position:relative;left:41.6666666667%}.medium-pull-5{position:relative;left:-41.6666666667%}.medium-offset-4{margin-left:33.3333333333%}.medium-6{width:50%}.medium-push-6{position:relative;left:50%}.medium-pull-6{position:relative;left:-50%}.medium-offset-5{margin-left:41.6666666667%}.medium-7{width:58.3333333333%}.medium-push-7{position:relative;left:58.3333333333%}.medium-pull-7{position:relative;left:-58.3333333333%}.medium-offset-6{margin-left:50%}.medium-8{width:66.6666666667%}.medium-push-8{position:relative;left:66.6666666667%}.medium-pull-8{position:relative;left:-66.6666666667%}.medium-offset-7{margin-left:58.3333333333%}.medium-9{width:75%}.medium-push-9{position:relative;left:75%}.medium-pull-9{position:relative;left:-75%}.medium-offset-8{margin-left:66.6666666667%}.medium-10{width:83.3333333333%}.medium-push-10{position:relative;left:83.3333333333%}.medium-pull-10{position:relative;left:-83.3333333333%}.medium-offset-9{margin-left:75%}.medium-11{width:91.6666666667%}.medium-push-11{position:relative;left:91.6666666667%}.medium-pull-11{position:relative;left:-91.6666666667%}.medium-offset-10{margin-left:83.3333333333%}.medium-12{width:100%}.medium-offset-11{margin-left:91.6666666667%}.medium-up-1>.column,.medium-up-1>.columns{float:left;width:100%}.medium-up-1>.column:nth-of-type(1n),.medium-up-1>.columns:nth-of-type(1n){clear:none}.medium-up-1>.column:nth-of-type(1n+1),.medium-up-1>.columns:nth-of-type(1n+1){clear:both}.medium-up-1>.column:last-child,.medium-up-1>.columns:last-child{float:left}.medium-up-2>.column,.medium-up-2>.columns{float:left;width:50%}.medium-up-2>.column:nth-of-type(1n),.medium-up-2>.columns:nth-of-type(1n){clear:none}.medium-up-2>.column:nth-of-type(odd),.medium-up-2>.columns:nth-of-type(odd){clear:both}.medium-up-2>.column:last-child,.medium-up-2>.columns:last-child{float:left}.medium-up-3>.column,.medium-up-3>.columns{float:left;width:33.3333333333%}.medium-up-3>.column:nth-of-type(1n),.medium-up-3>.columns:nth-of-type(1n){clear:none}.medium-up-3>.column:nth-of-type(3n+1),.medium-up-3>.columns:nth-of-type(3n+1){clear:both}.medium-up-3>.column:last-child,.medium-up-3>.columns:last-child{float:left}.medium-up-4>.column,.medium-up-4>.columns{float:left;width:25%}.medium-up-4>.column:nth-of-type(1n),.medium-up-4>.columns:nth-of-type(1n){clear:none}.medium-up-4>.column:nth-of-type(4n+1),.medium-up-4>.columns:nth-of-type(4n+1){clear:both}.medium-up-4>.column:last-child,.medium-up-4>.columns:last-child{float:left}.medium-up-5>.column,.medium-up-5>.columns{float:left;width:20%}.medium-up-5>.column:nth-of-type(1n),.medium-up-5>.columns:nth-of-type(1n){clear:none}.medium-up-5>.column:nth-of-type(5n+1),.medium-up-5>.columns:nth-of-type(5n+1){clear:both}.medium-up-5>.column:last-child,.medium-up-5>.columns:last-child{float:left}.medium-up-6>.column,.medium-up-6>.columns{float:left;width:16.6666666667%}.medium-up-6>.column:nth-of-type(1n),.medium-up-6>.columns:nth-of-type(1n){clear:none}.medium-up-6>.column:nth-of-type(6n+1),.medium-up-6>.columns:nth-of-type(6n+1){clear:both}.medium-up-6>.column:last-child,.medium-up-6>.columns:last-child{float:left}.medium-up-7>.column,.medium-up-7>.columns{float:left;width:14.2857142857%}.medium-up-7>.column:nth-of-type(1n),.medium-up-7>.columns:nth-of-type(1n){clear:none}.medium-up-7>.column:nth-of-type(7n+1),.medium-up-7>.columns:nth-of-type(7n+1){clear:both}.medium-up-7>.column:last-child,.medium-up-7>.columns:last-child{float:left}.medium-up-8>.column,.medium-up-8>.columns{float:left;width:12.5%}.medium-up-8>.column:nth-of-type(1n),.medium-up-8>.columns:nth-of-type(1n){clear:none}.medium-up-8>.column:nth-of-type(8n+1),.medium-up-8>.columns:nth-of-type(8n+1){clear:both}.medium-up-8>.column:last-child,.medium-up-8>.columns:last-child{float:left}.medium-collapse>.column,.medium-collapse>.columns{padding-right:0;padding-left:0}.expanded.row .medium-collapse.row,.medium-collapse .row{margin-right:0;margin-left:0}.medium-uncollapse>.column,.medium-uncollapse>.columns{padding-right:.9375rem;padding-left:.9375rem}.medium-centered{margin-right:auto;margin-left:auto}.medium-centered,.medium-centered:last-child:not(:first-child){float:none;clear:both}.medium-pull-0,.medium-push-0,.medium-uncentered{position:static;float:left;margin-right:0;margin-left:0}}@media print,screen and (min-width:64em){.large-1{width:8.3333333333%}.large-push-1{position:relative;left:8.3333333333%}.large-pull-1{position:relative;left:-8.3333333333%}.large-offset-0{margin-left:0}.large-2{width:16.6666666667%}.large-push-2{position:relative;left:16.6666666667%}.large-pull-2{position:relative;left:-16.6666666667%}.large-offset-1{margin-left:8.3333333333%}.large-3{width:25%}.large-push-3{position:relative;left:25%}.large-pull-3{position:relative;left:-25%}.large-offset-2{margin-left:16.6666666667%}.large-4{width:33.3333333333%}.large-push-4{position:relative;left:33.3333333333%}.large-pull-4{position:relative;left:-33.3333333333%}.large-offset-3{margin-left:25%}.large-5{width:41.6666666667%}.large-push-5{position:relative;left:41.6666666667%}.large-pull-5{position:relative;left:-41.6666666667%}.large-offset-4{margin-left:33.3333333333%}.large-6{width:50%}.large-push-6{position:relative;left:50%}.large-pull-6{position:relative;left:-50%}.large-offset-5{margin-left:41.6666666667%}.large-7{width:58.3333333333%}.large-push-7{position:relative;left:58.3333333333%}.large-pull-7{position:relative;left:-58.3333333333%}.large-offset-6{margin-left:50%}.large-8{width:66.6666666667%}.large-push-8{position:relative;left:66.6666666667%}.large-pull-8{position:relative;left:-66.6666666667%}.large-offset-7{margin-left:58.3333333333%}.large-9{width:75%}.large-push-9{position:relative;left:75%}.large-pull-9{position:relative;left:-75%}.large-offset-8{margin-left:66.6666666667%}.large-10{width:83.3333333333%}.large-push-10{position:relative;left:83.3333333333%}.large-pull-10{position:relative;left:-83.3333333333%}.large-offset-9{margin-left:75%}.large-11{width:91.6666666667%}.large-push-11{position:relative;left:91.6666666667%}.large-pull-11{position:relative;left:-91.6666666667%}.large-offset-10{margin-left:83.3333333333%}.large-12{width:100%}.large-offset-11{margin-left:91.6666666667%}.large-up-1>.column,.large-up-1>.columns{float:left;width:100%}.large-up-1>.column:nth-of-type(1n),.large-up-1>.columns:nth-of-type(1n){clear:none}.large-up-1>.column:nth-of-type(1n+1),.large-up-1>.columns:nth-of-type(1n+1){clear:both}.large-up-1>.column:last-child,.large-up-1>.columns:last-child{float:left}.large-up-2>.column,.large-up-2>.columns{float:left;width:50%}.large-up-2>.column:nth-of-type(1n),.large-up-2>.columns:nth-of-type(1n){clear:none}.large-up-2>.column:nth-of-type(odd),.large-up-2>.columns:nth-of-type(odd){clear:both}.large-up-2>.column:last-child,.large-up-2>.columns:last-child{float:left}.large-up-3>.column,.large-up-3>.columns{float:left;width:33.3333333333%}.large-up-3>.column:nth-of-type(1n),.large-up-3>.columns:nth-of-type(1n){clear:none}.large-up-3>.column:nth-of-type(3n+1),.large-up-3>.columns:nth-of-type(3n+1){clear:both}.large-up-3>.column:last-child,.large-up-3>.columns:last-child{float:left}.large-up-4>.column,.large-up-4>.columns{float:left;width:25%}.large-up-4>.column:nth-of-type(1n),.large-up-4>.columns:nth-of-type(1n){clear:none}.large-up-4>.column:nth-of-type(4n+1),.large-up-4>.columns:nth-of-type(4n+1){clear:both}.large-up-4>.column:last-child,.large-up-4>.columns:last-child{float:left}.large-up-5>.column,.large-up-5>.columns{float:left;width:20%}.large-up-5>.column:nth-of-type(1n),.large-up-5>.columns:nth-of-type(1n){clear:none}.large-up-5>.column:nth-of-type(5n+1),.large-up-5>.columns:nth-of-type(5n+1){clear:both}.large-up-5>.column:last-child,.large-up-5>.columns:last-child{float:left}.large-up-6>.column,.large-up-6>.columns{float:left;width:16.6666666667%}.large-up-6>.column:nth-of-type(1n),.large-up-6>.columns:nth-of-type(1n){clear:none}.large-up-6>.column:nth-of-type(6n+1),.large-up-6>.columns:nth-of-type(6n+1){clear:both}.large-up-6>.column:last-child,.large-up-6>.columns:last-child{float:left}.large-up-7>.column,.large-up-7>.columns{float:left;width:14.2857142857%}.large-up-7>.column:nth-of-type(1n),.large-up-7>.columns:nth-of-type(1n){clear:none}.large-up-7>.column:nth-of-type(7n+1),.large-up-7>.columns:nth-of-type(7n+1){clear:both}.large-up-7>.column:last-child,.large-up-7>.columns:last-child{float:left}.large-up-8>.column,.large-up-8>.columns{float:left;width:12.5%}.large-up-8>.column:nth-of-type(1n),.large-up-8>.columns:nth-of-type(1n){clear:none}.large-up-8>.column:nth-of-type(8n+1),.large-up-8>.columns:nth-of-type(8n+1){clear:both}.large-up-8>.column:last-child,.large-up-8>.columns:last-child{float:left}.large-collapse>.column,.large-collapse>.columns{padding-right:0;padding-left:0}.expanded.row .large-collapse.row,.large-collapse .row{margin-right:0;margin-left:0}.large-uncollapse>.column,.large-uncollapse>.columns{padding-right:.9375rem;padding-left:.9375rem}.large-centered{margin-right:auto;margin-left:auto}.large-centered,.large-centered:last-child:not(:first-child){float:none;clear:both}.large-pull-0,.large-push-0,.large-uncentered{position:static;float:left;margin-right:0;margin-left:0}}.column-block{margin-bottom:1.25rem}.column-block>:last-child{margin-bottom:0}@media print,screen and (min-width:40em){.column-block{margin-bottom:1.875rem}.column-block>:last-child{margin-bottom:0}}[type=color],[type=date],[type=datetime-local],[type=datetime],[type=email],[type=month],[type=number],[type=password],[type=search],[type=tel],[type=text],[type=time],[type=url],[type=week],textarea{display:block;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;height:2.4375rem;margin:0 0 1rem;padding:.5rem;border:1px solid #cacaca;border-radius:0;background-color:#fefefe;-webkit-box-shadow:inset 0 1px 2px hsla(0,0%,4%,.1);box-shadow:inset 0 1px 2px hsla(0,0%,4%,.1);font-family:inherit;font-size:1rem;font-weight:400;line-height:1.5;color:#0a0a0a;-webkit-transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:box-shadow .5s,border-color .25s ease-in-out;transition:box-shadow .5s,border-color .25s ease-in-out,-webkit-box-shadow .5s;-webkit-appearance:none;-moz-appearance:none;appearance:none}[type=color]:focus,[type=date]:focus,[type=datetime-local]:focus,[type=datetime]:focus,[type=email]:focus,[type=month]:focus,[type=number]:focus,[type=password]:focus,[type=search]:focus,[type=tel]:focus,[type=text]:focus,[type=time]:focus,[type=url]:focus,[type=week]:focus,textarea:focus{outline:none;border:1px solid #8a8a8a;background-color:#fefefe;-webkit-box-shadow:0 0 5px #cacaca;box-shadow:0 0 5px #cacaca;-webkit-transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:box-shadow .5s,border-color .25s ease-in-out;transition:box-shadow .5s,border-color .25s ease-in-out,-webkit-box-shadow .5s}textarea{max-width:100%}textarea[rows]{height:auto}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#cacaca}input:-ms-input-placeholder,input::-ms-input-placeholder,textarea:-ms-input-placeholder,textarea::-ms-input-placeholder{color:#cacaca}input::placeholder,textarea::placeholder{color:#cacaca}input:disabled,input[readonly],textarea:disabled,textarea[readonly]{background-color:#e6e6e6;cursor:not-allowed}[type=button],[type=submit]{-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:0}input[type=search]{-webkit-box-sizing:border-box;box-sizing:border-box}[type=checkbox],[type=file],[type=radio]{margin:0 0 1rem}[type=checkbox]+label,[type=radio]+label{display:inline-block;vertical-align:baseline;margin-left:.5rem;margin-right:1rem;margin-bottom:0}[type=checkbox]+label[for],[type=radio]+label[for]{cursor:pointer}label>[type=checkbox],label>[type=radio]{margin-right:.5rem}[type=file]{width:100%}label{display:block;margin:0;font-size:.875rem;font-weight:400;line-height:1.8;color:#0a0a0a}label.middle{margin:0 0 1rem;padding:.5625rem 0}.help-text{margin-top:-.5rem;font-size:.8125rem;font-style:italic;color:#0a0a0a}.input-group{display:table;width:100%;margin-bottom:1rem}.input-group>:first-child,.input-group>:last-child>*{border-radius:0 0 0 0}.input-group-button,.input-group-button a,.input-group-button button,.input-group-button input,.input-group-button label,.input-group-field,.input-group-label{margin:0;white-space:nowrap;display:table-cell;vertical-align:middle}.input-group-label{padding:0 1rem;border:1px solid #cacaca;background:#e6e6e6;color:#0a0a0a;text-align:center;white-space:nowrap;width:1%;height:100%}.input-group-label:first-child{border-right:0}.input-group-label:last-child{border-left:0}.input-group-field{border-radius:0;height:2.5rem}.input-group-button{padding-top:0;padding-bottom:0;text-align:center;width:1%;height:100%}.input-group-button a,.input-group-button button,.input-group-button input,.input-group-button label{height:2.5rem;padding-top:0;padding-bottom:0;font-size:1rem}.input-group .input-group-button{display:table-cell}fieldset{margin:0;padding:0;border:0}legend{max-width:100%;margin-bottom:.5rem}.fieldset{margin:1.125rem 0;padding:1.25rem;border:1px solid #cacaca}.fieldset legend{margin:0;margin-left:-.1875rem;padding:0 .1875rem}select{height:2.4375rem;margin:0 0 1rem;padding:.5rem;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:1px solid #cacaca;border-radius:0;background-color:#fefefe;font-family:inherit;font-size:1rem;font-weight:400;line-height:1.5;color:#0a0a0a;background-image:url("data:image/svg+xml;utf8, ");background-origin:content-box;background-position:right -1rem center;background-repeat:no-repeat;background-size:9px 6px;padding-right:1.5rem;-webkit-transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:box-shadow .5s,border-color .25s ease-in-out;transition:box-shadow .5s,border-color .25s ease-in-out,-webkit-box-shadow .5s}@media screen and (min-width:0\0){select{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAYCAYAAACbU/80AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIpJREFUeNrEkckNgDAMBBfRkEt0ObRBBdsGXUDgmQfK4XhH2m8czQAAy27R3tsw4Qfe2x8uOO6oYLb6GlOor3GF+swURAOmUJ+RwtEJs9WvTGEYxBXqI1MQAZhCfUQKRzDMVj+TwrAIV6jvSUEkYAr1LSkcyTBb/V+KYfX7xAeusq3sLDtGH3kEGACPWIflNZfhRQAAAABJRU5ErkJggg==")}}select:focus{outline:none;border:1px solid #8a8a8a;background-color:#fefefe;-webkit-box-shadow:0 0 5px #cacaca;box-shadow:0 0 5px #cacaca;-webkit-transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:box-shadow .5s,border-color .25s ease-in-out;transition:box-shadow .5s,border-color .25s ease-in-out,-webkit-box-shadow .5s}select:disabled{background-color:#e6e6e6;cursor:not-allowed}select::-ms-expand{display:none}select[multiple]{height:auto;background-image:none}.is-invalid-input:not(:focus){border-color:#cc4b37;background-color:#f9ecea}.is-invalid-input:not(:focus)::-webkit-input-placeholder{color:#cc4b37}.is-invalid-input:not(:focus):-ms-input-placeholder,.is-invalid-input:not(:focus)::-ms-input-placeholder{color:#cc4b37}.is-invalid-input:not(:focus)::placeholder{color:#cc4b37}.form-error,.is-invalid-label{color:#cc4b37}.form-error{display:none;margin-top:-.5rem;margin-bottom:1rem;font-size:.75rem;font-weight:700}.form-error.is-visible{display:block}.button{display:inline-block;vertical-align:middle;margin:0 0 1rem;font-family:inherit;padding:.85em 1em;-webkit-appearance:none;border:1px solid transparent;border-radius:0;-webkit-transition:background-color .25s ease-out,color .25s ease-out;transition:background-color .25s ease-out,color .25s ease-out;font-size:.9rem;line-height:1;text-align:center;cursor:pointer;background-color:#1779ba;color:#fefefe}[data-whatinput=mouse] .button{outline:0}.button:focus,.button:hover{background-color:#14679e;color:#fefefe}.button.tiny{font-size:.6rem}.button.small{font-size:.75rem}.button.large{font-size:1.25rem}.button.expanded{display:block;width:100%;margin-right:0;margin-left:0}.button.primary{background-color:#1779ba;color:#fefefe}.button.primary:focus,.button.primary:hover{background-color:#126195;color:#fefefe}.button.secondary{background-color:#767676;color:#fefefe}.button.secondary:focus,.button.secondary:hover{background-color:#5e5e5e;color:#fefefe}.button.success{background-color:#3adb76;color:#0a0a0a}.button.success:focus,.button.success:hover{background-color:#22bb5b;color:#0a0a0a}.button.warning{background-color:#ffae00;color:#0a0a0a}.button.warning:focus,.button.warning:hover{background-color:#cc8b00;color:#0a0a0a}.button.alert{background-color:#cc4b37;color:#fefefe}.button.alert:focus,.button.alert:hover{background-color:#a53b2a;color:#fefefe}.button.disabled,.button[disabled]{opacity:.25;cursor:not-allowed}.button.disabled,.button.disabled:focus,.button.disabled:hover,.button[disabled],.button[disabled]:focus,.button[disabled]:hover{background-color:#1779ba;color:#fefefe}.button.disabled.primary,.button[disabled].primary{opacity:.25;cursor:not-allowed}.button.disabled.primary,.button.disabled.primary:focus,.button.disabled.primary:hover,.button[disabled].primary,.button[disabled].primary:focus,.button[disabled].primary:hover{background-color:#1779ba;color:#fefefe}.button.disabled.secondary,.button[disabled].secondary{opacity:.25;cursor:not-allowed}.button.disabled.secondary,.button.disabled.secondary:focus,.button.disabled.secondary:hover,.button[disabled].secondary,.button[disabled].secondary:focus,.button[disabled].secondary:hover{background-color:#767676;color:#fefefe}.button.disabled.success,.button[disabled].success{opacity:.25;cursor:not-allowed}.button.disabled.success,.button.disabled.success:focus,.button.disabled.success:hover,.button[disabled].success,.button[disabled].success:focus,.button[disabled].success:hover{background-color:#3adb76;color:#0a0a0a}.button.disabled.warning,.button[disabled].warning{opacity:.25;cursor:not-allowed}.button.disabled.warning,.button.disabled.warning:focus,.button.disabled.warning:hover,.button[disabled].warning,.button[disabled].warning:focus,.button[disabled].warning:hover{background-color:#ffae00;color:#0a0a0a}.button.disabled.alert,.button[disabled].alert{opacity:.25;cursor:not-allowed}.button.disabled.alert,.button.disabled.alert:focus,.button.disabled.alert:hover,.button[disabled].alert,.button[disabled].alert:focus,.button[disabled].alert:hover{background-color:#cc4b37;color:#fefefe}.button.hollow{border:1px solid #1779ba;color:#1779ba}.button.hollow,.button.hollow.disabled,.button.hollow.disabled:focus,.button.hollow.disabled:hover,.button.hollow:focus,.button.hollow:hover,.button.hollow[disabled],.button.hollow[disabled]:focus,.button.hollow[disabled]:hover{background-color:transparent}.button.hollow:focus,.button.hollow:hover{border-color:#0c3d5d;color:#0c3d5d}.button.hollow.primary,.button.hollow:focus.disabled,.button.hollow:focus[disabled],.button.hollow:hover.disabled,.button.hollow:hover[disabled]{border:1px solid #1779ba;color:#1779ba}.button.hollow.primary:focus,.button.hollow.primary:hover{border-color:#0c3d5d;color:#0c3d5d}.button.hollow.primary:focus.disabled,.button.hollow.primary:focus[disabled],.button.hollow.primary:hover.disabled,.button.hollow.primary:hover[disabled]{border:1px solid #1779ba;color:#1779ba}.button.hollow.secondary{border:1px solid #767676;color:#767676}.button.hollow.secondary:focus,.button.hollow.secondary:hover{border-color:#3b3b3b;color:#3b3b3b}.button.hollow.secondary:focus.disabled,.button.hollow.secondary:focus[disabled],.button.hollow.secondary:hover.disabled,.button.hollow.secondary:hover[disabled]{border:1px solid #767676;color:#767676}.button.hollow.success{border:1px solid #3adb76;color:#3adb76}.button.hollow.success:focus,.button.hollow.success:hover{border-color:#157539;color:#157539}.button.hollow.success:focus.disabled,.button.hollow.success:focus[disabled],.button.hollow.success:hover.disabled,.button.hollow.success:hover[disabled]{border:1px solid #3adb76;color:#3adb76}.button.hollow.warning{border:1px solid #ffae00;color:#ffae00}.button.hollow.warning:focus,.button.hollow.warning:hover{border-color:#805700;color:#805700}.button.hollow.warning:focus.disabled,.button.hollow.warning:focus[disabled],.button.hollow.warning:hover.disabled,.button.hollow.warning:hover[disabled]{border:1px solid #ffae00;color:#ffae00}.button.hollow.alert{border:1px solid #cc4b37;color:#cc4b37}.button.hollow.alert:focus,.button.hollow.alert:hover{border-color:#67251a;color:#67251a}.button.hollow.alert:focus.disabled,.button.hollow.alert:focus[disabled],.button.hollow.alert:hover.disabled,.button.hollow.alert:hover[disabled]{border:1px solid #cc4b37;color:#cc4b37}.button.clear{border:1px solid #1779ba;color:#1779ba}.button.clear,.button.clear.disabled,.button.clear.disabled:focus,.button.clear.disabled:hover,.button.clear:focus,.button.clear:hover,.button.clear[disabled],.button.clear[disabled]:focus,.button.clear[disabled]:hover{background-color:transparent}.button.clear:focus,.button.clear:hover{border-color:#0c3d5d;color:#0c3d5d}.button.clear:focus.disabled,.button.clear:focus[disabled],.button.clear:hover.disabled,.button.clear:hover[disabled]{border:1px solid #1779ba;color:#1779ba}.button.clear,.button.clear.disabled,.button.clear:focus,.button.clear:focus.disabled,.button.clear:focus[disabled],.button.clear:hover,.button.clear:hover.disabled,.button.clear:hover[disabled],.button.clear[disabled]{border-color:transparent}.button.clear.primary{border:1px solid #1779ba;color:#1779ba}.button.clear.primary:focus,.button.clear.primary:hover{border-color:#0c3d5d;color:#0c3d5d}.button.clear.primary:focus.disabled,.button.clear.primary:focus[disabled],.button.clear.primary:hover.disabled,.button.clear.primary:hover[disabled]{border:1px solid #1779ba;color:#1779ba}.button.clear.primary,.button.clear.primary.disabled,.button.clear.primary:focus,.button.clear.primary:focus.disabled,.button.clear.primary:focus[disabled],.button.clear.primary:hover,.button.clear.primary:hover.disabled,.button.clear.primary:hover[disabled],.button.clear.primary[disabled]{border-color:transparent}.button.clear.secondary{border:1px solid #767676;color:#767676}.button.clear.secondary:focus,.button.clear.secondary:hover{border-color:#3b3b3b;color:#3b3b3b}.button.clear.secondary:focus.disabled,.button.clear.secondary:focus[disabled],.button.clear.secondary:hover.disabled,.button.clear.secondary:hover[disabled]{border:1px solid #767676;color:#767676}.button.clear.secondary,.button.clear.secondary.disabled,.button.clear.secondary:focus,.button.clear.secondary:focus.disabled,.button.clear.secondary:focus[disabled],.button.clear.secondary:hover,.button.clear.secondary:hover.disabled,.button.clear.secondary:hover[disabled],.button.clear.secondary[disabled]{border-color:transparent}.button.clear.success{border:1px solid #3adb76;color:#3adb76}.button.clear.success:focus,.button.clear.success:hover{border-color:#157539;color:#157539}.button.clear.success:focus.disabled,.button.clear.success:focus[disabled],.button.clear.success:hover.disabled,.button.clear.success:hover[disabled]{border:1px solid #3adb76;color:#3adb76}.button.clear.success,.button.clear.success.disabled,.button.clear.success:focus,.button.clear.success:focus.disabled,.button.clear.success:focus[disabled],.button.clear.success:hover,.button.clear.success:hover.disabled,.button.clear.success:hover[disabled],.button.clear.success[disabled]{border-color:transparent}.button.clear.warning{border:1px solid #ffae00;color:#ffae00}.button.clear.warning:focus,.button.clear.warning:hover{border-color:#805700;color:#805700}.button.clear.warning:focus.disabled,.button.clear.warning:focus[disabled],.button.clear.warning:hover.disabled,.button.clear.warning:hover[disabled]{border:1px solid #ffae00;color:#ffae00}.button.clear.warning,.button.clear.warning.disabled,.button.clear.warning:focus,.button.clear.warning:focus.disabled,.button.clear.warning:focus[disabled],.button.clear.warning:hover,.button.clear.warning:hover.disabled,.button.clear.warning:hover[disabled],.button.clear.warning[disabled]{border-color:transparent}.button.clear.alert{border:1px solid #cc4b37;color:#cc4b37}.button.clear.alert:focus,.button.clear.alert:hover{border-color:#67251a;color:#67251a}.button.clear.alert:focus.disabled,.button.clear.alert:focus[disabled],.button.clear.alert:hover.disabled,.button.clear.alert:hover[disabled]{border:1px solid #cc4b37;color:#cc4b37}.button.clear.alert,.button.clear.alert.disabled,.button.clear.alert:focus,.button.clear.alert:focus.disabled,.button.clear.alert:focus[disabled],.button.clear.alert:hover,.button.clear.alert:hover.disabled,.button.clear.alert:hover[disabled],.button.clear.alert[disabled]{border-color:transparent}.button.dropdown:after{display:block;width:0;height:0;border:.4em inset;content:"";border-bottom-width:0;border-top-style:solid;border-color:#fefefe transparent transparent;position:relative;top:.4em;display:inline-block;float:right;margin-left:1em}.button.dropdown.hollow.primary:after,.button.dropdown.hollow:after{border-top-color:#1779ba}.button.dropdown.hollow.secondary:after{border-top-color:#767676}.button.dropdown.hollow.success:after{border-top-color:#3adb76}.button.dropdown.hollow.warning:after{border-top-color:#ffae00}.button.dropdown.hollow.alert:after{border-top-color:#cc4b37}.button.arrow-only:after{top:-.1em;float:none;margin-left:0}a.button:focus,a.button:hover{text-decoration:none}.top-bar{padding:.5rem}.top-bar:after,.top-bar:before{display:table;content:" "}.top-bar:after{clear:both}.top-bar,.top-bar ul{background-color:#e6e6e6}.top-bar input{max-width:200px;margin-right:1rem}.top-bar .input-group-field{width:100%;margin-right:0}.top-bar input.button{width:auto}.top-bar .top-bar-left,.top-bar .top-bar-right{width:100%}@media print,screen and (min-width:40em){.top-bar .top-bar-left,.top-bar .top-bar-right{width:auto}}@media screen and (max-width:39.9375em){.top-bar.stacked-for-smedium .top-bar-left,.top-bar.stacked-for-smedium .top-bar-right{width:100%}}@media screen and (max-width:63.9375em){.top-bar.stacked-for-medium .top-bar-left,.top-bar.stacked-for-medium .top-bar-right{width:100%}}@media screen and (max-width:74.9375em){.top-bar.stacked-for-large .top-bar-left,.top-bar.stacked-for-large .top-bar-right{width:100%}}.top-bar-title{display:inline-block;float:left;padding:.5rem 1rem .5rem 0}.top-bar-title .menu-icon{bottom:2px}.top-bar-left{float:left}.top-bar-right{float:right}.menu{padding:0;margin:0;list-style:none;position:relative}[data-whatinput=mouse] .menu li{outline:0}.menu .button,.menu a{line-height:1;text-decoration:none;display:block;padding:.7rem 1rem}.menu a,.menu button,.menu input,.menu select{margin-bottom:0}.menu.horizontal li,.menu input,.menu li{display:inline-block}.menu.vertical li{display:block}.menu.expanded{display:table;width:100%}.menu.expanded>li{display:table-cell;vertical-align:middle}.menu.simple li+li{margin-left:1rem}.menu.simple a{padding:0}@media screen and (min-width:25em){.menu.smedium-horizontal li{display:inline-block}.menu.smedium-vertical li{display:block}.menu.smedium-expanded{display:table;width:100%}.menu.smedium-expanded>li{display:table-cell;vertical-align:middle}.menu.smedium-simple{display:table;width:100%}.menu.smedium-simple>li{display:table-cell;vertical-align:middle}}@media print,screen and (min-width:40em){.menu.medium-horizontal li{display:inline-block}.menu.medium-vertical li{display:block}.menu.medium-expanded{display:table;width:100%}.menu.medium-expanded>li{display:table-cell;vertical-align:middle}.menu.medium-simple{display:table;width:100%}.menu.medium-simple>li{display:table-cell;vertical-align:middle}}@media print,screen and (min-width:64em){.menu.large-horizontal li{display:inline-block}.menu.large-vertical li{display:block}.menu.large-expanded{display:table;width:100%}.menu.large-expanded>li{display:table-cell;vertical-align:middle}.menu.large-simple{display:table;width:100%}.menu.large-simple>li{display:table-cell;vertical-align:middle}}.menu.nested{margin-right:0;margin-left:1rem}.menu.icon-bottom i,.menu.icon-bottom i+span,.menu.icon-bottom img,.menu.icon-bottom img+span,.menu.icon-bottom svg,.menu.icon-bottom svg+span,.menu.icon-left i,.menu.icon-left i+span,.menu.icon-left img,.menu.icon-left img+span,.menu.icon-left svg,.menu.icon-left svg+span,.menu.icon-right i,.menu.icon-right i+span,.menu.icon-right img,.menu.icon-right img+span,.menu.icon-right svg,.menu.icon-right svg+span,.menu.icon-top i,.menu.icon-top i+span,.menu.icon-top img,.menu.icon-top img+span,.menu.icon-top svg,.menu.icon-top svg+span,.menu.icons i,.menu.icons i+span,.menu.icons img,.menu.icons img+span,.menu.icons svg,.menu.icons svg+span{vertical-align:middle}.menu.icon-left li a i,.menu.icon-left li a img,.menu.icon-left li a svg{margin-right:.25rem;display:inline-block}.menu.icon-right li a i,.menu.icon-right li a img,.menu.icon-right li a svg{margin-left:.25rem;display:inline-block}.menu.icon-top li a{text-align:center}.menu.icon-top li a i,.menu.icon-top li a img,.menu.icon-top li a svg{display:block;margin:0 auto .25rem}.menu.icon-bottom li a{text-align:center}.menu.icon-bottom li a i,.menu.icon-bottom li a img,.menu.icon-bottom li a svg{display:block;margin:.25rem auto 0}.menu .active>a,.menu .is-active>a{background:#1779ba;color:#fefefe}.menu.align-left{text-align:left}.menu.align-right{text-align:right}.menu.align-right .submenu li{text-align:left}.menu.align-right.vertical .submenu li{text-align:right}.menu.align-right .nested{margin-right:1rem;margin-left:0}.menu.align-center{text-align:center}.menu.align-center .submenu li{text-align:left}.menu .menu-text{padding:.7rem 1rem;font-weight:700;line-height:1;color:inherit}.menu-centered>.menu{text-align:center}.menu-centered>.menu .submenu li{text-align:left}.no-js [data-responsive-menu] ul{display:none}.menu-icon{position:relative;display:inline-block;vertical-align:middle;width:20px;height:16px;cursor:pointer}.menu-icon:after{position:absolute;top:0;left:0;display:block;width:100%;height:2px;background:#fefefe;-webkit-box-shadow:0 7px 0 #fefefe,0 14px 0 #fefefe;box-shadow:0 7px 0 #fefefe,0 14px 0 #fefefe;content:""}.menu-icon:hover:after{background:#cacaca;-webkit-box-shadow:0 7px 0 #cacaca,0 14px 0 #cacaca;box-shadow:0 7px 0 #cacaca,0 14px 0 #cacaca}.menu-icon.dark{position:relative;display:inline-block;vertical-align:middle;width:20px;height:16px;cursor:pointer}.menu-icon.dark:after{position:absolute;top:0;left:0;display:block;width:100%;height:2px;background:#0a0a0a;-webkit-box-shadow:0 7px 0 #0a0a0a,0 14px 0 #0a0a0a;box-shadow:0 7px 0 #0a0a0a,0 14px 0 #0a0a0a;content:""}.menu-icon.dark:hover:after{background:#8a8a8a;-webkit-box-shadow:0 7px 0 #8a8a8a,0 14px 0 #8a8a8a;box-shadow:0 7px 0 #8a8a8a,0 14px 0 #8a8a8a}.overflow-visible{overflow:visible!important}.overflow-x-visible{overflow-x:visible!important}.overflow-y-visible{overflow-y:visible!important}.overflow-hidden{overflow:hidden!important}.overflow-x-hidden{overflow-x:hidden!important}.overflow-y-hidden{overflow-y:hidden!important}.overflow-scroll{overflow:scroll!important}.overflow-x-scroll{overflow-x:scroll!important}.overflow-y-scroll{overflow-y:scroll!important}.dropdown-pane{position:absolute;z-index:10;width:300px;padding:1rem;visibility:hidden;display:none;border:1px solid #cacaca;border-radius:0;background-color:#fefefe;font-size:1rem}.dropdown-pane.is-opening{display:block}.dropdown-pane.is-open{visibility:visible;display:block}.dropdown-pane.tiny{width:100px}.dropdown-pane.small{width:200px}.dropdown-pane.large{width:400px}.dropdown.menu>li.opens-left>.is-dropdown-submenu{top:100%;right:0;left:auto}.dropdown.menu>li.opens-right>.is-dropdown-submenu{top:100%;right:auto;left:0}.dropdown.menu>li.is-dropdown-submenu-parent>a{position:relative;padding-right:1.5rem}.dropdown.menu>li.is-dropdown-submenu-parent>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-bottom-width:0;border-top-style:solid;border-color:#1779ba transparent transparent;right:5px;left:auto;margin-top:-3px}.dropdown.menu a{padding:.7rem 1rem}[data-whatinput=mouse] .dropdown.menu a{outline:0}.dropdown.menu .is-active>a{background:transparent;color:#1779ba}.no-js .dropdown.menu ul{display:none}.dropdown.menu .nested.is-dropdown-submenu{margin-right:0;margin-left:0}.dropdown.menu.vertical>li .is-dropdown-submenu{top:0}.dropdown.menu.vertical>li.opens-left>.is-dropdown-submenu{right:100%;left:auto;top:0}.dropdown.menu.vertical>li.opens-right>.is-dropdown-submenu{right:auto;left:100%}.dropdown.menu.vertical>li>a:after{right:14px}.dropdown.menu.vertical>li.opens-left>a:after{right:auto;left:5px;display:block;width:0;height:0;border:6px inset;content:"";border-left-width:0;border-right-style:solid;border-color:transparent #1779ba transparent transparent}.dropdown.menu.vertical>li.opens-right>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-right-width:0;border-left-style:solid;border-color:transparent transparent transparent #1779ba}@media screen and (min-width:25em){.dropdown.menu.smedium-horizontal>li.opens-left>.is-dropdown-submenu{top:100%;right:0;left:auto}.dropdown.menu.smedium-horizontal>li.opens-right>.is-dropdown-submenu{top:100%;right:auto;left:0}.dropdown.menu.smedium-horizontal>li.is-dropdown-submenu-parent>a{position:relative;padding-right:1.5rem}.dropdown.menu.smedium-horizontal>li.is-dropdown-submenu-parent>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-bottom-width:0;border-top-style:solid;border-color:#1779ba transparent transparent;right:5px;left:auto;margin-top:-3px}.dropdown.menu.smedium-vertical>li .is-dropdown-submenu{top:0}.dropdown.menu.smedium-vertical>li.opens-left>.is-dropdown-submenu{right:100%;left:auto;top:0}.dropdown.menu.smedium-vertical>li.opens-right>.is-dropdown-submenu{right:auto;left:100%}.dropdown.menu.smedium-vertical>li>a:after{right:14px}.dropdown.menu.smedium-vertical>li.opens-left>a:after{right:auto;left:5px;display:block;width:0;height:0;border:6px inset;content:"";border-left-width:0;border-right-style:solid;border-color:transparent #1779ba transparent transparent}.dropdown.menu.smedium-vertical>li.opens-right>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-right-width:0;border-left-style:solid;border-color:transparent transparent transparent #1779ba}}@media print,screen and (min-width:40em){.dropdown.menu.medium-horizontal>li.opens-left>.is-dropdown-submenu{top:100%;right:0;left:auto}.dropdown.menu.medium-horizontal>li.opens-right>.is-dropdown-submenu{top:100%;right:auto;left:0}.dropdown.menu.medium-horizontal>li.is-dropdown-submenu-parent>a{position:relative;padding-right:1.5rem}.dropdown.menu.medium-horizontal>li.is-dropdown-submenu-parent>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-bottom-width:0;border-top-style:solid;border-color:#1779ba transparent transparent;right:5px;left:auto;margin-top:-3px}.dropdown.menu.medium-vertical>li .is-dropdown-submenu{top:0}.dropdown.menu.medium-vertical>li.opens-left>.is-dropdown-submenu{right:100%;left:auto;top:0}.dropdown.menu.medium-vertical>li.opens-right>.is-dropdown-submenu{right:auto;left:100%}.dropdown.menu.medium-vertical>li>a:after{right:14px}.dropdown.menu.medium-vertical>li.opens-left>a:after{right:auto;left:5px;display:block;width:0;height:0;border:6px inset;content:"";border-left-width:0;border-right-style:solid;border-color:transparent #1779ba transparent transparent}.dropdown.menu.medium-vertical>li.opens-right>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-right-width:0;border-left-style:solid;border-color:transparent transparent transparent #1779ba}}@media print,screen and (min-width:64em){.dropdown.menu.large-horizontal>li.opens-left>.is-dropdown-submenu{top:100%;right:0;left:auto}.dropdown.menu.large-horizontal>li.opens-right>.is-dropdown-submenu{top:100%;right:auto;left:0}.dropdown.menu.large-horizontal>li.is-dropdown-submenu-parent>a{position:relative;padding-right:1.5rem}.dropdown.menu.large-horizontal>li.is-dropdown-submenu-parent>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-bottom-width:0;border-top-style:solid;border-color:#1779ba transparent transparent;right:5px;left:auto;margin-top:-3px}.dropdown.menu.large-vertical>li .is-dropdown-submenu{top:0}.dropdown.menu.large-vertical>li.opens-left>.is-dropdown-submenu{right:100%;left:auto;top:0}.dropdown.menu.large-vertical>li.opens-right>.is-dropdown-submenu{right:auto;left:100%}.dropdown.menu.large-vertical>li>a:after{right:14px}.dropdown.menu.large-vertical>li.opens-left>a:after{right:auto;left:5px;display:block;width:0;height:0;border:6px inset;content:"";border-left-width:0;border-right-style:solid;border-color:transparent #1779ba transparent transparent}.dropdown.menu.large-vertical>li.opens-right>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-right-width:0;border-left-style:solid;border-color:transparent transparent transparent #1779ba}}.dropdown.menu.align-right .is-dropdown-submenu.first-sub{top:100%;right:0;left:auto}.is-dropdown-menu.vertical{width:100px}.is-dropdown-menu.vertical.align-right{float:right}.is-dropdown-submenu-parent{position:relative}.is-dropdown-submenu-parent a:after{position:absolute;top:50%;right:5px;left:auto;margin-top:-6px}.is-dropdown-submenu-parent.opens-inner>.is-dropdown-submenu{top:100%;left:auto}.is-dropdown-submenu-parent.opens-left>.is-dropdown-submenu{right:100%;left:auto}.is-dropdown-submenu-parent.opens-right>.is-dropdown-submenu{right:auto;left:100%}.is-dropdown-submenu{position:absolute;top:0;left:100%;z-index:1;display:none;min-width:200px;border:1px solid #cacaca;background:#fefefe}.dropdown .is-dropdown-submenu a{padding:.7rem 1rem}.is-dropdown-submenu .is-dropdown-submenu-parent>a:after{right:14px}.is-dropdown-submenu .is-dropdown-submenu-parent.opens-left>a:after{right:auto;left:5px;display:block;width:0;height:0;border:6px inset;content:"";border-left-width:0;border-right-style:solid;border-color:transparent #1779ba transparent transparent}.is-dropdown-submenu .is-dropdown-submenu-parent.opens-right>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-right-width:0;border-left-style:solid;border-color:transparent transparent transparent #1779ba}.is-dropdown-submenu .is-dropdown-submenu{margin-top:-1px}.is-dropdown-submenu>li{width:100%}.is-dropdown-submenu.js-dropdown-active{display:block}.accordion{margin-left:0;background:#fefefe;list-style-type:none}.accordion[disabled] .accordion-title{cursor:not-allowed}.accordion-item:first-child>:first-child,.accordion-item:last-child>:last-child{border-radius:0 0 0 0}.accordion-title{position:relative;display:block;padding:1.25rem 1rem;border:1px solid #e6e6e6;border-bottom:0;font-size:.75rem;line-height:1;color:#1779ba}:last-child:not(.is-active)>.accordion-title{border-bottom:1px solid #e6e6e6;border-radius:0 0 0 0}.accordion-title:focus,.accordion-title:hover{background-color:#e6e6e6}.accordion-title:before{position:absolute;top:50%;right:1rem;margin-top:-.5rem;content:"+"}.is-active>.accordion-title:before{content:"–"}.accordion-content{display:none;padding:1rem;border:1px solid #e6e6e6;border-bottom:0;background-color:#fefefe;color:#0a0a0a}:last-child>.accordion-content:last-child{border-bottom:1px solid #e6e6e6}.accordion-menu li{width:100%}.accordion-menu .is-accordion-submenu a,.accordion-menu a{padding:.7rem 1rem}.accordion-menu .nested.is-accordion-submenu{margin-right:0;margin-left:1rem}.accordion-menu.align-right .nested.is-accordion-submenu{margin-right:1rem;margin-left:0}.accordion-menu .is-accordion-submenu-parent:not(.has-submenu-toggle)>a{position:relative}.accordion-menu .is-accordion-submenu-parent:not(.has-submenu-toggle)>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-bottom-width:0;border-top-style:solid;border-color:#1779ba transparent transparent;position:absolute;top:50%;margin-top:-3px;right:1rem}.accordion-menu.align-left .is-accordion-submenu-parent>a:after{left:auto;right:1rem}.accordion-menu.align-right .is-accordion-submenu-parent>a:after{right:auto;left:1rem}.accordion-menu .is-accordion-submenu-parent[aria-expanded=true]>a:after{-webkit-transform:rotate(180deg);transform:rotate(180deg);-webkit-transform-origin:50% 50%;transform-origin:50% 50%}.is-accordion-submenu-parent{position:relative}.has-submenu-toggle>a{margin-right:40px}.submenu-toggle{position:absolute;top:0;right:0;cursor:pointer;width:40px;height:40px}.submenu-toggle:after{display:block;width:0;height:0;border:6px inset;content:"";border-bottom-width:0;border-top-style:solid;border-color:#1779ba transparent transparent;top:0;bottom:0;margin:auto}.submenu-toggle[aria-expanded=true]:after{-webkit-transform:scaleY(-1);transform:scaleY(-1);-webkit-transform-origin:50% 50%;transform-origin:50% 50%}.submenu-toggle-text{position:absolute!important;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;-webkit-clip-path:inset(50%);clip-path:inset(50%);border:0}.margin-0{margin:0!important}.padding-0{padding:0!important}.margin-top-0{margin-top:0!important}.padding-top-0{padding-top:0!important}.margin-right-0{margin-right:0!important}.padding-right-0{padding-right:0!important}.margin-bottom-0{margin-bottom:0!important}.padding-bottom-0{padding-bottom:0!important}.margin-left-0{margin-left:0!important}.padding-left-0{padding-left:0!important}.margin-horizontal-0{margin-right:0!important;margin-left:0!important}.padding-horizontal-0{padding-right:0!important;padding-left:0!important}.margin-vertical-0{margin-top:0!important;margin-bottom:0!important}.padding-vertical-0{padding-top:0!important;padding-bottom:0!important}.margin-1{margin:1rem!important}.padding-1{padding:1rem!important}.margin-top-1{margin-top:1rem!important}.padding-top-1{padding-top:1rem!important}.margin-right-1{margin-right:1rem!important}.padding-right-1{padding-right:1rem!important}.margin-bottom-1{margin-bottom:1rem!important}.padding-bottom-1{padding-bottom:1rem!important}.margin-left-1{margin-left:1rem!important}.padding-left-1{padding-left:1rem!important}.margin-horizontal-1{margin-right:1rem!important;margin-left:1rem!important}.padding-horizontal-1{padding-right:1rem!important;padding-left:1rem!important}.margin-vertical-1{margin-top:1rem!important;margin-bottom:1rem!important}.padding-vertical-1{padding-top:1rem!important;padding-bottom:1rem!important}.margin-2{margin:2rem!important}.padding-2{padding:2rem!important}.margin-top-2{margin-top:2rem!important}.padding-top-2{padding-top:2rem!important}.margin-right-2{margin-right:2rem!important}.padding-right-2{padding-right:2rem!important}.margin-bottom-2{margin-bottom:2rem!important}.padding-bottom-2{padding-bottom:2rem!important}.margin-left-2{margin-left:2rem!important}.padding-left-2{padding-left:2rem!important}.margin-horizontal-2{margin-right:2rem!important;margin-left:2rem!important}.padding-horizontal-2{padding-right:2rem!important;padding-left:2rem!important}.margin-vertical-2{margin-top:2rem!important;margin-bottom:2rem!important}.padding-vertical-2{padding-top:2rem!important;padding-bottom:2rem!important}.margin-3{margin:3rem!important}.padding-3{padding:3rem!important}.margin-top-3{margin-top:3rem!important}.padding-top-3{padding-top:3rem!important}.margin-right-3{margin-right:3rem!important}.padding-right-3{padding-right:3rem!important}.margin-bottom-3{margin-bottom:3rem!important}.padding-bottom-3{padding-bottom:3rem!important}.margin-left-3{margin-left:3rem!important}.padding-left-3{padding-left:3rem!important}.margin-horizontal-3{margin-right:3rem!important;margin-left:3rem!important}.padding-horizontal-3{padding-right:3rem!important;padding-left:3rem!important}.margin-vertical-3{margin-top:3rem!important;margin-bottom:3rem!important}.padding-vertical-3{padding-top:3rem!important;padding-bottom:3rem!important}.top-bar-title{padding:0}.row:not(.expanded) .row{max-width:100%;margin-right:0;margin-left:0}.row:not(.expanded) .row .column.no-padding-left,.row:not(.expanded) .row .columns.no-padding-left{padding-left:0!important}.row:not(.expanded) .row .column.no-padding-right,.row:not(.expanded) .row .columns.no-padding-right{padding-right:0!important}.row:not(.expanded) .row .column.small-first,.row:not(.expanded) .row .columns.small-first{padding-left:0!important}.row:not(.expanded) .row .column.small-last,.row:not(.expanded) .row .columns.small-last{padding-right:0!important}@media screen and (min-width:25em){.row:not(.expanded) .row .column.smedium-first,.row:not(.expanded) .row .columns.smedium-first{padding-left:0!important}}@media screen and (min-width:25em){.row:not(.expanded) .row .column.smedium-last,.row:not(.expanded) .row .columns.smedium-last{padding-right:0!important}}@media print,screen and (min-width:40em){.row:not(.expanded) .row .column.medium-first,.row:not(.expanded) .row .columns.medium-first{padding-left:0!important}}@media print,screen and (min-width:40em){.row:not(.expanded) .row .column.medium-last,.row:not(.expanded) .row .columns.medium-last{padding-right:0!important}}@media print,screen and (min-width:64em){.row:not(.expanded) .row .column.large-first,.row:not(.expanded) .row .columns.large-first{padding-left:0!important}}@media print,screen and (min-width:64em){.row:not(.expanded) .row .column.large-last,.row:not(.expanded) .row .columns.large-last{padding-right:0!important}}@media screen and (min-width:75em){.row:not(.expanded) .row .column.xlarge-first,.row:not(.expanded) .row .columns.xlarge-first{padding-left:0!important}}@media screen and (min-width:75em){.row:not(.expanded) .row .column.xlarge-last,.row:not(.expanded) .row .columns.xlarge-last{padding-right:0!important}}@media screen and (min-width:90em){.row:not(.expanded) .row .column.xxlarge-first,.row:not(.expanded) .row .columns.xxlarge-first{padding-left:0!important}}@media screen and (min-width:90em){.row:not(.expanded) .row .column.xxlarge-last,.row:not(.expanded) .row .columns.xxlarge-last{padding-right:0!important}}.row.low-padding .column,.row.low-padding .columns{padding-left:.15rem;padding-right:.15rem}
\ No newline at end of file
diff --git a/public/css/wordRotator.css b/public/css/wordRotator.css
deleted file mode 100755
index 1bff4f8..0000000
--- a/public/css/wordRotator.css
+++ /dev/null
@@ -1 +0,0 @@
-.top-bar-title{white-space:nowrap}#action-bar .close-listener{position:fixed;top:0;left:0;right:0;bottom:0;background:transparent;z-index:9000}#action-bar #responsive-menu .top-bar-right{position:relative;text-align:right;width:100%}#action-bar .top-bar-right{width:auto}#action-bar .top-bar-right .menu.action-bar a img+span{display:none}#action-bar .top-bar-right .menu.action-bar .action{position:relative;z-index:9000}#action-bar .top-bar-right .menu.action-bar .action.is-dropdown-submenu-parent{z-index:9001}#action-bar .top-bar-right .menu.action-bar .action.hidden{display:none}@media screen and (max-width:24.9375em){#action-bar .top-bar-right .menu.action-bar .action.smedium{display:none}}@media screen and (max-width:39.9375em){#action-bar .top-bar-right .menu.action-bar .action li{display:table-cell}#action-bar .top-bar-right .menu.action-bar .action.medium{display:none}}@media screen and (max-width:63.9375em){#action-bar .top-bar-right .menu.action-bar .action.large{display:none}}#action-bar .top-bar-right .menu.action-bar .action.never{display:none}#action-bar .top-bar-right .menu.action-bar.hidden{display:inline-block;position:absolute;z-index:9000;border:1px solid #cacaca;padding:.2rem;-webkit-transform:translateX(-100%);transform:translateX(-100%);text-align:left}#action-bar .top-bar-right .menu.action-bar.hidden .action.hidden{display:none}#action-bar .top-bar-right .menu.action-bar.hidden .action.is-dropdown-submenu-parent{z-index:9001}#action-bar .top-bar-right .menu.action-bar.hidden .action.is-dropdown-submenu-parent ul.is-dropdown-submenu{top:auto}#action-bar .top-bar-right .menu.action-bar.hidden .action.is-dropdown-submenu-parent ul.is-dropdown-submenu>.close-listener,#action-bar .top-bar-right .menu.action-bar.hidden .action.is-dropdown-submenu-parent ul.is-dropdown-submenu>li.action{z-index:9001}#action-bar .top-bar-right .menu.action-bar.hidden .action.is-dropdown-submenu-parent>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-bottom-width:0;border-top-style:solid;border-color:#fff transparent transparent;right:5px;left:auto;margin-top:-3px}#action-bar .top-bar-right .menu.action-bar.hidden .action a{white-space:nowrap}#action-bar .top-bar-right .menu.action-bar.hidden .action a img{display:none}#action-bar .top-bar-right .menu.action-bar.hidden .action a img+span{display:inherit}@media print,screen and (min-width:40em){#action-bar .top-bar-right .menu.action-bar.hidden .action.medium{display:none}}@media print,screen and (min-width:25em){#action-bar .top-bar-right .menu.action-bar.hidden .action.smedium{display:none}}@media print,screen and (min-width:64em){#action-bar .top-bar-right .menu.action-bar.hidden .action.large{display:none}}@media screen and (max-width:24.9375em){#action-bar .top-bar-right .menu.action-bar.hidden .action.smedium{display:block}#action-bar .top-bar-right .menu.action-bar.hidden .action.smedium.hidden{display:none}}@media screen and (max-width:39.9375em){#action-bar .top-bar-right .menu.action-bar.hidden .action.medium{display:block}#action-bar .top-bar-right .menu.action-bar.hidden .action.medium.hidden{display:none}}@media screen and (max-width:63.9375em){#action-bar .top-bar-right .menu.action-bar.hidden .action.large{display:block}#action-bar .top-bar-right .menu.action-bar.hidden .action.large.hidden{display:none}}#action-bar .top-bar-right .menu.action-bar.hidden .action.never{display:block}#action-bar .top-bar-right .menu.action-bar.hidden .action.always,#action-bar .top-bar-right .menu.action-bar.hidden .action.never.hidden{display:none}#action-bar .top-bar-right .menu .action{z-index:100}@media screen and (max-width:39.9375em){#action-bar .top-bar-right .menu .action a{width:100%;padding-left:.68rem}}@media screen and (max-width:24.9375em){#action-bar .top-bar-right .menu .action a{padding-left:.236rem}}@media screen and (max-width:39.9375em){#action-bar .top-bar-right .menu .action:not(.is-dropdown-submenu-parent) a{padding-right:.68rem}}@media screen and (max-width:24.9375em){#action-bar .top-bar-right .menu .action:not(.is-dropdown-submenu-parent) a{padding-right:.236rem}}#action-bar .top-bar-right .menu .action.img a{padding-top:0}#action-bar .top-bar-right .menu .action.img a img{vertical-align:inherit;max-height:1.4rem}#action-bar .top-bar-right .menu>li>ul.is-dropdown-submenu{min-width:0}#action-bar .top-bar-right .menu>li>ul.is-dropdown-submenu .action{display:inherit}#action-bar .top-bar-right .menu>li.opens-right>ul.is-dropdown-submenu{right:auto;left:auto}#action-bar .top-bar-right .menu>li.opens-right>ul.is-dropdown-submenu a{text-align:left}.dropdown.menu>li.is-dropdown-submenu-parent>a:after{border-color:#fff transparent transparent}form{position:relative}.sending .sending-loader{position:absolute;background-color:hsla(0,0%,49%,.3);display:block;pointer-events:all;width:100%;height:100%;top:0;left:0;bottom:0;right:0;z-index:10;border-radius:2px}.sending .sending-loader .loader{position:absolute}.sending-loader{display:none}label{position:relative}label [type=color],label [type=date],label [type=datetime-local],label [type=datetime],label [type=email],label [type=month],label [type=number],label [type=password],label [type=search],label [type=tel],label [type=text],label [type=time],label [type=url],label [type=week],label input:not([type]),label input[type=text],label textarea{display:block;width:100%;height:2.4375rem;padding:.5rem;-webkit-box-shadow:none!important;box-shadow:none!important;font-size:1rem;font-weight:400;line-height:1.5;border:none;outline:0;margin:0 0 15px}label [type=color]:focus,label [type=date]:focus,label [type=datetime-local]:focus,label [type=datetime]:focus,label [type=email]:focus,label [type=month]:focus,label [type=number]:focus,label [type=password]:focus,label [type=search]:focus,label [type=tel]:focus,label [type=text]:focus,label [type=time]:focus,label [type=url]:focus,label [type=week]:focus,label input:not([type]):focus,label input[type=text]:focus,label textarea:focus{border:none;-webkit-box-shadow:none!important;box-shadow:none!important}label [type=color].notEmpty:not(:focus)~span,label [type=color]:focus~span,label [type=date].notEmpty:not(:focus)~span,label [type=date]:focus~span,label [type=datetime-local].notEmpty:not(:focus)~span,label [type=datetime-local]:focus~span,label [type=datetime].notEmpty:not(:focus)~span,label [type=datetime]:focus~span,label [type=email].notEmpty:not(:focus)~span,label [type=email]:focus~span,label [type=month].notEmpty:not(:focus)~span,label [type=month]:focus~span,label [type=number].notEmpty:not(:focus)~span,label [type=number]:focus~span,label [type=password].notEmpty:not(:focus)~span,label [type=password]:focus~span,label [type=search].notEmpty:not(:focus)~span,label [type=search]:focus~span,label [type=tel].notEmpty:not(:focus)~span,label [type=tel]:focus~span,label [type=text].notEmpty:not(:focus)~span,label [type=text]:focus~span,label [type=time].notEmpty:not(:focus)~span,label [type=time]:focus~span,label [type=url].notEmpty:not(:focus)~span,label [type=url]:focus~span,label [type=week].notEmpty:not(:focus)~span,label [type=week]:focus~span,label input:not([type]).notEmpty:not(:focus)~span,label input:not([type]):focus~span,label input[type=text].notEmpty:not(:focus)~span,label input[type=text]:focus~span,label textarea.notEmpty:not(:focus)~span,label textarea:focus~span{top:-11px;left:0;bottom:0;font-size:11px;opacity:1}label [type=color]~span,label [type=date]~span,label [type=datetime-local]~span,label [type=datetime]~span,label [type=email]~span,label [type=month]~span,label [type=number]~span,label [type=password]~span,label [type=search]~span,label [type=tel]~span,label [type=text]~span,label [type=time]~span,label [type=url]~span,label [type=week]~span,label input:not([type])~span,label input[type=text]~span,label textarea~span{position:absolute;pointer-events:none;left:10px;bottom:10px;top:7px;-webkit-transition:all .2s ease;transition:all .2s ease}label textarea{height:10rem;border-top-right-radius:3px;border-top-left-radius:3px}label [type=checkbox].before-text{margin-bottom:0}.listjs{position:relative}.listjs label{display:inline-block}.listjs label input{margin-bottom:0}.listjs table{border-collapse:collapse}.listjs table tfoot tr th,.listjs table thead tr th{text-align:left}.listjs table tfoot tr th.sort,.listjs table thead tr th.sort{cursor:pointer}.listjs table tbody.list tr:first-child td{border-top:1px solid #696969}.listjs table tbody.list tr:last-child td{border-bottom:1px solid #696969}.listjs table tbody.list tr td{border-top:1px solid #c8c8c8;padding:.3rem}.listjs ul.pagination{float:right;display:inline-block;margin:0}.listjs ul.pagination li{display:inline-block;padding-left:5px;padding-right:5px;text-decoration:underline}.listjs ul.pagination li.active,.listjs ul.pagination li.disabled{text-decoration:none}.background{position:fixed;z-index:1000000;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:rgba(55,55,55,.6)}.background .modal{position:relative;top:50%;margin:auto;width:80%;-webkit-transform:translateY(-50%);transform:translateY(-50%);padding:.5rem;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;max-height:80%;max-width:1024px}@media screen and (max-width:63.9375em){.background .modal.small-margin{width:90%}}@media screen and (max-width:24.9375em){.background .modal.small-margin{width:95%}}.background .modal.max-small{max-width:0}.background .modal.max-smedium{max-width:400px}.background .modal.max-medium{max-width:640px}.background .modal.max-large{max-width:1024px}.background .modal.max-xlarge{max-width:1200px}.background .modal.max-xxlarge{max-width:1440px}.background .modal .title{font-weight:700;padding-bottom:.5rem}.background .modal .content-container{overflow-y:auto;max-height:100%}.background .modal .content-container .loader{position:static;-webkit-transform:none;transform:none}.background .modal .close{text-align:right;float:right;font-size:28px;font-weight:700;line-height:1}.background .modal .close:focus,.background .modal .close:hover{text-decoration:none;cursor:pointer}.background .modal .modal-button-container{padding-top:.5rem}.background .modal .modal-button-container .button{margin-left:.2rem;margin-bottom:0!important;padding:.6em .8em}@media screen and (max-width:24.9375em){.background .modal .modal-button-container .button{margin-left:.1rem;padding:.3em .5em}}.rotated{-webkit-transform-origin:bottom center;transform-origin:bottom center;height:50%;position:absolute;top:0;bottom:0;left:0;right:0}.share-icon{margin:.1rem}.share-icon,.share-icon svg{width:1.5rem;max-width:1.5rem}.tab-header-container .tab-header{display:inline-block;background-color:#eee;border:1px solid #b0b0b0;border-top-left-radius:4px;border-top-right-radius:4px;padding:0 5px}.tab-header-container .tab-header.active{border-bottom:0;background-color:#fff}*,:after,:before{-webkit-box-sizing:inherit;box-sizing:inherit}html{width:100%;font-size:18px;letter-spacing:1px}.max-height,html{min-height:100%;height:100%}body{margin:0;padding:0;height:100%;width:100%;font-family:Helvetica Neue,Helvetica,Roboto,Arial,sans-serif;font-weight:400;line-height:1.5;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;background:#fefefe;color:#0a0a0a}footer{border-top:1px solid #d8d8d8;text-align:center}.top-bar .top-bar-title strong{vertical-align:middle;display:inline-block}nav.top-bar{color:#fff;font-size:20px;-webkit-box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 2px 9px 1px rgba(0,0,0,.12),0 4px 2px -2px rgba(0,0,0,.2);box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 2px 9px 1px rgba(0,0,0,.12),0 4px 2px -2px rgba(0,0,0,.2);padding:.6rem;display:block}a.button,button.button{border-radius:2px}.fill-me{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-ms-flex-direction:column;flex-direction:column}.fill-me,.fill-me.vertical{-webkit-box-direction:normal}.fill-me.vertical{-webkit-box-orient:horizontal;-ms-flex-direction:row;flex-direction:row}.fill-me .grow{-webkit-box-flex:1;-ms-flex:1;flex:1}.flex-center{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.flex-center>*{max-height:100%}.dropdown.menu a,.menu a{padding:.4rem .5rem}svg path{fill:currentColor}div.mainContainer{position:relative;max-height:100%;max-width:100%;overflow:auto;-webkit-box-flex:1;-ms-flex:1;flex:1;margin:.5rem}div.mainContainer #main-content,div.mainContainer #site-content,div.mainContainer>.row{position:absolute;width:100%;height:100%;top:0;bottom:0;left:0;right:0}.inline-block{display:inline-block}.right{float:right}#logo-img{max-height:2.2rem}a{cursor:pointer}a,a.hidden-link{text-decoration:none;color:inherit}label{cursor:pointer}.align-right{text-align:right}.view-panel{display:none}.loader{left:50%;top:50%;position:fixed;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);text-align:center}.loader.inline{left:auto;top:auto;position:static;-webkit-transform:initial;transform:none;text-align:center;display:inline}.loader.small #spinner{-webkit-transform:scale(.5);transform:scale(.5)}.loader #spinner{-webkit-box-sizing:border-box;box-sizing:border-box;stroke:#b71c1a;stroke-width:3px;-webkit-transform-origin:50%;transform-origin:50%;-webkit-animation:line 1.6s cubic-bezier(.4,0,.2,1) infinite,rotate 1.6s linear infinite;animation:line 1.6s cubic-bezier(.4,0,.2,1) infinite,rotate 1.6s linear infinite}@-webkit-keyframes rotate{0%{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(450deg);transform:rotate(450deg)}}@keyframes rotate{0%{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(450deg);transform:rotate(450deg)}}@-webkit-keyframes line{0%{stroke-dasharray:2,85.964;-webkit-transform:rotate(0);transform:rotate(0)}50%{stroke-dasharray:65.973,21.9911;stroke-dashoffset:0}to{stroke-dasharray:2,85.964;stroke-dashoffset:-65.973;-webkit-transform:rotate(90deg);transform:rotate(90deg)}}@keyframes line{0%{stroke-dasharray:2,85.964;-webkit-transform:rotate(0);transform:rotate(0)}50%{stroke-dasharray:65.973,21.9911;stroke-dashoffset:0}to{stroke-dasharray:2,85.964;stroke-dashoffset:-65.973;-webkit-transform:rotate(90deg);transform:rotate(90deg)}}#print-content{display:none}.action-button{max-height:1.7rem;margin-left:.4rem;margin-right:.4rem}.action-button:hover{background:#e8e8e8}.vcenter-container{width:100%;height:100%;display:table}.vcenter-container .vcenter{vertical-align:middle;display:table-cell;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.max-width{width:100%}button,input{letter-spacing:1px!important}.no-padding{padding:0;border:0}.center{text-align:center}@media print{#styles,.mainContainer,footer,nav{display:none!important}#print-content{display:block!important}}.overflow-y-auto{overflow-y:auto!important}.row.no-after:after{content:normal}.margin-bottom{margin-bottom:1rem}@media print,screen and (min-width:25em){.margin-bottom{margin-bottom:2rem}}@media print,screen and (min-width:40em){.margin-bottom{margin-bottom:3rem}}@media print,screen and (min-width:64em){.margin-bottom{margin-bottom:4rem}}@media screen and (min-width:75em){.margin-bottom{margin-bottom:5rem}}.font-small{font-size:.7em}.border-bottom{border-bottom:1px solid #cacaca}.border-right{border-right:1px solid #cacaca}.border-left{border-left:1px solid #cacaca}img.logo{vertical-align:inherit;display:inline-block;height:auto;max-width:1.1rem;margin-right:2px}.align-center{text-align:center}hr.separator{margin:1rem 0}.button-line{display:-webkit-box;display:-ms-flexbox;display:flex}.button-line .button{-webkit-box-flex:1;-ms-flex:1;flex:1;margin-left:1px;margin-right:1px;padding:.5rem .77rem}@media screen and (max-width:24.9375em){.small-small{font-size:small}}select{border:0;padding:.3rem}.hidden{display:none}img.action-image{max-height:1.4rem;cursor:pointer}img.back-button{max-height:.6rem;margin-right:.2rem;cursor:pointer;vertical-align:inherit}.no-margin-bottom{margin-bottom:0}div.flashMessage{font-size:.8rem;border-radius:25px;letter-spacing:0;z-index:1001;max-width:100%;display:inline-block;position:relative;-webkit-box-shadow:2px 2px 10px rgba(0,0,0,.28);box-shadow:2px 2px 10px rgba(0,0,0,.28);border:1px solid #626262;background-color:#6b6b6b;padding:.3em .6em;text-align:center;color:#fff}div.flashMessage:hover{opacity:.4;cursor:pointer}div.flashMessage:after,div.flashMessage:before{display:block;content:""}span.flashMessage{float:right;cursor:pointer}div.default{background-color:#1a9cc8}#flashMessageContainer{text-align:center;position:absolute}#flashMessageContainer,#flashMessageContainerAbsoulte{height:0!important;width:100%;overflow:visible!important}#flashMessageContainerAbsoulte{margin:5px 0;position:relative}.relative{position:relative}.no-transition,.no-transition *{-webkit-transition:none!important;transition:none!important}.settings-container{border:1px solid #000;border-radius:2px;padding:.3rem}@media print,screen and (min-width:40em){.settings-container #settings-fragments-container{border-left:1px solid #cacaca}}.settings-container #settings-fragments-container #settings-fragments>*{display:none}.settings-container #settings-fragments-container #settings-fragments>.active{display:block}.switch{position:relative;display:inline-block}@media screen and (max-width:24.9375em){.switch{font-size:.6em}}@media screen and (max-width:39.9375em){.switch{font-size:.7em}}.switch input{display:none}.switch input:checked+.slider:before{-webkit-transform:translateX(1.5em);transform:translateX(1.5em)}.switch .slider{display:inline-block;position:relative;cursor:pointer;width:3em;height:1.5em;border-radius:1.5em;background-color:#ccc;-webkit-transition:.4s;transition:.4s}.switch .slider:before{position:absolute;content:"";height:1.1em;width:1.1em;left:.15em;bottom:.15em;background-color:#fff;-webkit-transition:.4s;transition:.4s;border-radius:50%}.switch img,.switch svg{width:1.4em;display:inline;vertical-align:initial}.switch img path,.switch svg path{stroke-color:inherit}.zf-green{color:#68b604}.column:last-child:not(:first-child),.columns:last-child:not(:first-child){float:left}input[type=checkBox].form-control{height:24px;height:1.5rem;width:100%}[type=submit]{display:block;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;height:39px;height:2.4375rem;padding:8px;padding:.5rem;border:1px solid #cacaca;margin:0 0 16px;margin:0 0 1rem;font-family:inherit;font-size:16px;font-size:1rem;color:#0a0a0a;background-color:#fefefe;-webkit-box-shadow:inset 0 1px 2px hsla(0,0%,4%,.1);box-shadow:inset 0 1px 2px hsla(0,0%,4%,.1);border-radius:0;-webkit-transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:box-shadow .5s,border-color .25s ease-in-out;transition:box-shadow .5s,border-color .25s ease-in-out,-webkit-box-shadow .5s;-webkit-appearance:none;-moz-appearance:none}form ul li{color:red;font-size:12.8px;font-size:.8rem}.button-dropdown:after{border-color:#000 transparent transparent;border-width:.4em;border-style:solid;content:"";position:absolute;top:.4em;display:block;height:0;width:0;right:1em}.button-dropdown{position:relative;display:block;padding-right:2em}.button-dropdown.open:after{border-color:transparent transparent #000;top:0}a.ui-datepicker-next,a.ui-datepicker-prev{height:100%!important}div.container a.navbar-brand>img{display:inline;margin-right:4px}ul.menu.plain li.active a{background-color:#ededed;color:#000}ul.menu.plain li a{color:#000}ul.menu.plain li a:hover{color:#525252}ul.submenu{border-top:1px solid #bcbcbc;border-bottom:1px solid #bcbcbc;margin-left:10px}#cookie-compliance{line-height:1.2;font-size:.8rem;width:100%;margin:0;padding:.3rem 0}#cookie-compliance #close-cookie-msg{float:right;margin-bottom:0;margin-right:3px;padding:.4rem .8rem}.menu-container .button{text-align:center;width:100%}.height-5{height:5%}.max-height-5{max-height:5%}.width-5{width:5%}.max-width-5{max-width:5%}.height-10{height:10%}.max-height-10{max-height:10%}.width-10{width:10%}.max-width-10{max-width:10%}.height-15{height:15%}.max-height-15{max-height:15%}.width-15{width:15%}.max-width-15{max-width:15%}.height-20{height:20%}.max-height-20{max-height:20%}.width-20{width:20%}.max-width-20{max-width:20%}.height-25{height:25%}.max-height-25{max-height:25%}.width-25{width:25%}.max-width-25{max-width:25%}.height-30{height:30%}.max-height-30{max-height:30%}.width-30{width:30%}.max-width-30{max-width:30%}.height-35{height:35%}.max-height-35{max-height:35%}.width-35{width:35%}.max-width-35{max-width:35%}.height-40{height:40%}.max-height-40{max-height:40%}.width-40{width:40%}.max-width-40{max-width:40%}.height-45{height:45%}.max-height-45{max-height:45%}.width-45{width:45%}.max-width-45{max-width:45%}.height-50{height:50%}.max-height-50{max-height:50%}.width-50{width:50%}.max-width-50{max-width:50%}.height-55{height:55%}.max-height-55{max-height:55%}.width-55{width:55%}.max-width-55{max-width:55%}.height-60{height:60%}.max-height-60{max-height:60%}.width-60{width:60%}.max-width-60{max-width:60%}.height-65{height:65%}.max-height-65{max-height:65%}.width-65{width:65%}.max-width-65{max-width:65%}.height-70{height:70%}.max-height-70{max-height:70%}.width-70{width:70%}.max-width-70{max-width:70%}.height-75{height:75%}.max-height-75{max-height:75%}.width-75{width:75%}.max-width-75{max-width:75%}.height-80{height:80%}.max-height-80{max-height:80%}.width-80{width:80%}.max-width-80{max-width:80%}.height-85{height:85%}.max-height-85{max-height:85%}.width-85{width:85%}.max-width-85{max-width:85%}.height-90{height:90%}.max-height-90{max-height:90%}.width-90{width:90%}.max-width-90{max-width:90%}.height-95{height:95%}.max-height-95{max-height:95%}.width-95{width:95%}.max-width-95{max-width:95%}.height-100{height:100%}.max-height-100{max-height:100%}.width-100{width:100%}.max-width-100{max-width:100%}*{-webkit-transition:.25s ease-out,color .25s ease-out;transition:.25s ease-out,color .25s ease-out}body.red{background:#fff;color:#000}body.red #cookie-compliance{background-color:#870015;color:#fff}body.red #cookie-compliance a.link,body.red #cookie-compliance a.link:hover{color:#ff3d00;border-bottom-color:#ff3d00}body.red a.link{text-decoration:none;color:#ff3d00;border-bottom:none}body.red a.link:hover{color:#ff3d00;border-bottom-color:#ff3d00}body.red .loader #spinner{stroke:#b71c1a}body.red nav.top-bar{color:#fff;background:red}body.red .top-bar ul{background:red!important}body.red .top-bar ul a{color:#fff}body.red .switch input:checked+.slider,body.red a.button,body.red a.button.disabled,body.red a.button.disabled:focus,body.red a.button.disabled:hover,body.red a.button:hover,body.red button.button,body.red button.button.disabled,body.red button.button.disabled:focus,body.red button.button.disabled:hover,body.red button.button:hover{background-color:red}body.red .switch input:focus+.slider{-webkit-box-shadow:0 0 1px red;box-shadow:0 0 1px red}body.red label{color:#000}body.red .background .modal{background-color:#fff}body.red svg.fill-color,body.red svg .fill-color{fill:currentColor}body.red svg.fill-background,body.red svg .fill-background{fill:#fff}body.red label [type=color],body.red label [type=date],body.red label [type=datetime-local],body.red label [type=datetime],body.red label [type=email],body.red label [type=month],body.red label [type=number],body.red label [type=password],body.red label [type=search],body.red label [type=tel],body.red label [type=text],body.red label [type=time],body.red label [type=url],body.red label [type=week],body.red label input:not([type]),body.red label input[type=text],body.red label textarea{border-bottom:solid #000;background:#fff;color:#000}body.red label [type=color]:focus,body.red label [type=date]:focus,body.red label [type=datetime-local]:focus,body.red label [type=datetime]:focus,body.red label [type=email]:focus,body.red label [type=month]:focus,body.red label [type=number]:focus,body.red label [type=password]:focus,body.red label [type=search]:focus,body.red label [type=tel]:focus,body.red label [type=text]:focus,body.red label [type=time]:focus,body.red label [type=url]:focus,body.red label [type=week]:focus,body.red label input:not([type]):focus,body.red label input[type=text]:focus,body.red label textarea:focus{border-bottom:solid #000}body.red label [type=color].notEmpty:not(:focus)~span,body.red label [type=color]:focus~span,body.red label [type=date].notEmpty:not(:focus)~span,body.red label [type=date]:focus~span,body.red label [type=datetime-local].notEmpty:not(:focus)~span,body.red label [type=datetime-local]:focus~span,body.red label [type=datetime].notEmpty:not(:focus)~span,body.red label [type=datetime]:focus~span,body.red label [type=email].notEmpty:not(:focus)~span,body.red label [type=email]:focus~span,body.red label [type=month].notEmpty:not(:focus)~span,body.red label [type=month]:focus~span,body.red label [type=number].notEmpty:not(:focus)~span,body.red label [type=number]:focus~span,body.red label [type=password].notEmpty:not(:focus)~span,body.red label [type=password]:focus~span,body.red label [type=search].notEmpty:not(:focus)~span,body.red label [type=search]:focus~span,body.red label [type=tel].notEmpty:not(:focus)~span,body.red label [type=tel]:focus~span,body.red label [type=text].notEmpty:not(:focus)~span,body.red label [type=text]:focus~span,body.red label [type=time].notEmpty:not(:focus)~span,body.red label [type=time]:focus~span,body.red label [type=url].notEmpty:not(:focus)~span,body.red label [type=url]:focus~span,body.red label [type=week].notEmpty:not(:focus)~span,body.red label [type=week]:focus~span,body.red label input:not([type]).notEmpty:not(:focus)~span,body.red label input:not([type]):focus~span,body.red label input[type=text].notEmpty:not(:focus)~span,body.red label input[type=text]:focus~span,body.red label textarea.notEmpty:not(:focus)~span,body.red label textarea:focus~span{color:#000}body.red label [type=color]~span,body.red label [type=date]~span,body.red label [type=datetime-local]~span,body.red label [type=datetime]~span,body.red label [type=email]~span,body.red label [type=month]~span,body.red label [type=number]~span,body.red label [type=password]~span,body.red label [type=search]~span,body.red label [type=tel]~span,body.red label [type=text]~span,body.red label [type=time]~span,body.red label [type=url]~span,body.red label [type=week]~span,body.red label input:not([type])~span,body.red label input[type=text]~span,body.red label textarea~span{color:rgba(0,0,0,.65)}body.red label textarea{-webkit-box-shadow:0 0 3px 2px hsla(0,0%,53%,.31)!important;box-shadow:0 0 3px 2px hsla(0,0%,53%,.31)!important}body.red input.notEmpty:invalid{background-color:rgba(255,0,0,.65)}body.blue{background:#fff;color:#000}body.blue #cookie-compliance{background-color:#1a3062;color:#fff}body.blue #cookie-compliance a.link,body.blue #cookie-compliance a.link:hover{color:#546cfe;border-bottom-color:#546cfe}body.blue a.link{text-decoration:none;color:#546cfe;border-bottom:none}body.blue a.link:hover{color:#546cfe;border-bottom-color:#546cfe}body.blue .loader #spinner{stroke:#673ab7}body.blue nav.top-bar{color:#fff;background:#2c58ae}body.blue .top-bar ul{background:#2c58ae!important}body.blue .top-bar ul a{color:#fff}body.blue .switch input:checked+.slider,body.blue a.button,body.blue a.button.disabled,body.blue a.button.disabled:focus,body.blue a.button.disabled:hover,body.blue a.button:hover,body.blue button.button,body.blue button.button.disabled,body.blue button.button.disabled:focus,body.blue button.button.disabled:hover,body.blue button.button:hover{background-color:#2c58ae}body.blue .switch input:focus+.slider{-webkit-box-shadow:0 0 1px #2c58ae;box-shadow:0 0 1px #2c58ae}body.blue label{color:#000}body.blue .background .modal{background-color:#fff}body.blue svg.fill-color,body.blue svg .fill-color{fill:currentColor}body.blue svg.fill-background,body.blue svg .fill-background{fill:#fff}body.blue label [type=color],body.blue label [type=date],body.blue label [type=datetime-local],body.blue label [type=datetime],body.blue label [type=email],body.blue label [type=month],body.blue label [type=number],body.blue label [type=password],body.blue label [type=search],body.blue label [type=tel],body.blue label [type=text],body.blue label [type=time],body.blue label [type=url],body.blue label [type=week],body.blue label input:not([type]),body.blue label input[type=text],body.blue label textarea{border-bottom:solid #000;background:#fff;color:#000}body.blue label [type=color]:focus,body.blue label [type=date]:focus,body.blue label [type=datetime-local]:focus,body.blue label [type=datetime]:focus,body.blue label [type=email]:focus,body.blue label [type=month]:focus,body.blue label [type=number]:focus,body.blue label [type=password]:focus,body.blue label [type=search]:focus,body.blue label [type=tel]:focus,body.blue label [type=text]:focus,body.blue label [type=time]:focus,body.blue label [type=url]:focus,body.blue label [type=week]:focus,body.blue label input:not([type]):focus,body.blue label input[type=text]:focus,body.blue label textarea:focus{border-bottom:solid #000}body.blue label [type=color].notEmpty:not(:focus)~span,body.blue label [type=color]:focus~span,body.blue label [type=date].notEmpty:not(:focus)~span,body.blue label [type=date]:focus~span,body.blue label [type=datetime-local].notEmpty:not(:focus)~span,body.blue label [type=datetime-local]:focus~span,body.blue label [type=datetime].notEmpty:not(:focus)~span,body.blue label [type=datetime]:focus~span,body.blue label [type=email].notEmpty:not(:focus)~span,body.blue label [type=email]:focus~span,body.blue label [type=month].notEmpty:not(:focus)~span,body.blue label [type=month]:focus~span,body.blue label [type=number].notEmpty:not(:focus)~span,body.blue label [type=number]:focus~span,body.blue label [type=password].notEmpty:not(:focus)~span,body.blue label [type=password]:focus~span,body.blue label [type=search].notEmpty:not(:focus)~span,body.blue label [type=search]:focus~span,body.blue label [type=tel].notEmpty:not(:focus)~span,body.blue label [type=tel]:focus~span,body.blue label [type=text].notEmpty:not(:focus)~span,body.blue label [type=text]:focus~span,body.blue label [type=time].notEmpty:not(:focus)~span,body.blue label [type=time]:focus~span,body.blue label [type=url].notEmpty:not(:focus)~span,body.blue label [type=url]:focus~span,body.blue label [type=week].notEmpty:not(:focus)~span,body.blue label [type=week]:focus~span,body.blue label input:not([type]).notEmpty:not(:focus)~span,body.blue label input:not([type]):focus~span,body.blue label input[type=text].notEmpty:not(:focus)~span,body.blue label input[type=text]:focus~span,body.blue label textarea.notEmpty:not(:focus)~span,body.blue label textarea:focus~span{color:#000}body.blue label [type=color]~span,body.blue label [type=date]~span,body.blue label [type=datetime-local]~span,body.blue label [type=datetime]~span,body.blue label [type=email]~span,body.blue label [type=month]~span,body.blue label [type=number]~span,body.blue label [type=password]~span,body.blue label [type=search]~span,body.blue label [type=tel]~span,body.blue label [type=text]~span,body.blue label [type=time]~span,body.blue label [type=url]~span,body.blue label [type=week]~span,body.blue label input:not([type])~span,body.blue label input[type=text]~span,body.blue label textarea~span{color:rgba(0,0,0,.65)}body.blue label textarea{-webkit-box-shadow:0 0 3px 2px hsla(0,0%,53%,.31)!important;box-shadow:0 0 3px 2px hsla(0,0%,53%,.31)!important}body.blue input.notEmpty:invalid{background-color:rgba(44,88,174,.65)}body.green{background:#fff;color:#000}body.green #cookie-compliance{background-color:#003613;color:#fff}body.green #cookie-compliance a.link,body.green #cookie-compliance a.link:hover{color:#009829;border-bottom-color:#009829}body.green a.link{text-decoration:none;color:#009829;border-bottom:none}body.green a.link:hover{color:#009829;border-bottom-color:#009829}body.green .loader #spinner{stroke:green}body.green nav.top-bar{color:#fff;background:green}body.green .top-bar ul{background:green!important}body.green .top-bar ul a{color:#fff}body.green .switch input:checked+.slider,body.green a.button,body.green a.button.disabled,body.green a.button.disabled:focus,body.green a.button.disabled:hover,body.green a.button:hover,body.green button.button,body.green button.button.disabled,body.green button.button.disabled:focus,body.green button.button.disabled:hover,body.green button.button:hover{background-color:green}body.green .switch input:focus+.slider{-webkit-box-shadow:0 0 1px green;box-shadow:0 0 1px green}body.green label{color:#000}body.green .background .modal{background-color:#fff}body.green svg.fill-color,body.green svg .fill-color{fill:currentColor}body.green svg.fill-background,body.green svg .fill-background{fill:#fff}body.green label [type=color],body.green label [type=date],body.green label [type=datetime-local],body.green label [type=datetime],body.green label [type=email],body.green label [type=month],body.green label [type=number],body.green label [type=password],body.green label [type=search],body.green label [type=tel],body.green label [type=text],body.green label [type=time],body.green label [type=url],body.green label [type=week],body.green label input:not([type]),body.green label input[type=text],body.green label textarea{border-bottom:solid #000;background:#fff;color:#000}body.green label [type=color]:focus,body.green label [type=date]:focus,body.green label [type=datetime-local]:focus,body.green label [type=datetime]:focus,body.green label [type=email]:focus,body.green label [type=month]:focus,body.green label [type=number]:focus,body.green label [type=password]:focus,body.green label [type=search]:focus,body.green label [type=tel]:focus,body.green label [type=text]:focus,body.green label [type=time]:focus,body.green label [type=url]:focus,body.green label [type=week]:focus,body.green label input:not([type]):focus,body.green label input[type=text]:focus,body.green label textarea:focus{border-bottom:solid #000}body.green label [type=color].notEmpty:not(:focus)~span,body.green label [type=color]:focus~span,body.green label [type=date].notEmpty:not(:focus)~span,body.green label [type=date]:focus~span,body.green label [type=datetime-local].notEmpty:not(:focus)~span,body.green label [type=datetime-local]:focus~span,body.green label [type=datetime].notEmpty:not(:focus)~span,body.green label [type=datetime]:focus~span,body.green label [type=email].notEmpty:not(:focus)~span,body.green label [type=email]:focus~span,body.green label [type=month].notEmpty:not(:focus)~span,body.green label [type=month]:focus~span,body.green label [type=number].notEmpty:not(:focus)~span,body.green label [type=number]:focus~span,body.green label [type=password].notEmpty:not(:focus)~span,body.green label [type=password]:focus~span,body.green label [type=search].notEmpty:not(:focus)~span,body.green label [type=search]:focus~span,body.green label [type=tel].notEmpty:not(:focus)~span,body.green label [type=tel]:focus~span,body.green label [type=text].notEmpty:not(:focus)~span,body.green label [type=text]:focus~span,body.green label [type=time].notEmpty:not(:focus)~span,body.green label [type=time]:focus~span,body.green label [type=url].notEmpty:not(:focus)~span,body.green label [type=url]:focus~span,body.green label [type=week].notEmpty:not(:focus)~span,body.green label [type=week]:focus~span,body.green label input:not([type]).notEmpty:not(:focus)~span,body.green label input:not([type]):focus~span,body.green label input[type=text].notEmpty:not(:focus)~span,body.green label input[type=text]:focus~span,body.green label textarea.notEmpty:not(:focus)~span,body.green label textarea:focus~span{color:#000}body.green label [type=color]~span,body.green label [type=date]~span,body.green label [type=datetime-local]~span,body.green label [type=datetime]~span,body.green label [type=email]~span,body.green label [type=month]~span,body.green label [type=number]~span,body.green label [type=password]~span,body.green label [type=search]~span,body.green label [type=tel]~span,body.green label [type=text]~span,body.green label [type=time]~span,body.green label [type=url]~span,body.green label [type=week]~span,body.green label input:not([type])~span,body.green label input[type=text]~span,body.green label textarea~span{color:rgba(0,0,0,.65)}body.green label textarea{-webkit-box-shadow:0 0 3px 2px hsla(0,0%,53%,.31)!important;box-shadow:0 0 3px 2px hsla(0,0%,53%,.31)!important}body.green input.notEmpty:invalid{background-color:rgba(0,128,0,.65)}body.pink{background:#fff;color:#000}body.pink #cookie-compliance{background-color:#70374a;color:#fff}body.pink #cookie-compliance a.link,body.pink #cookie-compliance a.link:hover{color:#fe64af;border-bottom-color:#fe64af}body.pink a.link{text-decoration:none;color:#fe64af;border-bottom:none}body.pink a.link:hover{color:#fe64af;border-bottom-color:#fe64af}body.pink .loader #spinner{stroke:#ff69b4}body.pink nav.top-bar{color:#fff;background:#ff69b4}body.pink .top-bar ul{background:#ff69b4!important}body.pink .top-bar ul a{color:#fff}body.pink .switch input:checked+.slider,body.pink a.button,body.pink a.button.disabled,body.pink a.button.disabled:focus,body.pink a.button.disabled:hover,body.pink a.button:hover,body.pink button.button,body.pink button.button.disabled,body.pink button.button.disabled:focus,body.pink button.button.disabled:hover,body.pink button.button:hover{background-color:#ff69b4}body.pink .switch input:focus+.slider{-webkit-box-shadow:0 0 1px #ff69b4;box-shadow:0 0 1px #ff69b4}body.pink label{color:#000}body.pink .background .modal{background-color:#fff}body.pink svg.fill-color,body.pink svg .fill-color{fill:currentColor}body.pink svg.fill-background,body.pink svg .fill-background{fill:#fff}body.pink label [type=color],body.pink label [type=date],body.pink label [type=datetime-local],body.pink label [type=datetime],body.pink label [type=email],body.pink label [type=month],body.pink label [type=number],body.pink label [type=password],body.pink label [type=search],body.pink label [type=tel],body.pink label [type=text],body.pink label [type=time],body.pink label [type=url],body.pink label [type=week],body.pink label input:not([type]),body.pink label input[type=text],body.pink label textarea{border-bottom:solid #000;background:#fff;color:#000}body.pink label [type=color]:focus,body.pink label [type=date]:focus,body.pink label [type=datetime-local]:focus,body.pink label [type=datetime]:focus,body.pink label [type=email]:focus,body.pink label [type=month]:focus,body.pink label [type=number]:focus,body.pink label [type=password]:focus,body.pink label [type=search]:focus,body.pink label [type=tel]:focus,body.pink label [type=text]:focus,body.pink label [type=time]:focus,body.pink label [type=url]:focus,body.pink label [type=week]:focus,body.pink label input:not([type]):focus,body.pink label input[type=text]:focus,body.pink label textarea:focus{border-bottom:solid #000}body.pink label [type=color].notEmpty:not(:focus)~span,body.pink label [type=color]:focus~span,body.pink label [type=date].notEmpty:not(:focus)~span,body.pink label [type=date]:focus~span,body.pink label [type=datetime-local].notEmpty:not(:focus)~span,body.pink label [type=datetime-local]:focus~span,body.pink label [type=datetime].notEmpty:not(:focus)~span,body.pink label [type=datetime]:focus~span,body.pink label [type=email].notEmpty:not(:focus)~span,body.pink label [type=email]:focus~span,body.pink label [type=month].notEmpty:not(:focus)~span,body.pink label [type=month]:focus~span,body.pink label [type=number].notEmpty:not(:focus)~span,body.pink label [type=number]:focus~span,body.pink label [type=password].notEmpty:not(:focus)~span,body.pink label [type=password]:focus~span,body.pink label [type=search].notEmpty:not(:focus)~span,body.pink label [type=search]:focus~span,body.pink label [type=tel].notEmpty:not(:focus)~span,body.pink label [type=tel]:focus~span,body.pink label [type=text].notEmpty:not(:focus)~span,body.pink label [type=text]:focus~span,body.pink label [type=time].notEmpty:not(:focus)~span,body.pink label [type=time]:focus~span,body.pink label [type=url].notEmpty:not(:focus)~span,body.pink label [type=url]:focus~span,body.pink label [type=week].notEmpty:not(:focus)~span,body.pink label [type=week]:focus~span,body.pink label input:not([type]).notEmpty:not(:focus)~span,body.pink label input:not([type]):focus~span,body.pink label input[type=text].notEmpty:not(:focus)~span,body.pink label input[type=text]:focus~span,body.pink label textarea.notEmpty:not(:focus)~span,body.pink label textarea:focus~span{color:#000}body.pink label [type=color]~span,body.pink label [type=date]~span,body.pink label [type=datetime-local]~span,body.pink label [type=datetime]~span,body.pink label [type=email]~span,body.pink label [type=month]~span,body.pink label [type=number]~span,body.pink label [type=password]~span,body.pink label [type=search]~span,body.pink label [type=tel]~span,body.pink label [type=text]~span,body.pink label [type=time]~span,body.pink label [type=url]~span,body.pink label [type=week]~span,body.pink label input:not([type])~span,body.pink label input[type=text]~span,body.pink label textarea~span{color:rgba(0,0,0,.65)}body.pink label textarea{-webkit-box-shadow:0 0 3px 2px hsla(0,0%,53%,.31)!important;box-shadow:0 0 3px 2px hsla(0,0%,53%,.31)!important}body.pink input.notEmpty:invalid{background-color:rgba(255,105,180,.65)}body.black{background:#fff;color:#000}body.black #cookie-compliance{background-color:#353535;color:#fff}body.black #cookie-compliance a.link{color:#fff;border-bottom-color:#fff}body.black #cookie-compliance a.link:hover{color:#cacaca;border-bottom-color:#cacaca}body.black a.link{text-decoration:none;color:#000;border-bottom:1px solid #000}body.black a.link:hover{color:#4e4e4e;border-bottom-color:#4e4e4e}body.black .loader #spinner{stroke:#000}body.black nav.top-bar{color:#fff;background:#000}body.black .top-bar ul{background:#000!important}body.black .top-bar ul a{color:#fff}body.black .switch input:checked+.slider,body.black a.button,body.black a.button.disabled,body.black a.button.disabled:focus,body.black a.button.disabled:hover,body.black a.button:hover,body.black button.button,body.black button.button.disabled,body.black button.button.disabled:focus,body.black button.button.disabled:hover,body.black button.button:hover{background-color:#000}body.black .switch input:focus+.slider{-webkit-box-shadow:0 0 1px #000;box-shadow:0 0 1px #000}body.black label{color:#000}body.black .background .modal{background-color:#fff}body.black svg.fill-color,body.black svg .fill-color{fill:currentColor}body.black svg.fill-background,body.black svg .fill-background{fill:#fff}body.black label [type=color],body.black label [type=date],body.black label [type=datetime-local],body.black label [type=datetime],body.black label [type=email],body.black label [type=month],body.black label [type=number],body.black label [type=password],body.black label [type=search],body.black label [type=tel],body.black label [type=text],body.black label [type=time],body.black label [type=url],body.black label [type=week],body.black label input:not([type]),body.black label input[type=text],body.black label textarea{border-bottom:solid #000;background:#fff;color:#000}body.black label [type=color]:focus,body.black label [type=date]:focus,body.black label [type=datetime-local]:focus,body.black label [type=datetime]:focus,body.black label [type=email]:focus,body.black label [type=month]:focus,body.black label [type=number]:focus,body.black label [type=password]:focus,body.black label [type=search]:focus,body.black label [type=tel]:focus,body.black label [type=text]:focus,body.black label [type=time]:focus,body.black label [type=url]:focus,body.black label [type=week]:focus,body.black label input:not([type]):focus,body.black label input[type=text]:focus,body.black label textarea:focus{border-bottom:solid #000}body.black label [type=color].notEmpty:not(:focus)~span,body.black label [type=color]:focus~span,body.black label [type=date].notEmpty:not(:focus)~span,body.black label [type=date]:focus~span,body.black label [type=datetime-local].notEmpty:not(:focus)~span,body.black label [type=datetime-local]:focus~span,body.black label [type=datetime].notEmpty:not(:focus)~span,body.black label [type=datetime]:focus~span,body.black label [type=email].notEmpty:not(:focus)~span,body.black label [type=email]:focus~span,body.black label [type=month].notEmpty:not(:focus)~span,body.black label [type=month]:focus~span,body.black label [type=number].notEmpty:not(:focus)~span,body.black label [type=number]:focus~span,body.black label [type=password].notEmpty:not(:focus)~span,body.black label [type=password]:focus~span,body.black label [type=search].notEmpty:not(:focus)~span,body.black label [type=search]:focus~span,body.black label [type=tel].notEmpty:not(:focus)~span,body.black label [type=tel]:focus~span,body.black label [type=text].notEmpty:not(:focus)~span,body.black label [type=text]:focus~span,body.black label [type=time].notEmpty:not(:focus)~span,body.black label [type=time]:focus~span,body.black label [type=url].notEmpty:not(:focus)~span,body.black label [type=url]:focus~span,body.black label [type=week].notEmpty:not(:focus)~span,body.black label [type=week]:focus~span,body.black label input:not([type]).notEmpty:not(:focus)~span,body.black label input:not([type]):focus~span,body.black label input[type=text].notEmpty:not(:focus)~span,body.black label input[type=text]:focus~span,body.black label textarea.notEmpty:not(:focus)~span,body.black label textarea:focus~span{color:#000}body.black label [type=color]~span,body.black label [type=date]~span,body.black label [type=datetime-local]~span,body.black label [type=datetime]~span,body.black label [type=email]~span,body.black label [type=month]~span,body.black label [type=number]~span,body.black label [type=password]~span,body.black label [type=search]~span,body.black label [type=tel]~span,body.black label [type=text]~span,body.black label [type=time]~span,body.black label [type=url]~span,body.black label [type=week]~span,body.black label input:not([type])~span,body.black label input[type=text]~span,body.black label textarea~span{color:rgba(0,0,0,.65)}body.black label textarea{-webkit-box-shadow:0 0 3px 2px hsla(0,0%,53%,.31)!important;box-shadow:0 0 3px 2px hsla(0,0%,53%,.31)!important}body.black input.notEmpty:invalid{background-color:rgba(0,0,0,.65)}body.dark{background:#000;color:#fff}body.dark #cookie-compliance{background-color:#4b4b4b;color:#fff}body.dark #cookie-compliance a.link,body.dark #cookie-compliance a.link:hover{color:#fff;border-bottom-color:#fff}body.dark a.link{text-decoration:none;color:#fff;border-bottom:1px solid #fff}body.dark a.link:hover{color:#fff;border-bottom-color:#fff}body.dark .loader #spinner{stroke:#fff}body.dark nav.top-bar{color:#fff;background:#373737}body.dark .top-bar ul{background:#373737!important}body.dark .top-bar ul a{color:#fff}body.dark .switch input:checked+.slider,body.dark a.button,body.dark a.button.disabled,body.dark a.button.disabled:focus,body.dark a.button.disabled:hover,body.dark a.button:hover,body.dark button.button,body.dark button.button.disabled,body.dark button.button.disabled:focus,body.dark button.button.disabled:hover,body.dark button.button:hover{background-color:#373737}body.dark .switch input:focus+.slider{-webkit-box-shadow:0 0 1px #373737;box-shadow:0 0 1px #373737}body.dark label{color:#fff}body.dark .background .modal{background-color:#000}body.dark svg.fill-color,body.dark svg .fill-color{fill:currentColor}body.dark svg.fill-background,body.dark svg .fill-background{fill:#000}body.dark label [type=color],body.dark label [type=date],body.dark label [type=datetime-local],body.dark label [type=datetime],body.dark label [type=email],body.dark label [type=month],body.dark label [type=number],body.dark label [type=password],body.dark label [type=search],body.dark label [type=tel],body.dark label [type=text],body.dark label [type=time],body.dark label [type=url],body.dark label [type=week],body.dark label input:not([type]),body.dark label input[type=text],body.dark label textarea{border-bottom:solid #fff;background:#000;color:#fff}body.dark label [type=color]:focus,body.dark label [type=date]:focus,body.dark label [type=datetime-local]:focus,body.dark label [type=datetime]:focus,body.dark label [type=email]:focus,body.dark label [type=month]:focus,body.dark label [type=number]:focus,body.dark label [type=password]:focus,body.dark label [type=search]:focus,body.dark label [type=tel]:focus,body.dark label [type=text]:focus,body.dark label [type=time]:focus,body.dark label [type=url]:focus,body.dark label [type=week]:focus,body.dark label input:not([type]):focus,body.dark label input[type=text]:focus,body.dark label textarea:focus{border-bottom:solid #fff}body.dark label [type=color].notEmpty:not(:focus)~span,body.dark label [type=color]:focus~span,body.dark label [type=date].notEmpty:not(:focus)~span,body.dark label [type=date]:focus~span,body.dark label [type=datetime-local].notEmpty:not(:focus)~span,body.dark label [type=datetime-local]:focus~span,body.dark label [type=datetime].notEmpty:not(:focus)~span,body.dark label [type=datetime]:focus~span,body.dark label [type=email].notEmpty:not(:focus)~span,body.dark label [type=email]:focus~span,body.dark label [type=month].notEmpty:not(:focus)~span,body.dark label [type=month]:focus~span,body.dark label [type=number].notEmpty:not(:focus)~span,body.dark label [type=number]:focus~span,body.dark label [type=password].notEmpty:not(:focus)~span,body.dark label [type=password]:focus~span,body.dark label [type=search].notEmpty:not(:focus)~span,body.dark label [type=search]:focus~span,body.dark label [type=tel].notEmpty:not(:focus)~span,body.dark label [type=tel]:focus~span,body.dark label [type=text].notEmpty:not(:focus)~span,body.dark label [type=text]:focus~span,body.dark label [type=time].notEmpty:not(:focus)~span,body.dark label [type=time]:focus~span,body.dark label [type=url].notEmpty:not(:focus)~span,body.dark label [type=url]:focus~span,body.dark label [type=week].notEmpty:not(:focus)~span,body.dark label [type=week]:focus~span,body.dark label input:not([type]).notEmpty:not(:focus)~span,body.dark label input:not([type]):focus~span,body.dark label input[type=text].notEmpty:not(:focus)~span,body.dark label input[type=text]:focus~span,body.dark label textarea.notEmpty:not(:focus)~span,body.dark label textarea:focus~span{color:#fff}body.dark label [type=color]~span,body.dark label [type=date]~span,body.dark label [type=datetime-local]~span,body.dark label [type=datetime]~span,body.dark label [type=email]~span,body.dark label [type=month]~span,body.dark label [type=number]~span,body.dark label [type=password]~span,body.dark label [type=search]~span,body.dark label [type=tel]~span,body.dark label [type=text]~span,body.dark label [type=time]~span,body.dark label [type=url]~span,body.dark label [type=week]~span,body.dark label input:not([type])~span,body.dark label input[type=text]~span,body.dark label textarea~span{color:hsla(0,0%,100%,.65)}body.dark label textarea{-webkit-box-shadow:0 0 3px 2px hsla(0,0%,53%,.31)!important;box-shadow:0 0 3px 2px hsla(0,0%,53%,.31)!important}body.dark input.notEmpty:invalid{background-color:rgba(55,55,55,.65)}@-webkit-keyframes tutorialPointer{0%{top:25%}to{top:75%}}@keyframes tutorialPointer{0%{top:25%}to{top:75%}}.tutorial-blanket{display:none;position:fixed;top:0;bottom:0;left:0;right:0;z-index:9001;background:rgba(98,98,98,.51)}.tutorial .tutorial-blanket{display:block}.tutorial .tutorial-text{color:#fff;font-size:1.5rem;display:-webkit-box;display:-ms-flexbox;display:flex}.tutorial .tutorial-text,.tutorial .tutorial-text *{-webkit-transition:none!important;transition:none!important}.tutorial.step-1 #level .segment-row{position:inherit}.tutorial.step-1 #level .segment-parent:nth-child(3),.tutorial.step-1 #level .segment-parent:nth-child(3).rotating{z-index:9900!important}.tutorial.step-1 .tutorial-text .step-1{display:initial;z-index:9900!important;position:relative}.tutorial.step-2 #level{z-index:9900!important}.tutorial.step-2 .tutorial-text .step-2,.tutorial.step-3 .tutorial-text .step-3{display:initial;z-index:9900!important;position:relative}.tutorial.step-3 #help-button{position:relative;z-index:9900!important;overflow:visible;margin-right:10px;margin-top:10px;-webkit-box-shadow:0 0 10px 5px #fff;box-shadow:0 0 10px 5px #fff}.tutorial.step-4 .tutorial-text .step-4{display:initial;z-index:9900!important;position:relative}.tutorial.step-4 #level .segment-row{position:inherit}.tutorial.step-4 #level .segment-row>.child-container .segment-parent.layer-2,.tutorial.step-4 #level .segment-row>.child-container>.segment-parent.layer-2.rotating{z-index:9900!important}.tutorial.step-4 #level .segment-row>.child-container .segment-parent.layer-2 #tutorial-pointer,.tutorial.step-4 #level .segment-row>.child-container>.segment-parent.layer-2.rotating #tutorial-pointer{width:.6em;height:.6em;border-radius:50%;left:75%;position:absolute;top:75%;z-index:1;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-animation:tutorialPointer 2s infinite;animation:tutorialPointer 2s infinite;pointer-events:none}body.red #tutorial-pointer{background:red}body.red #level-number-container.in-main-menu{background:#fff;border-color:#000}body.red .segment.segment-parent{border-color:#555}body.red .segment.segment-parent.layer-2{border-color:#000}body.red #site-content>:not(.won) .segment.locked{border-color:#870015;background-color:red!important}body.red .segment:not(.segment-row):not(.segment-triangle).rotate-90,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-90,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-180,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-270,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-360,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-180,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-90,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-180,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-270,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-360,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-270,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-90,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-180,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-270,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-360,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-360,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-90,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-180,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-270,body.red .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-360{background-color:#fff}body.blue #tutorial-pointer{background:#2c58ae}body.blue #level-number-container.in-main-menu{background:#fff;border-color:#000}body.blue .segment.segment-parent{border-color:#555}body.blue .segment.segment-parent.layer-2{border-color:#000}body.blue #site-content>:not(.won) .segment.locked{border-color:#1a3062;background-color:#2c58ae!important}body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-90,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-90,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-180,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-270,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-360,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-180,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-90,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-180,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-270,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-360,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-270,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-90,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-180,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-270,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-360,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-360,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-90,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-180,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-270,body.blue .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-360{background-color:#fff}body.green #tutorial-pointer{background:green}body.green #level-number-container.in-main-menu{background:#fff;border-color:#000}body.green .segment.segment-parent{border-color:#555}body.green .segment.segment-parent.layer-2{border-color:#000}body.green #site-content>:not(.won) .segment.locked{border-color:#003613;background-color:green!important}body.green .segment:not(.segment-row):not(.segment-triangle).rotate-90,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-90,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-180,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-270,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-360,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-180,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-90,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-180,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-270,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-360,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-270,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-90,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-180,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-270,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-360,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-360,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-90,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-180,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-270,body.green .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-360{background-color:#fff}body.pink #tutorial-pointer{background:#ff69b4}body.pink #level-number-container.in-main-menu{background:#fff;border-color:#000}body.pink .segment.segment-parent{border-color:#555}body.pink .segment.segment-parent.layer-2{border-color:#000}body.pink #site-content>:not(.won) .segment.locked{border-color:#70374a;background-color:#ff69b4!important}body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-90,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-90,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-180,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-270,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-360,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-180,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-90,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-180,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-270,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-360,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-270,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-90,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-180,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-270,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-360,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-360,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-90,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-180,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-270,body.pink .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-360{background-color:#fff}body.black #tutorial-pointer{background:#000}body.black #level-number-container.in-main-menu{background:#fff;border-color:#000}body.black .segment.segment-parent{border-color:#555}body.black .segment.segment-parent.layer-2{border-color:#000}body.black #site-content>:not(.won) .segment.locked{border-color:#353535;background-color:#000!important}body.black .segment:not(.segment-row):not(.segment-triangle).rotate-90,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-90,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-180,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-270,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-360,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-180,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-90,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-180,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-270,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-360,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-270,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-90,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-180,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-270,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-360,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-360,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-90,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-180,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-270,body.black .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-360{background-color:#fff}body.dark #tutorial-pointer{background:#373737}body.dark #level-number-container.in-main-menu{background:#000;border-color:#fff}body.dark .segment.segment-parent{border-color:#9b9b9b}body.dark .segment.segment-parent.layer-2{border-color:#fff}body.dark #site-content>:not(.won) .segment.locked{border-color:#4b4b4b;background-color:#373737!important}body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-90,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-90,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-180,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-270,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-90>.child-container>.segment.rotate-360,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-180,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-90,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-180,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-270,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-180>.child-container>.segment.rotate-360,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-270,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-90,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-180,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-270,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-270>.child-container>.segment.rotate-360,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-360,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-90,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-180,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-270,body.dark .segment:not(.segment-row):not(.segment-triangle).rotate-360>.child-container>.segment.rotate-360{background-color:#000}body.dark .switch input:checked+.slider{border-color:#000}body.dark .switch .slider{border:1px solid #fff;background-color:inherit;padding:1px}body.dark #site-content>:not(.won) .segment.locked.layer-2{border-color:#565656}body.dark .modal{border:1px solid #fff;border-radius:2px}body.black #site-content>:not(.won) .segment.locked{background-color:#9d9d9d!important;border-color:#6e6e6e!important}body.black #site-content>:not(.won) .segment.locked>.child-container>.segment-leaf{background-color:transparent!important}body.black #logo{border:1px solid grey;border-radius:50%}body label{font-size:1em!important}body .setting-row:not(.hidden){line-height:1;padding-top:.5em;padding-bottom:.5em;width:100%;cursor:pointer;background:hsla(0,0%,76%,.13);display:inline-block}nav.top-bar.title-bar{padding:.3rem .6rem 0}#logo{max-width:2rem;-webkit-transition:none;transition:none}#action-bar .top-bar-right .menu .action.img a{padding-bottom:0}#action-bar .top-bar-right .menu .action.img a img{max-height:1.8rem}.dropdown.menu a,.menu a{padding:.2rem .5rem}.relative-level-number{position:relative}.relative-level-number #level-number-container{top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}#level-number-container{z-index:1;-webkit-transition:none;transition:none;position:absolute;left:50%;-webkit-transform:translate(-50%);transform:translate(-50%);border:3px solid #fff;border-radius:50%;visibility:hidden;display:table-cell;height:35px;width:35px;text-align:center;vertical-align:middle}#level-number-container.visible{visibility:visible}#level-number-container.in-main-menu{background:#fff;border-color:#000;height:1em;width:1em;min-height:1em;min-width:1em;max-height:1em;max-width:1em}#level-number-container #level-number{-webkit-transition:none;transition:none;position:absolute;left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);font-weight:700}.coin-counter{display:inline-block;position:relative;font-size:1.6rem}@media screen and (max-width:24.9375em){.coin-counter{font-size:1rem}}.coin-counter :after{background-image:url(../img/coinTower.png);background-size:28px 28px;width:28px;height:28px;display:inline-block;content:""}#coin-container{line-height:1}#coin-container .coin{margin-left:3px;margin-right:3px;max-width:20px;display:inline-block}@media print,screen and (min-width:25em){#coin-container .coin{max-width:25px}}@media print,screen and (min-width:40em){#coin-container .coin{max-width:30px}}@-webkit-keyframes rotate-90{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(90deg);transform:rotate(90deg)}}@keyframes rotate-90{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(90deg);transform:rotate(90deg)}}@-webkit-keyframes rotate-reverse-90{0%{-webkit-transform:rotate(180deg);transform:rotate(180deg)}to{-webkit-transform:rotate(90deg);transform:rotate(90deg)}}@keyframes rotate-reverse-90{0%{-webkit-transform:rotate(180deg);transform:rotate(180deg)}to{-webkit-transform:rotate(90deg);transform:rotate(90deg)}}@-webkit-keyframes rotate-180{0%{-webkit-transform:rotate(90deg);transform:rotate(90deg)}to{-webkit-transform:rotate(180deg);transform:rotate(180deg)}}@keyframes rotate-180{0%{-webkit-transform:rotate(90deg);transform:rotate(90deg)}to{-webkit-transform:rotate(180deg);transform:rotate(180deg)}}@-webkit-keyframes rotate-reverse-180{0%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}to{-webkit-transform:rotate(180deg);transform:rotate(180deg)}}@keyframes rotate-reverse-180{0%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}to{-webkit-transform:rotate(180deg);transform:rotate(180deg)}}@-webkit-keyframes rotate-270{0%{-webkit-transform:rotate(180deg);transform:rotate(180deg)}to{-webkit-transform:rotate(270deg);transform:rotate(270deg)}}@keyframes rotate-270{0%{-webkit-transform:rotate(180deg);transform:rotate(180deg)}to{-webkit-transform:rotate(270deg);transform:rotate(270deg)}}@-webkit-keyframes rotate-reverse-270{0%{-webkit-transform:rotate(1turn);transform:rotate(1turn)}to{-webkit-transform:rotate(270deg);transform:rotate(270deg)}}@keyframes rotate-reverse-270{0%{-webkit-transform:rotate(1turn);transform:rotate(1turn)}to{-webkit-transform:rotate(270deg);transform:rotate(270deg)}}@-webkit-keyframes rotate-360{0%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes rotate-360{0%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@-webkit-keyframes rotate-reverse-360{0%{-webkit-transform:rotate(450deg);transform:rotate(450deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes rotate-reverse-360{0%{-webkit-transform:rotate(450deg);transform:rotate(450deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.segment:not(.segment-row):not(.segment-triangle).rotating{z-index:10!important;overflow:hidden}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-90{-webkit-animation-name:rotate-90;animation-name:rotate-90;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-90>.child-container>.segment{-webkit-animation-name:rotate-360;animation-name:rotate-360;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;animation-direction:reverse;-webkit-animation-direction:reverse;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-90>.child-container>.segment.rotate-90{-webkit-animation-name:rotate-90;animation-name:rotate-90}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-90>.child-container>.segment.rotate-180{-webkit-animation-name:rotate-180;animation-name:rotate-180}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-90>.child-container>.segment.rotate-270{-webkit-animation-name:rotate-270;animation-name:rotate-270}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-90>.child-container>.segment.rotate-360{-webkit-animation-name:rotate-360;animation-name:rotate-360}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-90.reverse{-webkit-animation-name:rotate-reverse-90;animation-name:rotate-reverse-90}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-90.reverse>.child-container>.segment{-webkit-animation-name:rotate-reverse-180;animation-name:rotate-reverse-180}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-90.reverse>.child-container>.segment.rotate-90{-webkit-animation-name:rotate-reverse-270;animation-name:rotate-reverse-270}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-90.reverse>.child-container>.segment.rotate-180{-webkit-animation-name:rotate-reverse-360;animation-name:rotate-reverse-360}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-90.reverse>.child-container>.segment.rotate-270{-webkit-animation-name:rotate-reverse-90;animation-name:rotate-reverse-90}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-90.reverse>.child-container>.segment.rotate-360{-webkit-animation-name:rotate-reverse-180;animation-name:rotate-reverse-180}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-180{-webkit-animation-name:rotate-180;animation-name:rotate-180;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-180>.child-container>.segment{-webkit-animation-name:rotate-270;animation-name:rotate-270;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;animation-direction:reverse;-webkit-animation-direction:reverse;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-180>.child-container>.segment.rotate-90{-webkit-animation-name:rotate-360;animation-name:rotate-360}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-180>.child-container>.segment.rotate-180{-webkit-animation-name:rotate-90;animation-name:rotate-90}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-180>.child-container>.segment.rotate-270{-webkit-animation-name:rotate-180;animation-name:rotate-180}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-180>.child-container>.segment.rotate-360{-webkit-animation-name:rotate-270;animation-name:rotate-270}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-180.reverse{-webkit-animation-name:rotate-reverse-180;animation-name:rotate-reverse-180}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-180.reverse>.child-container>.segment{-webkit-animation-name:rotate-reverse-90;animation-name:rotate-reverse-90}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-180.reverse>.child-container>.segment.rotate-90{-webkit-animation-name:rotate-reverse-180;animation-name:rotate-reverse-180}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-180.reverse>.child-container>.segment.rotate-180{-webkit-animation-name:rotate-reverse-270;animation-name:rotate-reverse-270}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-180.reverse>.child-container>.segment.rotate-270{-webkit-animation-name:rotate-reverse-360;animation-name:rotate-reverse-360}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-180.reverse>.child-container>.segment.rotate-360{-webkit-animation-name:rotate-reverse-90;animation-name:rotate-reverse-90}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-270{-webkit-animation-name:rotate-270;animation-name:rotate-270;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-270>.child-container>.segment{-webkit-animation-name:rotate-180;animation-name:rotate-180;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;animation-direction:reverse;-webkit-animation-direction:reverse;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-270>.child-container>.segment.rotate-90{-webkit-animation-name:rotate-270;animation-name:rotate-270}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-270>.child-container>.segment.rotate-180{-webkit-animation-name:rotate-360;animation-name:rotate-360}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-270>.child-container>.segment.rotate-270{-webkit-animation-name:rotate-90;animation-name:rotate-90}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-270>.child-container>.segment.rotate-360{-webkit-animation-name:rotate-180;animation-name:rotate-180}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-270.reverse{-webkit-animation-name:rotate-reverse-270;animation-name:rotate-reverse-270}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-270.reverse>.child-container>.segment{-webkit-animation-name:rotate-reverse-360;animation-name:rotate-reverse-360}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-270.reverse>.child-container>.segment.rotate-90{-webkit-animation-name:rotate-reverse-90;animation-name:rotate-reverse-90}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-270.reverse>.child-container>.segment.rotate-180{-webkit-animation-name:rotate-reverse-180;animation-name:rotate-reverse-180}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-270.reverse>.child-container>.segment.rotate-270{-webkit-animation-name:rotate-reverse-270;animation-name:rotate-reverse-270}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-270.reverse>.child-container>.segment.rotate-360{-webkit-animation-name:rotate-reverse-360;animation-name:rotate-reverse-360}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-360{-webkit-animation-name:rotate-360;animation-name:rotate-360;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-360>.child-container>.segment{-webkit-animation-name:rotate-90;animation-name:rotate-90;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;animation-direction:reverse;-webkit-animation-direction:reverse;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-360>.child-container>.segment.rotate-90{-webkit-animation-name:rotate-180;animation-name:rotate-180}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-360>.child-container>.segment.rotate-180{-webkit-animation-name:rotate-270;animation-name:rotate-270}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-360>.child-container>.segment.rotate-270{-webkit-animation-name:rotate-360;animation-name:rotate-360}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-360>.child-container>.segment.rotate-360{-webkit-animation-name:rotate-90;animation-name:rotate-90}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-360.reverse{-webkit-animation-name:rotate-reverse-360;animation-name:rotate-reverse-360}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-360.reverse>.child-container>.segment{-webkit-animation-name:rotate-reverse-270;animation-name:rotate-reverse-270}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-360.reverse>.child-container>.segment.rotate-90{-webkit-animation-name:rotate-reverse-360;animation-name:rotate-reverse-360}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-360.reverse>.child-container>.segment.rotate-180{-webkit-animation-name:rotate-reverse-90;animation-name:rotate-reverse-90}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-360.reverse>.child-container>.segment.rotate-270{-webkit-animation-name:rotate-reverse-180;animation-name:rotate-reverse-180}.segment:not(.segment-row):not(.segment-triangle).rotating.rotate-360.reverse>.child-container>.segment.rotate-360{-webkit-animation-name:rotate-reverse-270;animation-name:rotate-reverse-270}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-90>.child-container>.segment{-webkit-transform:rotate(270deg);transform:rotate(270deg);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-90>.child-container>.segment.rotate-90{-webkit-transform:rotate(1turn);transform:rotate(1turn);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-90>.child-container>.segment.rotate-90.rotating{-webkit-animation-name:rotate-360;animation-name:rotate-360;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-90>.child-container>.segment.rotate-90.rotating.reverse{-webkit-animation-name:rotate-reverse-360;animation-name:rotate-reverse-360}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-90>.child-container>.segment.rotate-180{-webkit-transform:rotate(90deg);transform:rotate(90deg);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-90>.child-container>.segment.rotate-180.rotating{-webkit-animation-name:rotate-90;animation-name:rotate-90;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-90>.child-container>.segment.rotate-180.rotating.reverse{-webkit-animation-name:rotate-reverse-90;animation-name:rotate-reverse-90}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-90>.child-container>.segment.rotate-270{-webkit-transform:rotate(180deg);transform:rotate(180deg);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-90>.child-container>.segment.rotate-270.rotating{-webkit-animation-name:rotate-180;animation-name:rotate-180;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-90>.child-container>.segment.rotate-270.rotating.reverse{-webkit-animation-name:rotate-reverse-180;animation-name:rotate-reverse-180}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-90>.child-container>.segment.rotate-360{-webkit-transform:rotate(270deg);transform:rotate(270deg);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-90>.child-container>.segment.rotate-360.rotating{-webkit-animation-name:rotate-270;animation-name:rotate-270;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-90>.child-container>.segment.rotate-360.rotating.reverse{-webkit-animation-name:rotate-reverse-270;animation-name:rotate-reverse-270}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-180,.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-180>.child-container>.segment{-webkit-transform:rotate(180deg);transform:rotate(180deg);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-180>.child-container>.segment.rotate-90{-webkit-transform:rotate(270deg);transform:rotate(270deg);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-180>.child-container>.segment.rotate-90.rotating{-webkit-animation-name:rotate-270;animation-name:rotate-270;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-180>.child-container>.segment.rotate-90.rotating.reverse{-webkit-animation-name:rotate-reverse-270;animation-name:rotate-reverse-270}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-180>.child-container>.segment.rotate-180{-webkit-transform:rotate(1turn);transform:rotate(1turn);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-180>.child-container>.segment.rotate-180.rotating{-webkit-animation-name:rotate-360;animation-name:rotate-360;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-180>.child-container>.segment.rotate-180.rotating.reverse{-webkit-animation-name:rotate-reverse-360;animation-name:rotate-reverse-360}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-180>.child-container>.segment.rotate-270{-webkit-transform:rotate(90deg);transform:rotate(90deg);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-180>.child-container>.segment.rotate-270.rotating{-webkit-animation-name:rotate-90;animation-name:rotate-90;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-180>.child-container>.segment.rotate-270.rotating.reverse{-webkit-animation-name:rotate-reverse-90;animation-name:rotate-reverse-90}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-180>.child-container>.segment.rotate-360{-webkit-transform:rotate(180deg);transform:rotate(180deg);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-180>.child-container>.segment.rotate-360.rotating{-webkit-animation-name:rotate-180;animation-name:rotate-180;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-180>.child-container>.segment.rotate-360.rotating.reverse{-webkit-animation-name:rotate-reverse-180;animation-name:rotate-reverse-180}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-270>.child-container>.segment{-webkit-transform:rotate(90deg);transform:rotate(90deg);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-270>.child-container>.segment.rotate-90{-webkit-transform:rotate(180deg);transform:rotate(180deg);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-270>.child-container>.segment.rotate-90.rotating{-webkit-animation-name:rotate-180;animation-name:rotate-180;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-270>.child-container>.segment.rotate-90.rotating.reverse{-webkit-animation-name:rotate-reverse-180;animation-name:rotate-reverse-180}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-270>.child-container>.segment.rotate-180{-webkit-transform:rotate(270deg);transform:rotate(270deg);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-270>.child-container>.segment.rotate-180.rotating{-webkit-animation-name:rotate-270;animation-name:rotate-270;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-270>.child-container>.segment.rotate-180.rotating.reverse{-webkit-animation-name:rotate-reverse-270;animation-name:rotate-reverse-270}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-270>.child-container>.segment.rotate-270{-webkit-transform:rotate(1turn);transform:rotate(1turn);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-270>.child-container>.segment.rotate-270.rotating{-webkit-animation-name:rotate-360;animation-name:rotate-360;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-270>.child-container>.segment.rotate-270.rotating.reverse{-webkit-animation-name:rotate-reverse-360;animation-name:rotate-reverse-360}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-270>.child-container>.segment.rotate-360{-webkit-transform:rotate(90deg);transform:rotate(90deg);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-270>.child-container>.segment.rotate-360.rotating{-webkit-animation-name:rotate-90;animation-name:rotate-90;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-270>.child-container>.segment.rotate-360.rotating.reverse{-webkit-animation-name:rotate-reverse-90;animation-name:rotate-reverse-90}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-360{-webkit-transform:rotate(1turn);transform:rotate(1turn);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-360>.child-container>.segment{-webkit-transform:rotate(0deg);transform:rotate(0deg);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-360>.child-container>.segment.rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-360>.child-container>.segment.rotate-90.rotating{-webkit-animation-name:rotate-90;animation-name:rotate-90;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-360>.child-container>.segment.rotate-90.rotating.reverse{-webkit-animation-name:rotate-reverse-90;animation-name:rotate-reverse-90}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-360>.child-container>.segment.rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-360>.child-container>.segment.rotate-180.rotating{-webkit-animation-name:rotate-180;animation-name:rotate-180;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-360>.child-container>.segment.rotate-180.rotating.reverse{-webkit-animation-name:rotate-reverse-180;animation-name:rotate-reverse-180}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-360>.child-container>.segment.rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-360>.child-container>.segment.rotate-270.rotating{-webkit-animation-name:rotate-270;animation-name:rotate-270;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-360>.child-container>.segment.rotate-270.rotating.reverse{-webkit-animation-name:rotate-reverse-270;animation-name:rotate-reverse-270}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-360>.child-container>.segment.rotate-360{-webkit-transform:rotate(1turn);transform:rotate(1turn);background-color:inherit;z-index:1}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-360>.child-container>.segment.rotate-360.rotating{-webkit-animation-name:rotate-360;animation-name:rotate-360;-webkit-animation-duration:.25s;animation-duration:.25s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:linear;animation-timing-function:linear}.segment:not(.segment-row):not(.segment-triangle):not(.rotating).rotate-360>.child-container>.segment.rotate-360.rotating.reverse{-webkit-animation-name:rotate-reverse-360;animation-name:rotate-reverse-360}#level{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;white-space:nowrap;max-width:100%;-webkit-tap-highlight-color:rgba(255,255,255,0);overflow-y:visible}#level,#level *,.segment{-webkit-transition:none;transition:none}.segment{vertical-align:top;white-space:normal;cursor:pointer;display:inline-block;text-align:center;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:1;background-color:inherit;line-height:0}.segment.segment-row{display:block;width:100%;-webkit-animation:none!important;animation:none!important;white-space:nowrap}.segment.segment-column{padding-top:4px}.segment.segment-column>.child-container>.segment{display:block;width:100%}.segment.segment-leaf{background-color:transparent!important;min-width:1em;padding:.8em}.segment.segment-leaf:before{content:" ";display:block;padding-top:100%}.segment.segment-leaf .leaf-element{position:absolute;width:100%;height:100%;line-height:1.5em;top:0;left:0}.segment.segment-parent{border:1px solid #a9a9a9;border-radius:3px;padding:1px}.segment.segment-parent.layer-2{border:3px solid #000}#site-content>:not(.won) .show-when-won{display:none}.level-container{-webkit-transition:none;transition:none}.won .show-while-playing{display:none}.text-right{text-align:right}#continue-button{margin-bottom:2px}@media screen and (max-width:24.9375em){#continue-button{margin-bottom:0;padding:.3em .6em}}@media screen and (max-width:24.9375em){#play-button{margin-bottom:2px}}#help-button{margin:0;padding:.4em;max-width:3em}@media screen and (max-width:39.9375em){#help-button{padding:.2em;max-width:2em}}.line-height-1{line-height:1}body{overscroll-behavior:contain;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#site-content{overflow:visible}div.mainContainer{overflow-x:hidden}.clickable{cursor:pointer}#share-button{overflow:hidden}#share-button svg{cursor:pointer;max-width:1.5rem}
\ No newline at end of file
diff --git a/public/data.php b/public/data.php
deleted file mode 100755
index 4343eb7..0000000
--- a/public/data.php
+++ /dev/null
@@ -1,40 +0,0 @@
-run();
diff --git a/public/html/application/credits.html b/public/html/application/credits.html
deleted file mode 100644
index a84c5e8..0000000
--- a/public/html/application/credits.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/html/application/dialog/chooseTheme.html b/public/html/application/dialog/chooseTheme.html
deleted file mode 100644
index bac51ee..0000000
--- a/public/html/application/dialog/chooseTheme.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/html/application/dialog/share.html b/public/html/application/dialog/share.html
deleted file mode 100644
index d896a87..0000000
--- a/public/html/application/dialog/share.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/html/application/end.html b/public/html/application/end.html
deleted file mode 100755
index e572834..0000000
--- a/public/html/application/end.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/html/application/fragment/settings.html b/public/html/application/fragment/settings.html
deleted file mode 100644
index e132370..0000000
--- a/public/html/application/fragment/settings.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/html/application/impressum.html b/public/html/application/impressum.html
deleted file mode 100644
index dd5d9c9..0000000
--- a/public/html/application/impressum.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/html/application/level.html b/public/html/application/level.html
deleted file mode 100755
index 4578e48..0000000
--- a/public/html/application/level.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/html/application/menu.html b/public/html/application/menu.html
deleted file mode 100644
index 6a434b3..0000000
--- a/public/html/application/menu.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/html/application/privacyPolicy.html b/public/html/application/privacyPolicy.html
deleted file mode 100644
index 2c165a6..0000000
--- a/public/html/application/privacyPolicy.html
+++ /dev/null
@@ -1 +0,0 @@
-Datenschutzerklärung Diese Datenschutzerklärung klärt Sie über die Art, den Umfang und Zweck der Verarbeitung von personenbezogenen Daten (nachfolgend kurz „Daten“) im Rahmen der Erbringung unserer Leistungen sowie innerhalb unseres Onlineangebotes und der mit ihm verbundenen Webseiten, Funktionen und Inhalte sowie externen Onlinepräsenzen (nachfolgend gemeinsam bezeichnet als „Onlineangebot“). Im Hinblick auf die verwendeten Begrifflichkeiten, wie z.B. „Verarbeitung“ oder „Verantwortlicher“ verweisen wir auf die Definitionen im Art. 4 der Datenschutzgrundverordnung (DSGVO).
Verantwortlicher Silas Günther Mariabrunnstraße 48 52064 Aachen Deutschland E-Mailadresse: wordRotator@silas.link Link zum Impressum: https://wordrotator.silas.link/impressum
Arten der verarbeiteten Daten - Bestandsdaten (z.B., Personen-Stammdaten, Namen oder Adressen). - Kontaktdaten (z.B., E-Mail, Telefonnummern). - Nutzungsdaten (z.B., besuchte Webseiten, Interesse an Inhalten, Zugriffszeiten). - Meta-/Kommunikationsdaten (z.B., Geräte-Informationen, Anonymisierte IP-Adressen).
Kategorien betroffener Personen Besucher und Nutzer des Onlineangebotes (Nachfolgend bezeichnen wir die betroffenen Personen zusammenfassend auch als „Nutzer“).
Zweck der Verarbeitung - Zurverfügungstellung des Onlineangebotes, seiner Funktionen und Inhalte. - Beantwortung von Kontaktanfragen und Kommunikation mit Nutzern. - Sicherheitsmaßnahmen. - Reichweitenmessung/Marketing
Verwendete Begrifflichkeiten „Personenbezogene Daten“ sind alle Informationen, die sich auf eine identifizierte oder identifizierbare natürliche Person (im Folgenden „betroffene Person“) beziehen; als identifizierbar wird eine natürliche Person angesehen, die direkt oder indirekt, insbesondere mittels Zuordnung zu einer Kennung wie einem Namen, zu einer Kennnummer, zu Standortdaten, zu einer Online-Kennung (z.B. Cookie) oder zu einem oder mehreren besonderen Merkmalen identifiziert werden kann, die Ausdruck der physischen, physiologischen, genetischen, psychischen, wirtschaftlichen, kulturellen oder sozialen Identität dieser natürlichen Person sind. „Verarbeitung“ ist jeder mit oder ohne Hilfe automatisierter Verfahren ausgeführte Vorgang oder jede solche Vorgangsreihe im Zusammenhang mit personenbezogenen Daten. Der Begriff reicht weit und umfasst praktisch jeden Umgang mit Daten. „Pseudonymisierung“ die Verarbeitung personenbezogener Daten in einer Weise, dass die personenbezogenen Daten ohne Hinzuziehung zusätzlicher Informationen nicht mehr einer spezifischen betroffenen Person zugeordnet werden können, sofern diese zusätzlichen Informationen gesondert aufbewahrt werden und technischen und organisatorischen Maßnahmen unterliegen, die gewährleisten, dass die personenbezogenen Daten nicht einer identifizierten oder identifizierbaren natürlichen Person zugewiesen werden. „Profiling“ jede Art der automatisierten Verarbeitung personenbezogener Daten, die darin besteht, dass diese personenbezogenen Daten verwendet werden, um bestimmte persönliche Aspekte, die sich auf eine natürliche Person beziehen, zu bewerten, insbesondere um Aspekte bezüglich Arbeitsleistung, wirtschaftliche Lage, Gesundheit, persönliche Vorlieben, Interessen, Zuverlässigkeit, Verhalten, Aufenthaltsort oder Ortswechsel dieser natürlichen Person zu analysieren oder vorherzusagen. Als „Verantwortlicher“ wird die natürliche oder juristische Person, Behörde, Einrichtung oder andere Stelle, die allein oder gemeinsam mit anderen über die Zwecke und Mittel der Verarbeitung von personenbezogenen Daten entscheidet, bezeichnet. „Auftragsverarbeiter“ eine natürliche oder juristische Person, Behörde, Einrichtung oder andere Stelle, die personenbezogene Daten im Auftrag des Verantwortlichen verarbeitet.
Maßgebliche Rechtsgrundlagen Nach Maßgabe des Art. 13 DSGVO teilen wir Ihnen die Rechtsgrundlagen unserer Datenverarbeitungen mit. Für Nutzer aus dem Geltungsbereich der Datenschutzgrundverordnung (DSGVO), d.h. der EU und des EWG gilt, sofern die Rechtsgrundlage in der Datenschutzerklärung nicht genannt wird, Folgendes: Die Rechtsgrundlage für die Einholung von Einwilligungen ist Art. 6 Abs. 1 lit. a und Art. 7 DSGVO; Die Rechtsgrundlage für die Verarbeitung zur Erfüllung unserer Leistungen und Durchführung vertraglicher Maßnahmen sowie Beantwortung von Anfragen ist Art. 6 Abs. 1 lit. b DSGVO; Die Rechtsgrundlage für die Verarbeitung zur Erfüllung unserer rechtlichen Verpflichtungen ist Art. 6 Abs. 1 lit. c DSGVO; Für den Fall, dass lebenswichtige Interessen der betroffenen Person oder einer anderen natürlichen Person eine Verarbeitung personenbezogener Daten erforderlich machen, dient Art. 6 Abs. 1 lit. d DSGVO als Rechtsgrundlage. Die Rechtsgrundlage für die erforderliche Verarbeitung zur Wahrnehmung einer Aufgabe, die im öffentlichen Interesse liegt oder in Ausübung öffentlicher Gewalt erfolgt, die dem Verantwortlichen übertragen wurde ist Art. 6 Abs. 1 lit. e DSGVO. Die Rechtsgrundlage für die Verarbeitung zur Wahrung unserer berechtigten Interessen ist Art. 6 Abs. 1 lit. f DSGVO. Die Verarbeitung von Daten zu anderen Zwecken als denen, zu denen sie ehoben wurden, bestimmt sich nach den Vorgaben des Art 6 Abs. 4 DSGVO. Die Verarbeitung von besonderen Kategorien von Daten (entsprechend Art. 9 Abs. 1 DSGVO) bestimmt sich nach den Vorgaben des Art. 9 Abs. 2 DSGVO.
Sicherheitsmaßnahmen Wir treffen nach Maßgabe der gesetzlichen Vorgabenunter Berücksichtigung des Stands der Technik, der Implementierungskosten und der Art, des Umfangs, der Umstände und der Zwecke der Verarbeitung sowie der unterschiedlichen Eintrittswahrscheinlichkeit und Schwere des Risikos für die Rechte und Freiheiten natürlicher Personen, geeignete technische und organisatorische Maßnahmen, um ein dem Risiko angemessenes Schutzniveau zu gewährleisten. Zu den Maßnahmen gehören insbesondere die Sicherung der Vertraulichkeit, Integrität und Verfügbarkeit von Daten durch Kontrolle des physischen Zugangs zu den Daten, als auch des sie betreffenden Zugriffs, der Eingabe, Weitergabe, der Sicherung der Verfügbarkeit und ihrer Trennung. Des Weiteren haben wir Verfahren eingerichtet, die eine Wahrnehmung von Betroffenenrechten, Löschung von Daten und Reaktion auf Gefährdung der Daten gewährleisten. Ferner berücksichtigen wir den Schutz personenbezogener Daten bereits bei der Entwicklung, bzw. Auswahl von Hardware, Software sowie Verfahren, entsprechend dem Prinzip des Datenschutzes durch Technikgestaltung und durch datenschutzfreundliche Voreinstellungen.
Zusammenarbeit mit Auftragsverarbeitern, gemeinsam Verantwortlichen und Dritten Sofern wir im Rahmen unserer Verarbeitung Daten gegenüber anderen Personen und Unternehmen (Auftragsverarbeitern, gemeinsam Verantwortlichen oder Dritten) offenbaren, sie an diese übermitteln oder ihnen sonst Zugriff auf die Daten gewähren, erfolgt dies nur auf Grundlage einer gesetzlichen Erlaubnis (z.B. wenn eine Übermittlung der Daten an Dritte, wie an Zahlungsdienstleister, zur Vertragserfüllung erforderlich ist), Nutzer eingewilligt haben, eine rechtliche Verpflichtung dies vorsieht oder auf Grundlage unserer berechtigten Interessen (z.B. beim Einsatz von Beauftragten, Webhostern, etc.). Sofern wir Daten anderen Unternehmen unserer Unternehmensgruppe offenbaren, übermitteln oder ihnen sonst den Zugriff gewähren, erfolgt dies insbesondere zu administrativen Zwecken als berechtigtes Interesse und darüberhinausgehend auf einer den gesetzlichen Vorgaben entsprechenden Grundlage.
Rechte der betroffenen Personen Sie haben das Recht, eine Bestätigung darüber zu verlangen, ob betreffende Daten verarbeitet werden und auf Auskunft über diese Daten sowie auf weitere Informationen und Kopie der Daten entsprechend den gesetzlichen Vorgaben. Sie haben entsprechend. den gesetzlichen Vorgaben das Recht, die Vervollständigung der Sie betreffenden Daten oder die Berichtigung der Sie betreffenden unrichtigen Daten zu verlangen. Sie haben nach Maßgabe der gesetzlichen Vorgaben das Recht zu verlangen, dass betreffende Daten unverzüglich gelöscht werden, bzw. alternativ nach Maßgabe der gesetzlichen Vorgaben eine Einschränkung der Verarbeitung der Daten zu verlangen. Sie haben das Recht zu verlangen, dass die Sie betreffenden Daten, die Sie uns bereitgestellt haben nach Maßgabe der gesetzlichen Vorgaben zu erhalten und deren Übermittlung an andere Verantwortliche zu fordern. Sie haben ferner nach Maßgabe der gesetzlichen Vorgaben das Recht, eine Beschwerde bei der zuständigen Aufsichtsbehörde einzureichen.
Widerrufsrecht Sie haben das Recht, erteilte Einwilligungen mit Wirkung für die Zukunft zu widerrufen.
Widerspruchsrecht Sie können der künftigen Verarbeitung der Sie betreffenden Daten nach Maßgabe der gesetzlichen Vorgaben jederzeit widersprechen. Der Widerspruch kann insbesondere gegen die Verarbeitung für Zwecke der Direktwerbung erfolgen.
Cookies und Widerspruchsrecht bei Direktwerbung Als „Cookies“ werden kleine Dateien bezeichnet, die auf Rechnern der Nutzer gespeichert werden. Innerhalb der Cookies können unterschiedliche Angaben gespeichert werden. Ein Cookie dient primär dazu, die Angaben zu einem Nutzer (bzw. dem Gerät auf dem das Cookie gespeichert ist) während oder auch nach seinem Besuch innerhalb eines Onlineangebotes zu speichern. Als temporäre Cookies, bzw. „Session-Cookies“ oder „transiente Cookies“, werden Cookies bezeichnet, die gelöscht werden, nachdem ein Nutzer ein Onlineangebot verlässt und seinen Browser schließt. In einem solchen Cookie kann z.B. der Inhalt eines Warenkorbs in einem Onlineshop oder ein Login-Status gespeichert werden. Als „permanent“ oder „persistent“ werden Cookies bezeichnet, die auch nach dem Schließen des Browsers gespeichert bleiben. So kann z.B. der Login-Status gespeichert werden, wenn die Nutzer diese nach mehreren Tagen aufsuchen. Ebenso können in einem solchen Cookie die Interessen der Nutzer gespeichert werden, die für Reichweitenmessung oder Marketingzwecke verwendet werden. Als „Third-Party-Cookie“ werden Cookies bezeichnet, die von anderen Anbietern als dem Verantwortlichen, der das Onlineangebot betreibt, angeboten werden (andernfalls, wenn es nur dessen Cookies sind spricht man von „First-Party Cookies“). Wir können temporäre und permanente Cookies einsetzen und klären hierüber im Rahmen unserer Datenschutzerklärung auf. Falls die Nutzer nicht möchten, dass Cookies auf ihrem Rechner gespeichert werden, werden sie gebeten die entsprechende Option in den Systemeinstellungen ihres Browsers zu deaktivieren. Gespeicherte Cookies können in den Systemeinstellungen des Browsers gelöscht werden. Der Ausschluss von Cookies kann zu Funktionseinschränkungen dieses Onlineangebotes führen.
Löschung von Daten Die von uns verarbeiteten Daten werden nach Maßgabe der gesetzlichen Vorgaben gelöscht oder in ihrer Verarbeitung eingeschränkt. Sofern nicht im Rahmen dieser Datenschutzerklärung ausdrücklich angegeben, werden die bei uns gespeicherten Daten gelöscht, sobald sie für ihre Zweckbestimmung nicht mehr erforderlich sind und der Löschung keine gesetzlichen Aufbewahrungspflichten entgegenstehen. Sofern die Daten nicht gelöscht werden, weil sie für andere und gesetzlich zulässige Zwecke erforderlich sind, wird deren Verarbeitung eingeschränkt. D.h. die Daten werden gesperrt und nicht für andere Zwecke verarbeitet. Das gilt z.B. für Daten, die aus handels- oder steuerrechtlichen Gründen aufbewahrt werden müssen.
Änderungen und Aktualisierungen der Datenschutzerklärung Wir bitten Sie sich regelmäßig über den Inhalt unserer Datenschutzerklärung zu informieren. Wir passen die Datenschutzerklärung an, sobald die Änderungen der von uns durchgeführten Datenverarbeitungen dies erforderlich machen. Wir informieren Sie, sobald durch die Änderungen eine Mitwirkungshandlung Ihrerseits (z.B. Einwilligung) oder eine sonstige individuelle Benachrichtigung erforderlich wird.
Hosting und E-Mail-Versand
Die von uns in Anspruch genommenen Hosting-Leistungen dienen der Zurverfügungstellung der folgenden Leistungen: Infrastruktur- und Plattformdienstleistungen, Rechenkapazität, Speicherplatz und Datenbankdienste, E-Mail-Versand, Sicherheitsleistungen sowie technische Wartungsleistungen, die wir zum Zwecke des Betriebs dieses Onlineangebotes einsetzen. Hierbei verarbeiten wir, bzw. unser Hostinganbieter Bestandsdaten, Kontaktdaten, Vertragsdaten, Nutzungsdaten, Meta- und Kommunikationsdaten von Kunden, Interessenten und Besuchern dieses Onlineangebotes auf Grundlage unserer berechtigten Interessen an einer effizienten und sicheren Zurverfügungstellung dieses Onlineangebotes gem. Art. 6 Abs. 1 lit. f DSGVO i.V.m. Art. 28 DSGVO (Abschluss Auftragsverarbeitungsvertrag).
Erhebung von Zugriffsdaten und Logfiles
Wir, bzw. unser Hostinganbieter, erhebt auf Grundlage unserer berechtigten Interessen im Sinne des Art. 6 Abs. 1 lit. f. DSGVO Daten über jeden Zugriff auf den Server, auf dem sich dieser Dienst befindet (sogenannte Serverlogfiles). Zu den Zugriffsdaten gehören Name der abgerufenen Webseite, Datei, Datum und Uhrzeit des Abrufs, übertragene Datenmenge, Meldung über erfolgreichen Abruf, Browsertyp nebst Version, das Betriebssystem des Nutzers, Referrer URL (die zuvor besuchte Seite), IP-Adresse und der anfragende Provider. Logfile-Informationen werden aus Sicherheitsgründen (z.B. zur Aufklärung von Missbrauchs- oder Betrugshandlungen) für die Dauer von maximal 5 Wochen gespeichert und danach gelöscht. Daten, deren weitere Aufbewahrung zu Beweiszwecken erforderlich ist, sind bis zur endgültigen Klärung des jeweiligen Vorfalls von der Löschung ausgenommen.
Reichweitenmessung mit Matomo
Im Rahmen der Reichweitenanalyse von Matomo werden auf Grundlage unserer berechtigten Interessen (d.h. Interesse an der Analyse, Optimierung und wirtschaftlichem Betrieb unseres Onlineangebotes im Sinne des Art. 6 Abs. 1 lit. f. DSGVO) die folgenden Daten verarbeitet: der von Ihnen verwendete Browsertyp und die Browserversion, das von Ihnen verwendete Betriebssystem, Ihr Herkunftsland, Datum und Uhrzeit der Serveranfrage, die Anzahl der Besuche, Ihre Verweildauer auf der Website sowie die von Ihnen betätigten externen Links. Die IP-Adresse der Nutzer wird anonymisiert, bevor sie gespeichert wird. Matomo verwendet Cookies, die auf dem Computer der Nutzer gespeichert werden und die eine Analyse der Benutzung unseres Onlineangebotes durch die Nutzer ermöglichen. Dabei können aus den verarbeiteten Daten pseudonyme Nutzungsprofile der Nutzer erstellt werden. Die Cookies haben eine Speicherdauer von einer Woche. Die durch das Cookie erzeugten Informationen über Ihre Benutzung dieser Webseite werden nur auf unserem Server gespeichert und nicht an Dritte weitergegeben. Nutzer können der anonymisierten Datenerhebung durch das Programm Matomo jederzeit mit Wirkung für die Zukunft widersprechen, indem sie den unten befindlichen Schalter nutzen. In diesem Fall wird in ihrem Browser ein sog. Opt-Out-Cookie abgelegt, was zur Folge hat, dass Matomo keinerlei Sitzungsdaten mehr erhebt. Wenn Nutzer ihre Cookies löschen, so hat dies jedoch zur Folge, dass auch das Opt-Out-Cookie gelöscht wird und daher von den Nutzern erneut aktiviert werden muss. Die Logs mit den Daten der Nutzer werden nach spätestens einem Jahr gelöscht.
Erstellt mit Datenschutz-Generator.de von RA Dr. Thomas Schwenke und angepasst vom Webseitenbetreiber
\ No newline at end of file
diff --git a/public/html/application/setting-template.html b/public/html/application/setting-template.html
deleted file mode 100644
index a8080df..0000000
--- a/public/html/application/setting-template.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/html/application/sync.html b/public/html/application/sync.html
deleted file mode 100755
index 4d0bd53..0000000
--- a/public/html/application/sync.html
+++ /dev/null
@@ -1 +0,0 @@
-Sync
\ No newline at end of file
diff --git a/public/img/logo.png b/public/img/logo.png
deleted file mode 100644
index f125eed..0000000
Binary files a/public/img/logo.png and /dev/null differ
diff --git a/public/index.html b/public/index.html
deleted file mode 100755
index 5727992..0000000
--- a/public/index.html
+++ /dev/null
@@ -1,266 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- WordRotator
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/public/js/app.js b/public/js/app.js
deleted file mode 100755
index 25f5d9b..0000000
--- a/public/js/app.js
+++ /dev/null
@@ -1,8020 +0,0 @@
-class InitPromise
-{
- static addPromise(promise)
- {
- if (typeof promise === 'function')
- {
- let func = promise;
- promise = InitPromise.mainPromise.then(function(app){
- return (func(app));
- });
- }
- InitPromise.promises.push(promise);
- }
-
- static resolve(app)
- {
- InitPromise.mainResolver(app);
- return InitPromise.mainPromise.then(function(){
- return Promise.all(InitPromise.promises);
- });
- }
-}
-
-InitPromise.promises = [];
-InitPromise.mainPromise = new Promise(function(resolver){
- InitPromise.mainResolver = resolver;
-});
-
-class AndroidBridge {
-
- static addDefinition(definition, object) {
- if (typeof definition !== "function") {
- if (typeof definition === "string"){
- let parts = definition.split(".");
- for (let i = parts.length-1; i >= 1; i--) {
- let newObject = {};
- newObject[parts[i]] = object;
- object = newObject;
- }
- definition = parts[0];
- // console.log("parts for", definition, parts, object);
- }
- let textDefinition = definition;
- definition = () => {
- // console.log("defining", textDefinition, object);
- window[textDefinition] = object;
- };
- }
- AndroidBridge.definitions.push(definition);
- }
-
- static applyDefinitions() {
- for (let i = 0; i < AndroidBridge.definitions.length; i++) {
- AndroidBridge.definitions[i]();
- }
- return Promise.resolve();
- }
-}
-
-AndroidBridge.definitions = [];
-AndroidBridge.addDefinition("InitPromise.addPromise", InitPromise.addPromise);
-
-class MenuAction {
- constructor(title, callback, showFor, order) {
- this.title = Helper.nonNull(title, null);
- this.callback = callback;
- this.showFor = Helper.nonNull(showFor, MenuAction.SHOW_FOR_MEDIUM);
- this.order = Helper.nonNull(order, 1000);
- this._liClass = "";
-
- this._menu = null;
- this._activated = true;
- this._visible = true;
- this.id = MenuAction.maxId++;
- this._icon = null;
- this._shouldTranslate = true;
- this._copies = [];
- }
-
- setTitle(title)
- {
- this.title = title;
- }
-
- setShouldTranslate(shouldTranslate)
- {
- this._shouldTranslate = shouldTranslate;
- }
-
- getShowFor(){
- return this.showFor;
- }
-
- getTitle()
- {
- return this.title;
- }
-
- getShouldTranslate()
- {
- return this._shouldTranslate;
- }
-
- remove(removeCopies) {
- removeCopies = Helper.nonNull(removeCopies, false);
- if (Helper.isNotNull(this._menu)) {
- console.log(this._menu);
- this._menu.removeAction(this);
- this._menu = null;
- }
- if (removeCopies)
- {
- for (let i = 0; i < this._copies.length; i++) {
- this._copies[i].remove();
- }
- }
- }
-
- getMenu() {
- return this._menu;
- }
-
- setMenu(value) {
- this._menu = value;
- }
-
- getVisible() {
- return this._visible;
- }
-
- setVisible(value) {
- if (value !== this._visible) {
- this._visible = value;
- this.redraw();
- }
- }
-
- getActivated() {
- return this._activated;
- }
-
- getIcon() {
- return this._icon;
- }
-
- setIcon(value) {
- this._icon = value;
- }
-
- getId()
- {
- return this.id;
- }
-
- redraw() {
- if (Helper.isNotNull(this._menu)) {
- this._menu.updateAction(this);
- }
- }
- copy(instance){
- let copy = Helper.nonNull(instance, new MenuAction());
- copy.title = this.title;
- copy.callback = this.callback;
- copy.showFor = this.showFor;
- copy.order = this.order;
- copy._liClass = this._liClass;
-
- copy._activated = this._activated;
- copy._visible = this._visible;
- copy._icon = this._icon;
- copy._shouldTranslate = this._shouldTranslate;
-
- copy._menu = null;
- copy.id = MenuAction.maxId++;
- this._copies.push(copy);
- return copy;
- }
-
- redrawMenu()
- {
- if (Helper.isNotNull(this._menu)) {
- this._menu.redraw();
- }
- }
-}
-MenuAction.maxId = 0;
-
-MenuAction.SHOW_ALWAYS = "always";
-MenuAction.SHOW_FOR_MEDIUM = "medium";
-MenuAction.SHOW_FOR_LARGE = "large";
-MenuAction.SHOW_NEVER = "never";
-
-class OpenSubmenuAction extends MenuAction {
- constructor(title, menu, showFor, order) {
- super(title, function (action) {
- action.getSubmenu().toggle();
- action.redraw();
- }, showFor, order);
-
- this.submenu = menu;
- menu.setParentAction(this);
- }
-
- getSubmenu() {
- return this.submenu;
- }
-
- copy(instance) {
- instance = super.copy(Helper.nonNull(instance, new OpenSubmenuAction(null, this.submenu.copy())));
- return instance;
- }
-}
-
-class Menu {
- constructor(parentElementSelector) {
- this.actions = [];
- this.submenus = [];
- if (typeof parentElementSelector === 'string') {
- this.parentElements = document.querySelectorAll(parentElementSelector);
- }
- else if (Array.isArray(parentElementSelector)) {
- this.parentElements = parentElementSelector;
- }
- else {
- this.parentElements = [parentElementSelector];
- }
- }
-
- copy(instance) {
- instance = Helper.nonNull(instance, new Menu([]));
-
- instance.actions = [];
- for (let i = 0, n = this.actions.length; i < n; i++) {
- instance.actions.push(this.actions[i].copy());
- }
-
- instance.submenus = [];
- for (let i = 0, n = this.submenus.length; i < n; i++) {
- instance.submenus.push(this.submenus[i].copy());
- }
-
- return instance;
- }
-
- addAction(action) {
- if (Helper.includesNot(this.actions, action)) {
- this.actions.push(action);
- this.redraw();
- action.setMenu(this);
- if (action instanceof OpenSubmenuAction) {
- this.submenus.push(action.getSubmenu());
- }
- }
- }
-
- draw() {
- if (Helper.isNotNull(this.parentElements)) {
- this.sortActions();
-
- let actionElements = [];
- for (let i = 0; i < this.actions.length; i++) {
- let element = this.renderAction(this.actions[i]);
- this.actions[i]._htmlElement = element;
- actionElements.push(element);
- }
- for (let i = 0, n = this.parentElements.length; i < n; i++) {
- this.parentElements[i].removeAllChildren();
- for (let i2 = 0, n2 = actionElements.length; i2 < n2; i2++) {
- this.parentElements[i].appendChild(Helper.cloneNode(actionElements[i2]));
- }
- this.parentElements[i].onclick = this._getOnClickListener();
- }
- }
- }
-
- _getOnClickListener() {
- let menu = this;
- return function (event) {
- let _element = event.target;
- if (_element.matches('.action') || _element.matches('.action *')) {
- // while (!_element.matches('.action > a')) {
- // _element = _element.parentNode;
- // }
- _element = _element.closest(".action");
- let actionId = parseInt(_element.dataset["id"]);
- for (let i = 0, n = menu.actions.length; i < n; i++) {
- if (menu.actions[i].id === actionId) {
- if (typeof menu.actions[i].callback === 'function' && menu.actions[i].getActivated()) {
- menu.actions[i].callback(menu.actions[i], event);
- }
- return menu.actions[i];
- }
- }
- for (let i = 0, n = menu.submenus.length; i < n; i++) {
- if (menu.submenus[i].click(actionId, event)) {
- return menu.submenus[i];
- }
- }
- }
- return null;
- };
- }
-
- /** @protected */
- renderAction(action) {
- let aElement = document.createElement("a");
- if (typeof action.callback === 'string') {
- aElement.href = action.callback;
- }
-
- if (Helper.isNotNull(action.getIcon())) {
- let iconElement = document.createElement("img");
- iconElement.src = action.getIcon();
- iconElement.classList.add('action-image');
- if (action.getShouldTranslate()) {
- iconElement.dataset["translationTitle"] = action.title;
- }
- aElement.appendChild(iconElement);
- }
- let title = action.getTitle();
- if (action.getShouldTranslate()) {
- title = Translator.makePersistentTranslation(title);
- }
- else {
- title = document.createTextNode(title);
- }
- aElement.appendChild(title);
-
- return this.renderLiElement(aElement, action)
- }
-
- /** @protected */
- renderLiElement(aElement, action) {
- let liElement = document.createElement("li");
- liElement.classList.add('action');
- if (action._liClass.trim() !== "") {
- liElement.classList.add(action._liClass);
- }
- liElement.appendChild(aElement);
- liElement.dataset["id"] = action.id;
- if (Helper.isNotNull(action.getIcon())) {
- liElement.classList.add("img");
- }
-
- if (!action.getVisible()) {
- liElement.classList.add("hidden");
- }
-
- if (action instanceof OpenSubmenuAction) {
- action.getSubmenu().draw();
- liElement.appendChild(action.getSubmenu().getParentElement());
- liElement.classList.add("is-dropdown-submenu-parent");
- liElement.classList.add("opens-right");
- }
- return liElement;
- }
-
- /** @private */
- sortActions() {
- this.actions = this.actions.sort(function (first, second) {
- return first.order - second.order;
- });
- }
-
- _getElementsForAction(action) {
- let elements = [];
- for (let i = 0; i < this.parentElements.length; i++) {
- let elem = this.parentElements[i].querySelector("[data-id=\"" + action.getId() + "\"]");
- Helper.isNull(elem) || elements.push(elem);
- }
- return elements
- }
-
- updateAction(action) {
- let oldElements = this._getElementsForAction(action);
- if (oldElements.length === 0) {
- return;
- }
-
- let element = this.renderAction(action);
- action._htmlElement = element;
-
- for (let i = 0; i < oldElements.length; i++) {
- oldElements[i].replaceWith(Helper.cloneNode(element));
- }
- }
-
- removeAction(action) {
- let index = this.actions.indexOf(action);
- if (index > 0) {
- this.actions.splice(index, 1);
- let oldElements = this._getElementsForAction(action);
- for (let i = 0, n = oldElements.length; i < n; i++) {
- oldElements[i].remove();
- }
- if (action instanceof OpenSubmenuAction) {
- let index = this.submenus.indexOf(action.getSubmenu());
- this.submenus.splice(index, 1);
- }
- }
- }
-
- redraw() {
- this.draw();
- }
-}
-
-Menu.SHOW_ALWAYS = "always";
-Menu.SHOW_FOR_MEDIUM = "medium";
-Menu.SHOW_FOR_SMEDIUM = "smedium";
-Menu.SHOW_FOR_LARGE = "large";
-Menu.SHOW_NEVER = "never";
-
-class Submenu extends Menu
-{
- constructor()
- {
- let menuElement = document.createElement("ul");
- menuElement.classList.add("menu");
- menuElement.classList.add("vertical");
- menuElement.classList.add("submenu");
- menuElement.classList.add("is-dropdown-submenu");
- menuElement.classList.add("first-sub");
- super(menuElement);
-
- this.parentAction = null;
- this.isOpen = false;
- }
-
-
-
- copy(instance)
- {
- instance = super.copy(Helper.nonNull(instance, new Submenu()));
- instance.parentElements = [];
- for (let i = 0, n = this.parentElements.length; i < n; i++) {
- instance.parentElements.push(Helper.cloneNode(this.parentElements[i]));
- }
- instance.parentAction = this.parentAction;
- instance.isOpen = this.isOpen;
- return instance;
- }
-
- setParentAction(action)
- {
- this.parentAction = action;
- }
-
- draw()
- {
- super.draw();
- if (Helper.isNotNull(this.parentElements))
- {
- let self = this;
- for (let i = 0; i < this.parentElements.length; i++) {
- let closeListener = document.createElement("div");
- closeListener.classList.add("close-listener");
- closeListener.onclick = function(e){
- console.log(e);
- self.close();
- };
- this.parentElements[i].insertBefore(closeListener, this.parentElements[i].firstElementChild);
- }
- }
- }
-
- getParentElement()
- {
- return this.parentElements[0];
- }
-
- _getOnClickListener()
- {
- return function () {};
- }
-
- click(actionId, event)
- {
- for (let i = 0, n = this.actions.length; i < n; i++) {
- if (this.actions[i].id === actionId)
- {
- if (typeof this.actions[i].callback === 'function' && this.actions[i].getActivated()) {
- this.actions[i].callback(this.actions[i], event);
- }
- this.close();
- return true;
- }
- }
- return false;
- }
-
- toggle()
- {
- if (this.isOpen)
- {
- this.close();
- }
- else
- {
- this.open();
- }
- }
-
- open()
- {
- this.isOpen = true;
- for (let i = 0, n = this.parentElements.length; i < n; i++) {
- this.parentElements[i].classList.add("js-dropdown-active");
- }
- if (Helper.isNotNull(this.parentAction))
- {
- this.parentAction.redraw();
- }
- }
- close()
- {
- this.isOpen = false;
- for (let i = 0, n = this.parentElements.length; i < n; i++) {
- this.parentElements[i].classList.remove("js-dropdown-active");
- }
- if (Helper.isNotNull(this.parentAction))
- {
- this.parentAction.redraw();
- }
- }
-}
-
-class TranslatorDB {
- constructor() {
- this._indexedDB = indexedDB || mozIndexedDB || webkitIndexedDB || msIndexedDB;
- this._version = 3;
-
- let self = this;
- this._dbPromise = new Promise(function (resolve, reject) {
- let request = self._indexedDB.open("Translator", self._version);
- request.onupgradeneeded = function (event) {
- let db = event.target.result;
- self._upgradeDb(db);
- };
- request.onsuccess = function (event) {
- let db = event.target.result;
- resolve(db);
- };
- request.onerror = function (event) {
- reject(event);
- };
- }).catch(function(e){
- console.error(e);
- });
- }
-
- _upgradeDb(db) {
- try {
- db.deleteObjectStore("currentLang");
- db.deleteObjectStore("translations");
- }
- catch (e) {
- console.warn(e);
- }
- let currentLangObjectStore = db.createObjectStore("currentLang", {"keyPath": "id"});
- let translationsObjectStore = db.createObjectStore("translations", {"keyPath": ["lang","key"]});
- translationsObjectStore.createIndex("lang", "lang", {"unique": false});
- }
-
- setLanguage(lang) {
- this._dbPromise.then(function (db) {
- let transaction = TranslatorDB._openTransaction(["currentLang"], "readwrite", db);
- let currentLangObjectStore = transaction.objectStore("currentLang");
- currentLangObjectStore.put({"id": 1, "lang": lang});
- }).catch(function(e){
- console.error(e);
- });
- }
-
- saveTranslationsForLang(lang, translations) {
- return this._dbPromise.then(function (db) {
- return new Promise(function (resolve) {
- let transaction = TranslatorDB._openTransaction(["translations"], "readwrite", db);
- let translationsObjectStore = transaction.objectStore("translations");
- for (let k in translations) {
- translationsObjectStore.put({"lang": lang, "key": k, "translation": translations[k]});
- }
- transaction.oncomplete = function () {
- resolve();
- };
- });
- }).catch(function(e){
- // console.error(e);
- });
- }
-
- loadTranslationsForLang(lang) {
- return this._dbPromise.then(function (db) {
- return new Promise(function (resolve) {
- let transaction = TranslatorDB._openTransaction(["translations"], "readonly", db);
- let translationsObjectStore = transaction.objectStore("translations");
- let index = translationsObjectStore.index("lang");
- let request = index.openCursor(IDBKeyRange.only(lang));
-
- let translations = {};
- request.onsuccess = function (e) {
- let cursor = e.target.result;
- if (cursor) {
-
- let translation = cursor.value;
- translations[translation["key"]] = translation["translation"];
- cursor.continue();
- }
- };
- transaction.oncomplete = function(){
- resolve(translations);
- };
- });
- }).catch(function(e){
- console.error(e);
- return {};
- });
- }
-
- getLanguage() {
- return this._dbPromise.then(function (db) {
- return new Promise(function (resolve) {
- let transaction = TranslatorDB._openTransaction(["currentLang"], "readonly", db);
- let currentLangObjectStore = transaction.objectStore("currentLang");
- let req = currentLangObjectStore.get(1);
- req.onsuccess = function (e) {
- let data = e.currentTarget.result;
- if (data)
- {
- resolve(data["lang"]);
- }
- else
- {
- resolve(null);
- }
- };
- req.onerror = function (e) {
- resolve(null);
- };
- });
- }).catch(function(e){
- // console.error(e);
- });
- }
-
- static _openTransaction(name, transactionMode, db) {
- let transaction = null;
- try {
- transaction = db.transaction(name, transactionMode);
- }
- catch (e) {
- console.warn(e);
- transaction = db.transaction(name);
- }
- return transaction;
- }
-}
-
-class Translator {
- constructor() {
- this._translations = [];
- this._db = new TranslatorDB();
- this._currentLanguage = null;
- this._supportedLanguages = Translator.supportedLanguages;
- this._baseLanguage = Translator.baseLanguage;
- this._languageBasePath = Translator.languageBasePath;
- this._markUntranslatedTranslations = Translator.markUntranslatedTranslations;
- this._markTranslations = Translator.markTranslations;
-
- let self = this;
- this._initPromise = this.loadBaseLanguage().then(function () {
- return self.loadUserLanguage();
- });
- }
-
- _loadLanguage(language) {
- let self = this;
- return fetch(Helper.basePath(this._languageBasePath + language + ".json")).then(function (result) {
- return result.json();
- }).then(function (res) {
- self._translations[language] = Object.assign(res, self._translations[language]);
- self._db.saveTranslationsForLang(language, self._translations[language]);
- }).catch(function (err) {
- console.error("could not load lang " + language + " because of error: ", err);
- });
- }
-
- loadBaseLanguage() {
- let self = this;
- return this._loadLanguage(this._baseLanguage).then(function () {
- self._currentLanguage = self._baseLanguage;
- if (typeof document !== 'undefined') {
- document.getElementsByTagName("html")[0].setAttribute("lang", self._baseLanguage);
- }
- });
- };
-
- static setLanguage(language) {
- let instance = Translator.getInstance();
- if (instance) {
- return instance.setLanguage(language);
- }
- }
-
- setLanguage(language) {
- if (this._currentLanguage === language) {
- this.updateTranslations();
- return Promise.resolve();
- }
-
- if (this._supportedLanguages.indexOf(language) === -1) {
- return Promise.resolve();
- }
-
- this._currentLanguage = language;
- if (typeof localStorage !== 'undefined') {
- localStorage.setItem("language", language);
- }
- this._db.setLanguage(language);
-
- let self = this;
- return this._loadLanguage(language).then(function () {
- if (typeof document !== 'undefined') {
- document.getElementsByTagName("html")[0].setAttribute("lang", language);
- }
- self.updateTranslations();
- });
- }
-
- static translate(key, args) {
- let instance = Translator.getInstance();
- if (instance) {
- return instance.translate(key, args);
- }
- return "";
- }
-
- translate(key, args) {
- if (typeof key === 'object' && Helper.isNotNull(key)) {
- key = this.addDynamicTranslation(key);
- }
-
- let translation = null;
- if (Helper.isNotNull(this._translations[this._currentLanguage]) && Helper.isNotNull(this._translations[this._currentLanguage][key])) {
- translation = this._translations[this._currentLanguage][key];
- }
-
- if (Helper.isNull(translation)) {
- if (Translator.logMissingTranslations) {
- console.warn("missing translation for language " + this._currentLanguage + " and key " + key);
- }
- if (Helper.isNotNull(this._translations[this._baseLanguage])) {
- translation = this._translations[this._baseLanguage][key];
- }
-
- if (Helper.isNull(translation)) {
- if (Translator.logMissingTranslations) {
- console.error("missing base translation for key " + key + ". FIX IT");
- }
- translation = key;
- }
- if (this._markUntranslatedTranslations) {
- translation = ">>" + translation + "<<";
- }
- }
-
- if (this._markTranslations) {
- translation = "$" + translation + "$";
- }
-
- if (args !== undefined) {
- translation = translation.format(args);
- }
-
- return translation;
- }
-
- static addDynamicTranslation(trans) {
- let instance = Translator.getInstance();
- if (instance) {
- return instance.addDynamicTranslation(trans);
- }
- }
-
- addDynamicTranslation(trans) {
- let key = trans["key"];
- delete trans["key"];
- for (let lang in trans) {
- if (trans.hasOwnProperty(lang)) {
- if (Helper.isNull(this._translations[lang])) {
- this._translations[lang] = {};
- }
- this._translations[lang][key] = trans[lang];
- }
- }
- return key;
- }
-
- updateTranslations() {
- if (typeof document !== 'undefined') {
- let elements = document.querySelectorAll("[data-translation]");
- for (let i = 0, max = elements.length; i < max; i++) {
- if (elements[i].dataset["translation"] != "") {
- try {
- elements[i].innerHTML = this.translate(elements[i].dataset["translation"], (elements[i].dataset["translationArgs"] !== undefined) ? JSON.parse(elements[i].dataset["translationArgs"]) : undefined);
- }
- catch (err) {
- console.error("wrong configured translation: " + err);
- }
- }
- for (let k in elements[i].dataset) {
- if (k.startsWith("translation") && !k.endsWith("Args")) {
- try {
- elements[i][k.substr(11).toLowerCase()] = this.translate(elements[i].dataset[k], (elements[i].dataset[k + "Args"] !== undefined) ? JSON.parse(elements[i].dataset[k + "Args"]) : undefined);
- }
- catch (err) {
- console.error("wrong configured translation: " + err);
- }
- }
- }
- }
- }
- }
-
- loadUserLanguage() {
- let userLanguage = localStorage.getItem("language");
- if (Helper.isNull(userLanguage) || this._supportedLanguages.indexOf(userLanguage) === -1) {
- let userLanguages = [];
- if (Helper.isNotNull(navigator.languages)) {
- userLanguages = navigator.languages.slice(0); //.slice(0) klont das Array. Behebt einen Bug in Firefox
- }
-
- if (navigator.language !== undefined) {
- userLanguages.push(navigator.language);
- }
- //sicherstellen, dass überhaupt eine Sprache gefunden wird
- userLanguages.push(this._baseLanguage);
-
- if (userLanguages !== undefined) {
- for (let i = 0, numLanguages = userLanguages.length; i < numLanguages; i++) {
- if (this._supportedLanguages.indexOf(userLanguages[i]) !== -1) {
- userLanguage = userLanguages[i];
- break;
- }
- }
- }
- }
- return this.setLanguage(userLanguage.toLowerCase())
- }
-
- static makePersistentTranslation(key, args, tag) {
- tag = Helper.nonNull(tag, "span");
- if (typeof key === 'object') {
- key = Translator.addDynamicTranslation(key);
- }
-
- if (typeof document !== 'undefined') {
- let htmlElem = document.createElement(tag);
- htmlElem.dataset["translation"] = key;
- if (args !== undefined) {
- htmlElem.dataset["translationArgs"] = JSON.stringify(args);
- }
- htmlElem.innerHTML = Translator.translate(key, args);
- return htmlElem;
- }
- }
-
- static generateChangeLanguageMenuAction() {
- let submenu = new Submenu();
- submenu.addAction(new MenuAction("en", function () {
- Translator.getInstance().setLanguage("en");
- }));
- submenu.addAction(new MenuAction("de", function () {
- Translator.getInstance().setLanguage("de");
- }));
- return new OpenSubmenuAction("current-lang", submenu, Menu.SHOW_ALWAYS)
- }
-
- static init() {
- Translator.instance = new Translator();
- // Translator.loadBaseLanguage().then(function () {
- // Translator.loadUserLanguage();
- // });
- }
-
- static getInstance() {
- return Translator.instance;
- }
-}
-Translator.logMissingTranslations = false;
-
-Translator.instance = null;
-
-Translator.baseLanguage = "en";
-Translator.supportedLanguages = [
- "de",
- "en"
-];
-Translator.markUntranslatedTranslations = true;
-Translator.markTranslations = false;
-Translator.languageBasePath = "js/lang/";
-Translator.currentLanguage = null;
-Translator.translations = {};
-
-
-AndroidBridge.addDefinition("Translator.setLanguage", Translator.setLanguage);
-
-class Helper {
- static init() {
- Helper.heightMmToPxFactor = null;
- Helper.widthMmToPxFactor = null;
- }
-
- static includesNot(array, value, fromIndex) {
- return -1 === array.indexOf(value, fromIndex);
- }
-
- static includes(array, value, fromIndex) {
- return !Helper.includesNot(array, value, fromIndex);
- }
-
- static isSet() {
- if (arguments.length > 0) {
- const object = arguments[0];
- let keys = Array.prototype.slice.call(arguments, 1);
- return (Helper.isNotNull(object) && (keys.length === 0 || Helper.isSet.apply(null, [object[keys[0]]].concat(keys.slice(1)))));
- }
- return false;
- }
-
- static isNull(variable) {
- return (variable === null || variable === undefined);
- }
-
- static isNotNull(variable) {
- return !Helper.isNull(variable);
- }
-
- static nonNull(val1, val2) {
- for (let i = 0; i < arguments.length; i++) {
- if (Helper.isNotNull(arguments[i])) {
- return arguments[i];
- }
- }
- return null;
- }
-
- static notEmpty(value) {
- return !Helper.empty(value);
- }
-
- static buildQuery(values) {
- let queryStrings = [];
- for (let k in values) {
- queryStrings.push(encodeURIComponent(k) + "=" + encodeURIComponent(values[k]));
- }
- return "?" + queryStrings.join("&");
- }
-
- static empty(value) {
- return (Helper.isNull(value) || (typeof value === 'string' && value.trim() === ""))
- }
-
- static inflateElementsFromString(string) {
- let template = document.createElement('template');
- template.innerHTML = string;
- return template.content.childNodes;
- }
-
- static createLoadingSymbol() {
- let svgNS = "http://www.w3.org/2000/svg";
-
- let loader = document.createElement("div");
- loader.className = 'loader';
-
- let svg = document.createElementNS(svgNS, "svg");
- svg.setAttribute('viewBox', "0 0 32 32");
- svg.setAttribute("widh", "32");
- svg.setAttribute("height", "32");
-
- let circle = document.createElementNS(svgNS, "circle");
- circle.setAttribute("id", "spinner");
- circle.setAttribute("cx", "16");
- circle.setAttribute("cy", "16");
- circle.setAttribute("r", "14");
- circle.setAttribute("fill", "none");
-
- svg.appendChild(circle);
- loader.appendChild(svg);
-
- return loader;
- }
-
- static basePath(url) {
- return SystemSettings.getBasePath() + url;
- }
-
- static isMobileApple() {
- return navigator.userAgent.match(/iPhone|iPad|iPod/i);
- }
-
- static isMobile() {
- return (navigator.userAgent.match(/Android|BlackBerry|Opera Mini|IEMobile/i) !== null || Helper.isMobileApple() || (typeof window.orientation !== "undefined" || window.orientation === false || window.orientation === null));
- }
-
- static select(e) {
- let range = document.createRange();
- range.selectNodeContents(e);
- let sel = window.getSelection();
- sel.removeAllRanges();
- sel.addRange(range);
- }
-
- static format(number, leadingZeros) {
- number = "" + number;
- while (number.length < leadingZeros) {
- number = "0" + number;
- }
- return number;
- }
-
- static cloneNode(srcNode) {
- let destNode = srcNode.cloneNode(true);
- destNode.onclick = srcNode.onclick;
- return destNode;
- }
-
- static encodeToBase(stringToEncode, base) {
- let encodedString = "";
- let charlength = Math.floor(Math.log(265) / Math.log(base));
- for (let i = 0; i < stringToEncode.length; i++) {
- let value = stringToEncode.charCodeAt(i).toString(base);
- let joinLength = value.length % charlength;
- if (joinLength > 0) {
- let joinArray = new Array(charlength + 1 - (joinLength)); //+1, da join nur zwischen elemente einfügt
- value = joinArray.join("0") + value;
- }
- encodedString += value;
- }
- return encodedString;
- }
-
- static decodeToBase(stringToDecode, base) {
- let charlength = Math.floor(Math.log(265) / Math.log(base));
- let values = stringToDecode.match(new RegExp(".{1," + charlength + "}", "g")) || [];
- let encodedString = "";
- for (let i = 0, n = values.length; i < n; i++) {
- encodedString += String.fromCharCode(parseInt(values[i], base));
- }
- return encodedString;
- }
-
- static toggleVisibility(elem) {
- if (elem.style.display === "none") {
- elem.style.display = "";
- return true;
- }
- else {
- elem.style.display = "none";
- return false;
- }
- }
-
- static print(content) {
- let printContent = document.getElementById("print-content");
- if (content instanceof Element) {
- printContent.removeAllChildren();
- printContent.appendChild(content);
- }
- else {
- printContent.innerHTML = content;
- }
- window.print();
- }
-
- static strftime(sFormat, date, useUTC) {
- if (!(date instanceof Date)) date = new Date(date);
- useUTC = Helper.nonNull(useUTC, false);
- let nDay = (useUTC) ? date.getUTCDay() : date.getDay(),
- nDate = (useUTC) ? date.getUTCDate() : date.getDate(),
- nMonth = (useUTC) ? date.getUTCMonth() : date.getMonth(),
- nYear = (useUTC) ? date.getUTCFullYear() : date.getFullYear(),
- nHour = (useUTC) ? date.getUTCHours() : date.getHours(),
- aDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
- aMonths = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
- aDayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
- isLeapYear = function () {
- if ((nYear & 3) !== 0) return false;
- return nYear % 100 !== 0 || nYear % 400 === 0;
- },
- getThursday = function () {
- let target = new Date(date);
- target.setDate(nDate - ((nDay + 6) % 7) + 3);
- return target;
- },
- zeroPad = function (nNum, nPad) {
- return ('' + (Math.pow(10, nPad) + nNum)).slice(1);
- };
-
- return sFormat.replace(/%[a-z]/gi, function (sMatch) {
- return {
- '%a': Translator.makePersistentTranslation(aDays[nDay].slice(0, 3)).outerHTML,
- '%A': Translator.makePersistentTranslation(aDays[nDay]).outerHTML,
- '%b': Translator.makePersistentTranslation(aMonths[nMonth].slice(0, 3)).outerHTML,
- '%B': Translator.makePersistentTranslation(aMonths[nMonth]).outerHTML,
- '%c': date.toUTCString(),
- '%C': Math.floor(nYear / 100),
- '%d': zeroPad(nDate, 2),
- '%e': nDate,
- '%f': zeroPad(date.getTime() % 1000, 4),
- '%F': date.toISOString().slice(0, 10),
- '%G': getThursday().getFullYear(),
- '%g': ('' + getThursday().getFullYear()).slice(2),
- '%H': zeroPad(nHour, 2),
- '%I': zeroPad((nHour + 11) % 12 + 1, 2),
- '%j': zeroPad(aDayCount[nMonth] + nDate + ((nMonth > 1 && isLeapYear()) ? 1 : 0), 3),
- '%k': '' + nHour,
- '%l': (nHour + 11) % 12 + 1,
- '%m': zeroPad(nMonth + 1, 2),
- '%M': zeroPad(date.getMinutes(), 2),
- '%p': (nHour < 12) ? 'AM' : 'PM',
- '%P': (nHour < 12) ? 'am' : 'pm',
- '%s': Math.round(date.getTime() / 1000),
- '%S': zeroPad(date.getSeconds(), 2),
- '%u': nDay || 7,
- '%V': (function () {
- let target = getThursday(),
- n1stThu = target.valueOf();
- target.setMonth(0, 1);
- let nJan1 = target.getDay();
- if (nJan1 !== 4) target.setMonth(0, 1 + ((4 - nJan1) + 7) % 7);
- return zeroPad(1 + Math.ceil((n1stThu - target) / 604800000), 2);
- })(),
- '%w': '' + nDay,
- '%x': date.toLocaleDateString(),
- '%X': date.toLocaleTimeString(),
- '%y': ('' + nYear).slice(2),
- '%Y': nYear,
- '%z': date.toTimeString().replace(/.+GMT([+-]\d+).+/, '$1'),
- '%Z': date.toTimeString().replace(/.+\((.+?)\)$/, '$1')
- }[sMatch] || sMatch;
- });
- }
-
- static cloneJson(obj) {
- // https://stackoverflow.com/questions/4120475/how-to-create-and-clone-a-json-object/17502990#17502990
- let i;
-
- // basic type deep copy
- if (Helper.isNull(obj) || typeof obj !== 'object') {
- return obj
- }
- // array deep copy
- if (obj instanceof Array) {
- let cloneA = [];
- for (i = 0; i < obj.length; ++i) {
- cloneA[i] = Helper.cloneJson(obj[i]);
- }
- return cloneA;
- }
- if (obj instanceof Date)
- {
- return new Date(obj.getTime());
- }
- // object deep copy
- let cloneO = {};
- for (i in obj) {
- cloneO[i] = Helper.cloneJson(obj[i]);
- }
- return cloneO;
- }
-
- static htmlspecialcharsDecode(text) {
- const map = {
- '&': '&',
- '&': "&",
- '<': '<',
- '>': '>',
- '"': '"',
- ''': "'",
- '’': "’",
- '‘': "‘",
- '–': "–",
- '—': "—",
- '…': "…",
- '”': '”'
- };
-
- if (Helper.isNotNull(text) && typeof text.replace === "function") {
- return text.replace(/\&[\w\d\#]{2,5}\;/g, function (m) {
- return map[m];
- });
- }
- return text;
- }
-
- static formDataFromObject(obj) {
- let formData = new FormData();
- for (let k in obj) {
- formData.set(k, obj[k]);
- }
- return formData;
- }
-
- static scaleContentRecursive(element, content) {
-
- let elementStyle = window.getComputedStyle(element);
- let contentStyle = window.getComputedStyle(content);
-
- if (contentStyle.height > elementStyle.height || contentStyle.width > elementStyle.width) {
- return Helper.scaleDownContentRecursive(element, content);
- }
- }
-
- static scaleDownContentRecursive(element, content) {
- Helper.convertChildrenToRelativeRecursive(element);
-
- let elementStyle = window.getComputedStyle(element);
- let contentStyle = window.getComputedStyle(content);
-
- let runs = 0;
- let fontSize = parseFloat(contentStyle.getPropertyValue("font-size"));
- let width = contentStyle.width;
- let height = contentStyle.height;
- while (contentStyle.height > elementStyle.height || contentStyle.width > elementStyle.width) {
- fontSize *= 0.95;
-
- if (height > elementStyle.height) {
- height *= 0.95;
- }
- if (width > contentStyle.width) {
- width *= 0.95;
- }
- content.style["font-size"] = fontSize + "px";
- content.style["max-height"] = height + "px";
- content.style["max-width"] = width + "px";
-
- runs++;
- if (runs > 2000) {
- console.log("breaked");
- break;
- }
- }
- Helper.convertToRelative(content);
-
- contentStyle = window.getComputedStyle(content);
- content.style["font-size"] = (parseFloat(contentStyle.getPropertyValue("font-size")) / parseFloat(document.documentElement.clientHeight) * 100) + "vh";
- }
-
- static convertChildrenToRelativeRecursive(element) {
- let children = element.childNodes;
- for (let i = 0, n = children.length; i < n; i++) {
- if (children[i] instanceof Element) {
- Helper.convertToRelative(children[i]);
- Helper.convertChildrenToRelativeRecursive(children[i]);
- }
- }
- }
-
- static convertToRelative(element) {
- let hasTransitionClass = (element.classList.contains("no-transtition"));
-
- element.classList.add("no-transition");
-
- let parent = element.parentNode;
-
- console.log(element);
- let elementStyle = window.getComputedStyle(element);
- let parentStyle = window.getComputedStyle(parent);
-
- let fontSize = parseFloat(elementStyle.getPropertyValue("font-size")) / parseFloat(parentStyle.getPropertyValue("font-size"));
-
- let maxHeight = elementStyle.height;
- let maxWidth = elementStyle.width;
-
- let pHeight = parentStyle.height;
- let pWidth = parentStyle.width;
-
- let relativeAttributes = element.style;
- relativeAttributes['max-height'] = Math.floor(maxHeight / pHeight * 100) + "%";
- relativeAttributes['margin-left'] = Math.floor(parseFloat(elementStyle.getPropertyValue('margin-left')) / pWidth * 100) + "%";
- relativeAttributes['margin-right'] = Math.floor(parseFloat(elementStyle.getPropertyValue('margin-right')) / pWidth * 100) + "%";
- relativeAttributes['margin-top'] = Math.floor(parseFloat(elementStyle.getPropertyValue('margin-top')) / pHeight * 100) + "%";
- relativeAttributes['margin-bottom'] = Math.floor(parseFloat(elementStyle.getPropertyValue('margin-bottom')) / pHeight * 100) + "%";
- relativeAttributes['max-width'] = Math.floor(maxWidth / pWidth * 100) + "%";
- relativeAttributes["font-size"] = fontSize + "em";
- // console.log(relativeAttributes);
- // element.css(relativeAttributes);
-
- if (!hasTransitionClass) {
- element.classList.remove("no-transition");
- }
- }
-
- static isChrome() {
- let isChromium = window.chrome,
- winNav = window.navigator,
- vendorName = winNav.vendor,
- isOpera = winNav.userAgent.indexOf("OPR") > -1,
- isIEedge = winNav.userAgent.indexOf("Edge") > -1,
- isIOSChrome = winNav.userAgent.match("CriOS");
-
- if (isIOSChrome) {
- return true;
- } else {
- return isChromium !== null &&
- typeof isChromium !== "undefined" &&
- vendorName === "Google Inc." &&
- isOpera === false &&
- isIEedge === false;
- }
- }
-
- static getIndexedObject(array, keyValue) {
- let obj = {};
- for (let i = 0, n = array.length; i < n; i++) {
- obj[array[i][keyValue]] = array[i];
- }
- return obj;
- }
-
- static invertKeyValues(obj) {
- let new_obj = {};
-
- for (let prop in obj) {
- if (obj.hasOwnProperty(prop)) {
- new_obj[obj[prop]] = prop;
- }
- }
-
- return new_obj;
- }
-
- static toArray(object) {
- let res = [];
- for (let k in object) {
- res.push(object[k]);
- }
- return res;
- }
-}
-Helper.init();
-
-class SystemSettings {
- static setBasePath(basePath) {
- SystemSettings._basePath = basePath;
- }
-
- static getBasePath() {
- return SystemSettings._basePath;
- }
-
- static set(key, value) {
- SystemSettings._settings[key] = value;
- }
-
- static get(key, defaultValue) {
- return Helper.nonNull(SystemSettings._settings[key], defaultValue);
- }
-
- static has(key){
- return Helper.nonNull(SystemSettings._settings[key]);
- }
-}
-
-SystemSettings.setBasePath("/");
-SystemSettings._settings = {};
-
-class ThemeManager$1 {
- static init() {
- ThemeManager$1.loadCurrentTheme();
- }
-
- static changeCurrentTheme(newTheme) {
- let theme = null;
- if (typeof newTheme === 'string') {
- let themes = ThemeManager$1.themes.filter(function (theme) {
- return theme._name === newTheme;
- });
- if (themes.length > 0) {
- theme = themes[0];
- }
- }
- else if (ThemeManager$1.themes.indexOf(newTheme) !== -1) {
- theme = newTheme;
- }
- if (Helper.isNotNull(theme)) {
- localStorage.setItem("currentTheme", theme._name);
- let themePromise = new Promise(function (resolve) {
- document.querySelector("nav.top-bar").addEventListener("transitionend", function(){
- resolve();
- });
- });
- document.body.className = theme._className;
- ThemeManager$1.currentTheme = theme;
- for (let i = 0, n = ThemeManager$1.changeListeners.length; i < n; i++) {
- ThemeManager$1.changeListeners[i](ThemeManager$1.currentTheme, themePromise);
- }
- }
- }
-
- static addTheme(theme) {
- ThemeManager$1.themes.push(theme);
- }
-
- static loadCurrentTheme() {
- ThemeManager$1.changeCurrentTheme(localStorage.getItem("currentTheme"));
- if (Helper.isNull(ThemeManager$1.currentTheme)) {
- let className = document.body.className;
- let themes = ThemeManager$1.themes.filter(function (theme) {
- return theme._className === className;
- });
- if (themes.length > 0) {
- ThemeManager$1.changeCurrentTheme(themes[0]);
- }
- else if (ThemeManager$1.themes.length > 0) {
- ThemeManager$1.changeCurrentTheme(ThemeManager$1.themes[0]);
- }
- }
- }
-
- static generateChangeThemeMenuAction() {
- return new MenuAction(ThemeManager$1.currentTheme._name, function (action) {
- let currentThemeIndex = ThemeManager$1.themes.indexOf(ThemeManager$1.currentTheme);
- let nextIndex = (currentThemeIndex + 1) % ThemeManager$1.themes.length;
- ThemeManager$1.changeCurrentTheme(ThemeManager$1.themes[nextIndex]);
- action.title = ThemeManager$1.currentTheme._name;
- action._menu.redraw();
- }, Menu.SHOW_ALWAYS)
- }
-
- static addChangeListener(listener) {
- ThemeManager$1.changeListeners.push(listener);
- }
-
- static getCurrentTheme(){
- return ThemeManager$1.currentTheme;
- }
-}
-
-ThemeManager$1.currentTheme = null;
-ThemeManager$1.themes = [];
-ThemeManager$1.changeListeners = [];
-
-AndroidBridge.addDefinition("ThemeManager", {
- "addChangeListener": ThemeManager$1.addChangeListener,
- "getCurrentTheme": ThemeManager$1.getCurrentTheme,
-});
-
-class CookieCompliance {
-
- static async showIfNeeded(cookieContainer) {
- let cookieCompliance = new CookieCompliance(cookieContainer);
- return cookieCompliance.showIfNeeded();
- }
-
- constructor(cookieContainerId) {
- this.cookieContainerId = cookieContainerId;
- this.dropCookie = true;
- this.cookieDuration = 365 * 10;
- this.cookieName = 'complianceCookie';
- this.cookieValue = 'true';
- }
-
- async showIfNeeded() {
- if (CookieCompliance.checkCookie(this.cookieName) !== this.cookieValue) {
- return this.show();
- }
- return Promise.resolve();
- }
-
- removeMe() {
- this.createCookie(this.cookieName, this.cookieValue, this.cookieDuration);
- }
-
- createCookie(name, value, days) {
- let expires;
- if (Helper.isNotNull(days)) {
- const date = new Date();
- date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
- expires = "; expires=" + date.toGMTString();
- }
- else {
- expires = "";
- }
- if (this.dropCookie) {
- document.cookie = name + "=" + value + expires + "; path=/";
- }
- }
-
- eraseCookie(name) {
- this.createCookie(name, "", -1);
- }
-
- static checkCookie(name) {
- const nameEQ = name + "=";
- const cookies = document.cookie.split(';');
- for (let i = 0; i < cookies.length; i++) {
- let c = cookies[i];
- while (c.charAt(0) === ' ') {
- c = c.substring(1, c.length);
- }
- if (c.indexOf(nameEQ) === 0) {
- return c.substring(nameEQ.length, c.length);
- }
- }
- return null;
- }
-
- show() {
- let cookieCompliance = this;
- const cookieMessage = document.getElementById(this.cookieContainerId);
- cookieMessage.style.display = 'block';
- return new Promise(r => {
- cookieMessage.querySelector("#close-cookie-msg").onclick = function () {
- cookieCompliance.removeMe();
- cookieMessage.remove();
- r();
- };
- });
- }
-}
-
-class ActionBarMenu extends Menu {
- static init() {
- function parseStyleToObject(str) {
- let styleObject = {};
-
- if (typeof str !== 'string') {
- return styleObject;
- }
-
- str = str.trim().slice(1, -1); // browsers re-quote string style values
-
- if (!str) {
- return styleObject;
- }
-
- styleObject = str.split('&').reduce(function (ret, param) {
- const parts = param.replace(/\+/g, ' ').split('=');
- let key = parts[0];
- let val = parts[1];
- key = decodeURIComponent(key);
-
- // missing `=` should be `null`:
- // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
- val = val === undefined ? null : decodeURIComponent(val);
-
- if (!ret.hasOwnProperty(key)) {
- ret[key] = val;
- } else if (Array.isArray(ret[key])) {
- ret[key].push(val);
- } else {
- ret[key] = [ret[key], val];
- }
- return ret;
- }, {});
-
- return styleObject;
- }
-
- let cssStyle = document.getElementsByClassName('foundation-mq');
- if (cssStyle.length === 0) {
- return;
- }
- let queries = [];
- cssStyle = parseStyleToObject(window.getComputedStyle(cssStyle[0]).getPropertyValue('font-family'));
- for (let key in cssStyle) {
- if (cssStyle.hasOwnProperty(key)) {
- queries.push({
- _name: key,
- value: 'only screen and (min-width: ' + cssStyle[key] + ')'
- });
- }
- }
-
- window.addEventListener('resize', function () {
- if (Helper.isNotNull(ActionBarMenu.currentMenu)) {
- ActionBarMenu.currentMenu.updateToggleButton();
- }
- });
- let responsiveMenu = document.getElementById("responsive-menu");
- document.getElementById("responsive-menu-toggle").onclick = function () {
- if (window.getComputedStyle(responsiveMenu).getPropertyValue('display') === 'none') {
- responsiveMenu.style.display = 'block';
- }
- else if (Helper.isNotNull(ActionBarMenu.currentMenu)) {
- ActionBarMenu.currentMenu.close();
-
- }
- };
- responsiveMenu.firstElementChild.addEventListener("click", function (e) {
- if (e.target === responsiveMenu.firstElementChild && Helper.isNotNull(ActionBarMenu.currentMenu)) {
- ActionBarMenu.currentMenu.close();
- }
- }
- );
- ActionBarMenu.queries = queries;
- }
-
- static _getCurrentSize() {
- let matched;
-
- for (let i = 0; i < ActionBarMenu.queries.length; i++) {
- let query = ActionBarMenu.queries[i];
-
- if (matchMedia(query.value).matches) {
- matched = query;
- }
- }
-
- if (typeof matched === 'object') {
- return matched._name;
- } else {
- return matched;
- }
- }
-
- static filterVisibleElements(elements) {
- let visibleElements = [];
- for (let i = 0, n = elements.length; i < n; i++) {
- if (!elements[i].classList.contains("hidden")) {
- visibleElements.push(elements[i]);
- }
- }
- return visibleElements;
- }
-
- renderLiElement(aElement, action) {
- let liElement = super.renderLiElement(aElement, action);
- liElement.classList.add(action.getShowFor());
- return liElement;
- }
-
- updateToggleButton() {
- let size = ActionBarMenu._getCurrentSize();
- let firstParentElement = this.parentElements[0];
- if ((size === "medium" || size === "smedium" || size === "small") && ActionBarMenu.filterVisibleElements(firstParentElement.getElementsByClassName(Menu.SHOW_FOR_LARGE)).length > 0 ||
- (size === "smedium" || size === "small") && ActionBarMenu.filterVisibleElements(firstParentElement.getElementsByClassName(Menu.SHOW_FOR_MEDIUM)).length > 0 ||
- (size === "small") && ActionBarMenu.filterVisibleElements(firstParentElement.getElementsByClassName(Menu.SHOW_FOR_SMEDIUM)).length > 0 ||
- ActionBarMenu.filterVisibleElements(firstParentElement.getElementsByClassName(Menu.SHOW_NEVER)).length > 0) {
- document.getElementById("responsive-menu-toggle").style.display = 'block';
- } else {
- document.getElementById("responsive-menu-toggle").style.display = 'none';
- if (Helper.isNotNull(ActionBarMenu.currentMenu)) {
- ActionBarMenu.currentMenu.close();
- }
- }
- }
-
- _getOnClickListener() {
- let superListener = super._getOnClickListener();
- return function (event) {
- let action = superListener(event);
- if (!(action instanceof OpenSubmenuAction) && Helper.isNotNull(ActionBarMenu.currentMenu)) {
- ActionBarMenu.currentMenu.close();
- }
- }
- }
-
- draw(parentElement) {
- let returnValue = super.draw(parentElement);
- this.updateToggleButton();
-
- ActionBarMenu.currentMenu = this;
- return returnValue;
- }
-
- close() {
- document.getElementById("responsive-menu").style.display = 'none';
- for (let i = 0, n = this.submenus.length; i < n; i++) {
- this.submenus[i].close();
- }
- }
-
- removeAction(action) {
- let res = super.removeAction(action);
- this.updateToggleButton();
- return res;
- }
-}
-
-ActionBarMenu.queries = [];
-ActionBarMenu.currentMenu = null;
-ActionBarMenu.init();
-
-class ViewInflater {
- static inflate(viewUrl, parentUrls) {
- parentUrls = Helper.nonNull(parentUrls, []).slice(0);
-
- let resultPromise = Promise.resolve();
- if (viewUrl instanceof Element) {
- resultPromise = Promise.resolve(viewUrl);
- }
- else {
- if (parentUrls.indexOf(viewUrl) !== -1) {
- return Promise.reject("views are in a circuit! cannot resolve view for url " + parentUrls[0] + "! url " + viewUrl + " is in stack before!");
- }
- parentUrls.push(viewUrl);
- resultPromise = fetch(Helper.basePath(viewUrl), {credentials: "same-origin"}).then(function (result) {
- return result.text();
- }).then(function (htmlText) {
- let doc = (new DOMParser()).parseFromString(htmlText, "text/html");
- if (Helper.isNull(doc)) {
- doc = document.implementation.createHTMLDocument('');
- doc.body.innerHTML = htmlText;
- }
- return doc.body.firstChild
- });
- }
-
- return resultPromise.then(function (parentElement) {
- let promises = [];
- let childViews = parentElement.querySelectorAll("[data-view]");
-
- for (let i = 0, n = childViews.length; i < n; i++) {
- promises.push(ViewInflater.inflate(childViews[i].dataset["view"], parentUrls).then(function (element) {
- childViews[i].replaceWith(element);
- }));
- }
- return Promise.all(promises).then(function () {
- return parentElement;
- });
- });
- }
-}
-
-class Context {
- constructor(view) {
- let self = this;
- this._siteContent = null;
- this.firstStart = true;
- this.inflatePromise = new Promise(function (resolver) {
- self.inflatePromiseResolver = resolver;
- });
- this.fragments = {};
-
- if (Helper.isNotNull(view)) {
- this.inflateView(view);
- }
- }
-
- onConstruct() {
- let results = [];
- for (let k in this.fragments) {
- results.push(this.fragments[k].onConstruct.apply(this.fragments[k], arguments));
- results.push(this.fragments[k].inflatePromise);
- }
- return Promise.all(results);
- }
-
- onStart() {
- if (this.firstStart) {
- this.onFirstStart();
- this.firstStart = false;
- }
-
- for (let k in this.fragments) {
- let fragment = this.fragments[k];
- fragment.onStart.apply(this.fragments[k], arguments);
- this.fragments[k].inflatePromise.then(function (fragmentView) {
- if (fragment.isActive()) {
- fragmentView.classList.remove("hidden");
- }
- else {
- fragmentView.classList.add("hidden");
- }
- });
- }
- }
-
- onFirstStart() {
- // for (let k in this.fragments) {
- // this.fragments[k].onFirstStart.apply(this.fragments[k], arguments);
- // }
- }
-
- onPause() {
- for (let k in this.fragments) {
- this.fragments[k].onPause.apply(this.fragments[k], arguments);
- }
- }
-
- onDestroy() {
- for (let k in this.fragments) {
- this.fragments[k].onDestroy.apply(this.fragments[k], arguments);
- }
- }
-
- addFragment(viewQuery, fragment) {
- this.fragments[viewQuery] = fragment;
- this.inflatePromise = this.inflatePromise.then(function (siteContent) {
- return fragment.inflatePromise.then(function (fragmentView) {
- siteContent.querySelector(viewQuery).appendChild(fragmentView);
- return siteContent;
- });
- });
- }
-
- /** @protected */
- inflateView(link) {
- let self = this;
- this.inflatePromiseResolver(ViewInflater.inflate(link).then(function (siteContent) {
- self._siteContent = siteContent;
- return siteContent;
- }));
-
- return this.inflatePromise;
- }
-
- findBy(query, all, asPromise) {
- all = Helper.nonNull(all, false);
- asPromise = Helper.nonNull(asPromise, false);
-
- let getVal = function (root) {
- let res = null;
- if (all) {
- res = root.querySelectorAll(query);
- if (root.matches(query)) {
- res.push(root);
- }
- }
- else {
- if (root.matches(query)) {
- res = root;
- }
- else {
- res = root.querySelector(query);
- }
- }
- return res;
- };
-
- if (asPromise) {
- return this.inflatePromise.then(function (rootView) {
- return getVal(rootView);
- });
- }
- return getVal(this._siteContent);
- }
-}
-
-class AbstractSite extends Context {
- constructor(siteManager, view, deepLink) {
- super(view);
-
- this.isVisible = false;
- this.siteManager = siteManager;
- this.isFinishing = false;
- this.actionMenu = null;
- this.url = "";
- this.deepLink = deepLink;
- this.startArgs = {};
- this.title = siteManager.getDefaultTitle();
- }
-
- setTitle(titleElement, title) {
- if (typeof titleElement === "string") {
- title = titleElement;
- titleElement = document.createTextNode(titleElement);
- }
- this.title = {
- element: titleElement
- };
- this.title["title"] = Helper.nonNull(title, this.title["title"]);
-
- if (this.isVisible) {
- this.siteManager.updateTitle();
- }
- }
-
- startStartsite() {
- return this.startSite(this.siteManager.getStartSiteName());
- }
-
- inflateView(link) {
- let self = this;
- return super.inflateView(link).then(function (res) {
- let promises = [];
- for (let i = 0, n = self.fragments.length; i < n; i++) {
- promises.push(self.fragments[i].inflatePromise);
- }
- return Promise.all(promises).then(function () {
- return res;
- });
- });
- }
-
- onConstruct(args) {
- this.startArgs = args;
- if (Helper.isNotNull(this.deepLink)) {
- this.setUrlFromParams(args);
- }
- return super.onConstruct(args);
- }
-
- onStart(args) {
- this.isVisible = true;
- let res = super.onStart(args);
- this.actionMenu.redraw();
- return res;
- }
-
- onPause(args) {
- super.onPause(args);
- this.isVisible = false;
- }
-
- finish(result) {
- if (!this.isFinishing) {
- this.isFinishing = true;
- this.siteManager.endSite(this, result);
- }
- }
-
- startSite(siteName, args) {
- return this.siteManager.startSite(siteName, args);
- }
-
- toForeground() {
- this.siteManager.toForeground(this);
- }
-
- finishAndStartNext(siteName, startParams, finishResult) {
- this.startSite(siteName, startParams);
- this.finish(finishResult);
- }
-
- createActionBarMenu(menu) {
- let defaultActions = this.siteManager.getDefaultActions();
- for (let i = 0, n = defaultActions.length; i < n; i++) {
- menu.addAction(defaultActions[i].copy());
- }
- return menu;
- }
-
- setUrl(url) {
- this.url = url;
- this.siteManager.updateUrl(this);
- }
-
- setUrlFromParams(params) {
- this.setUrl(this.deepLink + Helper.buildQuery(params));
- }
-
- updateUrlParams(params) {
- this.startArgs = Object.assign(this.startArgs, params);
- this.setUrlFromParams(this.startArgs);
- }
-
- getUrl() {
- return this.url;
- }
-
- getFullUrl() {
- return Helper.basePath(this.url);
- }
-
- onBackPressed() {
- }
-
- addListener(event, selector, listenerFunction) {
- this.siteManager.addListener(this, event, selector, listenerFunction);
- }
-
- addKeyListener(keycode, listenerFunction)
- {
- this.siteManager.addKeyListener(this, keycode, listenerFunction);
- }
-
- addKeyAndEventListener(keycode, event, selector, listenerFunction) {
- this.siteManager.addKeyAndEventListener(this, keycode, event, selector, listenerFunction);
- }
-}
-
-class SiteContainer {
- constructor(site, finishResolver) {
- this._site = site;
- this._siteContent = null;
- this._pauseParameters = {};
- this._startParameters = {};
- this._finishResolver = finishResolver;
- }
- getSite() {
- return this._site;
- }
-
- setSite(site) {
- if (site instanceof AbstractSite) {
- this._site = site;
- }
- }
-
- getSiteContent() {
- return this._siteContent;
- }
-
- setSiteContent(value) {
- this._siteContent = value;
- }
-
- getPauseParameters() {
- return this._pauseParameters;
- }
-
- setPauseParameters(value) {
- this._pauseParameters = value;
- }
-
- getStartParameters() {
- return this._startParameters;
- }
-
- setStartParameters(value) {
- this._startParameters = value;
- }
-
- getFinishResolver() {
- return this._finishResolver;
- }
-
- setFinishResolver(value) {
- this._finishResolver = value;
- }
-}
-
-class SiteManager {
- constructor(siteDivId, actionBarMenuSelector, app) {
- this.siteDiv = document.getElementById(siteDivId);
- this.siteContainerStack = [];
- this.currentSiteContainerToShow = null;
- this.actionBarMenuSelector = Helper.nonNull(actionBarMenuSelector, '.action-bar');
-
- this.siteStartingPromise = Promise.resolve();
- this.defaultActions = [];
- this.startSiteName = null;
- this.app = app;
-
- this.titleElement = document.querySelector(".top-bar-title");
-
- const defaultTitleElem = document.createElement("span");
- while (this.titleElement.childNodes.length > 0) {
- const child = this.titleElement.firstChild;
- child.remove();
- defaultTitleElem.appendChild(child);
- }
-
- this.defaultTitle = {
- element: defaultTitleElem,
- title: document.title
- };
-
- let siteManager = this;
- window.onpopstate = function (e) {
- if (siteManager.siteContainerStack.length >= 1) {
- let site = siteManager.siteContainerStack[siteManager.siteContainerStack.length - 1].getSite();
- if (site.onBackPressed() !== false) {
- siteManager.endSite(site);
- }
- }
- };
- }
-
- getDefaultTitle() {
- return this.defaultTitle;
- }
-
- setStartSiteName(startSiteName) {
- this.startSiteName = startSiteName;
- }
-
- getStartSiteName() {
- return this.startSiteName;
- }
-
- addDefaultAction(action) {
- this.defaultActions.push(action);
- }
-
- getDefaultActions() {
- return this.defaultActions;
- }
-
- getCurrentSite(){
- if (Helper.isNotNull(this.currentSiteContainerToShow)){
- return this.currentSiteContainerToShow.getSite();
- }
- return null;
- }
-
- async findSite(filter){
- for (let i = this.siteContainerStack.length-1; i >= 0; i--) {
- if (await filter(this.siteContainerStack[i].getSite())){
- return this.siteContainerStack[i].getSite();
- }
- }
- return null;
- }
-
- async startSite(siteConstructor, paramsPromise) {
- if (!(siteConstructor.prototype instanceof AbstractSite)) {
- throw {
- "error": "wrong class given! Expected AbstractSite, given " + siteConstructor.name
- };
- }
-
- let site = new siteConstructor(this);
- let resolver = {};
- let finishPromise = new Promise(function (resolve, reject) {
- resolver.resolve = resolve;
- resolver.reject = reject;
- });
- let siteContainer = new SiteContainer(site, resolver);
- this.siteDiv.removeAllChildren().appendChild(Helper.createLoadingSymbol());
-
- this.siteStartingPromise = Promise.resolve(paramsPromise).then(async (params) => {
- siteContainer.setStartParameters(params);
- await Promise.all([site.onConstruct(params), site.inflatePromise]);
-
- site.actionMenu = site.createActionBarMenu(this.buildActionBarMenu());
- return this.show(siteContainer);
- }).catch((e) => {
- console.error("site start error for site ", siteConstructor.name, e);
- });
-
- return finishPromise;
- }
-
- endSite(site, result) {
- let manager = this;
- this.siteStartingPromise.then(function () {
- let index = manager.findContainerIndexBySite(site);
- let container = manager.siteContainerStack.splice(index, 1);
- container = container[0];
-
- let showSiteContainer = null;
- if (container === manager.currentSiteContainerToShow) {
- manager.currentSiteContainerToShow.getSite().onPause();
- manager.currentSiteContainerToShow = null;
- let newSiteContainerIndex = manager.siteContainerStack.length - 1;
- if (newSiteContainerIndex < 0) {
-
- manager.showAppEndedMessage();
- app.endApp();
- // manager.startSite(manager.startSiteName);
- return;
- }
- manager.siteDiv.removeAllChildren().appendChild(Helper.createLoadingSymbol());
- showSiteContainer = manager.siteContainerStack[newSiteContainerIndex];
- }
- container.getSite().onDestroy();
-
- Promise.resolve(result).then(function (resValue) {
- container.getFinishResolver().resolve(resValue);
- if (Helper.isNotNull(showSiteContainer)) {
- manager.show(showSiteContainer);
- }
- });
- });
- }
-
- addListener(site, event, _selector, listener) {
- this.siteDiv.addEventListener(event, function (_event) {
- let _element = _event.target;
- if (site.isVisible && _element.matches(_selector)) {
- listener(_element, _event);
- }
- });
- }
-
- addKeyAndEventListener(site, keycode, event, selector, listener) {
- this.addListener(site, event, selector, listener);
- this.addKeyListener(site, keycode, listener);
- }
-
- addKeyListener(site, keycode, listener) {
- window.addEventListener("keydown", function (e) {
- if (site.isVisible && e.which === keycode) {
- listener(this, e);
- }
- });
- }
-
- toForeground(site) {
- let index = this.findContainerIndexBySite(site);
- let container = this.siteContainerStack.splice(index, 1);
- container = container[0];
-
- this.show(container);
- }
-
- refreshCurrentSite() {
- return this.show(this.currentSiteContainerToShow);
- }
-
- /** @private */
- show(siteContainer) {
- if (Helper.isNotNull(this.currentSiteContainerToShow)) {
- this.currentSiteContainerToShow.setPauseParameters(this.currentSiteContainerToShow.getSite().onPause());
- this.currentSiteContainerToShow.setSiteContent(this.siteDiv.innerHTML);
- }
- this.siteDiv.removeAllChildren().appendChild(Helper.createLoadingSymbol());
-
- let siteManager = this;
- this.currentSiteContainerToShow = siteContainer;
- if (-1 === this.siteContainerStack.indexOf(siteContainer)) {
- this.siteContainerStack.push(siteContainer);
- }
-
- return siteContainer.getSite().inflatePromise.then(function (data) {
- siteContainer.getSite().actionMenu.redraw();
- siteManager.siteDiv.removeAllChildren().appendChild(data);
- siteManager.updateTitle();
- Translator.getInstance().updateTranslations();
- return data;
- }).then(function (data) {
- siteContainer.getSite().onStart(siteContainer.getPauseParameters());
- history.pushState({
- 'siteName': siteContainer.getSite().constructor.name,
- 'siteData': data.outerHTML,
- 'stackPosition': siteManager.siteContainerStack.length - 1
- }, siteContainer.getSite().constructor.name, siteContainer.getSite().getFullUrl());
- });
- }
-
- updateUrl(site) {
- if (Helper.isNotNull(this.currentSiteContainerToShow) && this.currentSiteContainerToShow.getSite() === site) {
- let self = this;
- history.replaceState({
- 'siteName': site.constructor.name,
- 'siteData': site._siteContent.outerHTML,
- 'stackPosition': self.siteContainerStack.length - 1
- }, site.constructor.name, site.getFullUrl());
- }
- }
-
- getCurrentSite() {
- if (this.currentSiteContainerToShow != null)
- return this.currentSiteContainerToShow.getSite();
- }
-
- redrawCurrentActionBar() {
- if (this.currentSiteContainerToShow != null)
- this.currentSiteContainerToShow.getSite().actionMenu.redraw();
- }
-
- updateTitle() {
- let title = this.getCurrentSite().title;
- this.titleElement.removeAllChildren().appendChild(title.element);
- document.title = Helper.nonNull(title.title, this.defaultTitle.title);
- }
-
- /** @private */
- findContainerIndexBySite(site) {
- for (let i = 0, n = this.siteContainerStack.length; i < n; i++) {
- if (this.siteContainerStack[i].getSite() === site) {
- return i;
- }
- }
- return -1;
- }
-
- /** @private */
- findContainerBySite(site) {
- let index = this.findContainerIndexBySite(site);
- if (index === -1) {
- return null;
- }
- return this.siteContainerStack[index];
- }
-
- /** @private */
- showAppEndedMessage() {
- this.siteDiv.removeAllChildren().appendChild(Translator.makePersistentTranslation("The app has ended! Please close the window."));
- }
-
- /** @private */
- buildActionBarMenu() {
- return new ActionBarMenu(this.actionBarMenuSelector);
- }
-}
-
-class PauseSite extends AbstractSite {
- onConstruct(args) {
- let pausedElement = null;
-
- if (Helper.isSet(args, "url")) {
- pausedElement = args["url"];
- }
- else {
- pausedElement = document.createElement("div");
- pausedElement.innerHTML = "Paused...";
- }
-
- this.inflateView(pausedElement);
- }
-
- onPause() {
- for (let i = 0; i < PauseSite.onStartListeners.length; i++) {
- if (typeof PauseSite.onStartListeners[i] === "function") {
- PauseSite.onStartListeners[i]();
- }
- }
- return super.onPause();
- }
-
- onStart() {
- for (let i = 0; i < PauseSite.onPauseListeners.length; i++) {
- if (typeof PauseSite.onPauseListeners[i] === "function") {
- PauseSite.onPauseListeners[i]();
- }
- }
- return super.onPause();
- }
-}
-
-PauseSite.onPauseListeners = [];
-PauseSite.onStartListeners = [];
-
-class App {
- constructor() {
- this._siteManager = null;
- this._actionBarMenuSelector = '.action-bar';
- this._basePath = SystemSettings.getBasePath();
- this._siteContentId = 'site-content';
- this._deepLinks = new Map();
- this._defaultActions = [];
- this._addThemeAction = false;
- this._showCookieCompliance = true;
- this._startSite = null;
- this._appEndListener = () => {
- return this.startSite(this._startSite);
- };
- }
-
- getSiteManager()
- {
- return this._siteManager;
- }
-
- addDefaultAction(action) {
- this._defaultActions.push(action);
- }
-
- setAddThemeAction(addThemeAction) {
- this._addThemeAction = addThemeAction;
- }
-
- getSiteContentId() {
- return this._siteContentId;
- }
-
- setSiteContentId(value) {
- this._siteContentId = value;
- }
-
- getActionBarMenuSelector() {
- return this._actionBarMenuSelector;
- }
-
- setActionBarMenuSelector(value) {
- this._actionBarMenuSelector = value;
- }
-
- getBasePath() {
- return this._basePath;
- }
-
- setBasePath(value) {
- this._basePath = value;
- }
-
- addDeepLink(alias, site) {
- this._deepLinks.set(alias.toLowerCase(), site);
- }
-
- setShowCookieCompliance(cookieCompliance)
- {
- this._showCookieCompliance = cookieCompliance;
- }
-
- refreshCurrentSite()
- {
- this._siteManager.refreshCurrentSite();
- }
-
- pause(elementToShow){
- this.startSite(PauseSite, {"url": elementToShow});
- }
-
- resume(){
- const currentSite = this._siteManager.getCurrentSite();
- if (currentSite instanceof PauseSite)
- {
- currentSite.finish();
- }
- }
-
- _resolveDeepLink(deepLink) {
- deepLink = deepLink.toLowerCase();
- if (this._deepLinks.has(deepLink)) {
- return this._deepLinks.get(deepLink);
- }
- return null;
- }
-
- _getDeepLink() {
- let deepLink = "";
- if (window.location.pathname.search(this._basePath) === 0) {
- deepLink = window.location.pathname.substr(this._basePath.length).trim();
- }
- if (deepLink.charAt(0) === '/') {
- deepLink = deepLink.substr(1).trim();
- }
- if (deepLink.charAt(deepLink.length - 1) === '/') {
- deepLink = deepLink.substr(0, deepLink.length - 2).trim();
- }
- if (deepLink.length === 0 && window.location.hash) {
- deepLink = window.location.hash.substr(1).trim();
- }
-
- return this._resolveDeepLink(deepLink);
- }
-
- _addDeepLinksListener() {
- let app = this;
- let elements = document.getElementsByClassName("deep-link");
- for (let i = 0, n = elements.length; i < n; i++) {
- elements[i].addEventListener("click", function (e) {
- e.preventDefault();
- app._siteManager.startSite(Helper.nonNull(app._resolveDeepLink(this.dataset["siteName"]), app._startSite), App._extractParams(this.dataset["siteArgs"]));
- return true;
- });
- }
- }
-
- removeDefaultAction(action)
- {
- let index = this._defaultActions.indexOf(action);
- if (index >= 0)
- {
- this._defaultActions[index].remove(true);
- this._defaultActions.splice(index, 1);
- }
- }
-
- startSite(site, parameter)
- {
- return this._siteManager.startSite(site, parameter);
- }
-
- start(fallbackStartSite) {
- SystemSettings.setBasePath(this._basePath);
- let startSite = Helper.nonNull(this._getDeepLink(), fallbackStartSite);
- let startParams = App._getStartParams();
- this._startSite = fallbackStartSite;
-
- Translator.init();
- ThemeManager$1.init();
- if (this._addThemeAction) {
- this.addDefaultAction(ThemeManager$1.generateChangeThemeMenuAction());
- }
- this._siteManager = new SiteManager(this._siteContentId, this._actionBarMenuSelector);
- this._siteManager.defaultActions = this._defaultActions;
- this._siteManager.setStartSiteName(fallbackStartSite);
- this._siteManager.startSite(startSite, startParams);
- this._addDeepLinksListener();
-
- if (this._showCookieCompliance)
- {
- this._cookieClosePromise = CookieCompliance.showIfNeeded('cookie-compliance');
- }
- }
-
- getCurrentSite(){
- return this._siteManager.getCurrentSite();
- }
-
- async endApp(){
- if (typeof this._appEndListener === "function"){
- this._appEndListener();
- }
- }
-
- setAppEndListener(appEndListener){
- this._appEndListener = appEndListener;
- }
-
- async findSite(filter){
- return this._siteManager.findSite(filter);
- }
-
- static _extractParams(paramString) {
- if (Helper.isNull(paramString)) {
- return null;
- }
- let result = {}, tmp = [];
- let items = paramString.split("&");
- for (let index = 0; index < items.length; index++) {
- tmp = items[index].split("=");
- if (tmp[0].trim().length > 0) {
- result[tmp[0]] = decodeURIComponent(tmp[1]);
- }
- }
- return result;
- }
-
- static _getStartParams() {
- return App._extractParams(window.location.search.substr(1));
- }
-}
-
-class Dialog {
- constructor(content, title) {
- this.resolver = null;
- this.content = null;
- this.backgroundElement = null;
- this.cancelable = true;
- this.title = Helper.nonNull(title, "");
- this.translatable = true;
- this.additionalClasses = "";
- this.buttons = [];
- this.result = null;
-
- if (Helper.isNotNull(content)) {
- this.setContent(content);
- }
- }
-
- setTitle(title) {
- this.title = title;
- return this;
- }
-
- setTranslatable(translatable) {
- this.translatable = translatable;
- }
-
- setAdditionalClasses(classes) {
- this.additionalClasses = classes;
- }
-
- getTitle() {
- return this.title;
- }
-
- setCancelable(cancelable) {
- this.cancelable = (cancelable === true);
- return this;
- }
-
- async setContent(content) {
- this.contentPromise = Promise.resolve(content);
- this.content = await this.contentPromise;
- return this;
- }
-
- addButton(elementOrText, listenerOrResult, shouldClose) {
- shouldClose = Helper.nonNull(shouldClose, true);
-
- let button = null;
- if (typeof elementOrText === "string") {
- button = document.createElement("button");
- button.classList.add("button");
- button.classList.add("right");
- button.appendChild(Translator.makePersistentTranslation(elementOrText));
- }
- else {
- button = elementOrText;
- }
-
- let self = this;
- if (typeof listenerOrResult !== "function") {
- let result = listenerOrResult;
- listenerOrResult = function () {
- self.result = result;
- };
- }
-
- let callback = null;
- if (shouldClose) {
- callback = function (e) {
- if (Helper.isNotNull(listenerOrResult)) {
- listenerOrResult(e);
- }
- self.close();
- };
- }
- else {
- callback = listenerOrResult;
- }
-
- if (Helper.isNotNull(callback)) {
- button.addEventListener("click", callback);
- }
- this.buttons.push(button);
- }
-
- async show() {
-
- let titleElement = document.createElement("span");
- titleElement.classList.add("title");
- if (this.translatable && this.title !== "") {
- titleElement.appendChild(Translator.makePersistentTranslation(this.title));
- }
- else {
- titleElement.innerHTML = this.title;
- }
-
- let titleBar = document.createElement("div");
- titleBar.appendChild(titleElement);
-
- let contentContainer = document.createElement("div");
- contentContainer.classList.add("content-container");
-
- let modalDialog = document.createElement("div");
- modalDialog.className = this.additionalClasses;
- modalDialog.classList.add("modal");
- modalDialog.appendChild(titleBar);
- modalDialog.appendChild(contentContainer);
-
- let buttonBar = document.createElement("div");
- buttonBar.classList.add("modal-button-container");
-
- for (let i = 0, n = this.buttons.length; i < n; i++) {
- buttonBar.appendChild(this.buttons[i]);
- }
-
- await this.contentPromise;
- if (!(this.content instanceof Node)) {
- this.content = (this.translatable) ? Translator.makePersistentTranslation(this.content) : document.createTextNode(this.content);
- }
- contentContainer.appendChild(this.content);
-
- this.backgroundElement = document.createElement("div");
- this.backgroundElement.classList.add("background");
- this.backgroundElement.appendChild(modalDialog);
-
- this.backgroundElement.querySelector(".modal").appendChild(buttonBar);
- this.backgroundElement.style.display = "block";
-
- let self = this;
- if (this.cancelable) {
- let closeButton = document.createElement("span");
- closeButton.classList.add("close");
- closeButton.innerHTML = "×";
-
- titleBar.appendChild(closeButton);
- closeButton.addEventListener("click", function () {
- self.close();
- });
- window.addEventListener("click", function (e) {
- if (e.target === self.backgroundElement) {
- self.close();
- }
- });
- }
-
- document.body.appendChild(this.backgroundElement);
- Translator.getInstance().updateTranslations();
-
- return new Promise(function (resolve) {
- self.resolver = resolve;
- });
- }
-
- close() {
- if (Helper.isNotNull(this.backgroundElement)) {
- this.backgroundElement.style.display = "none";
- this.backgroundElement.remove();
- this.backgroundElement = null;
- }
- if (Helper.isNotNull(this.resolver)) {
- this.resolver(this.result);
- }
- }
-
- addDefaultButton(){
- this.addButton("confirm-button");
- }
-}
-
-class ConfirmDialog extends Dialog {
- constructor(content, title) {
- super(content, title);
- }
-
- async show() {
- this.addButton("confirm-button", true);
- this.addButton("cancel-button", false);
-
- return super.show();
- }
-
-
- close() {
- if (Helper.isNull(this.result))
- {
- this.result = false;
- }
- return super.close();
- }
-}
-
-class FlashMessenger {
- static deleteMessage(_idNumber, _delayInMilliSeconds) {
- _delayInMilliSeconds = Helper.nonNull(_delayInMilliSeconds, 0);
- setTimeout(function () {
- let elem = document.getElementById("flashMessage" + _idNumber);
- elem.fadeOut(.2).then(function () {
- elem.remove();
- });
- }, _delayInMilliSeconds);
- }
-
- static addMessage(messageType, messageText, timeToShow, translate){
-
- let translationArgs = null;
- if (Helper.isNull(messageText) || typeof messageText === "object")
- {
- translationArgs = messageText;
- messageText = messageType;
- messageType = FlashMessenger.MESSAGE_TYPE_SUCCESS;
- translate = true;
- }
- translate = Helper.nonNull(translate, false);
-
- let id = FlashMessenger.messageCount;
-
- let wrapper = document.createElement("div");
-
- let _flashMessage = document.createElement("div");
- _flashMessage.className = "flashMessage " + messageType;
- _flashMessage.id = "flashMessage" + id;
- _flashMessage.style.opacity = '0';
- _flashMessage.addEventListener("click", function () {
- FlashMessenger.deleteMessage(id);
- });
- _flashMessage.appendChild((translate) ? Translator.makePersistentTranslation(messageText, translationArgs, "span") : document.createTextNode(messageText));
-
- wrapper.appendChild(_flashMessage);
- document.getElementById("flashMessageContainer").appendChild(wrapper);
- _flashMessage.fadeIn();
- timeToShow = Helper.nonNull(timeToShow, FlashMessenger.defaultTimeToShow);
- if (timeToShow > 0) {
- FlashMessenger.deleteMessage(FlashMessenger.messageCount, timeToShow);
- }
- FlashMessenger.messageCount++;
- }
-}
-
-FlashMessenger.messageCount = 0;
-FlashMessenger.defaultTimeToShow = 3500;
-FlashMessenger.LENGTH_SHORT= 1000;
-
-FlashMessenger.MESSAGE_TYPE_SUCCESS = 'success';
-FlashMessenger.MESSAGE_TYPE_ERROR = 'error';
-FlashMessenger.MESSAGE_TYPE_DEFAULT = 'default';
-FlashMessenger.MESSAGE_TYPE_INFO = 'info';
-FlashMessenger.MESSAGE_TYPE_WARNING = 'warning';
-
-class MyDb {
- constructor(dbName, version) {
- this.queryPromise = new Promise(async (resolve, reject) => {
- let indexedDB = null;
- if (window["sqlite"]){
- indexedDB = new Promise(sqliteResolve => {
- function testSqlLiteResolve(){
- if (window["sqliteIndexedDB"]){
- sqliteResolve(window["sqliteIndexedDB"]);
- }
- else {
- setTimeout(testSqlLiteResolve, 200);
- }
- }
- testSqlLiteResolve();
- });
- }
- else {
- indexedDB = Promise.resolve(window["myIndexedDB"] || window["indexedDB"] || window["mozIndexedDB"]|| window["webkitIndexedDB"]|| window["msIndexedDB"] || window["shimIndexedDB"]);
- }
- this.indexeddb = (await indexedDB);
- this._conn = this.indexeddb.open(dbName, version);
-
- let myDB = this;
- this._conn.onupgradeneeded = function (upgradeEvent) {
- try {
- myDB.upgrade(myDB._conn.result, upgradeEvent.oldVersion, upgradeEvent.newVersion, upgradeEvent);
- }
- catch(e){
- reject(e);
- throw e;
- }
- };
- myDB._conn.onsuccess = function (e) {
- myDB._db = myDB._conn.result;
- resolve(e);
- };
- });
- }
-
- openTransaction(name, transactionMode, callback) {
- let myDb = this;
- if (typeof transactionMode === 'function' && Helper.isNull(callback)) {
- callback = transactionMode;
- transactionMode = "read";
- }
-
- return this.queryPromise.then(function () {
- let res = null;
- try {
- res = myDb._conn.result.transaction(name, transactionMode);
- }
- catch (e) {
- console.warn(e);
- res = myDb._conn.result.transaction(name);
- }
- callback(res);
- });
- }
-
- openStore(name, transactionMode, callback) {
- if (typeof transactionMode === 'function' && Helper.isNull(callback)) {
- callback = transactionMode;
- transactionMode = "readonly";
- }
- return this.openTransaction(name, transactionMode, function (t) {
- callback(t.objectStore(name));
- });
- }
-
- saveObj(obj, objectStore) {
- let self = this;
- return new Promise(function (resolve) {
- self.openStore(objectStore, "readwrite", function (store) {
- let request = store.put(obj);
- request.onsuccess = resolve;
- request.onerror = function (e) {
- throw {
- "type": "indexed-db-error",
- "event": e
- }
- };
- });
- });
- }
-
- saveMany(manyObj, objectStore) {
- let self = this;
- return new Promise(function (resolve) {
- self.openStore(objectStore, "readwrite", function (store) {
- let promises = [];
- for (let i = 0, n = manyObj.length; i < n; i++) {
- promises.push(new Promise(function (resolveInner) {
- let request = store.put(manyObj[i]);
- request.onsuccess = resolveInner;
- request.onerror = function (e) {
- throw {
- "type": "indexed-db-error",
- "event": e
- }
- };
- }));
- }
- resolve(Promise.all(promises));
- });
- });
- }
-
- load(key, objectStore) {
- let self = this;
- return new Promise((resolve, reject) => {
- self.openStore(objectStore, function (store) {
- let request = store.get(key);
- request.onsuccess = function (e) {
- resolve(e.currentTarget.result);
- };
- request.onerror = function (e) {
- console.warn(e);
- throw {
- "type": "indexed-db-load-error",
- "event": e
- }
- };
- }).catch(e => {
- console.warn(e);
- reject(e);
- });
- });
- }
-
- loadAll(objectStore, query, count) {
- let self = this;
- return new Promise((resolve, reject) => {
- self.openStore(objectStore, function (store) {
- let request = store.getAll(query, count);
- request.onsuccess = function (e) {
- resolve(e.currentTarget.result);
- };
- request.onerror = function (e) {
- console.warn(e);
- throw {
- "type": "indexed-db-load-error",
- "event": e
- }
- };
- }).catch(e => {
- console.warn(e);
- reject(e);
- });
- });
- }
-
- loadMany(index, value, objectStore, limit, direction) {
- let self = this;
- return new Promise(function (resolve) {
- self.openStore(objectStore, function (store) {
- let indexRequest = store.index(index);
- indexRequest.onerror = function (e) {
- throw {
- "type": "indexed-db-index-error",
- "event": e
- }
- };
- let request = indexRequest.openCursor(value, direction);
- request.onerror = function (e) {
- throw {
- "type": "indexed-db-index-error",
- "event": e
- }
- };
- let objects = [];
- let numberResults = 0;
- request.onsuccess = function (e) {
- let cursor = e.target.result;
- if (cursor) {
- objects.push(cursor.value);
- numberResults++;
- if (Helper.isNull(limit) || numberResults < limit) {
- cursor.continue();
- return;
- }
- }
- resolve(objects);
- };
- });
- });
- }
-
- remove(id, objectStore) {
- let self = this;
- return new Promise(function (resolve) {
- self.openStore(objectStore, "readwrite", function (store) {
- let deleteRequest = store.delete(id);
- deleteRequest.onerror = function (e) {
- throw {
- "type": "indexed-db-delete-error",
- "event": e
- }
- };
- deleteRequest.onsuccess = function (e) {
- resolve();
- };
- });
- });
- }
-
- removeMany(ids, objectStore) {
- let self = this;
- return new Promise(function (resolve) {
- self.openStore(objectStore, "readwrite", function (store) {
- let promises = [];
- for (let i = 0, n = ids.length; i < n; i++) {
- let deleteRequest = store.delete(ids[i]);
- deleteRequest.onerror = function (e) {
- throw {
- "type": "indexed-db-delete-error",
- "event": e
- }
- };
- promises.push(new Promise(function (resolve) {
- deleteRequest.onsuccess = function () {
- resolve();
- };
- }));
- }
- resolve(Promise.all(promises));
- });
- });
- }
-
- removeWithIndex(index, value, objectStore) {
- let self = this;
- return new Promise(function (resolve) {
- self.openStore(objectStore, "readwrite", function (store) {
- let indexRequest = store.index(index);
- indexRequest.onerror = function (e) {
- throw {
- "type": "indexed-db-index-error",
- "event": e
- }
- };
- let request = indexRequest.openCursor(value);
- request.onerror = function (e) {
- throw {
- "type": "indexed-db-index-error",
- "event": e
- }
- };
- request.onsuccess = function (e) {
- let cursor = e.target.result;
- if (cursor) {
- cursor.delete();
- cursor.continue();
- }
- else {
- resolve();
- }
- };
- });
- });
- }
-
- removeAll(objectStore) {
- return new Promise((resolve) => {
- this.openStore(objectStore, "readwrite", (store) => {
- let req = store.clear();
- req.onerror = (e) => {
- throw {
- "type": "indexed-db-index-error",
- "event": e
- }
- };
- req.onsuccess = resolve;
- });
- })
- }
-
- upgrade(db) {
- };
-}
-
-class ScriptLoader {
- static loadScript(scriptSrc) {
- if (Helper.isNotNull(ScriptLoader.scriptPromises[scriptSrc])) {
- return ScriptLoader.scriptPromises[scriptSrc];
- }
- else {
- let scriptPromise = new Promise(function (resolve) {
- let script = document.createElement("script");
- script.src = Helper.basePath(scriptSrc);
- script.onload = resolve;
-
- document.body.appendChild(script);
- });
- ScriptLoader.scriptPromises[scriptSrc] = scriptPromise;
- return scriptPromise;
- }
- }
- static loadCss(cssFile, media){
- if (Helper.isNotNull(ScriptLoader.cssPromises[cssFile])) {
- return ScriptLoader.cssPromises[cssFile];
- }
- else {
- media = Helper.nonNull(media, "all");
- let cssPromise = new Promise(function (resolve) {
- let link = document.createElement("link");
- link.rel='stylesheet';
- link.type="text/css";
- link.href = Helper.basePath(cssFile);
- link.media = media;
- link.onload = resolve;
-
- document.head.appendChild(link);
- });
- ScriptLoader.cssPromises[cssFile] = cssPromise;
- return cssPromise;
- }
- }
-}
-
-ScriptLoader.scriptPromises = {};
-ScriptLoader.cssPromises = {};
-
-class ShareButton {
- constructor(deviceType, icon, callback, shouldLoadImg)
- {
- this._deviceType = deviceType;
- this._icon = icon;
- this._callback = callback;
-
- if (Helper.nonNull(shouldLoadImg, false)){
- this._icon = ViewInflater.inflate(this._icon);
- }
- }
-
- shouldShowFor(deviceType)
- {
- return (deviceType === (deviceType & this._deviceType))
- }
-
- getIcon()
- {
- return this._icon;
- }
-
- getCallback()
- {
- return this._callback;
- }
-}
-ShareButton.TYPE_DESKTOP = 1;
-ShareButton.TYPE_MOBILE_APPLE = 2;
-ShareButton.TYPE_MOBILE_LEFTOVER = 4;
-ShareButton.TYPE_MOBILE = ShareButton.TYPE_MOBILE_APPLE+ShareButton.TYPE_MOBILE_LEFTOVER;
-ShareButton.TYPE_ALL = ShareButton.TYPE_DESKTOP+ShareButton.TYPE_MOBILE;
-
-AndroidBridge.addDefinition(() => {
- window["ShareButton"] = ShareButton;
- window["ShareButton"]["TYPE_ALL"] = ShareButton.TYPE_ALL;
-
-});
-
-class MultipleShareButton extends ShareButton{
- constructor(deviceType, icon, callbacks, shouldLoadImg)
- {
- if (Array.isArray(deviceType) && deviceType[0] instanceof ShareButton){
- let btn = deviceType[0];
- callbacks = deviceType;
- deviceType = btn._deviceType;
- icon = btn._icon;
- shouldLoadImg = Helper.nonNull(shouldLoadImg, icon);
- }
-
- super(deviceType, icon, function (link, element, event) {
- if (!Array.isArray(callbacks)){
- callbacks = [callbacks];
- }
- for (let i = 0; i < callbacks.length; i++) {
- if (callbacks[i] instanceof ShareButton){
- callbacks[i].getCallback()(link, element, event);
- }
- else {
- console.log(callbacks, i);
- callbacks[i](link, element, event);
- }
- }
- }, shouldLoadImg);
- }
-}
-
-class ShareManager {
- static init() {
- ShareManager.shareButtons = [];
- }
-
- static addShareButton(shareButton) {
- ShareManager.shareButtons.push(shareButton);
- }
-
- static generateDefaultShareElement(shareUrl) {
- return ShareManager.generateShareElement(shareUrl, ShareManager.getDefaultGenerateCallback());
- }
-
- static generateDefaultShareElementForButtons(shareUrl, buttons) {
- return ShareManager.generateShareElementForButtons(shareUrl, buttons, ShareManager.getDefaultGenerateCallback());
- }
-
- static generateShareElement(shareUrl, generateCallback) {
- return ShareManager.generateShareElementForButtons(shareUrl, ShareManager.shareButtons, generateCallback);
- }
-
- static generateShareElementForButtons(shareUrl, buttons, generateCallback) {
- let shareButtonElement = document.createElement("div");
- let currentDeviceType = ShareManager.getCurrentDeviceType();
- for (let i = 0, n = buttons.length; i < n; i++) {
- if (buttons[i].shouldShowFor(currentDeviceType)) {
- let elem = generateCallback(buttons[i], shareUrl);
- elem.onclick = function (event) {
- buttons[i].getCallback()(shareUrl, this, event);
- };
- shareButtonElement.appendChild(elem);
- }
- }
- return shareButtonElement;
- }
-
- static getCurrentDeviceType() {
- if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
- return ShareButton.TYPE_MOBILE_APPLE;
- }
- else if ((navigator.userAgent.match(/Android|BlackBerry|Opera Mini|IEMobile/i) !== null || (typeof window.orientation !== "undefined"))) {
- return ShareButton.TYPE_MOBILE_LEFTOVER;
- }
- else {
- return ShareButton.TYPE_DESKTOP;
- }
- }
-
- static getDefaultGenerateCallback() {
- return function (button) {
- let linkElement = document.createElement("a");
- linkElement.classList.add("share-icon");
- let iconUrl = button.getIcon();
- if (typeof iconUrl === "string") {
- let iconElement = document.createElement("img");
- iconElement.src = Helper.basePath(button.getIcon());
- iconElement.classList.add("share-icon");
- linkElement.appendChild(iconElement);
- }
- else {
- Promise.resolve(iconUrl).then(elem => {
- linkElement.appendChild(elem);
- });
- }
-
- return linkElement;
- }
- }
-}
-
-ShareManager.init();
-
-AndroidBridge.addDefinition("ShareManager.addShareButton", ShareManager.addShareButton);
-
-class SmsShareButton extends ShareButton
-{
- constructor(icon, shouldLoadImg) {
- super(ShareButton.TYPE_MOBILE, icon, function (link) {
- let linkToOpen = "";
- if (ShareManager.getCurrentDeviceType() === ShareButton.TYPE_MOBILE_APPLE) {
- linkToOpen = "sms:&body="+encodeURIComponent(link);
- }
- else {
- linkToOpen = "sms:?&body=" + encodeURIComponent(link);
- }
- window.open(linkToOpen, '_blank', "noopener");
- }, shouldLoadImg);
- }
-}
-
-class TelegramShareButton extends ShareButton {
- constructor(icon, shouldLoadImg) {
- super(ShareButton.TYPE_ALL, icon, function (link) {
- let linkToOpen = "https://t.me/share/url?url="+encodeURIComponent(link);
- window.open(linkToOpen, '_blank', "noopener");
- }, shouldLoadImg);
- }
-}
-
-class WhatsappShareButton extends ShareButton {
- constructor(icon, shouldLoadImg) {
- super(ShareButton.TYPE_ALL, icon, function (link) {
- let linkToOpen = "";
- if (ShareManager.getCurrentDeviceType() === ShareButton.TYPE_DESKTOP) {
- linkToOpen = "https://web.whatsapp.com/send?text="+encodeURIComponent(link);
- }
- else {
- linkToOpen = "whatsapp://send?text=" + encodeURIComponent(link);
- }
- window.open(linkToOpen, '_blank', "noopener");
- }, shouldLoadImg);
- }
-}
-
-class Fragment extends Context
-{
- constructor(site, view)
- {
- super(view);
- this.site = site;
- this.active = true;
- }
-
- getSite()
- {
- return this.site;
- }
-
- isActive()
- {
- return this.active;
- }
-}
-
-class Theme
-{
- constructor(name, className, icon)
- {
- this._name = name;
- this._className = className;
- this._icon = icon;
- }
-}
-
-function applyPolyfills() {
- if (!String.prototype.format) {
- String.prototype["format"] = function (args) {
- return this.replace(/{(\d+)}/g, function (match, number) {
- return args[number] !== undefined
- ? args[number]
- : match
- ;
- });
- };
- }
- Object["assign"] = Helper.nonNull(Object["assign"], function (base, obj) {
- base = Helper.nonNull(base, {});
- if (obj === null || typeof(obj) !== 'object' || 'isActiveClone' in obj)
- return base;
-
- // if (obj instanceof Date) {
- // temp = new obj.constructor(); //or new Date(obj);
- // }
- // else {
- // temp = obj.constructor();
- // }
-
- for (let key in obj) {
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
- obj['isActiveClone'] = null;
- base[key] = obj[key];
- delete obj['isActiveClone'];
- }
- }
-
- return base;
- });
-
- if (typeof window !== 'undefined') {
- if (Helper.isNotNull(window["Node"]) && !window["Node"]["prototype"]["removeAllChildren"]) {
- Node.prototype["removeAllChildren"] = function () {
- while (this.firstChild) {
- this.removeChild(this.firstChild);
- }
- return this;
- };
- }
-
- if (HTMLElement) {
- HTMLElement.prototype["fadeOut"] = Helper.nonNull(HTMLElement.prototype["fadeOut"],
- function (time, effect, delay) {
- time = Helper.nonNull(time, 0.5);
- effect = Helper.nonNull(effect, "ease-in-out");
- delay = Helper.nonNull(delay, 0);
- this.style.transition = "opacity " + time + "s " + effect + " " + delay + "s";
- let elem = this;
- let animPromise = new Promise(function (resolve) {
- let transEndLis = function (e) {
- elem.removeEventListener("transitionend", transEndLis);
- elem.removeEventListener("transitioncancel", transCancelledLis);
- elem.style.opacity = null;
- elem.style.transition = null;
- resolve(true, e);
- };
-
- let transCancelledLis = function (e) {
- elem.removeEventListener("transitionend", transEndLis);
- elem.removeEventListener("transitioncancel", transCancelledLis);
- elem.style.opacity = null;
- elem.style.transition = null;
- resolve(false, e);
- };
- elem.addEventListener("transitionend", transEndLis);
- elem.addEventListener("transitioncancel", transCancelledLis);
- //Fallback
- setTimeout(() => {
- resolve(false);
- }, (time + delay) * 1000);
- });
-
- //Nach Seitenneuzeichnen, damit chrome das immer macht (und FF auch)
- requestAnimationFrame(function () {
- requestAnimationFrame(function () {
- elem.style.opacity = 0;
- });
- });
- return animPromise
- });
-
- HTMLElement.prototype["fadeIn"] = Helper.nonNull(HTMLElement.prototype["fadeIn"], function (time, effect, delay) {
- time = Helper.nonNull(time, 0.5);
- effect = Helper.nonNull(effect, "ease-in-out");
- delay = Helper.nonNull(delay, 0);
- this.style.transition = "opacity " + time + "s " + effect + " " + delay + "s";
-
- let elem = this;
- let animPromise = new Promise(function (resolve) {
- let transEndLis = function (e) {
- elem.removeEventListener("transitionend", transEndLis);
- elem.removeEventListener("transitioncancel", transCancelledLis);
- elem.style.opacity = null;
- elem.style.transition = null;
- resolve(true, e);
- };
-
- let transCancelledLis = function (e) {
- elem.removeEventListener("transitionend", transEndLis);
- elem.removeEventListener("transitioncancel", transCancelledLis);
- elem.style.opacity = null;
- elem.style.transition = null;
- resolve(false, e);
- };
- elem.addEventListener("transitionend", transEndLis);
- elem.addEventListener("transitioncancel", transCancelledLis);
-
- if (getComputedStyle(elem).getPropertyValue("opacity") === "1") {
- resolve(false);
- }
- //Fallback
- setTimeout(() => {
- resolve(false);
- }, (time + delay) * 1000);
-
- //Nach Seitenneuzeichnen, damit chrome das immer macht (und FF auch)
- requestAnimationFrame(function () {
- requestAnimationFrame(function () {
- elem.style.opacity = 1;
- });
- });
- });
- return animPromise;
- });
- }
-
- if (Node) {
- Node.prototype["replaceWith"] = Helper.nonNull(Node.prototype["replaceWith"], function (elem) {
- this.parentElement.replaceChild(elem, this);
- });
- Node.prototype["remove"] = Helper.nonNull(Node.prototype["remove"], function () {
- this.parentElement.removeChild(this);
- });
- }
-
- if (Element) {
- Element.prototype.matches = Helper.nonNull(Element.prototype.matches, Helper.nonNull(Element.prototype["matchesSelector"], Element.prototype["webkitMatchesSelector"]));
-
- window["Element"]["prototype"]["closest"] = Helper.nonNull(window["Element"]["prototype"]["getAll"], function (s) {
- // if (!Element.prototype.matches)
- // Element.prototype.matches = Element.prototype.msMatchesSelector ||
- // Element.prototype.webkitMatchesSelector;
- //
- // if (!Element.prototype.closest)
- // Element.prototype.closest = function(s) {
- let el = this;
- if (!document.documentElement.contains(el)) return null;
- do {
- if (el.matches(s)) return el;
- el = el.parentElement;
- } while (el !== null);
- return null;
- // };
- });
- }
-
- window["IDBObjectStore"]["prototype"]["getAll"] = Helper.nonNull(window["IDBObjectStore"]["prototype"]["getAll"], function () {
- let res = {};
- let items = [];
- this.openCursor().onsuccess = function (e) {
- let cursor = e.target.result;
- if (Helper.isNotNull(cursor)) {
- items.push(cursor.value);
- cursor.continue();
- }
- else if (Helper.isNotNull(res.onsuccess)) {
- res.onsuccess({currentTarget: {result: items}});
- }
- };
- return res;
- });
- }
-
- String.prototype.startsWith = Helper.nonNull(String.prototype.startsWith, function (searchString, position) {
- position = position || 0;
- return this.indexOf(searchString, position) === position;
- });
-
- String.prototype.includes = Helper.nonNull(String.prototype.includes, function (searchString) {
- return this.indexOf(searchString) >= 0;
- });
-
- String.prototype.endsWith = Helper.nonNull(String.prototype.endsWith, function (searchString, position) {
- var subjectString = this.toString();
- if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
- position = subjectString.length;
- }
- position -= searchString.length;
- var lastIndex = subjectString.indexOf(searchString, position);
- return lastIndex !== -1 && lastIndex === position;
- });
-
-
- window["fetch"] = Helper.nonNull(window["fetch"], function (url, params) {
- console.log("customFetch", url);
- let request = null;
- if (window.XMLHttpRequest) { // Mozilla, Safari, ...
- request = new XMLHttpRequest();
- } else if (window.ActiveXObject) { // IE
- try {
- request = new ActiveXObject('Msxml2.XMLHTTP');
- }
- catch (e) {
- try {
- request = new ActiveXObject('Microsoft.XMLHTTP');
- }
- catch (e) {
- }
- }
- }
-
- let onloadPromise = new Promise((r) => {
- // this.result
- request.onload = r;
- request.onerror = function (err) {
- r(Promise.reject(err));
- };
- });
-
- let resultPromise = new Promise(function (resolve) {
-
- let response = {
- "json": function () {
- request.send();
-
- return onloadPromise.then(() => {
- return JSON.parse(request.responseText)
- });
- },
- "text": function () {
- request.send();
- return onloadPromise.then(() => request.responseText);
- },
- "arrayBuffer": () => {
- request.responseType = "arraybuffer";
- request.send();
- return onloadPromise.then(() => request.response);
- }
- };
- resolve(response);
- });
-
-
- request.open('get', url, true);
- // request.send();
- return resultPromise;
- });
-}
-
-class Constants{}
-Constants.SCRIPTS = {
- CKEDITOR:"version/2/ckeditor/ckeditor.js",
- LIST_JS: "version/1/listjs/list.min.js"
-};
-
-class DataManager {
- static async load(url, isCachable, raw) {
- isCachable = Helper.nonNull(isCachable, false);
- raw = Helper.nonNull(raw, false);
- let fullUrl = (isCachable) ? Helper.basePath(DataManager.cachePath + url) : Helper.basePath(DataManager.dataPath + url);
-
- return this._load(fullUrl, raw);
- }
-
- static async _load(url, raw) {
- return fetch(url, {"credentials": "same-origin"}).then(function (res) {
- if (raw) {
- return res.text();
- }
- return res.json();
- }).catch(function (e) {
- if (!raw) {
- return {
- "success": false,
- "errors": [
- "not-online"
- ]
- }
- }
- });
- }
-
- static async loadStatic(url, raw) {
- raw = Helper.nonNull(raw, false);
- let fullUrl = Helper.basePath(url);
-
- return this._load(fullUrl, raw);
- }
-
- static async send(url, params) {
- let fullUrl = Helper.basePath(DataManager.dataPath + url);
-
- if (!(params instanceof FormData)) {
- let newParams = new FormData();
- for (let k in params) {
- newParams.append(k, params[k]);
- }
- params = newParams;
- }
-
- return fetch(fullUrl, {
- "credentials": "same-origin",
- "method": "POST",
- "body": params
- }).then(function (res) {
- return res.json();
- }).catch(function (e) {
- console.error("error", e);
- return {
- "success": false,
- "errors": [
- "not-online"
- ]
- }
- });
- }
-
- static buildQuery(values) {
- return Helper.buildQuery(values);
- }
-}
-
-DataManager.dataPath = "data/";
-DataManager.cachePath = "cached/";
-
-class Form {
- constructor(formElem, url, method, isCachable) {
- this.formElem = formElem;
- this.method = Helper.nonNull(method, Helper.nonNull(formElem["method"], "POST"));
- this.isCachable = (Helper.nonNull(isCachable, this.method.toLowerCase() === "get") === true);
-
- this.isBusy = false;
-
- if (typeof url === "string")
- {
- this.submitHandler = function(values){
- if (self.method.toLowerCase() === "get") {
- return (DataManager.load(url + DataManager.buildQuery(values), self.isCachable));
- }
- else {
- return (DataManager.send(url, values));
- }
- };
- }
- else {
- this.submitHandler = url;
- }
-
- let self = this;
-
- this.submitCallback = null;
- this.errorCallback = async function (errors) {
- await self.setErrors(errors);
- };
-
- formElem.addEventListener("submit", async function (e) {
- console.log("submitting!", e);
- e.preventDefault();
- await self.doSubmit(e);
- });
-
- for (let i = 0, n = formElem.elements.length; i < n; i++) {
- let elem = formElem.elements[i];
- elem.addEventListener("change", function () {
- if (this.value.trim() !== "") {
- this.classList.add("notEmpty");
- }
- else {
- this.classList.remove("notEmpty");
- }
- this.setCustomValidity("");
- });
- elem.addEventListener("keydown", function () {
- this.setCustomValidity("");
- });
- }
- }
-
- onError(errorHandler, ownHandlerForOptimisticLocking){
- ownHandlerForOptimisticLocking = Helper.nonNull(ownHandlerForOptimisticLocking, true);
- let callback = null;
-
- if (ownHandlerForOptimisticLocking){
- callback = function(errors){
- if (Array.isArray(errors) && errors.indexOf("optimistic-locking-exception") >= 0){
- let dialog = new Dialog("optimistic-locking-dialog", "optimistic-locking-dialog-title");
- dialog.addDefaultButton();
- dialog.show();
- }
- else
- {
- errorHandler(errors);
- }
- };
- }
- else
- {
- callback = errorHandler;
- }
- this.errorCallback = callback;
- }
-
- doSubmit() {
- if (!this.isBusy) {
- let self = this;
- return this.submit().then(function (res) {
- if (res["success"]) {
- if (self.submitCallback !== null) {
- return self.submitCallback(res["result"]);
- }
- }
- else if (Helper.isNotNull(self.errorCallback)) {
- return self.errorCallback(res["errors"]);
- }
- });
- }
- }
-
- load(url, isCached) {
- this.setValues(DataManager.load(url, isCached).then(function (values) {
- if (values["success"]) {
- return values["result"];
- }
- return {};
- }));
- return this;
- }
-
- setValues(valuePromise) {
- this.setIsBusy(true);
-
- let self = this;
- return Promise.resolve(valuePromise).then(function (values) {
- self.setIsBusy(false);
- for (let k in values) {
- if (Helper.isNotNull(self.formElem.elements[k])) {
- if (Helper.isNotNull(self.formElem.elements[k].options) && Helper.isNotNull(values[k+"Options"]))
- {
- let options = self.formElem.elements[k].options;
- for (let val in values[k+"Options"])
- {
- let option = document.createElement("option");
- option.value = val;
- option.innerText = values[k+"Options"][val];
- options.add(option);
- }
- }
-
- self.formElem.elements[k].value = Helper.htmlspecialcharsDecode(values[k]);
- if (Helper.isNotNull(values[k]) && (""+values[k]).trim() !== "") {
- self.formElem.elements[k].classList.add("notEmpty");
- }
- else {
- self.formElem.elements[k].classList.remove("notEmpty");
- }
- }
- }
- return self;
- });
- }
-
- async setErrors(errors) {
- let hasElem = false;
- let firstError = null;
-
- for (let k in errors) {
- if (Helper.isNotNull(this.formElem.elements[k]) && this.formElem.elements[k].type !== "hidden"
- && Helper.isNull(this.formElem.elements[k].readonly) && (
- Helper.isNull(this.formElem.elements[k].disabled) || !this.formElem.elements[k].disabled)
- ) {
- this.formElem.elements[k].setCustomValidity(Translator.translate(Helper.nonNull(errors[k], "form-default-error")));
- hasElem = true;
- }
- if (Helper.isNull(firstError)) {
- firstError = Helper.nonNull(errors[k], "form-default-error");
- }
- }
- if (!hasElem && Helper.isNotNull(firstError)) {
- for (let k in this.formElem.elements) {
- if (this.formElem.elements[k].type !== "hidden") {
- this.formElem.elements[k].setCustomValidity(Translator.translate(firstError));
- hasElem = true;
- break;
- }
- }
- }
-
- if (hasElem) {
- this.formElem.querySelector("input[type=submit]").click();
- }
- }
-
- setIsBusy(isBusy) {
- this.isBusy = isBusy;
- if (this.isBusy) {
- this.formElem.classList.add("sending");
- }
- else {
- this.formElem.classList.remove("sending");
- }
- }
-
- submit() {
- let self = this;
- return new Promise(function (resolve) {
- self.setIsBusy(true);
- let values = new FormData(self.formElem);
- resolve(self.submitHandler(values));
- }).then(function (data) {
- self.setIsBusy(false);
- return data;
- });
- }
-
- onSubmit(callback) {
- this.submitCallback = callback;
- }
-}
-
-class SettingsManager {
- static getInstance() {
- if (SettingsManager._instance === null) {
- SettingsManager._instance = new SettingsManager();
- }
- return SettingsManager._instance;
- }
-
- constructor() {
- this._settings = null;
- this._localStorageKey = "settings";
- }
-
- getSettings() {
- if (Helper.isNull(this._settings)) {
- this._loadSettings();
- }
- return this._settings;
- }
-
- getSetting(name, defaultValue) {
- const settings = this.getSettings();
-
- if (Helper.isNotNull(settings[name])) {
- return settings[name].value;
- }
- else {
- return defaultValue;
- }
- }
-
- deleteSetting(name) {
- this.getSettings();
- delete this._settings[name];
- this._saveSettings();
- }
-
- setSetting(name, value) {
- this.getSettings();
- this._settings[name] = {
- date: new Date().getTime(),
- value: value
- };
- this._saveSettings();
- }
-
- setSettings(settingsObject) {
- this.getSettings();
- for (const k in settingsObject) {
- this._settings[k] = settingsObject[k];
- }
- this._saveSettings();
- }
-
- hasSetting(name)
- {
- return Helper.nonNull(this._settings[name]);
- }
-
- _loadSettings() {
- this._settings = localStorage.getItem(this._localStorageKey);
- console.log("settings", this._settings);
- if (this._settings === null) {
- this._settings = {};
- }
- else {
- this._settings = JSON.parse(this._settings);
- }
- }
-
- _saveSettings() {
- if (this._settings !== null) {
- localStorage.setItem(this._localStorageKey, JSON.stringify(this._settings));
- }
- }
-}
-
-SettingsManager._instance = null;
-
-class LocalStorageSettingsFragment extends Fragment {
- onFirstStart() {
- let res = super.onFirstStart();
- let settings = this.findBy(".setting", true);
- const settingsManager = SettingsManager.getInstance();
-
- for (let i = 0; i < settings.length; i++) {
- let setting = settings[i];
- const name = setting.name;
- let value;
- if (!setting["dataset"]["raw"]) {
- value = settingsManager.getSetting(name);
- } else {
- value = localStorage.getItem(name);
- }
-
- let isCheckable = false;
- if (setting instanceof HTMLInputElement && (setting.type === 'checkbox' || setting.type === 'radio')) {
- isCheckable = true;
- }
- if (((!setting["dataset"]["raw"] && !settingsManager.hasSetting(name)) || (setting["dataset"]["raw"] && value === null))
- && Helper.isNotNull(settings[i]["dataset"]["default"])) {
- value = setting["dataset"]["default"];
- if (Helper.isNotNull(setting["dataset"]["defaultTranslateable"])) {
-
- setting["dataset"]["translation"] = "";
- setting["dataset"]["translationValue"] = value;
- value = Translator.translate(value);
- }
- }
-
- if (Helper.isNotNull(value)) {
- if (isCheckable) {
- setting.checked = (value === setting.value);
- }
- else {
- setting.value = value;
- }
- if (value !== "") {
- setting.classList.add("notEmpty");
- }
- }
-
- setting.addEventListener("change", function () {
- let value = this.value;
- if (isCheckable && !this.checked) {
- value = null;
- }
- if (!setting["dataset"]["raw"]) {
- settingsManager.setSetting(name, value);
- } else {
- localStorage.setItem(name, value);
- }
- delete setting["dataset"]["translationValue"];
- delete setting["dataset"]["translation"];
- });
- }
- return res;
- }
-
- onStart() {
- let res = super.onStart();
- let settings = this.findBy(".setting", true);
- const settingsManager = SettingsManager.getInstance();
-
- for (let i = 0; i < settings.length; i++) {
- let setting = settings[i];
- const name = setting.name;
- let value;
- if (!setting["dataset"]["raw"]) {
- value = settingsManager.getSetting(name);
- } else {
- value = localStorage.getItem(name);
- }
-
- let isCheckable = false;
- if (setting instanceof HTMLInputElement && (setting.type === 'checkbox' || setting.type === 'radio')) {
- isCheckable = true;
- }
-
- if (Helper.isNotNull(value)) {
- if (isCheckable) {
- setting.checked = (value === setting.value);
- }
- else {
- setting.value = value;
- }
- if (value !== "") {
- setting.classList.add("notEmpty");
- }
- }
- }
- return res;
- }
-}
-
-class SmartColumn{
- constructor(name, label, translateable){
- this._name = name;
- this._label = label;
- this._translateable = Helper.nonNull(translateable, true);
- this._sortable = true;
-
- this._index = -1;
-
- this._clickListener = null;
- }
-
- setClickListener(listener)
- {
- this._clickListener = listener;
- return this;
- }
-
- setIndex(index)
- {
- this._index = index;
- }
-
- getName()
- {
- return this._name;
- }
-
- getLabel()
- {
- return this._label;
- }
-
- getHeadElement()
- {
- const headElement = document.createElement("th");
- headElement.appendChild((this._translateable)?Translator.makePersistentTranslation(this._label):document.createTextNode(this._label));
-
- if (this._sortable)
- {
- headElement.classList.add("sort");
- headElement["dataset"]["sort"] = this._name;
- }
-
- headElement["dataset"]["column"] = this._index;
-
- this._headElement = headElement;
- return this._headElement;
- }
-
- getValueName(){
- return this._name;
- }
-
- prepareData(myData, rowData)
- {
- return myData;
- }
-
- getItemElement(){
- const element = document.createElement("td");
- element.classList.add(this._name);
- element["dataset"]["column"] = this._index;
-
- if (Helper.isNotNull(this._clickListener))
- {
- element.classList.add("clickable");
- }
-
- return element;
- }
-
- click(tableCell, table, event){
- if (Helper.isNotNull(this._clickListener))
- {
- this._clickListener(tableCell, table, event);
- }
- }
-}
-
-class ConstSmartColumn extends SmartColumn{
- constructor(name, label, translatable, valueTranslatable) {
- super(name, label, translatable);
- this._sortable = false;
- this._valueTranslatable = Helper.nonNull(valueTranslatable, false);
- }
-
- getValueName() {
- return null;
- }
-
- getItemElement(){
- const element = super.getItemElement();
- element.classList.remove(this._name);
- element.appendChild((this._valueTranslatable)?Translator.makePersistentTranslation(this._name):document.createTextNode(this._name));
- return element;
- }
-}
-
-class DataSmartColumn extends SmartColumn{
- constructor(name, label, translateable) {
- translateable = Helper.nonNull(translateable, false);
- super(name, label, translateable);
- }
-
- getHeadElement() {
- return document.createTextNode("");
- }
-
- getValueName() {
- return {
- "data":[this._name]
- };
- }
-
- getItemElement() {
- return document.createTextNode("");
- }
-}
-
-class ImgConstSmartColumn extends ConstSmartColumn{
- constructor(name, label, translateable) {
- super(name, label, translateable);
- this._valueTranslatable = false;
- }
-
- getItemElement() {
- const element = super.getItemElement();
- const imgElement = document.createElement("img");
- imgElement["src"] = this._name;
-
- element.removeAllChildren().appendChild(imgElement);
- return element;
- }
-}
-
-class ListHelper {
- constructor(id, options, values) {
- this._tableElement = id;
- this._options = Helper.nonNull(options, {});
- this._values = values;
-
- if (typeof this._tableElement === "string") {
- this._tableElement = document.getElementById(this._tableElement);
- }
-
- this._columns = [];
- if (Array.isArray(options)) {
- this._columns = options;
- }
- else if (Helper.isNotNull(options["columns"])) {
- this._columns = options["columns"];
- }
- }
-
- prepareData(data) {
- console.log("prepareData", data);
- if (Helper.isNotNull(data)) {
- for (let i = 0, n = data.length; i < n; i++) {
- data[i] = this.prepareDataset(data[i]);
- }
- }
- return data;
- }
-
- prepareDataset(dataset) {
- console.log("prepareDataset", dataset);
- for (let i = 0, n = this._columns.length; i < n; i++) {
- if (Helper.isNotNull(dataset[this._columns[i].getName()])) {
- dataset[this._columns[i].getName()] = this._columns[i].prepareData(dataset[this._columns[i].getName()], dataset);
- }
- }
- return dataset;
- }
-
- createTable() {
- if (Helper.isNotNull(this._columns)) {
- this.updateColumns();
- }
-
- let id = this._tableElement;
- let options = this._options;
- let values = this._values;
-
- options["item"] = Helper.nonNull(options["item"], id["id"] + "-template-item");
- options["page"] = Helper.nonNull(options["page"], 5);
- options["pagination"] = Helper.nonNull(options["pagination"], {
- "outerWindow": 1,
- "innerWindow": 1
- });
-
- let template = document.getElementById(options["item"]);
- if (template) {
- options["item"] = template.outerHTML;
- template.remove();
- }
-
- values = this.prepareData(values);
-
- const list = new List(id, options, values);
- let self = this;
- id.querySelector("." + Helper.nonNull(options["listClass"], "list")).addEventListener("click", function (e) {
- let columnElem = e.target.closest("td[data-column]");
- const column = parseInt(columnElem["dataset"]["column"]);
- if (self._columns.length > column) {
- self._columns[column].click(columnElem, list, e);
- }
- });
- this.list = list;
-
- return list;
- }
-
- updateColumns() {
- const head = document.createElement("tr");
- const item = document.createElement("tr");
- const valueNames = [];
-
- for (let i = 0, n = this._columns.length; i < n; i++) {
- this._columns[i].setIndex(i);
-
- head.appendChild(this._columns[i].getHeadElement());
- item.appendChild(this._columns[i].getItemElement());
-
- const valueName = this._columns[i].getValueName();
- if (Helper.isNotNull(valueName)) {
- valueNames.push(valueName);
- }
- }
- const header = this._tableElement.querySelector("thead");
- const footer = this._tableElement.querySelector("tfoot");
-
- if (Helper.isNotNull(header)) {
- header.removeAllChildren().appendChild(head);
- }
- if (Helper.isNotNull(footer)) {
- footer.removeAllChildren().appendChild(Helper.cloneNode(head));
- }
-
-
- this._options["item"] = item.outerHTML;
- this._options["valueNames"] = valueNames;
- }
-
- getList() {
- return this.list;
- }
-
- updateItem(valueName, value, newValues) {
- const items = this.list.get(valueName, value);
- if (Helper.isNotNull(items) && items.length >= 1) {
- newValues = this.prepareDataset(newValues);
- items[0].values(newValues);
- }
- }
-
- setBusy(isBusy) {
- if (isBusy) {
- this._tableElement.classList.add("sending");
- }
- else {
- this._tableElement.classList.remove("sending");
- }
- }
-}
-
-class ChooseThemeDialog extends Dialog {
-
- constructor() {
- let viewPromise = ViewInflater.inflate("core/html/dialog/chooseTheme.html").then(view => {
-
- let template = view.querySelector("#choose-theme-template");
- template.remove();
- template.id = null;
-
- let themeTemplateContainer = view.querySelector("#theme-choose-container");
-
- for (let i = 0; i < ThemeManager.themes.length; i++) {
- let themeElem = Helper.cloneNode(template);
- let theme = ThemeManager.themes[i];
- themeElem.querySelector(".name").appendChild(Translator.makePersistentTranslation(theme._name));
- themeElem["dataset"]["theme"] = theme._name;
-
- themeElem.addEventListener("click", () => {
- this.result = themeElem["dataset"]["theme"];
- this.close();
- });
- themeTemplateContainer.appendChild(themeElem);
- }
-
- return view;
- });
-
- super(viewPromise, "choose-theme-dialog-title");
- }
-}
-
-class SettingsSite extends AbstractSite {
- constructor(siteManager) {
- super(siteManager, SettingsSite.template, "settings");
- for (let k in SettingsSite.settingsFragments) {
- this.addSettingsFragment(k, new SettingsSite.settingsFragments[k](this));
- }
- this.active = null;
- }
-
- addSettingsFragment(name, settingsFragment) {
- this.addFragment("#settings-fragments", settingsFragment);
- delete this.fragments["#settings-fragments"];
- this.fragments[name] = settingsFragment;
- }
-
- onStart() {
- let res = super.onStart();
- if (Helper.isNotNull(this.active) && !this.fragments[this.active].isActive()) {
- this.setActive(null);
- }
-
- this.buildList();
- return res;
- }
-
- setActive(name) {
- if (Helper.isNotNull(this.active)) {
- this.fragments[this.active].inflatePromise.then(function (view) {
- view.classList.remove("active");
- });
- this.findBy("#show-fragment-" + this.active).classList.remove("active");
- }
- this.active = name;
- if (Helper.isNotNull(this.active)) {
- this.fragments[this.active].inflatePromise.then(function (view) {
- view.classList.add("active");
- });
- this.findBy("#show-fragment-" + this.active).classList.add("active");
- }
- }
-
- buildList() {
- let listNameElem = this.findBy("#settings-fragment-list");
- listNameElem.removeAllChildren();
-
- let self = this;
- for (let k in this.fragments) {
- if (this.fragments[k].isActive()) {
-
- let liElement = document.createElement("li");
- liElement.id = "show-fragment-" + k;
- liElement.appendChild(Translator.makePersistentTranslation(k, null, "a"));
- liElement.addEventListener("click", function () {
- self.setActive(k);
- });
- listNameElem.appendChild(liElement);
-
- if (Helper.isNull(this.active)) {
- this.setActive(k);
- }
- }
- }
- }
-
- static addSettingsFragment(name, settingsFragment) {
- SettingsSite.settingsFragments[name] = settingsFragment;
- }
-
- static setAddSettingsSite(addLink) {
- SettingsSite.shouldAddSettingsSite = addLink;
- }
-
- static setTemplate(template) {
- SettingsSite.template = template;
- }
-}
-
-SettingsSite.template = 'core/html/settings.html';
-SettingsSite.settingsFragments = {};
-SettingsSite.shouldAddSettingsSite = true;
-SettingsSite.settingsAction = null;
-SettingsSite.shouldAddSettingsAction = true;
-
-InitPromise.addPromise(function (app) {
- if (SettingsSite.shouldAddSettingsSite) {
- app.addDeepLink("settings", SettingsSite);
-
- if (Helper.isNull(SettingsSite.settingsAction)) {
- let settingsAction = new MenuAction("settings", async () => {
- let currentSite = app.getCurrentSite();
- if (currentSite instanceof SettingsSite) {
- currentSite.finish();
- }
- else {
- let settingsSite = await app.findSite((site) => {
- return (site instanceof SettingsSite);
- });
- if (Helper.isNotNull(settingsSite)) {
- settingsSite.toForeground();
- }
- else {
- app.startSite(SettingsSite);
- }
- }
- }, MenuAction.SHOW_FOR_LARGE, 10000);
- settingsAction.setIcon("img/settings.png");
- SettingsSite.settingsAction = settingsAction;
- }
- if (SettingsSite.shouldAddSettingsAction) {
- app.addDefaultAction(SettingsSite.settingsAction);
- }
- }
-});
-
-class GeneralSettingsFragment extends LocalStorageSettingsFragment {
-
- constructor(site) {
- super(site, "core/html/fragment/generalSettingsFragment.html");
- }
-
- onFirstStart() {
- this.addThemeListener();
- return super.onFirstStart();
- }
-
- addThemeListener(){
- let currentThemeName = ThemeManager$1.currentTheme._name;
- SettingsManager.getInstance().setSetting("theme", currentThemeName);
-
- let themeNameElem = this.findBy("#theme-name");
- themeNameElem.removeAllChildren().appendChild(Translator.makePersistentTranslation(currentThemeName));
- this.findBy("#theme-chooser").addEventListener("click", async () => {
- let newTheme = await (new ChooseThemeDialog()).show();
- if (Helper.isNotNull(newTheme)) {
- SettingsManager.getInstance().setSetting("theme", newTheme);
- ThemeManager$1.changeCurrentTheme(newTheme);
- themeNameElem.removeAllChildren().appendChild(Translator.makePersistentTranslation(newTheme));
- }
- });
- }
-}
-
-GeneralSettingsFragment.addFragment = false;
-InitPromise.addPromise(function () {
- if (GeneralSettingsFragment.addFragment) {
- SettingsSite.addSettingsFragment("general-settings-fragment", GeneralSettingsFragment);
- }
-});
-
-class UserManager {
- static init(app) {
- UserManager.getMeUrl = null;
- UserManager.userData = {
- online: false,
- id: null,
- accesses: ["default"]
- };
- UserManager.app = app;
-
- UserManager.fetchMePromise = new Promise(function (resolve) {
- UserManager.fetchMePromiseResolver = resolve;
- });
- }
-
- static setData(data) {
- UserManager.userData = Object.assign(UserManager.userData, data);
- let siteManager = UserManager.app.getSiteManager();
-
- if (siteManager)
- siteManager.redrawCurrentActionBar();
- }
-
- static fetchMe(url) {
- UserManager.getMeUrl = Helper.nonNull(url, UserManager.getMeUrl);
- return DataManager.load(UserManager.getMeUrl).then(function (result) {
- if (result["success"]) {
- UserManager.setData(result["result"]);
- }
- UserManager.fetchMePromiseResolver();
- });
- }
-
- static logOut() {
- return DataManager.load("u/logout").then(function (data) {
- if (data["success"]) {
- UserManager.setData(data["result"]);
- let siteManager = UserManager.app.getSiteManager();
-
- if (siteManager)
- siteManager.refreshCurrentSite();
- FlashMessenger.addMessage(FlashMessenger.MESSAGE_TYPE_SUCCESS, Translator.translate("logged-out-successfully"));
- }
- });
- }
-
- static hasAccess(access) {
- // console.log("Has access", access, UserManager.userData["accesses"].indexOf(access), UserManager.userData);
- return (UserManager.userData["accesses"].indexOf(access) >= 0)
- }
-
- static addCurrentUserListener(userId, listener) {
- UserManager.addIsLoggedInListener(function (isLoggedIn) {
- listener(isLoggedIn && UserManager.isCurrentUser(userId));
- });
- }
-
- static addIsLoggedInListener(listener) {
- this.fetchMePromise.then(function () {
- listener(UserManager.isLoggedIn());
- });
- }
-
- static isCurrentUser(userId) {
- return UserManager.userData.id === userId;
- }
-
- static isLoggedIn() {
- return Helper.isNotNull(UserManager.userData) && Helper.isNotNull(UserManager.userData.id);
- }
-}
-UserManager.waitForData = true;
-
-
-InitPromise.addPromise(function(app){
- UserManager.init(app);
- let userManagerPromise = UserManager.fetchMe("u/me").then(function(){
- UserManager.addIsLoggedInListener(function (isLoggedIn) {
- if (isLoggedIn) {
- const settingsManager = SettingsManager.getInstance();
- const settings = Helper.cloneJson(settingsManager.getSettings());
- for (let k in settings) {
- settings[k]["value"] = JSON.stringify(settings[k]["value"]);
- }
- DataManager.send("u/syncSettings", settings).then(function(res){
- if (res["success"])
- {
- for (let k in res["result"])
- {
- res["result"][k]["value"] = JSON.parse(res["result"][k]["value"]);
- }
- settingsManager.setSettings(res["result"]);
- }
- });
- }
- });
- });
-
- if (UserManager.waitForData){
- return userManagerPromise;
- }
-});
-
-class UserAction extends MenuAction {
- constructor(title, callback, icon, order, access) {
- super(title, callback, icon, order);
- this._access = Helper.nonNull(access, "default");
- }
-
- getVisible() {
- // console.log("Action-access: ", this._access);
- return (super.getVisible() && UserManager.hasAccess(this._access));
- }
-
- getAccess() {
- return this._access;
- }
-
- copy(instance){
- let copy = super.copy(Helper.nonNull(instance, new UserAction()));
- copy._access = this._access;
- return copy;
- }
-}
-
-class NotAllowedSite extends AbstractSite{
- constructor(siteManager) {
- super(siteManager, 'userManagement/html/403.html');
- }
-}
-
-class UserSite extends AbstractSite {
-
- constructor(siteManager, view, deepLink, access) {
- super(siteManager, view, deepLink);
- this._access = access;
- }
-
- onConstruct(args) {
- if (!UserManager.hasAccess(this._access))
- {
- this.startSite(NotAllowedSite);
- this.finish({
- "error":403
- });
- return;
- }
- return super.onConstruct(args);
- }
-
- onStart(args) {
- if (!UserManager.hasAccess(this._access))
- {
- this.startSite(NotAllowedSite);
- this.finish({
- "error":403
- });
- return;
- }
- return super.onStart(args);
- }
-}
-
-class LoginForm extends Form {
-
- constructor(formElem, url, method, isCachable) {
- super(formElem, url, method, isCachable);
-
- let emailElem = formElem.querySelector("#email");
- let passwordElem = formElem.querySelector("#password");
-
- let listener = function(){
- emailElem.setCustomValidity("");
- passwordElem.setCustomValidity("");
- };
-
- emailElem.addEventListener("keydown", listener);
- passwordElem.addEventListener("keydown", listener);
- }
-}
-
-class RegistrationForm extends Form {
- constructor(formElem, url, method, isCachable) {
- super(formElem, url, method, isCachable);
-
- // this.pw1 = formElem.querySelector("#password1");
- // this.pw2 = formElem.querySelector("#password2");
-
- // let self=this;
- // this.pw1.addEventListener("change", function(){
- // self.checkPw();
- // });
- // this.pw2.addEventListener("change", function(){
- // self.checkPw();
- // });
- }
-
- checkPw(){
- // if (this.pw1.value !== this.pw2.value || this.pw1.value.length < 8)
- // {
- //
- // }
- }
-}
-
-class UserFragment extends Fragment{
-
- constructor(site, view, access) {
- super(site, view);
- this._access = access;
- }
-
- isActive() {
- return super.isActive() && UserManager.hasAccess(this._access);
- }
-}
-
-class PasswordSettingsFragment extends UserFragment{
- constructor(site)
- {
- super(site, "userManagement/html/fragments/passwordSettings.html", "online");
- }
- onFirstStart() {
- let res = super.onFirstStart();
- let form = new Form(document.getElementById("change-password-form"), "u/passwordSettings/set", "post");
- form.onSubmit(function(res){
- for (let i = 0, n = res.length; i < n; i++)
- {
- FlashMessenger.addMessage(res[i]);
- }
- form.setValues({
- "oldPassword":"",
- "newPassword1":"",
- "newPassword2":""
- });
- });
- return res;
- }
-}
-InitPromise.addPromise(function(){
- SettingsSite.addSettingsFragment("password-settings", PasswordSettingsFragment);
-});
-
-class UserSettingsFragment extends UserFragment{
- constructor(site)
- {
- super(site, "userManagement/html/fragments/userSettings.html", "online");
- }
-
- onFirstStart() {
- let res = super.onFirstStart();
- (new Form(document.getElementById("user-settings-form"), "u/userSettings/set", "post")).load('u/userSettings').onSubmit(function(res){
- for (let i = 0, n = res.length; i < n; i++)
- {
- FlashMessenger.addMessage(res[i]);
- }
- });
- return res;
- }
-}
-InitPromise.addPromise(function(){
- SettingsSite.addSettingsFragment("user-settings", UserSettingsFragment);
-});
-
-class EditUserRolesSite extends UserSite {
- constructor(siteManager) {
- super(siteManager, 'userManagement/html/editUserRoles.html', "userRoles", "admin");
- }
-
- onConstruct(args) {
- let res = super.onConstruct(args);
- this.userId = args["id"];
-
- let self = this;
- return Promise.all([
- ScriptLoader.loadScript(Constants.SCRIPTS.LIST_JS),
- DataManager.load("u/userRoles" + DataManager.buildQuery({"id": self.userId})).then(function (res) {
- if (!res["success"]) {
- FlashMessenger.addMessage(res["errors"][0]);
- self.finish();
- }
- else {
- self.setUserRoles(res["result"]["userRoles"]);
- self.setAvailableRoles(res["result"]["availableRoles"]);
- self.setUsername(res["result"]["username"]);
- }
- })
- ]).then(function () {
- return res;
- });
- }
-
- onFirstStart() {
- this.findBy("#username").innerHTML = this.username;
-
- const userRolesElement = this.findBy("#userRoles");
- const availableRolesElement = this.findBy("#availableRoles");
-
- const imgColumnUserRoles = new ImgConstSmartColumn("img/minus.png", "", false);
- const imgColumnAvailableRoles = new ImgConstSmartColumn("img/plus.png", "", false);
-
- const userRolesColumns = [
- new DataSmartColumn("id"),
- new SmartColumn("name", "name"),
- new SmartColumn("description", "description"),
- imgColumnUserRoles,
- ];
-
- const availableRolesColumns = [
- new DataSmartColumn("id"),
- new SmartColumn("name", "name"),
- new SmartColumn("description", "description"),
- imgColumnAvailableRoles,
- ];
-
- const userRolesListHelper = new ListHelper(userRolesElement, userRolesColumns, this.userRoles);
- const availableRolesListHelper = new ListHelper(availableRolesElement, availableRolesColumns, this.availableRoles);
-
- const userRolesTable = userRolesListHelper.createTable();
- const availableRolesTable = availableRolesListHelper.createTable();
-
- let self = this;
- const changeRoleFunction = function (roleId, addRole) {
- userRolesListHelper.setBusy(true);
- availableRolesListHelper.setBusy(true);
-
- return DataManager.send("u/changeUserRole", {
- "id": roleId,
- "userId": self.userId,
- "add": addRole
- }).then(function (res) {
- userRolesListHelper.setBusy(false);
- availableRolesListHelper.setBusy(false);
-
- if (!res["success"]) {
- FlashMessenger.addMessage(res["errors"][0]);
- return res;
- }
-
- let removingTable = null;
- let addingTable = null;
- if (res["result"]["hasRole"]) {
- removingTable = availableRolesTable;
- addingTable = userRolesTable;
- }
- else {
- addingTable = availableRolesTable;
- removingTable = userRolesTable;
- }
-
- const rowData = removingTable.get("id", roleId);
- if (rowData.length === 1) {
- addingTable.add(rowData[0].values());
- removingTable.remove("id", roleId);
- }
-
- return res;
- });
- };
-
- imgColumnUserRoles.setClickListener(function (cell) {
- let userRoleId = cell.closest("tr")["dataset"]["id"];
- changeRoleFunction(userRoleId, false);
- });
-
- imgColumnAvailableRoles.setClickListener(function (cell) {
- let availableRoleId = cell.closest("tr")["dataset"]["id"];
- changeRoleFunction(availableRoleId, true);
- });
-
- }
-
- setUserRoles(userRoles) {
- this.userRoles = userRoles;
- }
-
- setAvailableRoles(availableRoles) {
- this.availableRoles = availableRoles;
- }
-
- setUsername(username) {
- this.username = username;
- }
-}
-
-InitPromise.addPromise(function (app) {
- app.addDeepLink("userRoles", EditUserRolesSite);
- app.addDefaultAction(new UserAction('userRoles', function(){
- app.startSite(EditUserRolesSite);
- }, null, 1100, "admin"));
-});
-
-class ForgotPasswordSite extends UserSite{
-
- constructor(siteManager) {
- super(siteManager, 'userManagement/html/forgotPassword.html', "forgotPassword", "offline");
- }
-
- onFirstStart() {
- let self = this;
- (new Form(document.getElementById("forgot-password-form"), "u/newPassword", "post")).onSubmit(function(res){
- // UserManager.setData(res);
- // self.startStartsite();
- FlashMessenger.addMessage(FlashMessenger.MESSAGE_TYPE_SUCCESS, Translator.translate("new-password-code-send"));
- self.finish();
- });
- }
-}
-InitPromise.addPromise(function(app){
- app.addDeepLink("forgotPassword", ForgotPasswordSite);
-});
-
-class LoginSite extends UserSite {
- constructor(siteManager) {
- super(siteManager, 'userManagement/html/login.html', "login", "offline");
- }
-
- onFirstStart() {
- let self = this;
- (new LoginForm(document.getElementById("login-form"), "u/login", "post")).onSubmit(function (res) {
- UserManager.setData(res);
- self.startStartsite();
- FlashMessenger.addMessage(FlashMessenger.MESSAGE_TYPE_SUCCESS, Translator.translate("login-success"));
- self.finish();
- });
-
- this.findBy("#forgot-password-link").addEventListener("click", function () {
- self.startSite(ForgotPasswordSite);
- self.finish();
- });
- }
-}
-
-LoginSite.loginAction = null;
-LoginSite.logoutAction = null;
-LoginSite.addLoginAction = true;
-LoginSite.addLogoutAction = true;
-
-InitPromise.addPromise(function (app) {
- app.addDeepLink("login", LoginSite);
-
- if (Helper.isNull(LoginSite.loginAction)) {
- LoginSite.loginAction = new UserAction('login', function () {
- app.startSite(LoginSite);
- }, Menu.SHOW_NEVER, 1100, "offline");
- }
- if (Helper.isNull(LoginSite.logoutAction)) {
- LoginSite.logoutAction = new UserAction('logout', function () {
- UserManager.logOut();
- }, Menu.SHOW_NEVER, 1100, "online");
- }
- if (LoginSite.addLoginAction){
- app.addDefaultAction(LoginSite.loginAction);
- }
- if (LoginSite.addLogoutAction){
- app.addDefaultAction(LoginSite.logoutAction);
- }
-});
-
-class RegistrationSite extends UserSite {
- constructor(siteManager) {
- super(siteManager, 'userManagement/html/registration.html', "registration", "offline");
- }
-
- onFirstStart() {
- (new RegistrationForm(document.getElementById("registration-form"), "u/registration", "post")).onSubmit(function (res) {
- FlashMessenger.addMessage(FlashMessenger.MESSAGE_TYPE_SUCCESS, Translator.translate("registration-success"));
- });
- }
-}
-
-RegistrationSite.action = null;
-RegistrationSite.addAction = true;
-
-InitPromise.addPromise(function (app) {
- app.addDeepLink("registration", RegistrationSite);
-
- if (Helper.isNull(RegistrationSite.action)) {
- RegistrationSite.action = new UserAction('registration', function () {
- app.startSite(RegistrationSite);
- }, null, 1100, "offline");
- }
- if (RegistrationSite.addAction) {
- app.addDefaultAction(RegistrationSite.action);
- }
-});
-
-class SetNewPasswordSite extends UserSite {
- constructor(siteManager) {
- super(siteManager, 'userManagement/html/setNewPassword.html', "newPassword", "offline");
- }
-
- onConstruct(args) {
- this.code = args["code"];
- return super.onConstruct(args);
- }
-
- onFirstStart() {
- let formElem = document.getElementById("new-password-form");
- document.getElementById("code").value = this.code;
-
- let self = this;
- (new Form(formElem, "c/code", "post")).onSubmit(function(res){
- FlashMessenger.addMessage(FlashMessenger.MESSAGE_TYPE_SUCCESS, Translator.translate("password-updated"));
- self.startSite(LoginSite);
- self.finish();
- });
- }
-}
-InitPromise.addPromise(function(app){
- app.addDeepLink("newPassword", SetNewPasswordSite);
-});
-
-class MyStorageManager {
- static getInstance() {
- if (Helper.isNull(MyStorageManager.instance)) {
- MyStorageManager.instance = new MyStorageManager();
- }
- return MyStorageManager.instance;
- }
-
- async estimate() {
- if ('storage' in navigator && 'estimate' in navigator["storage"]) {
- // We've got the real thing! Return its response.
- return navigator["storage"]["estimate"]();
- }
-
- if ('webkitTemporaryStorage' in navigator &&
- 'queryUsageAndQuota' in navigator["webkitTemporaryStorage"]) {
- // Return a promise-based wrapper that will follow the expected interface.
- return new Promise(function (resolve, reject) {
- navigator["webkitTemporaryStorage"]["queryUsageAndQuota"](
- function (usage, quota) {
- resolve({"usage": usage, "quota": quota});
- },
- );
- });
- }
- // If we can't estimate the values, return a Promise that resolves with NaN.
- return Promise.resolve({"usage": NaN, "quota": NaN});
- }
-
- async isPersistent(){
- if (this.canPersist()){
- return navigator["storage"]["persisted"]();
- }
- return Promise.resolve(false);
- }
-
- canEstimateStorage() {
- return ('storage' in navigator && 'estimate' in navigator["storage"]|| 'webkitTemporaryStorage' in navigator &&
- 'queryUsageAndQuota' in navigator["webkitTemporaryStorage"]);
- }
-
- canPersist() {
- return (navigator["storage"] && navigator["storage"]["persist"]);
- }
-
- persist(){
- if (this.canPersist()){
- return navigator["storage"]["persist"]();
- }
- return Promise.resolve(false);
- }
-}
-
-MyStorageManager.instance = null;
-
-class InstallManager {
- static init() {
- window.addEventListener('beforeinstallprompt', e => {
- e.preventDefault();
- this.setDeferredPrompt(e);
- });
- }
-
- static setDeferredPrompt(e){
- this.deferredPromt = e;
- if (this.canInstallListener) {
- this.canInstallListener(this.deferredPromt);
- }
- }
-
- static async prompt(){
- if (Helper.isNotNull(this.deferredPromt)){
- this.deferredPromt["prompt"]();
- return this.deferredPromt["userChoice"].then(r => {
- MyStorageManager.getInstance().persist();
- return r;
- });
- }
- return Promise.resolve({
- "outcome":"dismissed",
- "platform":""
- });
- }
-
- static isInstalled(){
- return matchMedia("(display-mode: standalone)").matches;
- }
-
- static setCanInstallListener(listener, callIfCanInstall) {
- this.canInstallListener = listener;
- callIfCanInstall = Helper.nonNull(callIfCanInstall, true);
-
- if (callIfCanInstall && Helper.nonNull(this.deferredPromt)) {
- this.canInstallListener(this.deferredPromt);
- }
- }
-}
-
-InstallManager.init();
-
-class Matomo {
-
- static init() {
- Matomo.isTrackingPromise = new Promise(async (resolve) => {
- let shouldTrack = Helper.nonNull(localStorage.getItem(Matomo.LOCAL_STORAGE_KEY), "1");
- if (Helper.isNull(shouldTrack)) {
- shouldTrack = await Matomo._askIsTracking();
- localStorage.setItem(Matomo.LOCAL_STORAGE_KEY, shouldTrack);
- }
- else {
- shouldTrack = (shouldTrack === "1");
- Matomo.setTrack(shouldTrack);
- }
- resolve(shouldTrack);
- });
- Matomo.isTrackingPromise.then(() => {
- Matomo.push(['trackPageView'], true);
- Matomo.push(['enableLinkTracking'], true);
- Matomo.push(['setTrackerUrl', Matomo.TRACK_SITE + '/piwik.php'], true);
- Matomo.push(['setSiteId', Matomo.SIDE_ID + ""], true);
-
- let d = document, g = d.createElement('script'), s = d.getElementsByTagName('head')[0];
- g.type = 'text/javascript';
- g.async = true;
- g.defer = true;
- g.src = Matomo.TRACK_SITE + '/piwik.js';
- s.appendChild(g);
- });
- }
-
- static update(title) {
- if (Helper.nonNull(Matomo.currentUrl)) {
- Matomo.push(['setReferrerUrl', Matomo.currentUrl]);
- }
- Matomo.currentUrl = window.location.pathname + window.location.search;
- Matomo.push(['setCustomUrl', Matomo.currentUrl]);
- Matomo.push(['setDocumentTitle', title]);
-
- // remove all previously assigned custom variables, requires Matomo (formerly Piwik) 3.0.2
- Matomo.push(['deleteCustomVariables', 'page']);
- Matomo.push(['setGenerationTimeMs', 0]);
- Matomo.push(['trackPageView']);
-
- // make Matomo aware of newly added content
- var content = document.getElementById('site-content');
- Matomo.push(['MediaAnalytics::scanForMedia', content]);
- Matomo.push(['FormAnalytics::scanForForms', content]);
- Matomo.push(['trackContentImpressionsWithinNode', content]);
- Matomo.push(['enableLinkTracking']);
- }
-
- static async _askIsTracking() {
- Matomo.isTrackingPromise = new Promise(resolve => {
- Matomo.push([function () {
- resolve(!this["isUserOptedOut"]());
- }]);
- Matomo.push([function () {
- resolve(!this["isUserOptedOut"]());
- }]);
- });
- return Matomo.isTrackingPromise;
- }
-
- static async query(method) {
- return fetch(Matomo.TRACK_SITE + Matomo.BASE_PATH + method, {
- "mode": "cors",
- "credentials": "include",
- }).then(res => res.text()).then(text => (new window.DOMParser()).parseFromString(text, "text/xml"));
- }
-
- static getTrackingPromise() {
- return Matomo.isTrackingPromise;
- }
-
- static async setTrack(shouldTrack) {
- Matomo.isTrackingPromise = Promise.resolve(shouldTrack);
- localStorage.setItem(Matomo.LOCAL_STORAGE_KEY, (shouldTrack === true) ? "1" : "0");
-
- if (shouldTrack) {
- Matomo.push(["forgetUserOptOut"], true);
- }
- else {
- Matomo.push(["optUserOut"], true);
- }
- }
-
- static async trackEvent(event, name, label, value){
- let ev = ["trackEvent", event, name];
- if (Helper.isNotNull(label)){
- ev.push(label);
- }
- if (Helper.isNotNull(value) && !isNaN(parseFloat(value)) && isFinite(value)){
- ev.push(value);
- }
-
- return this.push(ev);
- }
-
- static async push(arr, force) {
-
- if (!Array.isArray(arr)) {
- arr = [arr];
- }
- window["_paq"].push(arr);
- }
-}
-
-Matomo.currentUrl = null;
-
-Matomo.LOCAL_STORAGE_KEY = "matomoShouldTrack";
-Matomo.TRACK_SITE = "//matomo.silas.link";
-Matomo.BASE_PATH = "/index.php?module=API&method=AjaxOptOut.";
-Matomo.SIDE_ID = "1";
-
-InitPromise.addPromise(() => {
- window["_paq"] = window["_paq"] || [];
- Matomo.init();
-});
-
-class MatomoShareButton extends MultipleShareButton{
-
- constructor(baseButton, platform, shouldLoadImg) {
- super([baseButton, (url) => {
- Matomo.trackEvent("shared", url, platform);
- }], shouldLoadImg);
- }
-}
-
-AndroidBridge.addDefinition("MatomoShareButton", MatomoShareButton);
-
-class ScaleHelper {
- async scaleTo(scale, fontElement, container, ignoreHeight, ignoreWidth, margin, fontWeight, animationDelay, addListener) {
-
- addListener = Helper.nonNull(addListener, true);
- animationDelay = Helper.nonNull(animationDelay, 0);
-
- let newFontSize = await this._getNewFontSize(scale, fontElement, container, ignoreHeight, ignoreWidth, margin, fontWeight, animationDelay === 0);
-
- if (animationDelay > 0) {
- await new Promise(r => {
- setTimeout(r, animationDelay);
- fontElement.style.fontSize = newFontSize + "px";
- });
- }
-
- let self = this;
- let listener = function () {
- return new Promise(resolve => {
- let timeout = (typeof addListener === 'number') ? addListener : 255;
- setTimeout(() => {
- resolve(self.scaleTo(scale, fontElement, container, ignoreHeight, ignoreWidth, margin, fontWeight, animationDelay, false));
- }, timeout);
- });
- };
- if (addListener !== false) {
- window.addEventListener("resize", listener);
- }
- return listener;
- }
-
- async scaleToFull(fontElement, container, ignoreHeight, ignoreWidth, margin, fontWeight, animDelay, addListener) {
- return this.scaleTo(1, fontElement, container, ignoreHeight, ignoreWidth, margin, fontWeight, animDelay, addListener);
- }
-
- async _getNewFontSize(scale, fontElement, container, ignoreHeight, ignoreWidth, margin, fontWeight, setFontSize) {
- margin = Helper.nonNull(margin, 10);
- ignoreHeight = Helper.nonNull(ignoreHeight, false);
- ignoreWidth = Helper.nonNull(ignoreWidth, false);
- fontWeight = Helper.nonNull(fontWeight, fontElement.innerHTML.length);
- setFontSize = Helper.nonNull(setFontSize, true);
-
- let hasNoTransitionClass = container.classList.contains("no-transition");
-
- if (!hasNoTransitionClass) {
- container.classList.add("no-transition");
- }
-
- const numChanged = 5;
- let oldDiffIndex = 0;
- let oldDiff = [];
-
- for (let i = 0; i < numChanged; i++) {
- oldDiff.push(0);
- }
-
- let beforeFontSize = fontElement.style.fontSize;
- let currentFontSize = 1;
- let widthDiff = 0;
- let heightDiff = 0;
- let containerWidth = 0;
- let containerHeight = 0;
- do {
- currentFontSize += oldDiff[oldDiffIndex] / (fontWeight + 1);
- fontElement.style.fontSize = currentFontSize + 'px';
-
- let containerStyle = window.getComputedStyle(container);
-
- containerWidth = containerStyle.getPropertyValue("width").replace('px', '');
- containerHeight = containerStyle.getPropertyValue("height").replace('px', '');
-
- widthDiff = containerWidth - fontElement.offsetWidth;
- heightDiff = containerHeight - fontElement.offsetHeight;
-
- oldDiffIndex = (oldDiffIndex+1)%numChanged;
- let newDiff = (ignoreWidth ? heightDiff : (ignoreHeight ? widthDiff : Math.min(widthDiff, heightDiff)));
- if (newDiff === oldDiff[(oldDiffIndex+1)%numChanged]) {
- break;
- }
- oldDiff[oldDiffIndex] = newDiff;
- } while ((widthDiff > (1 - scale) * containerWidth || ignoreWidth) && (heightDiff > (1 - scale) * containerHeight || ignoreHeight));
-
- currentFontSize -= margin;
- fontElement.style.fontSize = ((setFontSize) ? currentFontSize + "px" : beforeFontSize);
-
- if (!hasNoTransitionClass) {
- await new Promise((r) => {
- setTimeout(r, 50);
- });
- container.classList.remove("no-transition");
- }
-
- return currentFontSize;
- }
-}
-
-class AudioChain {
-
- constructor(context, sourceBuffer, chainFunction) {
- this.buffer = sourceBuffer;
- this.shouldLoop = false;
- this.loopStart = null;
- this.loopEnd = null;
- this.chainFunction = chainFunction;
- this.context = context;
-
- this.startTime = null;
- this.pauseTime = null;
- this.source = null;
-
- this.running = false;
- }
-
- setBuffer(buffer) {
- this.buffer = buffer;
- }
-
- setLooping(shouldLoop, loopStart, loopEnd) {
- this.shouldLoop = shouldLoop;
-
- if (Helper.isNotNull(loopStart)) {
- this.loopStart = loopStart;
- }
- if (Helper.isNotNull(loopEnd)) {
- this.loopEnd = loopEnd;
- }
- }
-
- async start(delay, offset, duration) {
- //sind sonst null, schmeißt in Android 5 einen fehler
- delay = Helper.nonNull(delay, 0);
- offset = Helper.nonNull(offset, 0);
- //Duration darf nicht gesetzt werden
- // duration = Helper.nonNull(duration, -1);
-
- let source = this.context.createBufferSource();
-
- source.loop = this.shouldLoop;
- if (Helper.isNotNull(this.loopStart)) {
- source.loopStart = this.loopStart;
- }
- if (Helper.isNotNull(this.loopEnd)) {
- source.loopEnd = this.loopEnd;
- }
- source.buffer = this.buffer;
- await this.chainFunction(source);
-
- if (Helper.isNull(duration)){
- source.start(delay, offset);
- }
- else{
- source.start(delay, offset, duration);
- }
- this.startTime = (new Date()).getTime() - (Helper.nonNull(offset, 0) * 1000);
- this.source = source;
- this.running = true;
- }
-
- async stop(delay) {
- if (Helper.isNotNull(this.source)) {
- delay = Helper.nonNull(delay, 0);
-
- this.pauseTime = ((new Date()).getTime()) - this.startTime;
- this.running = false;
- return this.source.stop(delay);
- }
- return null;
- }
-
- async resume() {
-
- if (!this.running) {
- return this.start(null, Helper.nonNull(this.pauseTime, 0) / 1000.0);
- }
- }
-}
-
-class SoundManager {
- static getInstance() {
- if (Helper.isNull(SoundManager.instance)) {
- SoundManager.instance = new SoundManager();
- }
- return SoundManager.instance;
- }
-
- constructor() {
- this.channels = {};
- if ('AudioContext' in window){
- this.context = new AudioContext();
- }
- else if ('webkitAudioContext' in window){
- this.context = new webkitAudioContext();
- }
- else {
- throw new Error("No audio context found!");
- }
- this.context.onstatechange = function () {
- console.log("stateChange from context", arguments);
- };
- this.context.oncomplete = function () {
- console.log("onComplete from context", arguments);
- };
-
- window.addEventListener("visibilitychange", (e) => {
- // console.log("visibility Change event", e);
- this.handleVisibilityChange();
- });
- //For safari
- let checkVisibility = ()=>{
- this.handleVisibilityChange();
- setTimeout(checkVisibility, 500);
- };
- checkVisibility();
- }
-
- isNotSuspended(){
- // return false;
- return this.context.state !== "suspended";
- }
-
- set(options, channel) {
- channel = Helper.nonNull(channel, SoundManager.CHANNELS.DEFAULT);
- let audioObject = Helper.nonNull(this.channels[channel], {});
-
- if (typeof options === "string") {
- options = {audio: options};
- }
-
- let audio = options.audio;
- if (Helper.isNotNull(audio)) {
- audioObject.loadedPromise = fetch(audio).then(res => res.arrayBuffer()).then(arrayBuffer => {
- return new Promise((r) => this.context.decodeAudioData(arrayBuffer, r));
- }).catch(e => console.error(e));
- this.stop(channel);
- }
- audioObject.muted = Helper.nonNull(options.muted, audioObject.muted, false);
- audioObject.volume = Helper.nonNull(options.volume, audioObject.volume, 1);
- audioObject.loop = Helper.nonNull(options.loop, audioObject.loop, false);
- audioObject.timeOffset = Helper.nonNull(options.timeOffset, audioObject.timeOffset, 0);
- this.channels[channel] = audioObject;
-
- if (audioObject.muted) {
- this.stop(channel);
- }
-
- return this.channels[channel];
- }
-
- async resumeContext(){
- if (typeof this.context.resume === "function") {
- return this.context.resume();
- }
- }
-
- async play(channel, audioOrOptions) {
- this.resumeContext();
- channel = Helper.nonNull(channel, SoundManager.CHANNELS.DEFAULT);
- if (Helper.isNull(audioOrOptions)) {
- audioOrOptions = {};
- } else if (!(typeof audioOrOptions === "object")) {
- audioOrOptions = {
- audio: audioOrOptions
- };
- }
- audioOrOptions.timeOffset = Helper.nonNull(audioOrOptions.timeOffset, 0);
-
- this.stop(channel);
- this.set(audioOrOptions, channel);
-
- if (!this.channels[channel].muted) {
- let buffer = await this.channels[channel].loadedPromise;
- let source = new AudioChain(this.context, buffer, (sourceNode) => {
- let gain = this.context.createGain();
- gain.gain.value = this.channels[channel].volume;
-
- sourceNode.connect(gain);
- gain.connect(this.context.destination);
- });
-
- source.setBuffer(buffer);
-
- //to prevent gap in mp3-files
- source.setLooping(this.channels[channel].loop, 0.3, buffer.duration - 0.3);
-
- this.channels[channel].source = source;
- await source.start();
- }
- return this.channels[channel];
- }
-
- stop(channel) {
- channel = Helper.nonNull(channel, SoundManager.CHANNELS.DEFAULT);
-
-
- let oldAudio = this.channels[channel];
- if (Helper.isNotNull(oldAudio) && Helper.isNotNull(oldAudio.source)) {
- oldAudio.source.stop();
- }
- }
-
- get(channel) {
- channel = Helper.nonNull(channel, SoundManager.CHANNELS.DEFAULT);
- return this.channels[channel];
- }
-
- async resume(channel) {
- channel = Helper.nonNull(channel, SoundManager.CHANNELS.DEFAULT);
- if (Helper.isNotNull(this.channels[channel]) && !this.channels[channel].muted && Helper.isNotNull(this.channels[channel].source)) {
- return this.channels[channel].source.resume();
- }
- }
-
- stopAll(){
- for (let k in this.channels) {
- if (Helper.isNotNull(this.channels[k].source)) {
- this.channels[k].source.stop();
- }
- }
- }
-
- resumeAllIfNotMuted(){
- for (let k in this.channels) {
- if (Helper.isNotNull(this.channels[k]) && !this.channels[k].muted && Helper.isNotNull(this.channels[k].source)) {
- this.channels[k].source.resume();
- }
- }
- }
-
- handleVisibilityChange() {
- if (document.hidden) {
- this.stopAll();
- }
- else {
- this.resumeAllIfNotMuted();
- }
- }
-}
-
-SoundManager.CHANNELS = {
- MUSIC: "music",
- SOUND: "sound",
- DEFAULT: "default"
-};
-
-InitPromise.addPromise(() => {
- PauseSite.onPauseListeners.push(() => {
- SoundManager.getInstance().stopAll();
- });
- PauseSite.onStartListeners.push(() => {
- SoundManager.getInstance().resumeAllIfNotMuted();
- });
-});
-
-class Code {
- constructor(args) {
- if (typeof args === "string") {
- args = {
- "code": args
- };
- }
- this.args = args;
- this.isCacheable = false;
- }
-
- setIsCacheable(isCacheable) {
- this.isCacheable = isCacheable;
- }
-
- getIsCacheable() {
- return this.isCacheable;
- }
-
- activate() {
- return DataManager.send("c/code", this.args);
- }
-}
-
-class CodeSite extends AbstractSite {
- constructor(siteManager) {
- super(siteManager, "core/html/load.html", "code");
- }
-
- onConstruct(args) {
- super.onConstruct(args);
- console.log(args);
-
- let resPromise = Promise.resolve();
- if (Helper.isNotNull(args["code"])) {
- let code = args["code"];
- let isCachable = Helper.nonNull(args["cachable"], false);
-
- let codeObject = new Code(code);
- codeObject.setIsCacheable(isCachable);
-
- let self = this;
- resPromise = codeObject.activate().then(function (res) {
- if (!res["success"]) {
- FlashMessenger.addMessage(FlashMessenger.MESSAGE_TYPE_SUCCESS, Translator.translate(res["errors"][0]));
- }
- else {
- FlashMessenger.addMessage(FlashMessenger.MESSAGE_TYPE_SUCCESS, Translator.translate(Helper.nonNull(res["result"]["successMessage"], "code-activated")));
- }
- self.finish();
- });
- }
- }
-}
-
-InitPromise.addPromise(function (app) {
- app.addDeepLink("code", CodeSite);
-});
-
-class ContactSite extends AbstractSite{
- constructor(siteManager) {
- super(siteManager, 'contact/html/contact.html', ContactSite.DEEP_LINK);
- }
-
- onFirstStart() {
- new Form(this.findBy("#contact-form"), "contact", "post").onSubmit((d) => {
- FlashMessenger.addMessage("contact-message-sent");
- this.finish();
- });
-
- super.onFirstStart();
- }
-}
-ContactSite.DEEP_LINK = "contactMe";
-
-InitPromise.addPromise((app) => {
- if (ContactSite.DEEP_LINK){
- app.addDeepLink(ContactSite.DEEP_LINK, ContactSite);
- }
-});
-
-class WordRotatorBaseSite extends AbstractSite {
- // createActionBarMenu(menu) {
- // menu = super.createActionBarMenu(menu);
- // // menu.addAction(SettingsSite.settingsAction.copy());
- // // let actions = menu.actions;
- // // for (let i = 0; i < actions.length; i++) {
- // // if (actions[i].title === "login" || actions[i].title === "registration"){
- // // actions[i].setVisible(false);
- // // }
- // // }
- // return menu;
- // }
-}
-
-class TemplateContainer{
- constructor(leafTemplate, parentTemplate, rowTemplate, triangleTemplate, columnTemplate){
- this.leafTemplate = leafTemplate;
- this.parentTemplate = parentTemplate;
- this.rowTemplate = rowTemplate;
- this.triangleTemplate = triangleTemplate;
- this.columnTemplate = columnTemplate;
- }
-
- copyLeafTemplate()
- {
- return Helper.cloneNode(this.leafTemplate);
- }
-
- copyParentTemplate()
- {
- return Helper.cloneNode(this.parentTemplate);
- }
-
- copyRowTemplate()
- {
- return Helper.cloneNode(this.rowTemplate);
- }
-
- copyTriangleTemplate()
- {
- return Helper.cloneNode(this.triangleTemplate);
- }
-
- copyColumnTemplate(){
- return Helper.cloneNode(this.columnTemplate);
- }
-}
-
-class Segment{
- constructor(element){
- this.rotation = 0;
- this.element = element;
- this.parent = null;
- }
-
- getCurrentRotations(rotations){
- return rotations;
- }
-
- sameAs(otherSegment){
- return false;
- }
-
- setParent(parent)
- {
- this.parent = parent;
- }
-
- getLevel()
- {
- if (this.parent!==null)
- {
- return this.parent.getLevel();
- }
- }
-
- canRotate(){
- return false;
- }
-
- isSolved(){
- return (this.rotation === 0);
- }
-
- async rotate(){
- return Promise.resolve();
- };
-
- _updateElement(){};
-
- applyRotations(rotations){
- return rotations;
- }
-
- applyLocks(locks)
- {
- return locks;
- }
-
- getCurrentLocked(lockedArray){
- return lockedArray;
- }
-
- getElement()
- {
- return this.element;
- }
-}
-
-class LeafSegment extends Segment {
-
- constructor(element, leaf) {
- super(element);
- this.leaf = 'A';
- if (Helper.isNotNull(leaf)) {
- this.setLeaf(leaf);
- }
- }
-
- sameAs(otherSegment) {
- // debugger;
- return (otherSegment instanceof LeafSegment && otherSegment.leaf === this.leaf);
- }
-
- setLeaf(leaf) {
- this.leaf = leaf;
- }
-
- _updateElement() {
- this.element.querySelector(".leaf-element").removeAllChildren().appendChild(document.createTextNode(this.leaf));
- }
-}
-
-class ParentSegment extends Segment {
- static initListener() {
- window.addEventListener("mousedown", (e) => {
- ParentSegment.mouseDownTarget = e.target;
- ParentSegment.clickPosition = {x: e.pageX, y: e.pageY};
- });
- window.addEventListener("mouseup", (e) => {
- ParentSegment.mouseDownTarget = null;
- ParentSegment.clickPosition = {};
- });
-
- window.addEventListener("touchstart", (e) => {
- if (e.targetTouches.length === 1) {
- ParentSegment.mouseDownTarget = e.targetTouches[0].target;
- ParentSegment.clickPosition = {x: e.targetTouches[0].pageX, y: e.targetTouches[0].pageY};
- }
- // else if (Array.isArray(e.path) && e.path.length >= 1) {
- // ParentSegment.mouseDownTarget = e.path[0];
- // ParentSegment.clickPosition = null;
- // }
- });
- window.addEventListener("touchend", (e) => {
- ParentSegment.mouseDownTarget = null;
- ParentSegment.clickPosition = {};
- });
- }
-
- setIsRotatable(rotatable) {
- this.rotatable = rotatable;
- this._updateElement();
- }
-
- constructor(element) {
- super(element);
- this.children = [];
- this.class = "rotate-0";
- this.rotatable = true;
-
- this.userRotationDelta = 100;
- this.lastUserRotation = 0;
-
- let self = this;
- this.touchendListener = function (e) {
- let now = new Date().getTime();
-
- // console.log("touchendListener", e,now, self.lastUserRotation);
- let target = null;
- let position = null;
-
- if (e.changedTouches.length >= 1) {
- target = document.elementFromPoint(e.changedTouches[0].pageX, e.changedTouches[0].pageY);
- position = {x: e.changedTouches[0].pageX, y: e.changedTouches[0].pageY};
- }
- if (target != null && e.targetTouches.length === 0 && self.element.contains(ParentSegment.mouseDownTarget) && self.element.contains(target)) {
- e.stopPropagation();
- e.preventDefault();
- if (self.lastUserRotation+self.userRotationDelta > now){
- return;
- }
- self.getLevel().segmentClickedListener(self);
- self.rotate(ParentSegment.mouseDownTarget, target, ParentSegment.clickPosition, position);
- // console.log("touchendListener stopped event", e);
-
- self.lastUserRotation = new Date().getTime();
- }
- };
- this.mouseupListener = function (e) {
- let now = new Date().getTime();
- // console.log("mouseupListener", e,now, self.lastUserRotation);
-
- if (ParentSegment.mouseDownTarget !== null && self.element.contains(ParentSegment.mouseDownTarget) && self.element.contains(e.target)) {
- let position = {x: e.pageX, y: e.pageY};
- e.stopPropagation();
- e.preventDefault();
- if (self.lastUserRotation+self.userRotationDelta > now){
- return;
- }
- self.getLevel().segmentClickedListener(self);
- self.rotate(ParentSegment.mouseDownTarget, e.target, ParentSegment.clickPosition, position);
- // console.log("mouseupListener stopped event", e);
- self.lastUserRotation = new Date().getTime();
- }
- };
- }
-
- canRotate() {
- return (this.rotatable && !this.getLevel().getHasWon());
- }
-
- async rotate(firstElem, secondElem, firstPosition, secondPosition) {
- const timeout = 250;
- const clickTolerance = 5;
-
- let rotationDirection = 1;
- if (Helper.isNotNull(secondElem) && Helper.isNotNull(firstElem) &&
- (Helper.isNull(firstPosition) || Helper.isNull(secondPosition) ||
- Math.abs(firstPosition.x - secondPosition.x) > clickTolerance ||
- Math.abs(firstPosition.y - secondPosition.y) > clickTolerance)) {
-
- let firstIndex = -1;
- let secondIndex = -1;
- let rotationIndexes = [0, 1, 3, 2];
- for (let i = 0; i < this.children.length; i++) {
- if (this.children[rotationIndexes[i]].element === firstElem || this.children[rotationIndexes[i]].element.contains(firstElem)) {
- firstIndex = (i + this.rotation / 90) % 4;
- }
- if (this.children[rotationIndexes[i]].element === secondElem || this.children[rotationIndexes[i]].element.contains(secondElem)) {
- secondIndex = (i + this.rotation / 90) % 4;
- }
- }
-
- if (firstIndex >= 0 && secondIndex >= 0) {
- if (firstIndex === 2 && (secondIndex === 0 || secondIndex === 1)
- || firstIndex === 1 && (secondIndex === 0 || secondIndex === 3)
- || (firstIndex === 0 && secondIndex === 3)
- || (firstIndex === 3 && secondIndex === 2)) {
- rotationDirection = -1;
- }
- }
- }
-
- if (this.canRotate()) {
- this.rotation += 360 + 90 * rotationDirection;
- this.rotation %= 360;
-
- let currentRotation = this.rotation;
-
- this._updateRotationClass();
- this.element.classList.add("rotating");
- if (rotationDirection === -1) {
- this.element.classList.add("reverse");
- }
-
- let delayPromise = new Promise(function (resolve) {
- setTimeout(resolve, timeout);
- }).then(() => {
- if (this.rotation === currentRotation) {
- this.element.classList.remove("rotating");
- this.element.classList.remove("reverse");
- }
- });
- this.getLevel().checkHasWon(delayPromise);
- return delayPromise;
- }
- }
-
- sameAs(otherSegment) {
- if (!(otherSegment instanceof ParentSegment) || otherSegment.children.length !== this.children.length) {
- return false;
- }
- for (let i = 0; i < this.children.length; i++) {
- if (!this.children[i].sameAs(otherSegment.children[i])) {
- return false;
- }
- }
- return true;
- }
-
- applyRotations(rotations) {
- this.rotation = rotations[0];
-
- if (isNaN(this.rotation)) {
- this.rotation = 0;
- }
-
- rotations.splice(0, 1);
- for (let i = 0, n = this.children.length; i < n; i++) {
- rotations = this.children[i].applyRotations(rotations);
- }
- return rotations;
- }
-
- applyLocks(locks) {
- this.rotatable = (locks[0] !== false);
- locks.splice(0, 1);
- for (let i = 0, n = this.children.length; i < n; i++) {
- locks = this.children[i].applyLocks(locks);
- }
- return locks;
- }
-
- getCurrentRotations(rotations) {
- rotations.push(this.rotation);
- for (let i = 0, n = this.children.length; i < n; i++) {
- rotations = this.children[i].getCurrentRotations(rotations);
- }
- return rotations;
- }
-
- getCurrentLocked(locked) {
- locked.push(this.rotatable);
- for (let i = 0, n = this.children.length; i < n; i++) {
- locked = this.children[i].getCurrentLocked(locked);
- }
- return locked;
- }
-
- isSolved(checkChildren) {
- checkChildren = Helper.nonNull(checkChildren, true);
- if (checkChildren) {
- for (let i = 0, n = this.children.length; i < n; i++) {
- if (!this.children[i].isSolved()) {
- return false;
- }
- }
- }
- return (this.rotation === 0 || (
- this.children[0].sameAs(this.children[3]) && this.children[1].sameAs(this.children[2]) && (
- this.rotation === 180 || this.children[0].sameAs(this.children[1]))))
- }
-
- setChildren(children) {
- this.children = [];
- for (let i = 0, n = children.length; i < n; i++) {
- this.addChild(children[i]);
- }
- }
-
- addChild(child) {
- this.children.push(child);
- child.setParent(this);
- this._updateElement();
- }
-
- _updateRotationClass() {
- // this.style.transform = "rotate("+this.rotation+"deg)";
- this.element.classList.remove(this.class);
- this.class = "rotate-" + this.rotation;
- if (this.class === "rotate-0") {
- this.class = "rotate-360";
- }
- this.element.classList.add(this.class);
- }
-
- _updateElement() {
- let layer = this._getLayer();
- if (layer >= 2) {
- this.element.classList.add("layer-" + layer);
- }
-
- if (!this.rotatable) {
- this.element.classList.add("locked");
- }
-
- const childContainer = this.element.querySelector(".child-container");
- childContainer.removeAllChildren();
-
- this._updateRotationClass();
-
- this.element.removeEventListener("mouseup", this.mouseupListener);
- this.element.removeEventListener("touchend", this.touchendListener);
-
- this.element.addEventListener("mouseup", this.mouseupListener);
- this.element.addEventListener("touchend", this.touchendListener);
-
- for (let i = 0, n = this.children.length; i < n; i++) {
- this.children[i]._updateElement();
- childContainer.appendChild(this.children[i].getElement());
- if (i % 2 === 1 && this.children.length - 1 !== i) {
- childContainer.appendChild(document.createElement("br"));
- }
- }
- }
-
- _getLayer() {
- if (this.children.length >= 1 && this.children[0] && this.children[0] instanceof ParentSegment) {
- return this.children[0]._getLayer() + 1;
- }
- return 1;
- }
-}
-
-ParentSegment.initListener();
-
-class Level {
- constructor(templateContainer) {
- this.rootSegment = null;
- this.words = [];
- this.startRotations = [];
- this.templateContainer = templateContainer;
-
- this.hasWon = false;
- this.id = null;
-
- this.wonResolver = null;
- this.giveUpResolver = null;
-
- const self = this;
- this.wonPromise = new Promise((resolve, reject) => {
- self.wonResolver = resolve;
- self.giveUpResolver = reject;
- });
-
- this.segmentClickedListener = () => {};
- }
-
- saveAsCurrentLevel(){
- let rotations = this.getCurrentRotations();
- let locked = this.getCurrentLocked();
- localStorage.setItem("currentLevel", JSON.stringify({"id": this.id, "rotations": rotations, "locks":locked}));
- }
-
- getCurrentLocked(){
- if (this.rootSegment !== null)
- {
- return this.rootSegment.getCurrentLocked([]);
- }
- return [];
- }
-
- getCurrentRotations(){
- if (this.rootSegment !== null)
- {
- return this.rootSegment.getCurrentRotations([]);
- }
- return [];
- }
-
- setLocks(locks)
- {
- if (this.rootSegment !== null){
- this.rootSegment.applyLocks(locks);
- }
- }
-
- setId(id)
- {
- this.id = id;
- }
-
- getId()
- {
- return this.id;
- }
-
- getLevel()
- {
- return this;
- }
-
- setRootSegment(rootSegment)
- {
- this.rootSegment = rootSegment;
- this.rootSegment.setParent(this);
- if (this.startRotations)
- {
- this.applyRotations();
- }
- }
-
- setWords(words)
- {
- this.words = [];
- for (let i = 0, n = words.length; i < n; i++) {
- this.words.push(words[i].replace(/ß/g, "ẞ").toUpperCase());
- }
- }
-
- setStartRotations(rotations)
- {
- this.startRotations = rotations;
- }
-
- applyRotations(rotations)
- {
- if (this.rootSegment)
- {
- rotations = Helper.nonNull(rotations, this.startRotations);
- this.rootSegment.applyRotations(rotations);
- }
- }
-
- getHasWon()
- {
- return this.hasWon;
- }
-
- checkHasWon(delayPromise) {
- if (this.rootSegment.isSolved()){
- this.hasWon = true;
- const self = this;
- Promise.resolve(delayPromise).then(()=>{
- self.wonResolver(true);
- });
- return true;
- }
- this.saveAsCurrentLevel();
- return false;
- }
-
- getWonPromise(){
- return this.wonPromise;
- }
-
- getRootSegment(){
- return this.rootSegment;
- }
-
- createSegments() {};
-
- getRotatableSegments(){
- return Level._getRotatableSegmentsFrom(this.rootSegment);
- }
-
- setSegmentClickedListener(listener){
- this.segmentClickedListener = listener;
- }
-
- static _getRotatableSegmentsFrom(segment){
- let rotatable = [];
- if (segment.canRotate())
- {
- rotatable.push(segment);
- }
- if (segment instanceof ParentSegment){
- for (let i = 0; i < segment.children.length; i++) {
- rotatable.push.apply(rotatable, Level._getRotatableSegmentsFrom(segment.children[i]));
- }
- }
- return rotatable;
- }
-
- static _createLeafsForWord(word, leafSegmentTemplate)
- {
- let leafSegments = [];
- for (let i = 0, n = word.length; i < n; i++) {
- leafSegments.push(new LeafSegment(Helper.cloneNode(leafSegmentTemplate), word.charAt(i)));
- }
- return leafSegments;
- }
-}
-
-class RowSegment extends ParentSegment{
- constructor(element) {
- super(element);
- this.rotatable = false;
- }
-
- applyRotations(rotations)
- {
- for (let i = 0, n = this.children.length; i < n; i++) {
- rotations = this.children[i].applyRotations(rotations);
- }
- return rotations;
- }
-
- getCurrentRotations(rotations){
- for (let i = 0, n = this.children.length; i < n; i++) {
- rotations = this.children[i].getCurrentRotations(rotations);
- }
- return rotations;
- }
-
- getCurrentLocked(locked) {
- for (let i = 0, n = this.children.length; i < n; i++) {
- locked = this.children[i].getCurrentLocked(locked);
- }
- return locked;
- }
-
- applyLocks(locks) {
- for (let i = 0, n = this.children.length; i < n; i++) {
- locks = this.children[i].applyLocks(locks);
- }
- return locks;
- }
-
- _updateElement() {
- const childContainer = this.element.querySelector(".child-container");
- childContainer.removeAllChildren();
-
- this._updateRotationClass();
-
- const self = this;
- this.element.onclick = function (e) {
- self.rotate();
- e.stopPropagation();
- };
-
- for (let i = 0, n = this.children.length; i < n; i++) {
- this.children[i]._updateElement();
- childContainer.appendChild(this.children[i].getElement());
- }
- }
-}
-
-class RowLevel extends Level {
- constructor(container, wordLength) {
- super(container);
- this.wordLength = wordLength;
- }
-
- createSegments() {
- if (this.words.length >= 2 && this.words[0].length >= this.wordLength && this.words[1].length >= this.wordLength) {
- let leafsWordOne = Level._createLeafsForWord(this.words[0], this.templateContainer.copyLeafTemplate());
- let leafsWordTwo = Level._createLeafsForWord(this.words[1], this.templateContainer.copyLeafTemplate());
-
- let rootSegment = new RowSegment(this.templateContainer.copyRowTemplate());
- for (let i = 0, n = this.wordLength / 2; i < n; i++) {
- let parent = new ParentSegment(this.templateContainer.copyParentTemplate());
- parent.addChild(leafsWordOne[2 * i]);
- parent.addChild(leafsWordOne[2 * i + 1]);
- parent.addChild(leafsWordTwo[2 * i]);
- parent.addChild(leafsWordTwo[2 * i + 1]);
- rootSegment.addChild(parent);
- }
- // rootSegment.applyRotations(this.startRotations);
- this.setRootSegment(rootSegment);
- }
- }
-}
-
-class SimpleLevel extends RowLevel{
- constructor(container) {
- super(container, 6);
- }
-}
-
-class RowLevel8 extends RowLevel{
- constructor(container) {
- super(container, 8);
- }
-}
-
-class RowLevel10 extends RowLevel{
- constructor(container) {
- super(container, 10);
- }
-}
-
-class TriangleSegment extends RowSegment{
-
-}
-
-class SixWordsRowLevel extends Level {
-
- constructor(templateContainer, wordLength) {
- super(templateContainer);
- this.wordLength = wordLength;
- }
-
- createSegments() {
- if (this.words.length >= 6 &&
- this.words[0].length >= this.wordLength &&
- this.words[1].length >= this.wordLength &&
- this.words[2].length >= this.wordLength &&
- this.words[3].length >= this.wordLength &&
- this.words[4].length >= this.wordLength &&
- this.words[5].length >= this.wordLength
- ) {
- let leafsWords = [];
- leafsWords[0] = Level._createLeafsForWord(this.words[0], this.templateContainer.copyLeafTemplate());
- leafsWords[1] = Level._createLeafsForWord(this.words[1], this.templateContainer.copyLeafTemplate());
- leafsWords[2] = Level._createLeafsForWord(this.words[2], this.templateContainer.copyLeafTemplate());
- leafsWords[3] = Level._createLeafsForWord(this.words[3], this.templateContainer.copyLeafTemplate());
- leafsWords[4] = Level._createLeafsForWord(this.words[4], this.templateContainer.copyLeafTemplate());
- leafsWords[5] = Level._createLeafsForWord(this.words[5], this.templateContainer.copyLeafTemplate());
-
- let rootSegment = new RowSegment(this.templateContainer.copyRowTemplate());
- for (let i = 0; i < this.wordLength / 4; i++) {
-
- let parents = [];
- parents[0] = new ParentSegment(this.templateContainer.copyParentTemplate());
- parents[1] = new ParentSegment(this.templateContainer.copyParentTemplate());
- parents[2] = new ParentSegment(this.templateContainer.copyParentTemplate());
- parents[3] = new ParentSegment(this.templateContainer.copyParentTemplate());
- parents[4] = new ParentSegment(this.templateContainer.copyParentTemplate());
- parents[5] = new ParentSegment(this.templateContainer.copyParentTemplate());
-
- parents[0].addChild(leafsWords[0][4*i]);
- parents[0].addChild(leafsWords[0][4*i+1]);
- parents[0].addChild(leafsWords[1][4*i]);
- parents[0].addChild(leafsWords[1][4*i+1]);
-
- parents[1].addChild(leafsWords[0][4*i+2]);
- parents[1].addChild(leafsWords[0][4*i+3]);
- parents[1].addChild(leafsWords[1][4*i+2]);
- parents[1].addChild(leafsWords[1][4*i+3]);
-
- parents[2].addChild(leafsWords[2][4*i]);
- parents[2].addChild(leafsWords[2][4*i+1]);
- parents[2].addChild(leafsWords[3][4*i]);
- parents[2].addChild(leafsWords[3][4*i+1]);
-
- parents[3].addChild(leafsWords[2][4*i+2]);
- parents[3].addChild(leafsWords[2][4*i+3]);
- parents[3].addChild(leafsWords[3][4*i+2]);
- parents[3].addChild(leafsWords[3][4*i+3]);
-
- parents[4].addChild(leafsWords[4][4*i]);
- parents[4].addChild(leafsWords[4][4*i+1]);
- parents[4].addChild(leafsWords[5][4*i]);
- parents[4].addChild(leafsWords[5][4*i+1]);
-
- parents[5].addChild(leafsWords[4][4*i+2]);
- parents[5].addChild(leafsWords[4][4*i+3]);
- parents[5].addChild(leafsWords[5][4*i+2]);
- parents[5].addChild(leafsWords[5][4*i+3]);
-
- let parent = new ParentSegment(this.templateContainer.copyParentTemplate());
- let triangle = new TriangleSegment(this.templateContainer.copyTriangleTemplate());
- if (i % 2 === 0) {
- parent.addChild(parents[0]);
- parent.addChild(parents[1]);
- parent.addChild(parents[2]);
- parent.addChild(parents[3]);
-
- let rowSegment = new RowSegment(this.templateContainer.copyRowTemplate());
-
- rowSegment.addChild(parents[4]);
- rowSegment.addChild(parents[5]);
-
- triangle.addChild(parent);
- triangle.addChild(rowSegment);
-
- triangle.getElement().classList.add("type-1");
- }
- else {
-
- let rowSegment = new RowSegment(this.templateContainer.copyRowTemplate());
-
- rowSegment.addChild(parents[0]);
- rowSegment.addChild(parents[1]);
-
- triangle.addChild(rowSegment);
- triangle.addChild(parent);
-
- parent.addChild(parents[2]);
- parent.addChild(parents[3]);
- parent.addChild(parents[4]);
- parent.addChild(parents[5]);
-
- triangle.getElement().classList.add("type-2");
- }
- rootSegment.addChild(triangle);
- }
- this.setRootSegment(rootSegment);
- }
- }
-}
-
-class SixWordsRowLevel8 extends SixWordsRowLevel {
- constructor(templateContainer) {
- super(templateContainer, 8);
- }
-}
-
-class SixWordsRowLevel12 extends SixWordsRowLevel {
- constructor(templateContainer) {
- super(templateContainer, 12);
- }
-}
-
-class FourWordsLevel extends Level {
-
- constructor(templateContainer, wordLength) {
- super(templateContainer);
- this.wordLength = wordLength;
- }
-
- createSegments() {
- if (this.words.length >= 4 &&
- this.words[0].length >= this.wordLength &&
- this.words[1].length >= this.wordLength &&
- this.words[2].length >= this.wordLength &&
- this.words[3].length >= this.wordLength
- ) {
- let leafsWords = [];
- leafsWords[0] = Level._createLeafsForWord(this.words[0], this.templateContainer.copyLeafTemplate());
- leafsWords[1] = Level._createLeafsForWord(this.words[1], this.templateContainer.copyLeafTemplate());
- leafsWords[2] = Level._createLeafsForWord(this.words[2], this.templateContainer.copyLeafTemplate());
- leafsWords[3] = Level._createLeafsForWord(this.words[3], this.templateContainer.copyLeafTemplate());
-
- let rootSegment = new RowSegment(this.templateContainer.copyRowTemplate());
- for (let i = 0; i < this.wordLength / 4; i++) {
-
- let parents = [];
- parents[0] = new ParentSegment(this.templateContainer.copyParentTemplate());
- parents[1] = new ParentSegment(this.templateContainer.copyParentTemplate());
- parents[2] = new ParentSegment(this.templateContainer.copyParentTemplate());
- parents[3] = new ParentSegment(this.templateContainer.copyParentTemplate());
-
- parents[0].addChild(leafsWords[0][4 * i]);
- parents[0].addChild(leafsWords[0][4 * i + 1]);
- parents[0].addChild(leafsWords[1][4 * i]);
- parents[0].addChild(leafsWords[1][4 * i + 1]);
-
- parents[1].addChild(leafsWords[0][4 * i + 2]);
- parents[1].addChild(leafsWords[0][4 * i + 3]);
- parents[1].addChild(leafsWords[1][4 * i + 2]);
- parents[1].addChild(leafsWords[1][4 * i + 3]);
-
- parents[2].addChild(leafsWords[2][4 * i]);
- parents[2].addChild(leafsWords[2][4 * i + 1]);
- parents[2].addChild(leafsWords[3][4 * i]);
- parents[2].addChild(leafsWords[3][4 * i + 1]);
-
- parents[3].addChild(leafsWords[2][4 * i + 2]);
- parents[3].addChild(leafsWords[2][4 * i + 3]);
- parents[3].addChild(leafsWords[3][4 * i + 2]);
- parents[3].addChild(leafsWords[3][4 * i + 3]);
-
- let parent = new ParentSegment(this.templateContainer.copyParentTemplate());
- parent.addChild(parents[0]);
- parent.addChild(parents[1]);
- parent.addChild(parents[2]);
- parent.addChild(parents[3]);
-
- rootSegment.addChild(parent);
- }
- this.setRootSegment(rootSegment);
- }
- }
-}
-
-class FourWordsLevel8 extends FourWordsLevel{
- constructor(templateContainer) {
- super(templateContainer, 8);
- }
-}
-
-class FourWordsLevel12 extends FourWordsLevel{
- constructor(templateContainer) {
- super(templateContainer, 12);
- }
-}
-
-class ColumnSegment extends RowSegment{
-
- _updateElement() {
- const childContainer = this.element.querySelector(".child-container");
- childContainer.removeAllChildren();
-
- this._updateRotationClass();
-
- const self = this;
- this.element.onclick = function (e) {
- self.rotate();
- e.stopPropagation();
- };
-
- for (let i = 0, n = this.children.length; i < n; i++) {
- this.children[i]._updateElement();
- childContainer.appendChild(this.children[i].getElement());
- }
- }
-
- // constructor(element) {
- // super(element);
- // this.rotatable = false;
- // }
- //
- // applyRotations(rotations)
- // {
- // for (let i = 0, n = this.children.length; i < n; i++) {
- // rotations = this.children[i].applyRotations(rotations);
- // }
- // return rotations;
- // }
- //
- // getCurrentRotations(rotations){
- // for (let i = 0, n = this.children.length; i < n; i++) {
- // rotations = this.children[i].getCurrentRotations(rotations);
- // }
- // return rotations;
- // }
- //
- // getCurrentLocked(locked) {
- // for (let i = 0, n = this.children.length; i < n; i++) {
- // locked = this.children[i].getCurrentLocked(locked);
- // }
- // return locked;
- // }
- //
- // applyLocks(locks) {
- // for (let i = 0, n = this.children.length; i < n; i++) {
- // locks = this.children[i].applyLocks(locks);
- // }
- // return locks;
- // }
- //
- // _updateElement() {
- // const childContainer = this.element.querySelector(".child-container");
- // childContainer.removeAllChildren();
- //
- // this._updateRotationClass();
- //
- // const self = this;
- // this.element.onclick = function (e) {
- // self.rotate();
- // e.stopPropagation();
- // };
- //
- // for (let i = 0, n = this.children.length; i < n; i++) {
- // this.children[i]._updateElement();
- // childContainer.appendChild(this.children[i].getElement());
- // }
- // }
-}
-
-class BigSegmentsLevels extends Level{
- constructor(templateContainer, wordLength, bigSegmentPositions) {
- super(templateContainer);
- this.wordLength = wordLength;
- this.bigSegmentPositions = bigSegmentPositions;
- }
-
- createSegments() {
- if (this.words.length >= 4 &&
- this.words[0].length >= this.wordLength &&
- this.words[1].length >= this.wordLength &&
- this.words[2].length >= this.wordLength &&
- this.words[3].length >= this.wordLength &&
- this.wordLength >= 4
- ) {
- let leafsWords = [];
- leafsWords[0] = Level._createLeafsForWord(this.words[0], this.templateContainer.copyLeafTemplate());
- leafsWords[1] = Level._createLeafsForWord(this.words[1], this.templateContainer.copyLeafTemplate());
- leafsWords[2] = Level._createLeafsForWord(this.words[2], this.templateContainer.copyLeafTemplate());
- leafsWords[3] = Level._createLeafsForWord(this.words[3], this.templateContainer.copyLeafTemplate());
-
- let rootSegment = new RowSegment(this.templateContainer.copyRowTemplate());
- for (let i = 0; i < this.wordLength / 2; i++) {
- let parents = [];
- parents[0] = new ParentSegment(this.templateContainer.copyParentTemplate());
- parents[1] = new ParentSegment(this.templateContainer.copyParentTemplate());
-
- parents[0].addChild(leafsWords[0][2 * i]);
- parents[0].addChild(leafsWords[0][2 * i + 1]);
- parents[0].addChild(leafsWords[1][2 * i]);
- parents[0].addChild(leafsWords[1][2 * i + 1]);
-
- parents[1].addChild(leafsWords[2][2 * i]);
- parents[1].addChild(leafsWords[2][2 * i + 1]);
- parents[1].addChild(leafsWords[3][2 * i]);
- parents[1].addChild(leafsWords[3][2 * i + 1]);
-
- let parentSegment =null;
- if (this.bigSegmentPositions.indexOf(i) !== -1){
- parents[2] = new ParentSegment(this.templateContainer.copyParentTemplate());
- parents[3] = new ParentSegment(this.templateContainer.copyParentTemplate());
-
- parents[2].addChild(leafsWords[0][2 * i + 2]);
- parents[2].addChild(leafsWords[0][2 * i + 3]);
- parents[2].addChild(leafsWords[1][2 * i + 2]);
- parents[2].addChild(leafsWords[1][2 * i + 3]);
-
- parents[3].addChild(leafsWords[2][2 * i + 2]);
- parents[3].addChild(leafsWords[2][2 * i + 3]);
- parents[3].addChild(leafsWords[3][2 * i + 2]);
- parents[3].addChild(leafsWords[3][2 * i + 3]);
-
- parentSegment = new ParentSegment(this.templateContainer.copyParentTemplate());
- parentSegment.addChild(parents[0]);
- parentSegment.addChild(parents[2]);
- parentSegment.addChild(parents[1]);
- parentSegment.addChild(parents[3]);
- i++;
- }
- else{
- parentSegment = new ColumnSegment(this.templateContainer.copyColumnTemplate());
- parentSegment.addChild(parents[0]);
- parentSegment.addChild(parents[1]);
- }
-
- rootSegment.addChild(parentSegment);
- }
- this.setRootSegment(rootSegment);
- }
- }
-}
-
-class SimpleFourWordsLevel extends BigSegmentsLevels{
- constructor(templateContainer, wordLength, bigSegmentPosition) {
- super(templateContainer, wordLength, [bigSegmentPosition]);
- }
-}
-
-class SimpleFourWordsLevel10_0 extends SimpleFourWordsLevel{
- constructor(templateContainer) {
- super(templateContainer, 10, 0);
- }
-}
-
-class SimpleFourWordsLevel10_1 extends SimpleFourWordsLevel{
- constructor(templateContainer) {
- super(templateContainer, 10, 1);
- }
-}
-
-class SimpleFourWordsLevel10_2 extends SimpleFourWordsLevel{
- constructor(templateContainer) {
- super(templateContainer, 10, 2);
- }
-}
-
-class SimpleFourWordsLevel10_3 extends SimpleFourWordsLevel{
- constructor(templateContainer) {
- super(templateContainer, 10, 3);
- }
-}
-
-class TwoSegmentFourWordsLevel10_0_3 extends BigSegmentsLevels{
- constructor(templateContainer) {
- super(templateContainer, 10, [0,3]);
- }
-}
-
-class TwoSegmentFourWordsLevel10_1_3 extends BigSegmentsLevels{
- constructor(templateContainer) {
- super(templateContainer, 10, [1,3]);
- }
-}
-
-class TwoSegmentFourWordsLevel10_0_2 extends BigSegmentsLevels{
- constructor(templateContainer) {
- super(templateContainer, 10, [0,2]);
- }
-}
-
-class LevelHelper {
- static setLevelType(typeId, level) {
- LevelHelper.types[typeId] = level;
- }
-
- static getLevelClass(type) {
- return LevelHelper.types[type];
- }
-
- static inflateLevel(jsonLevel, templateContainer) {
- let level = new (LevelHelper.types[jsonLevel["rendererType"]])(templateContainer);
- level.setWords(jsonLevel["words"]);
- level.setId(jsonLevel["id"]);
-
- for (let i = 0, n = jsonLevel["rotations"].length; i < n; i++) {
- if (jsonLevel["rotations"][i] <= 4) {
- jsonLevel["rotations"][i] = 90 * jsonLevel["rotations"][i];
- }
- }
-
- level.setStartRotations(jsonLevel["rotations"]);
- return level;
- }
-}
-
-LevelHelper.types = {
- 20: SimpleLevel,
- 40: RowLevel8,
- 60: RowLevel10,
- 80: SimpleFourWordsLevel10_0,
- 81: SimpleFourWordsLevel10_1,
- 82: SimpleFourWordsLevel10_2,
- 83: SimpleFourWordsLevel10_3,
- 100: SixWordsRowLevel8,
- 110: TwoSegmentFourWordsLevel10_0_3,
- 111: TwoSegmentFourWordsLevel10_1_3,
- 112: TwoSegmentFourWordsLevel10_0_2,
- 120: FourWordsLevel8,
- 140: SixWordsRowLevel12,
- 160: FourWordsLevel12,
-};
-
-class WordRotatorDb extends MyDb {
-
- static async getInstance() {
- if (Helper.isNull(WordRotatorDb.instance)) {
- WordRotatorDb.instance = new WordRotatorDb();
- }
- await WordRotatorDb.instance.queryPromise;
- return WordRotatorDb.instance;
- }
-
- constructor() {
- super("wordRotator", 6);
- }
-
- upgrade(db, oldVersion, newVersion, e) {
- console.log("upgrading!");
-
- if (Helper.isNull(oldVersion) || oldVersion < 1 && newVersion >= 1) {
- let levelObjectStore = db.createObjectStore(WordRotatorDb.OBJECT_STORE.LEVEL, {"keyPath": "id"});
- }
- if (Helper.isNull(oldVersion) || oldVersion < 2 && newVersion >= 2) {
- let levelObjectStore = e.target.transaction.objectStore(WordRotatorDb.OBJECT_STORE.LEVEL);
- levelObjectStore.createIndex("played", ["deleted", "played", "difficulty", "id"], {"unique": false});
- }
- if (Helper.isNull(oldVersion) || oldVersion < 3 && newVersion >= 3) {
- let levelObjectStore = e.target.transaction.objectStore(WordRotatorDb.OBJECT_STORE.LEVEL);
- levelObjectStore.createIndex("difficulty", "difficulty", {"unique": false});
- }
-
- console.log("update", oldVersion, newVersion);
- if (Helper.isNull(oldVersion) || oldVersion < 6 && newVersion >= 6) {
- try {
- db.deleteObjectStore(WordRotatorDb.OBJECT_STORE.SYSTEM_VARS);
- } catch (e) {}
- let levelObjectStore = db.createObjectStore(WordRotatorDb.OBJECT_STORE.SYSTEM_VARS, {"keyPath": "name"});
- }
- };
-
- async saveManyLevels(levels) {
- return this.saveMany(levels, WordRotatorDb.OBJECT_STORE.LEVEL).catch(e => {
- console.error("insert error!", e);
- });
- }
-
- async loadLevel(levelId) {
- // console.log("load Level", levelId);
- return this.load(levelId, WordRotatorDb.OBJECT_STORE.LEVEL);
- }
-
- async loadNextLevel(rendererTypes) {
- let levels = await this.loadAll(WordRotatorDb.OBJECT_STORE.LEVEL);
- levels = levels.sort((a, b) => {
- return (a["difficulty"] - b["difficulty"]);
- });
-
- let wrongLevels = [];
- let newLevels = [];
- let difficulty = -1;
- for (let i = 0, n = levels.length; i < n; i++) {
- if ((difficulty < 0 || difficulty === levels[i]["difficulty"]) && !levels[i]["deleted"] && !levels[i]["played"] && rendererTypes.indexOf(levels[i]["rendererType"]) !== -1) {
- newLevels.push(levels[i]);
- difficulty = levels[i]["difficulty"];
- }
- else if (levels[i]["difficulty"] !== 0 && !levels[i]["deleted"] && !levels[i]["played"]) {
- wrongLevels.push(levels[i]);
- }
- }
-
- if (newLevels.length === 0) {
- return null;
- }
-
- return newLevels[Math.round(Math.random() * newLevels.length) % newLevels.length];
- }
-
- async saveLevelPlayed(levelId) {
- const level = await this.loadLevel(levelId);
- level.played = true;
- return await this.saveObj(level, WordRotatorDb.OBJECT_STORE.LEVEL);
- }
-
- async loadDateLastSync() {
- let dateLastSync = await this.load("date-last-sync", WordRotatorDb.OBJECT_STORE.SYSTEM_VARS);
- if (dateLastSync) {
- return dateLastSync["value"];
- }
- return null;
- }
-
- async saveDateLastSync(value) {
- return await this.saveObj({"name": "date-last-sync", "value": value}, WordRotatorDb.OBJECT_STORE.SYSTEM_VARS)
- }
-}
-
-WordRotatorDb.OBJECT_STORE = {
- LEVEL: "level",
- SYSTEM_VARS: "vars"
-};
-WordRotatorDb.instance = null;
-
-class EndSite extends WordRotatorBaseSite{
- constructor(siteManager) {
- super(siteManager, "html/application/end.html");
- }
-
- onStart(args) {
- Matomo.update("End Site");
- return super.onStart(args);
- }
-}
-
-class LevelSite extends WordRotatorBaseSite {
- constructor(siteManager) {
- super(siteManager, "html/application/level.html");
- }
-
- createActionBarMenu(menu) {
- menu = super.createActionBarMenu(menu);
-
- let coinAction = new MenuAction(Helper.nonNull(localStorage.getItem("coins"), "0"), () => {
- }, MenuAction.SHOW_ALWAYS, 900);
- coinAction.setShouldTranslate(false);
- coinAction._liClass = "coin-counter";
- menu.addAction(coinAction);
- this.coinAction = coinAction;
-
- return menu;
- }
-
- onConstruct(args) {
- this.levelCounter = Helper.nonNull(localStorage.getItem("levelCounter"), 1);
- this.levelScaler = () => {
- };
- this.wonParams = {
- aborted: false,
- coinCounterTimer: null,
- };
- this.coinPromise = Promise.resolve();
-
- let settingsManager = SettingsManager.getInstance();
- let soundManager = SoundManager.getInstance();
- soundManager.set({
- audio: "sound/single_coin_fall_on_concrete_.mp3",
- muted: (settingsManager.getSetting("play-sound", "1") !== "1"),
- volume: 0.7
- }, SoundManager.CHANNELS.SOUND);
-
- soundManager.resume(SoundManager.CHANNELS.MUSIC);
-
- return super.onConstruct(args);
- }
-
- async onFirstStart() {
- super.onFirstStart();
- let leafSegmentTemplate = this.findBy("#segment-leaf-template");
- let parentSegmentTemplate = this.findBy("#segment-parent-template");
- let rowSegmentTemplate = this.findBy("#segment-row-template");
- let triangleTemplate = this.findBy("#segment-triangle-template");
- let columnTemplate = this.findBy("#segment-column-template");
-
- leafSegmentTemplate.removeAttribute("id");
- parentSegmentTemplate.removeAttribute("id");
- rowSegmentTemplate.removeAttribute("id");
- triangleTemplate.removeAttribute("id");
- columnTemplate.removeAttribute("id");
-
- leafSegmentTemplate.remove();
- parentSegmentTemplate.remove();
- rowSegmentTemplate.remove();
- triangleTemplate.remove();
- columnTemplate.remove();
-
- let continueButton = this.findBy("#continue-button");
- continueButton.addEventListener("click", () => {
- this.nextLevel();
- });
-
- let wonText = this.findBy("#won-text");
-
- let scaleHelper = new ScaleHelper();
- this.continueButtonScaler = await scaleHelper.scaleToFull(continueButton, continueButton.parentElement, false, true, 2);
- this.wonTextScaler = await scaleHelper.scaleToFull(wonText, wonText.parentElement, false, false, 2, null, 5);
- this.wonText = wonText;
- this.wonText.style.fontSize = "0";
-
- //Benutze Document, da Element außerhalb von Seite (eigentlich unschön!)
- this.levelCounterActionContainer = document.getElementById("level-number-container");
- this.levelCounterAction = document.getElementById("level-number");
- this.levelCounterAction.innerText = this.levelCounter;
- this.levelNumberScaler = await scaleHelper.scaleToFull(this.levelCounterAction, this.levelCounterActionContainer, false, false, 4);
- this.levelCounterActionContainer.classList.add("visible");
- this.templateContainer = new TemplateContainer(leafSegmentTemplate, parentSegmentTemplate, rowSegmentTemplate, triangleTemplate, columnTemplate);
-
- this.coinTemplate = this.findBy("#coin-template");
- this.coinContainer = this.findBy("#coin-container");
-
- this.coinTemplate.id = null;
- this.coinContainer.removeAllChildren();
-
- this.findBy("#help-button").addEventListener("click", () => {
- this.help();
- });
- await this.loadLastLevel();
- }
-
- async loadLastLevel() {
- try {
- let currentLevelInfo = localStorage.getItem("currentLevel");
- if (Helper.isNotNull(currentLevelInfo)) {
- currentLevelInfo = JSON.parse(currentLevelInfo);
-
- const db = await WordRotatorDb.getInstance();
- const levelJson = await db.loadLevel(currentLevelInfo["id"]);
-
- if (levelJson === null) {
- return this.nextLevel();
- }
-
- let level = LevelHelper.inflateLevel(levelJson, this.templateContainer);
- level.setStartRotations(currentLevelInfo["rotations"]);
-
- const self = this;
- level.getWonPromise().then(() => {
- self.levelWon(level);
- });
-
- level.createSegments();
- level.setLocks(currentLevelInfo["locks"]);
- level.getRootSegment()._updateElement();
-
- level.saveAsCurrentLevel();
-
- let levelSegment = this.findBy("#level");
- levelSegment.removeAllChildren().appendChild(level.getRootSegment().getElement());
- let scaleHelper = new ScaleHelper();
- this.levelScaler = await scaleHelper.scaleToFull(levelSegment, levelSegment.parentElement, false, false, 1, level.words[0].length * 1.5, null, 0);
-
- this.level = level;
- let res = this.tutorial();
- Matomo.push(["trackEvent", "LevelSite", "LoadLastLevel"]);
- this.level.checkHasWon();
- return res;
- }
- } catch (e) {
- console.error(e);
- }
- return this.nextLevel();
- }
-
- startEndSite() {
- this.startSite(EndSite);
- this.finish();
- }
-
- async nextLevel(loadingElement) {
- loadingElement = Helper.nonNull(loadingElement, Helper.createLoadingSymbol());
- this._siteContent.replaceWith(loadingElement);
-
- try {
- const db = await WordRotatorDb.getInstance();
- const nextLevelJson = await db.loadNextLevel(LevelSite.RENDERER_TYPES);
-
- console.log("nextLevelJson", nextLevelJson);
- if (nextLevelJson === null) {
- this.startEndSite();
- return;
- }
- const level = LevelHelper.inflateLevel(nextLevelJson, this.templateContainer);
-
- //Waiting for Level to be done
- if (this.level && level.id === this.level.id) {
- console.log("Level is the same as before! reload!");
- await new Promise((resolve) => setTimeout(resolve, 50));
- // return;
- return this.nextLevel(loadingElement);
- }
-
- level.getWonPromise().then(() => {
- this.levelWon(level);
- });
-
- level.createSegments();
- level.getRootSegment()._updateElement();
-
- level.saveAsCurrentLevel();
-
- let levelSegment = this.findBy("#level");
- levelSegment.removeAllChildren().appendChild(level.getRootSegment().getElement());
-
- this._siteContent.classList.remove('won');
- this.wonText.style.fontSize = "0";
- loadingElement.replaceWith(this._siteContent);
-
- let scaleHelper = new ScaleHelper();
- this.levelScaler = await scaleHelper.scaleToFull(levelSegment, levelSegment.parentElement, false, false, 1, level.words[0].length * 1.5, null, 0);
-
- this.level = level;
- this.levelCounterAction.innerText = this.levelCounter;
- this.levelNumberScaler();
-
- this.coinAction.setTitle(Helper.nonNull(localStorage.getItem("coins"), "0"));
- this.coinAction.redraw();
-
- this.wonParams.aborted = true;
- clearTimeout(this.wonParams.coinCounterTimer);
-
- Matomo.push(["trackEvent", "LevelSite", "NextLevel", "Level Number Normal", this.levelCounter]);
-
- this.level.checkHasWon();
-
- return this.tutorial();
- } catch (e) {
- // loadingElement.replaceWith(this._siteContent);
- console.log("Fehler!");
- console.error(e);
- this.startEndSite();
- }
- }
-
- onStart(args) {
- Matomo.update("Level Site");
- let res = super.onStart(args);
-
- if (this.levelCounterAction) {
-
- this.levelCounterAction.innerText = this.levelCounter;
- this.levelCounterActionContainer.classList.add("visible");
- }
- this.levelScaler();
-
- let settingsManager = SettingsManager.getInstance();
- let soundManager = SoundManager.getInstance();
- soundManager.set({
- audio: "sound/single_coin_fall_on_concrete_.mp3",
- muted: (settingsManager.getSetting("play-sound", "1") !== "1"),
- volume: 0.7
- }, SoundManager.CHANNELS.SOUND);
-
- return res;
- }
-
- onPause(args) {
- super.onPause(args);
- this.levelCounterActionContainer.classList.remove("visible");
- }
-
- async levelWon(level) {
- try {
- const db = await WordRotatorDb.getInstance();
- const savePromise = db.saveLevelPlayed(level.getId());
-
- savePromise.then((r) => console.log("levelSaved!", r)).then(() => {
- return db.loadLevel(level.id);
- }).then(level => console.log("saved level", level));
-
- this.levelCounter++;
- localStorage.setItem("levelCounter", this.levelCounter);
-
- this._siteContent.classList.add('won');
- localStorage.removeItem("currentLevel");
-
- let continueButton = this.findBy("#continue-button");
- continueButton.style.transition = "none";
- continueButton.style.opacity = 0;
-
- this.coinContainer.removeAllChildren();
- let coinsPerLevel = SystemSettings.get("coinsPerLevel", 5);
-
- let coinsBefore = 0;
-
- let soundManager = SoundManager.getInstance();
- let audioOptions = soundManager.get(SoundManager.CHANNELS.SOUND);
-
- this.coinPromise = this.coinPromise.then(() => {
- coinsBefore = parseInt(Helper.nonNull(localStorage.getItem("coins"), "0"));
- localStorage.setItem("coins", coinsBefore + parseInt(coinsPerLevel));
- }).then(() => {
- return Promise.all([new Promise((r) => {
- setTimeout(() => {
- r(continueButton.fadeIn());
- }, 500);
- }), audioOptions.loadedPromise.catch(e => {
- console.error(e);
- })]);
- });
-
- this.wonParams.aborted = false;
-
- for (let i = 0; i < coinsPerLevel; i++) {
- let coinElem = Helper.cloneNode(this.coinTemplate);
- this.coinContainer.appendChild(coinElem);
- this.coinPromise = this.coinPromise.then(() => {
- return new Promise(r => {
- let timeout = 350;
- if (!this.wonParams.aborted) {
- coinElem.fadeIn(timeout / 1000);
- soundManager.play(SoundManager.CHANNELS.SOUND);
-
- this.wonParams.coinCounterTimer = setTimeout(() => {
- if (!this.wonParams.aborted) {
- this.coinAction.setTitle(++coinsBefore);
- this.coinAction.redraw();
- }
- }, timeout / 2);
- } else {
- r();
- }
- //Always do the next promise for garbage collection
- setTimeout(r, timeout);
- })
- });
- }
-
- this.coinPromise = this.coinPromise.catch((e) => {
- console.error(e);
- });
-
- this.wonTextScaler();
- this.continueButtonScaler();
- this.levelScaler();
-
- Matomo.push(["trackEvent", "LevelSite", "LevelWon", "Coins", parseInt(Helper.nonNull(localStorage.getItem("coins"), "0"))]);
-
- await savePromise;
- } catch (e) {
- console.error(e);
- }
- }
-
- help() {
- let cost = SystemSettings.get("costForHelp", 25);
- let currentCoins = parseInt(Helper.nonNull(localStorage.getItem("coins"), 0));
-
- if (currentCoins >= cost) {
- currentCoins -= cost;
- localStorage.setItem("coins", currentCoins);
- this.coinAction.title = currentCoins;
- this.coinAction.redraw();
-
- let rotatables = this.level.getRotatableSegments();
- rotatables = rotatables.filter((segment) => {
- return (!segment.isSolved(false));
- });
-
- let index = Math.floor(Math.random() * rotatables.length);
-
- let segmentToHelp = rotatables[index];
- while (segmentToHelp.rotation !== 0) {
- segmentToHelp.rotate();
- }
- segmentToHelp.setIsRotatable(false);
- this.level.saveAsCurrentLevel();
-
- Matomo.push(["trackEvent", "LevelSite", "Help", "Coins", parseInt(Helper.nonNull(localStorage.getItem("coins"), "0"))]);
- } else {
- FlashMessenger.addMessage("not-enough-coins");
- Matomo.push(["trackEvent", "LevelSite", "Help", "Not enough Coins", parseInt(Helper.nonNull(localStorage.getItem("coins"), "0"))]);
- }
- }
-
- async tutorial() {
- if (this.level.id === LevelSite.TUTORIAL.FIRST_LEVEL) {
- let currentStep = Helper.nonNull(localStorage.getItem("tutorial-step"), "1");
-
- let scaleHelper = new ScaleHelper();
- this._siteContent.classList.add("tutorial");
- this._siteContent.classList.add("step-" + currentStep);
-
- switch (currentStep) {
- case "1": {
- this.level.setSegmentClickedListener(() => {
- this._siteContent.classList.remove("step-1");
- localStorage.setItem("tutorial-step", "2");
- this.tutorial();
- });
-
- let textElem = this.findBy(".tutorial-text .step-1");
-
- await this.levelScaler();
- scaleHelper.scaleToFull(textElem, textElem.parentElement, null, true, 1, 2);
-
- break;
- }
- case "2": {
- this.level.setSegmentClickedListener(() => {
- });
- this.level.getWonPromise().then(() => {
- this._siteContent.classList.remove("tutorial");
- this._siteContent.classList.remove("step-2");
- localStorage.removeItem("tutorial-step");
- this.coinPromise = this.coinPromise.then(() => {
- FlashMessenger.addMessage("extra-coins-after-first-level");
- localStorage.setItem("coins", parseInt(Helper.nonNull(localStorage.getItem("coins"), "0")) + 50);
- this.coinAction.setTitle(Helper.nonNull(localStorage.getItem("coins"), "0"));
- this.coinAction.redraw();
- });
- // this.levelScaler();
- });
-
- let textElem = this.findBy(".tutorial-text .step-2");
-
- await this.levelScaler();
- scaleHelper.scaleToFull(textElem, textElem.parentElement, null, true, 1, 2);
-
- break;
- }
- default: {
- this._siteContent.classList.remove("tutorial");
- }
- }
- } else if (this.level.id === LevelSite.TUTORIAL.SECOND_LEVEL) {
- let currentStep = Helper.nonNull(localStorage.getItem("tutorial-step"), "3");
-
- switch (currentStep) {
- case "3": {
- let scaleHelper = new ScaleHelper();
-
- this._siteContent.classList.add("tutorial");
- this._siteContent.classList.add("step-" + currentStep);
-
- let eventListener = () => {
- this._siteContent.classList.remove("tutorial");
- this._siteContent.classList.remove("step-3");
- localStorage.setItem("tutorial-step", "4");
- this.findBy("#help-button").removeEventListener("click", eventListener);
- this.levelScaler();
- };
- this.findBy("#help-button").addEventListener("click", eventListener);
-
- let textElem = this.findBy(".tutorial-text .step-3");
-
- await this.levelScaler();
- scaleHelper.scaleToFull(textElem, textElem.parentElement, null, true, 1, 2);
- break;
- }
- default: {
- this._siteContent.classList.remove("tutorial");
- }
- }
- } else if (this.level.id === LevelSite.TUTORIAL.BIG_SEGMENT_LEVEL) {
- let currentStep = Helper.nonNull(localStorage.getItem("tutorial-step"), "4");
-
- switch (currentStep) {
- case "4": {
-
- let scaleHelper = new ScaleHelper();
- this._siteContent.classList.add("tutorial");
- this._siteContent.classList.add("step-" + currentStep);
-
- let rotatableSegments = this.level.getRotatableSegments();
- let firstSegment = rotatableSegments[2];
- console.log(firstSegment);
-
- let pointer = this.findBy("#tutorial-pointer");
- pointer.remove();
- firstSegment.element.appendChild(pointer);
-
- this.level.setSegmentClickedListener((segment) => {
- console.log("clicked Segment", segment);
- if (firstSegment === segment) {
- this._siteContent.classList.remove("tutorial");
- this._siteContent.classList.remove("step-4");
- localStorage.setItem("tutorial-step", "5");
- this.levelScaler();
- }
- });
-
- let textElem = this.findBy(".tutorial-text .step-4");
-
- await this.levelScaler();
- scaleHelper.scaleToFull(textElem, textElem.parentElement, null, true, 1, 2);
-
- break;
- }
- default: {
- this._siteContent.classList.remove("tutorial");
- }
- }
- }
- }
-}
-
-LevelSite.RENDERER_TYPES = [20, 40, 60, 80, 81, 82, 83, 100, 110, 111, 112, 120, 140, 160];
-LevelSite.TUTORIAL = {
- FIRST_LEVEL: 67,
- SECOND_LEVEL: 15,
- BIG_SEGMENT_LEVEL: 1921
-};
-
-class MainMenuLevel extends FourWordsLevel{
-
- constructor(templateContainer) {
- super(templateContainer, 4);
- }
-
- saveAsCurrentLevel() {
- }
-
- // checkHasWon(delayPromise) {
- // }
-}
-
-class ShareDialog extends Dialog{
- constructor() {
- let viewPromise = ViewInflater.inflate("html/application/dialog/share.html").then(view => {
- view.appendChild(ShareManager.generateDefaultShareElement(window.location.hostname + Helper.basePath("")));
- let closeListener = () => {
- this.close();
- };
-
- view.querySelectorAll("a").forEach((element) => {
- element.addEventListener("click", closeListener);
- });
- return view;
- });
-
- super(viewPromise, "share-dialog");
- }
-}
-
-class MenuSite extends WordRotatorBaseSite {
- constructor(siteManager) {
- super(siteManager, "html/application/menu.html");
- this.loadLevelPromise = this.loadLevels();
- this.listener = null;
- }
-
- onStart(args) {
- Matomo.update("Menu Site");
- let res = super.onStart(args);
-
- let level = new MainMenuLevel(this.templateContainer);
- level.setWords(["WORD", "ROTA", "TORW", "ORDR"]);
- level.createSegments();
-
- level.getWonPromise().then(() => {
- Matomo.push(["trackEvent", "MainMenu", "levelSolved"]);
- this.startLevelSite();
- });
-
- let segment = level.getRootSegment();
- segment._updateElement();
-
- let levelSegment = this.findBy("#level");
- levelSegment.removeAllChildren().appendChild(segment.getElement());
-
- let rotationsSegments = level.getRotatableSegments();
-
- let randomRotationFunction = () => {
- let timeout = Math.random() * 4500 + 1500;
- this.randomRotateTimeout = setTimeout(() => {
- let indexBlocked = -1;
- let indexesNotRight = [];
- for (let i = 0; i < rotationsSegments.length; i++) {
- if (rotationsSegments[i].rotation !== 0) {
- indexesNotRight.push(i);
- if (indexesNotRight.length >= 2) {
- break;
- }
- }
- }
- if (indexesNotRight.length === 1) {
- indexBlocked = indexesNotRight[0];
- }
-
- let index = Math.floor(Math.random() * rotationsSegments.length);
- if (index === indexBlocked) {
- index = (index + 1) % rotationsSegments.length;
- }
-
- rotationsSegments[index].rotate();
- randomRotationFunction();
- }, timeout);
- };
- randomRotationFunction();
-
- this.listener = async () => {
- let playButton = this.findBy("#play-button");
- let levelNumber = this.findBy("#level-number");
- levelNumber.innerText = Helper.nonNull(localStorage.getItem("levelCounter"), 1);
-
- let levelSegment = this.findBy("#level");
-
- let scaleHelper = new ScaleHelper();
- await scaleHelper.scaleToFull(levelSegment, levelSegment.parentElement, false, false, 2, 8, null, false);
-
- // debugger;
- let levelStyle = getComputedStyle(levelSegment);
- playButton.style.width = levelStyle.getPropertyValue("width");
- scaleHelper.scaleToFull(playButton.children[0], playButton, null, null, null, 4, null, false);
-
- await scaleHelper.scaleTo(0.2, levelNumber.parentElement, levelNumber.parentElement.parentElement, null, null, null, 10, null, false);
- scaleHelper.scaleToFull(levelNumber, levelNumber.parentElement, false, false, 8, null, null, false);
- };
-
- this.listener();
- window.addEventListener("resize", this.listener);
-
- //Musikbuttons update, falls in den Einstellungen umgestellt
- let settingsManager = SettingsManager.getInstance();
- let playSoundButton = this.findBy("#play-sound");
- playSoundButton.checked = (settingsManager.getSetting("play-sound", "1") === "1");
- let playMusicButton = this.findBy("#play-music");
- playMusicButton.checked = (settingsManager.getSetting("play-music", "1") === "1");
-
- return res;
- }
-
- async startLevelSite() {
- SoundManager.getInstance().resumeContext();
- this.startSite(LevelSite, Promise.race([this.loadLevelPromise, new Promise(async resolve => {
- const db = await WordRotatorDb.getInstance();
- let level = await db.loadNextLevel(LevelSite.RENDERER_TYPES);
- if (level !== null) {
- resolve();
- }
- })]));
- }
-
- async onFirstStart() {
- super.onFirstStart();
-
- let playButton = this.findBy("#play-button");
- playButton.addEventListener("click", () => {
- Matomo.push(["trackEvent", "MainMenu", "startButton"]);
- this.startLevelSite();
- });
-
- let leafSegmentTemplate = this.findBy("#segment-leaf-template");
- let parentSegmentTemplate = this.findBy("#segment-parent-template");
- let rowSegmentTemplate = this.findBy("#segment-row-template");
- let triangleTemplate = this.findBy("#segment-triangle-template");
-
- leafSegmentTemplate.id = null;
- parentSegmentTemplate.id = null;
- rowSegmentTemplate.id = null;
- triangleTemplate.id = null;
-
- leafSegmentTemplate.remove();
- parentSegmentTemplate.remove();
- rowSegmentTemplate.remove();
- triangleTemplate.remove();
-
- this.templateContainer = new TemplateContainer(leafSegmentTemplate, parentSegmentTemplate, rowSegmentTemplate, triangleTemplate);
-
- if (Helper.nonNull(MenuSite.app._cookieClosePromise)) {
- MenuSite.app._cookieClosePromise.then(() => {
- if (this.listener) {
- this.listener();
- }
- });
- }
-
- let settingsManager = SettingsManager.getInstance();
- let soundManager = SoundManager.getInstance();
-
- let playMusicButton = this.findBy("#play-music");
- playMusicButton.checked = (settingsManager.getSetting("play-music", "1") === "1");
- playMusicButton.addEventListener("change", () => {
- settingsManager.setSetting("play-music", (playMusicButton.checked) ? "1" : "0");
- soundManager.set({muted: !playMusicButton.checked}, SoundManager.CHANNELS.MUSIC);
- if (playMusicButton.checked) {
- soundManager.play(SoundManager.CHANNELS.MUSIC);
- }
- Matomo.push(["trackEvent", "MainMenu", "PlayMusic", "Play Music", (playMusicButton.checked) ? 1 : 0]);
- });
-
- let playSoundButton = this.findBy("#play-sound");
- playSoundButton.checked = (settingsManager.getSetting("play-sound", "1") === "1");
- playSoundButton.addEventListener("change", () => {
- settingsManager.setSetting("play-sound", (playSoundButton.checked) ? "1" : "0");
- soundManager.set({muted: !playSoundButton.checked}, SoundManager.CHANNELS.SOUND);
- Matomo.push(["trackEvent", "MainMenu", "PlaySound", "Play Sound", (playSoundButton.checked) ? 1 : 0]);
- });
-
- this.findBy("#share-button").addEventListener("click", () => {
- new ShareDialog().show();
- });
- // this.findBy("#share-buttons").appendChild(ShareManager.generateDefaultShareElement("https://wordrotator.silas.link"));
- }
-
- onPause(args) {
- clearTimeout(this.randomRotateTimeout);
- window.removeEventListener("resize", this.listener);
- super.onPause(args);
- }
-
- async loadLevels() {
- try {
- const db = await WordRotatorDb.getInstance();
- const dateLastSync = Helper.nonNull(await db.loadDateLastSync(), 0);
- // const dateLastSync = Helper.nonNull(localStorage.getItem("date-last-sync"), 0);
-
- // let numberLevels = db.countLevels();
- let newLastSync = null;
- let maxRuns = 1;
- let levelPromises = [];
- for (let run = 0; run < maxRuns; run++) {
- let res = await DataManager.load("wordRotator/levels" + DataManager.buildQuery({
- "currentRun": run,
- "dateLastSync": dateLastSync
- }));
- if (!res["success"]) {
- if (await db.loadNextLevel(LevelSite.RENDERER_TYPES) === null) {
- FlashMessenger.addMessage("sync-error", null, 6000);
- }
- newLastSync = null;
- break;
- }
- res = res["result"];
- newLastSync = Helper.nonNull(newLastSync, res["currentSyncDate"]);
- maxRuns = res["maxRuns"];
-
- let levels = res["levels"];
- for (let i = 0; i < levels.length; i++) {
- let currentLevel = levels[i];
- levelPromises.push(db.loadLevel(levels[i]["id"]).then(level => {
- currentLevel["played"] = (Helper.nonNull(Helper.nonNull(level, {}).played, false));
- return currentLevel;
- }));
- }
- }
- let levels = await Promise.all(levelPromises);
- await db.saveManyLevels(levels);
-
- if (newLastSync != null && newLastSync !== "null") {
- localStorage.setItem("date-last-sync", newLastSync);
- db.saveDateLastSync(newLastSync);
- }
- }
- catch(e){
- // if (await db.loadNextLevel(LevelSite.RENDERER_TYPES) === null) {
- FlashMessenger.addMessage("sync-error", null, 6000);
- // }
- console.error(e);
- }
- }
-}
-
-MenuSite.app = null;
-InitPromise.addPromise(app => {
- MenuSite.app = app;
-});
-
-class PrivacyPolicySite extends WordRotatorBaseSite {
- constructor(siteManager) {
- super(siteManager, "html/application/privacyPolicy.html", "privacyPolicy");
- }
-
- onFirstStart() {
- let trackSwitch =this.findBy("#track-switch");
-
- trackSwitch.addEventListener("change", function (e) {
- Matomo.setTrack(this.checked === true);
- e.stopPropagation();
- e.preventDefault();
- });
- super.onFirstStart();
- }
-
- onStart(args) {
- let trackSwitch =this.findBy("#track-switch");
- let shouldTrack = (Helper.nonNull(localStorage.getItem("matomoShouldTrack"), "1") === "1");
- trackSwitch.checked = shouldTrack;
-
- Matomo.update("Privacy Policy Site");
- return super.onStart(args);
- }
-}
-
-InitPromise.addPromise(app => {
- app.addDeepLink("privacyPolicy", PrivacyPolicySite);
-});
-
-class CreditsSite extends WordRotatorBaseSite{
- constructor(siteManager) {
- super(siteManager, "html/application/credits.html", "credits");
- }
-
- onStart(args) {
- Matomo.update("Credits Site");
- return super.onStart(args);
- }
-}
-
-InitPromise.addPromise(app => {
- app.addDeepLink("credits", CreditsSite);
-});
-
-class ChooseThemeDialog$1 extends Dialog {
-
- constructor() {
- let viewPromise = ViewInflater.inflate("html/application/dialog/chooseTheme.html").then(view => {
-
- let template = view.querySelector("#choose-theme-template");
- template.remove();
- template.id = null;
-
- let themeTemplateContainer = view.querySelector("#theme-choose-container");
-
- for (let i = 0; i < ThemeManager$1.themes.length; i++) {
- let themeElem = Helper.cloneNode(template);
- let theme = ThemeManager$1.themes[i];
- themeElem.querySelector(".name").appendChild(Translator.makePersistentTranslation(theme._name));
- themeElem["dataset"]["theme"] = theme._name;
-
- themeElem.addEventListener("click", () => {
- this.result = themeElem["dataset"]["theme"];
- this.close();
- });
- themeTemplateContainer.appendChild(themeElem);
- }
-
- return view;
- });
-
- super(viewPromise, "choose-theme-dialog-title");
- }
-}
-
-class ImpressumSite extends WordRotatorBaseSite{
- constructor(siteManager) {
- super(siteManager, "html/application/impressum.html", "impressum");
- }
-}
-
-InitPromise.addPromise(app => {
- app.addDeepLink("impressum", ImpressumSite);
-});
-
-class PersistDialog extends ConfirmDialog{
- constructor() {
- super(Helper.isChrome()?"persist-storage-dialog-message":"persist-storage-dialog-message-firefox", "persist-storage-dialog-title");
- }
-}
-
-class WordRotatorSettingFragment extends LocalStorageSettingsFragment {
- constructor(site) {
- super(site, "html/application/fragment/settings.html");
- }
-
- onFirstStart() {
- let currentThemeName = ThemeManager$1.currentTheme._name;
- SettingsManager.getInstance().setSetting("theme", currentThemeName);
-
- let themeNameElem = this.findBy("#theme-name");
- themeNameElem.removeAllChildren().appendChild(Translator.makePersistentTranslation(currentThemeName));
- this.findBy("#theme-chooser").addEventListener("click", async () => {
- let newTheme = await (new ChooseThemeDialog$1()).show();
- if (Helper.isNotNull(newTheme)) {
- SettingsManager.getInstance().setSetting("theme", newTheme);
- ThemeManager$1.changeCurrentTheme(newTheme);
- themeNameElem.removeAllChildren().appendChild(Translator.makePersistentTranslation(newTheme));
- }
- });
-
- this.findBy("#reset-levels").addEventListener("click", async () => {
- localStorage.removeItem("currentLevel");
- localStorage.removeItem("date-last-sync");
- localStorage.removeItem("levelCounter");
- localStorage.removeItem("tutorial-step");
- (await WordRotatorDb.getInstance()).removeAll(WordRotatorDb.OBJECT_STORE.LEVEL);
- (await WordRotatorDb.getInstance()).removeAll(WordRotatorDb.OBJECT_STORE.SYSTEM_VARS);
- });
-
- if (location.hostname.includes("beta") || location.hostname.includes("127.0.0.1")) {
- this.findBy("#reset-levels").classList.remove("hidden");
- }
-
- let playMusicButton = this.findBy("#play-music");
- playMusicButton.addEventListener("change", () => {
- let soundManager = SoundManager.getInstance();
- soundManager.set({muted: !playMusicButton.checked}, SoundManager.CHANNELS.MUSIC);
- if (playMusicButton.checked) {
- soundManager.play(SoundManager.CHANNELS.MUSIC);
- }
- });
-
- this.findBy("#track-switch").addEventListener("change", function (e) {
- Matomo.setTrack(this.checked === true);
- e.stopPropagation();
- e.preventDefault();
- });
-
- this.findBy("#credits-button").addEventListener("click", () => {
- this.getSite().startSite(CreditsSite);
- });
- this.findBy("#privacy-policy-button").addEventListener("click", () => {
- this.getSite().startSite(PrivacyPolicySite);
- });
- this.findBy("#contact-button").addEventListener("click", () => {
- this.getSite().startSite(ContactSite);
- });
- this.findBy("#impressum-button").addEventListener("click", () => {
- this.getSite().startSite(ImpressumSite);
- });
- this.findBy("#version-info").innerText = window["version"];
-
- InstallManager.setCanInstallListener(() => {
- let installButton = this.findBy("#install-button");
- installButton.addEventListener("click", () => {
- installButton.classList.add("hidden");
- InstallManager.prompt().then((e) => {
- console.log("clicked", e);
- if (e["outcome"] === "accepted") {
- Matomo.trackEvent("installed", "installed");
- }
- });
- });
- installButton.classList.remove("hidden");
- });
-
- let storageManager = MyStorageManager.getInstance();
- if (storageManager.canPersist()) {
- Promise.all([storageManager.isPersistent(), navigator.serviceWorker["ready"]]).then(res => {
- let isPersisted = res[0];
- let storageObject = this.findBy("#storage-info");
- storageObject.appendChild(Translator.makePersistentTranslation("storage-info", [
- ((isPersisted) ? "" : "nicht")]));
- storageObject.parentElement.classList.remove("hidden");
- storageObject.parentElement.addEventListener("click", async () => {
- if (!isPersisted) {
- let shouldAskForNotifications = false;
- try {
- // Helper.isChrome()
- shouldAskForNotifications = await (new PersistDialog().show());
- if (shouldAskForNotifications) {
- if (Helper.isChrome()) {
- let sub = await res[1]["pushManager"]["subscribe"]({
- "userVisibleOnly": true,
- "applicationServerKey": new Uint8Array([4, 148, 221, 15, 14, 122, 35, 21, 93, 74, 222, 174, 235, 216, 129, 40, 51, 187, 105, 151, 5, 96, 178, 155, 61, 201, 78, 209, 176, 187, 145, 94, 98, 96, 95, 27, 59, 90, 162, 0, 12, 225, 59, 105, 99, 135, 208, 210, 69, 29, 148, 141, 4, 178, 66, 114, 80, 207, 22, 90, 0, 115, 60, 150, 217])
- });
- }
- }
- } catch (e) {
- if ('Notification' in window && Notification.permission === 'denied') {
- FlashMessenger.addMessage('notification-permission-denied');
- }
- }
- if (Helper.isChrome() || shouldAskForNotifications) {
- isPersisted = await storageManager.persist();
- storageObject.removeAllChildren().appendChild(Translator.makePersistentTranslation("storage-info", [
- ((isPersisted) ? "" : "nicht")]));
- }
- }
- else {
- new Dialog("already-persisted-dialog-message", "already-persisted-dialog-title").show();
- }
- // storageManager.persist().then(isPersisted => {
- // storageObject.removeAllChildren().appendChild(Translator.makePersistentTranslation("storage-info", [
- // Math.round(storage.usage / (1024 * 1024) * 100) / 100,
- // Math.round(storage.quota / (1024 * 1024) * 100) / 100,
- // Math.round(storage.usage / storage.quota * 10000) / 100,
- // ((isPersisted) ? "" : "nicht")]));
- //
- // console.log("p", isPersisted);
- // if (!isPersisted){
- // FlashMessenger.addMessage("storage-permission-not-get");
- // }
- // else {
- // FlashMessenger.addMessage("storage-permission-get");
- // }
- // });
- });
- });
- }
- return super.onFirstStart();
- }
-
- onStart() {
- Matomo.update("Settings Site");
- super.onStart();
- }
-}
-
-InitPromise.addPromise(function () {
- SettingsSite.addSettingsFragment("settings", WordRotatorSettingFragment);
-});
-
-class SelectWordsSite extends UserSite{
-
- constructor(siteManager) {
- super(siteManager, "version/2/html/selectWords.html", null, "select-words");
- }
-
- async onConstruct(args) {
- let res = await super.onConstruct(args);
- this.stats = (await DataManager.load("words"))["result"];
- this.words = this.stats["wordsToCheck"];
- console.log(this.stats);
- return res;
- }
-
- onFirstStart() {
- super.onFirstStart();
- this.findBy("#not-checked").appendChild(document.createTextNode(this.stats["wordsNotChecked"]));
- this.findBy("#checked").appendChild(document.createTextNode(this.stats["wordsChecked"]));
- this.findBy("#not-sure").appendChild(document.createTextNode(this.stats["wordsUnsure"]));
- this.findBy("#deleted").appendChild(document.createTextNode(this.stats["wordsDeleted"]));
- this.findBy("#unused").appendChild(document.createTextNode(this.stats["wordsNotUsed"]));
-
- let template = this.findBy("#word-template");
- template.id = null;
- template.remove();
-
- let container = this.findBy("#word-container");
-
- let numWords = this.words.length;
- for (let i = 0; i < numWords; i++) {
- let wordElement = Helper.cloneNode(template);
- wordElement.dataset["id"] = -1;
- this.setWord(wordElement, this.words[i]);
- container.appendChild(wordElement);
-
- wordElement.querySelector(".button-ok").addEventListener("click", async () => {
- let newWord = (await DataManager.send("checkWord", {
- "wordId":wordElement.dataset["id"],
- "action":"1"
- }))["result"];
- this.setWord(wordElement, newWord[0]);
- });
-
- wordElement.querySelector(".button-unsure").addEventListener("click", async () => {
- let newWord = (await DataManager.send("checkWord", {
- "wordId":wordElement.dataset["id"],
- "action":"2"
- }))["result"];
- this.setWord(wordElement, newWord[0]);
- });
-
- wordElement.querySelector(".button-delete").addEventListener("click", async () => {
- let newWord = (await DataManager.send("checkWord", {
- "wordId":wordElement.dataset["id"],
- "action":"3"
- }))["result"];
- this.setWord(wordElement, newWord[0]);
- });
- }
- }
-
- setWord(wordElement, word){
- wordElement.querySelector(".word").removeAllChildren().appendChild(document.createTextNode(word["word"]));
- wordElement.dataset["id"] = word["id"];
- }
-}
-
-InitPromise.addPromise(app => {
- app.addDefaultAction(new UserAction("select-words", () => {
- app.startSite(SelectWordsSite);
- }, null, null, "select-words"));
-});
-
-class DeleteWordsSite extends UserSite {
- constructor(siteManager) {
- super(siteManager, "version/2/html/deleteLevels.html", null, "admin");
- }
-
- async onConstruct(args) {
- let res = super.onConstruct(args);
- this.words = (await DataManager.load("getDoubleUsedWordsAction"))["result"];
- return res;
- }
-
-
- onFirstStart() {
- super.onFirstStart();
-
- let levelTemplate = this.findBy("#level-template");
- let wordTemplate = this.findBy("#word-template");
- let wordContainer = this.findBy("#word-container");
-
- levelTemplate.id = null;
- levelTemplate.remove();
-
- wordTemplate.id = null;
- wordTemplate.remove();
-
- for (let k in this.words) {
- let wordElem = Helper.cloneNode(wordTemplate);
- wordElem.querySelector(".name").appendChild(document.createTextNode(k));
- let levelContainer = wordElem.querySelector(".level-container");
- for (let j = 0; j < this.words[k].length; j++) {
- let level = this.words[k][j];
- let levelElem = Helper.cloneNode(levelTemplate);
- levelElem.querySelector(".id").appendChild(document.createTextNode(level["id"]));
- levelElem.querySelector(".words").appendChild(document.createTextNode(level["words"]));
- levelElem.querySelector(".positions").appendChild(document.createTextNode(level["rotations"]));
-
- levelElem.querySelector(".delete-button").addEventListener("click", async () => {
- let res = await DataManager.send("deleteLevel", {"levelId": level["id"]});
- if (res["success"]){
- levelElem.remove();
- }
- });
-
- levelContainer.appendChild(levelElem);
- }
- wordContainer.appendChild(wordElem);
- }
- }
-}
-
-InitPromise.addPromise(app => {
- app.addDefaultAction(new UserAction("delete-levels", () => {
- app.startSite(DeleteWordsSite);
- },null, null, "admin"));
-});
-
-let basePath = "/pwa/wordRotator/public/";
-if (window.location.pathname.indexOf("publicTest/") >= 0)
-{
- basePath = "/pwa/wordRotator/publicTest/";
-}
-
-SystemSettings.setBasePath(basePath);
-Translator.supportedLanguages = ["de"];
-Translator.markTranslations = false;
-window["version"] = "1-local";
-
-
-Matomo.SIDE_ID = "2";
-
-window.onerror = (e, u, l) => {
- console.error(e, u, l);
-};
-
-applyPolyfills();
-
-ThemeManager$1.addTheme(new Theme('red', 'red'));
-ThemeManager$1.addTheme(new Theme("blue", "blue"));
-ThemeManager$1.addTheme(new Theme("black", "black"));
-ThemeManager$1.addTheme(new Theme("green", "green"));
-ThemeManager$1.addTheme(new Theme("pink", "pink"));
-ThemeManager$1.addTheme(new Theme("dark", "dark"));
-
-ShareManager.addShareButton(new MatomoShareButton(new WhatsappShareButton('img/whatsapp.svg'), "whatsapp", true));
-ShareManager.addShareButton(new MatomoShareButton(new SmsShareButton('img/sms.svg'), "sms", true));
-ShareManager.addShareButton(new MatomoShareButton(new TelegramShareButton('img/telegram.svg'), "telegram", true));
-// ShareManager.addShareButton(new CopyShareButton('img/copy.svg'));
-
-let app$1 = new App();
-
-AndroidBridge.addDefinition(() => {
- window["app"] = app$1;
- window["app"]["pause"] = app$1.pause;
- window["app"]["resume"] = app$1.resume;
- window["app"]["setAppEndListener"] = app$1.setAppEndListener;
-});
-
-SettingsSite.setTemplate("html/application/setting-template.html");
-// SettingsSite.shouldAddSettingsAction = false;
-
-RegistrationSite.addAction = false;
-LoginSite.addLoginAction = false;
-UserManager.waitForData = false;
-
-InitPromise.resolve(app$1).then(async function () {
- SettingsSite.settingsAction.showFor = MenuAction.SHOW_ALWAYS;
-
- let settingsManager = SettingsManager.getInstance();
-
- let soundManager = SoundManager.getInstance();
- soundManager.play(SoundManager.CHANNELS.MUSIC, {
- audio: "sound/brightAndBeautifull__.mp3",
- loop: true,
- volume: 0.6,
- muted: (settingsManager.getSetting("play-music", "1") !== "1")
- }).catch(e => console.error(e));
-
- app$1.start(MenuSite);
- Translator.setLanguage("de");
-
- InstallManager.setCanInstallListener(e => {});
- let storageManager = MyStorageManager.getInstance();
- if (InstallManager.isInstalled()){
- storageManager.persist();
- }
-
- window["applyAndroidBridge"] = AndroidBridge.applyDefinitions;
-
- let wasOpened = (Helper.nonNull(localStorage.getItem('was-open'), "0") === "1");
- if (wasOpened && storageManager.canPersist()){
- Promise.all([storageManager.isPersistent(), navigator["serviceWorker"]["ready"]]).then(res => {
- if (!res[0]){
- FlashMessenger.addMessage("warning-data-not-persistent");
- }
- });
- }
- else{
- localStorage.setItem("was-open", "1");
- }
-});
-
-// console.log("trying push... 1");
-// navigator.serviceWorker["ready"].then(function (registration) {
-// console.log("trying push... 2");
-// registration["pushManager"]["subscribe"]({
-// "userVisibleOnly": true,
-// "applicationServerKey": new Uint8Array([0x4, 0x53, 0xb7, 0x8d, 0xc6, 0xd1, 0x1a, 0xd4, 0x8b, 0xb2, 0xeb, 0x82, 0xf0, 0x9e, 0x12, 0xf6, 0xd, 0x32, 0x18, 0xa, 0x35, 0xf, 0x2d, 0x4c, 0x5, 0x29, 0x15, 0x95, 0x23, 0xb1, 0xd3, 0xab, 0x87, 0x88, 0x85, 0x1d, 0xc0, 0x98, 0x6e, 0x65, 0xe3, 0xcb, 0xa2, 0x28, 0x63, 0x7, 0x34, 0x9b, 0xfa, 0x46, 0x9a, 0x49, 0xcc, 0x70, 0x7a, 0xdd, 0xbe, 0x1e, 0xfc, 0xde, 0xcc, 0xb3, 0x5b, 0xcb, 0xf4])
-// }).then(function (sub) {
-// console.log("trying push... 3");
-// console.log("Subscription", sub);
-// }).catch(function (e) {
-// // if ('Notification' in window && Notification.permission === 'denied') {
-// // console.warn('Permission for notifications was denied');
-// // } else {
-// // console.error('Unable to subscribe to push', e);
-// // }
-// });
-// });
diff --git a/public/js/lang/de.json b/public/js/lang/de.json
deleted file mode 100755
index 001738c..0000000
--- a/public/js/lang/de.json
+++ /dev/null
@@ -1 +0,0 @@
-{"won":"Gewonnen!","continue":"Weiter","help":"?","not-enough-coins":"Du hast zu wenig Münzen!","sync-error":"Es gab einen Fehler beim Aktualisieren der Level. Bitte stelle sicher, dass du eine aktive Internetverbindung hast und versuche es später erneut.","game-ended":"Oh nein! Es sieht so aus, als ob du schon alle Level gespielt hast... Schau später noch einmal rein, evtl gibt es dann neue Level.","play":"Spielen!","tutorial-step-1":"Klicke auf ein Feld, um dieses rotieren zu lassen!","tutorial-step-2":"Um zu gewinnen, drehe die Segmente so, dass du zwei Wörter lesen kannst.","tutorial-step-3":"Die Hilfe löst ein Segment, kostet aber 25 Münzen. Probiere jetzt die Hilfe aus.","tutorial-step-4":"Große Segmente drehst du, indem du diese ziehst.","extra-coins-after-first-level":"Für das erste Level gibt es 50 extra Münzen!","dark":"Dunkel","theme":"Theme:","sound":"Sound:","music":"Musik:","credits":"Credits","privacy-policy":"Datenschutzbestimmungen","impressum":"Impressum","track":"Anonymisierte Nutzungsdaten senden:",">":">","choose-theme-dialog-title":"Theme auswählen:","install":"Installieren","share-dialog":"Teilen:","credits-sister-text":"Ich danke meiner Lieblingsschwester, denn ohne Sie würde diese App nicht so aussehen, wie sie aussieht (wahrscheinlich eher schlechter :p)","credits-coin-text":"Sound: Der Münz-Sound ist von der Webseite {0} . Alle Rechte für diesen Münz-Sound gehören {0} .","credits-music-text":"Musik: Bright And Beautiful - GEMAfreie Musik von {0} Licensed under Creative Commons: By Attribution 4.0 International (CC BY 4.0){1} Angepasst (geschnitten) für diese App","storage-info":"Fortschritt {0} dauerhaft gespeichert","storage-permission-not-get":"Der Browser gibt nicht die Erlaubnis zur dauerhaften Speicherung...","storage-permission-get":"Die Daten sind nun dauerhaft gespeichert","persist-storage-dialog-title":"Daten dauerhaft speichern?","persist-storage-dialog-message":"Der Fortschritt und die Level dieser WebApp sind nur temporär gespeichert. Damit die Daten dauerhaft gespeichert werden, muss eins von drei Kriterien erfüllt sein: 1) Die Seite muss als Lesezeichen gespeichert werden (und maximal 5 Lesezeichen ingsesamt). 2) Die Seite muss mit die meistbenutzte Seite sein. 3) Benachrichtigungen müssen erlaubt werden. Damit die Daten dieser Webseite nicht gelöscht werden, erlaube bitte Benachrichtigungen. Alternativ kannst du die Seite auch als Lesezeichen speichern.","notification-permission-denied":"Die Berechtigung für Benachrichtigungen wurde verwährt","already-persisted-dialog-message":"Damit die Daten dauerhaft gespeichert werden, muss eins von drei Kriterien erfüllt sein: 1) Die Seite muss als Lesezeichen gespeichert werden (und maximal 5 Lesezeichen ingsesamt). 2) Die Seite muss mit die meistbenutzte Seite sein. 3) Benachrichtigungen müssen erlaubt werden. Du erfüllst schon ein Kriterium und daher wird dein Fortschritt dauerhaft gespeichert (außer du löscht sie)","already-persisted-dialog-title":"Daten werden dauerhaft gespeichert!","persist-storage-dialog-message-firefox":"Damit dein Fortschritt dauerhaft gespeichert wird, musst du zulassen, dass Daten dauerhaft gespeichert werden.","warning-data-not-persistent":"Achtung! Dein Fortschritt kann verloren gehen! Gehe die Einstellungen für mehr Infos.","version-label":"Version:","Sunday":"Sonntag","Monday":"Montag","Tuesday":"Dienstag","Wednesday":"Mittwoch","Thursday":"Donnerstag","Friday":"Freitag","Saturday":"Samstag","January":"Januar","February":"Februar","March":"März","April":"April","May":"Mai","June":"Juni","July":"Juli","August":"August","September":"September","October":"Oktober","November":"November","December":"Dezember","Sun":"So","Mon":"Mo","Tue":"Di","Wed":"Mi","Thu":"Do","Fri":"Fr","Sat":"Sa","Jan":"Jan","Feb":"Feb","Mar":"Mär","Apr":"Apr","Jun":"Jun","Jul":"Jul","Aug":"Aug","Sep":"Sep","Oct":"Okt","Nov":"Nov","Dec":"Dez","code-not-valid":"Der angegebebe Code ist nicht gültig!","code-activated":"Der Code wurde erfolgreich aktiviert!","contact":"Kontakt","contact-email":"E-Mailadresse","contact-accepted-privacy-policy-2":" gelesen und akzepiert","contact-message":"Nachricht","contact-submit":"Absenden","contact-email-empty":"Die E-Mailadresse wird benötigt, um Ihre Nachricht zu beantworten.","contact-email-not-valid":"Die gegebene E-Mailadresse ist nicht gültig!","contact-accept-privacy-policy-empty":"Die Datenschutzbestimmungen müssen akzeptiert werden!","contact-message-empty":"Bitte geben Sie eine Nachricht ein.","contact-message-sent":"Ihre Nachricht wurde gesendet!","current-lang":"DE","en":"Englisch","de":"Deutsch","black":"Schwarz","red":"Rot","blue":"Blau","green":"Grün","pink":"Rosa","cancel-button":"ABBRECHEN","confirm-button":"OK","we-use-cookie-hint":"Diese Seite nutzt Cookies. Lesen Sie unsere Datenschutzerklärung , um mehr zu erfahren.","policy-heading":"Datenschutzerklärung","area-of-validity-heading":"Geltungsbereich","area-of-validity":"Diese Datenschutzerklärung klärt Nutzer über die Art, den Umfang und Zwecke der Erhebung und Verwendung personenbezogener Daten durch den verantwortlichen Anbieter Silas Günther, Langenbusch 263b - 42897 Remscheid, matrix[at]silas.link auf dieser Website (im folgenden \"Angebot\") auf. Die rechtlichen Grundlagen des Datenschutzes finden sich im Bundesdatenschutzgesetz (BDSG) und dem Telemediengesetz (TMG).","logfiles-heading":"Zugriffsdaten / Server-Logfiles","logfiles":"Der Anbieter (beziehungsweise sein Webspace-Provider) erhebt Daten über jeden Zugriff auf das Angebot (so genannte Serverlogfiles). Zu den Zugriffsdaten gehören: Name der abgerufenen Webseite, Datei, Datum und Uhrzeit des Abrufs, übertragene Datenmenge, Meldung über erfolgreichen Abruf, Browsertyp nebst Version, das Betriebssystem des Nutzers, Referrer URL (die zuvor besuchte Seite), IP-Adresse und der anfragende Provider. Der Anbieter verwendet die Protokolldaten nur für statistische Auswertungen zum Zweck des Betriebs, der Sicherheit und der Optimierung des Angebotes. Der Anbieter behält sich jedoch vor, die Protokolldaten nachträglich zu überprüfen, wenn aufgrund konkreter Anhaltspunkte der berechtigte Verdacht einer rechtswidrigen Nutzung besteht.","contact-support-heading":"Kontaktaufnahme","contact-support":"Bei der Kontaktaufnahme mit dem Anbieter (zum Beispiel per Post oder E-Mail) werden die Angaben des Nutzers zwecks Bearbeitung der Anfrage sowie für den Fall, dass Anschlussfragen entstehen, gespeichert.","cookies-heading":"Cookies","cookies":"Cookies sind kleine Dateien, die es ermöglichen, auf dem Zugriffsgerät der Nutzer (PC, Smartphone o.ä.) spezifische, auf das Gerät bezogene Informationen zu speichern. Sie dienen zum einem der Benutzerfreundlichkeit von Webseiten und damit den Nutzern (z.B. Speicherung von Logindaten). Zum anderen dienen sie, um die statistische Daten der Webseitennutzung zu erfassen und sie zwecks Verbesserung des Angebotes analysieren zu können. Die Nutzer können auf den Einsatz der Cookies Einfluss nehmen. Die meisten Browser verfügen eine Option mit der das Speichern von Cookies eingeschränkt oder komplett verhindert wird. Allerdings wird darauf hingewiesen, dass die Nutzung und insbesondere der Nutzungskomfort ohne Cookies eingeschränkt werden. Sie können viele Online-Anzeigen-Cookies von Unternehmen über die US-amerikanische Seite http://www.aboutads.info/choices/ oder die EU-Seite http://www.youronlinechoices.com/uk/your-ad-choices/ verwalten.","google-analytics-heading":"Google Analytics","google-analytics":"Dieses Angebot benutzt Google Analytics, einen Webanalysedienst der Google Inc. („Google“). Google Analytics verwendet sog. „Cookies“, Textdateien, die auf Computer der Nutzer gespeichert werden und die eine Analyse der Benutzung der Website durch sie ermöglichen. Die durch den Cookie erzeugten Informationen über Benutzung dieser Website durch die Nutzer werden in der Regel an einen Server von Google in den USA übertragen und dort gespeichert. Im Falle der Aktivierung der IP-Anonymisierung auf dieser Webseite, wird die IP-Adresse der Nutzer von Google jedoch innerhalb von Mitgliedstaaten der Europäischen Union oder in anderen Vertragsstaaten des Abkommens über den Europäischen Wirtschaftsraum zuvor gekürzt. Nur in Ausnahmefällen wird die volle IP-Adresse an einen Server von Google in den USA übertragen und dort gekürzt. Die IP-Anonymisierung ist auf dieser Website aktiv. Im Auftrag des Betreibers dieser Website wird Google diese Informationen benutzen, um die Nutzung der Website durch die Nutzer auszuwerten, um Reports über die Websiteaktivitäten zusammenzustellen und um weitere mit der Websitenutzung und der Internetnutzung verbundene Dienstleistungen gegenüber dem Websitebetreiber zu erbringen. Die im Rahmen von Google Analytics von Ihrem Browser übermittelte IP-Adresse wird nicht mit anderen Daten von Google zusammengeführt. Die Nutzer können die Speicherung der Cookies durch eine entsprechende Einstellung Ihrer Browser-Software verhindern; Dieses Angebot weist die Nutzer jedoch darauf hin, dass Sie in diesem Fall gegebenenfalls nicht sämtliche Funktionen dieser Website vollumfänglich werden nutzen können. Die Nutzer können darüber hinaus die Erfassung der durch das Cookie erzeugten und auf ihre Nutzung der Website bezogenen Daten (inkl. Ihrer IP-Adresse) an Google sowie die Verarbeitung dieser Daten durch Google verhindern, indem sie das unter dem folgenden Link verfügbare Browser-Plugin herunterladen und installieren: http://tools.google.com/dlpage/gaoptout?hl=de . Weitere Informationen zur Datennutzung zu Werbezwecken durch Google, Einstellungs- und Widerspruchsmöglichkeiten erfahren Sie auf den Webseiten von Google:https://www.google.com/intl/de/policies/privacy/partners/ („Datennutzung durch Google bei Ihrer Nutzung von Websites oder Apps unserer Partner“),http://www.google.com/policies/technologies/ads („Datennutzung zu Werbezwecken“), http://www.google.de/settings/ads („Informationen verwalten, die Google verwendet, um Ihnen Werbung einzublenden“) undhttp://www.google.com/ads/preferences/ („Bestimmen Sie, welche Werbung Google Ihnen zeigt“).","edited-hint":"Der generierte Text wurde vom Webseiteninhaber angepasst.","generated-hint":"Erstellt mit Datenschutz-Generator.de von RA Dr. Thomas Schwenke","google-play-services-heading":"Google Play Dienste","google-play-services":"Features wie die Bestenliste und Erfolge benötigen einen Login bei Google Play. Hierfür wird die Identität benötigt, um die entsprechenden Punktzahlen und Erfolge an das jeweilige Google Play-Konto zu knüpfen. Alle anderen Features sind weiterhin auch ohne Login bei Google Play nutzbar. Außerdem kann sich jederzeit in den Einstellungen von Google Play abgemeldet werden.","settings":"Einstellungen","close":"Schließen","other-apps":"Andere Apps","optimistic-locking-dialog":"Deine Änderungen können nicht gespeichert werden! Ein anderer Benutzer hat die Daten bereits verändert. Bitte lade die Daten neu und speichere danach.","optimistic-locking-dialog-title":"Nicht gespeichert!","not-online":"Du bist nicht mit dem Internet verbunden. Bitte überprüfe deine Verbindung.","search":"Suchen...","site":"Seite","HTTP-Exception (403) Forbidden":"Nicht erlaubt!","general-settings-fragment":"Allgemeine Einstellungen","login":"Login","login-email":"E-Mail","login-password":"Passwort","login-automated-login":"Automatischer Login","login-submit":"Login","logout":"Ausloggen","username-or-password-wrong":"Entweder der Username oder das Passwort stimmt nicht!","login-success":"Willkommen zurück!","logged-out-successfully":"Tschüss!","registration":"Registrieren","registration-username":"Username","registration-email":"E-Mail","registration-password1":"Passwort","registration-password2":"Passwort wiederholen","registration-submit":"Registrieren","registration-success":"Ein Registrierungscode wurde an Ihre E-Mailadresse gesendet.","not-allowed-title":"Nicht erlaubt!","not-allowed":"Du hast keine Berechtigung für diese Seite. Wenn das ein Fehler ist, wende dich bitte an einen Admin.","forgot-password":"Passwort vergessen?","forgot-password-title":"Passwort vergessen","forgot-password-email":"E-Mail","forgot-password-submit":"Absenden","forgot-password-text":"Gib deine E-Mailadresse in das Feld ein. Ist die Adresse registriert, werden wir eine E-Mail mit einem Passwort-Resetcode senden.","no-user-found":"Es gibt keinen Benutzer mit dieser E-Mailadresse","new-password-code-send":"Es wurde ein Reset-Code an deine E-Mailadresse gesendet.","new-password":"Neues Passwort","new-password-password1":"Passwort","new-password-password2":"Passwort wiederholen","new-password-submit":"Passwort setzten","password-updated":"Das Passwort ist geupdated!","user-settings":"E-Mail & Username","user-settings-title":"E-Mail & Username","user-settings-form-username":"Username","user-settings-form-old-email":"Aktuelle E-Mail","user-settings-form-new-email":"Neue E-Mail","user-settings-form-submit":"Speichern","user-data-is-changed":"Die Daten wurden gespeichert.","email-code-send":"Ein Änderungscode wurde an die neue E-Mailadresse gesendet. Sobald der Code aktiviert wurde, werden Ihnen E-Mails an die neue Adresse gesendet.","change-email-new-automated-login":"Wenn die E-Mailadresse geändert wird, muss der automatische Login erneut aktiviert werden!","password-settings":"Passwort","change-password-title":"Passwort","change-password-new-automated-login":"Wenn das Passwort geändert wird, muss der automatische Login erneut aktiviert werden!","change-password-old-password":"Altes Passwort","change-password-new-password1":"Neues Passwort","change-password-new-password2":"Neues Passwort wiederholen","change-password-submit":"Speichern","password-changed":"Das Passwort wurde erfolgreich geändert!","registration-username-empty":"Der Username darf nicht leer sein.","registration-username-wrong-char":"Der Username darf nur aus Buchstaben, Zahlen oder den folgenden Zeichen bestehen: -_.&;()#!?$+\",","registration-username-already-taken":"Der Username ist schon vergeben. Bitte wähle einen anderen.","registration-password-empty":"Das Passwort darf nicht leer sein.","registration-password-short":"Das Passwort muss mindestens 8 Zeichen lang sein.","registration-password-not-identical":"Die Passwörter sind nicht identlisch.","registration-email-empty":"Die Email darf nicht leer sein.","registration-email-not-valid":"Die Emailadresse ist keine gültige Emailadresse.","registration-email-already-taken":"Es gibt bereits einen Account mit der Emailadresse.","change-password-old-password-wrong":"Das Passwort stimmt nicht!","user-roles-heading":"Benutzerrollen","user-roles-list":"Aktuelle Rollen:","available-roles-list":"Verfügbare Rollen:","name":"Name","description":"Beschreibung"}
\ No newline at end of file
diff --git a/public/js/lang/en.json b/public/js/lang/en.json
deleted file mode 100755
index de8f1cf..0000000
--- a/public/js/lang/en.json
+++ /dev/null
@@ -1 +0,0 @@
-{"won":"Won!","continue":"Continue","help":"?","not-enugh-coins":"You have to few coins!","Sunday":"Sunday","Monday":"Monday","Tuesday":"Tuesday","Wednesday":"Wednesday","Thursday":"Thursday","Friday":"Friday","Saturday":"Saturday","January":"January","February":"February","March":"March","April":"April","May":"May","June":"June","July":"July","August":"August","September":"September","October":"October","November":"November","December":"December","Sun":"Sun","Mon":"Mon","Tue":"Tue","Wed":"Wed","Thu":"Thu","Fri":"Fri","Sat":"Sat","Jan":"Jan","Feb":"Feb","Mar":"Mar","Apr":"Apr","Jun":"Jun","Jul":"Jul","Aug":"Aug","Sep":"Sep","Oct":"Oct","Nov":"Nov","Dec":"Dec","code-not-valid":"The given code is not valid!","code-activated":"The code has been successfully activated!","contact":"Contact","contact-email":"EMail","contact-accepted-privacy-policy":" read and accepted","contact-message":"Message","contact-submit":"Send","contact-email-empty":"The EMail must be given!","contact-email-not-valid":"The given EMail is not vaild!","contact-accept-privacy-policy-empty":"The Privacy Policy must be accepted!","contact-message-empty":"Please enter a message.","contact-message-sent":"Your message was sent.","current-lang":"EN","en":"English","de":"German","black":"Black","red":"Red","blue":"Blue","green":"Green","pink":"Pink","cancel-button":"CANCEL","confirm-button":"OK","we-use-cookie-hint":"Our website uses cookies. By continuing we assume your permission to deploy cookies, as detailed in our privacy policy .","policy-heading":"Privacy Policy","area-of-validity-heading":"Area of validity","area-of-validity":"This privacy policy clarifies the nature, extent and purpose of the collection and use of personal data by Silas Günther, Langenbusch 263b - 42897 Remscheid, matrix[at]silas.link on this website (hereinafter referred to as \"the offer\"). The legal basis of data protection can be found in the Bundesdatenschutzgesetz (BDSG) and the Telemediengesetz (TMG).","logfiles-heading":"Acess data / Server log files","logfiles":"The owner of this website (or his webspace provider) collects data about every access to the offer (so-called server log files). The access data include: the name of the retrieved web page, file, date and time of the retrieval, transmitted data volume, message of successful retrieval, browser type and version, the user's operating system, referrer URL (the previous visited site), IP address and the requesting provider. The owner uses the protocol data only for statistical evaluations for the purpose of operation, security and optimization of the offer. However, the owner reserves the right to check the log data subsequently if, due to concrete grounds, the legitimate suspicion of unlawful use exists.","contact-support-heading":"Contacting","contact-support":"When contacting the owner (for example by mail or e-mail), the user's data are stored for the purpose of processing the inquiry as well as in the event that connection questions arise.","cookies-heading":"Cookies","cookies":"Cookies are small files that allow you to store specific information related to the device on the user's access point (PC, smartphone, etc.). On the one hand they serve the user friendliness of web pages and therefore the users (for example storage of logindates). On the other hand, they are used to record the statistical data of the website and to be able to analyze them for the purpose of improving the offer. Users can influence the use of cookies. Most browsers have an option to restrict or prevent cookies from being stored. However, it is noted that the use and, in particular, the convenience of use is restricted without cookies. You can manage many online cookies from companies across the US site 'http://www.aboutads.info/choices/'>http://www.aboutads.info/choices/ or the EU site http://www.youronlinechoices.com/uk/your-ad-choices/ code. ","google-analytics-heading":"Google Analytics","google-analytics":"This offer uses Google Analytics, a web analytics service provided by Google, Inc. (\"Google\"). Google Analytics uses so-called \"cookies\", text files that are stored on users' computers and which allow an analysis of the use of the website through them. The information generated by the cookie about the use of this website by the users is usually transmitted to a Google server in the USA and stored there. In the case of the activation of the IP anonymization on this website, the IP address of users of Google will be previously abridged within Member States of the European Union or in other States Parties to the Agreement on the European Economic Area. Only in exceptional cases will the full IP address be transferred to a Google server in the USA and abbreviated there. IP anonymization is active on this website. On behalf of the operator of this website, Google will use this information to evaluate the use of the website, to compile reports on the website activity and to provide other services related to the website usage and the Internet usage against the website operator. The IP address transmitted by your browser as part of Google Analytics will not be merged with other Google data. Users can prevent the storage of cookies by setting their browser software accordingly; However, this offer warrants to users that in this case, you may not be able to fully utilize all the functions of this website. Users may also block Google's collection of the data (including your IP address) generated by the cookie and its use of the website (including your IP address), as well as the processing of such data by Google by using the browser plug-in available under the following link download and install: http://tools.google.com/dlpage/gaoptout?hl=en For further information on the use of the data for advertising purposes by Google, please refer to the websites of Google: https://www.google.com/intl/en/policies/privacy/partners/ , http://www.google.com/policies/technologies/ads http://www.google.com/settings/ads and http://www.google.com/ads/preferences/ ","edited-hint":"This text was modified and translated by the owner of this website.","generated-hint":"Created in german with Datenschutz-Generator.de from RA Dr. Thomas Schwenke","google-play-services-heading":"Google Play Services","google-play-services":"Features such as leaderboards and achievements require a login to Google Play. For this, your identity is needed in order to tie the scores and achievements to your Google Play account. All other features can still be used without logging in to Google Play. You can also logout from Google Play at any time through the settings.","settings":"Settings","close":"Close","other-apps":"Other Apps","optimistic-locking-dialog":"Your changes cannot be saved! Another user has already changed the data. Please reload the data and save it afterwards.","optimistic-locking-dialog-title":"Not saved!","not-online":"You are not connected with the Internet. Please check your connection.","search":"Search...","site":"Page","HTTP-Exception (403) Forbidden":"Not allowed!","theme":"Theme:","general-settings-fragment":"General Settings","choose-theme-dialog-title":"Choose Theme:","install":"Install","login":"Login","login-email":"E-Mail:","login-password":"Password:","login-automated-login":"Automated Login","login-submit":"Login","logout":"Logout","username-or-password-wrong":"Either the username or the password is wrong!","login-success":"Welcome back!","logged-out-successfully":"Good Bye!","registration":"Registration","registration-username":"Username","registration-email":"E-Mail","registration-password1":"Password","registration-password2":"Re-enter password","registration-submit":"Create Account","registration-success":"A registration code was send to your E-Mail address.","not-allowed-title":"Not allowed!","not-allowed":"You do not have permission for this page. If this is a mistake, please contact an admin.","forgot-password":"Forgot your password?","forgot-password-title":"Password forgotten","forgot-password-email":"E-Mail","forgot-password-submit":"Send","forgot-password-text":"Enter your e-mail address in the field below. If the address is registered, we will send you an e-mail with a password reset code.","no-user-found":"There is no user with this e-mail address","new-password-code-send":"A reset code has been sent to your e-mail address.","new-password":"New Password","new-password-password1":"Password","new-password-password2":"Re-enter password","new-password-submit":"Set password","password-updated":"The password was updated!","user-settings":"E-Mail & Username","user-settings-title":"E-Mail & Username","user-settings-form-username":"Username","user-settings-form-old-email":"Current E-Mail","user-settings-form-new-email":"New E-Mail","user-settings-form-submit":"Save","user-data-is-changed":"The data has been saved.","email-code-send":"A code has been sent to the new e-mail address. Once the code has been activated, you will receive e-mails to the new address.","change-email-new-automated-login":"If the e-mail address is changed, the automatic login must be activated again!","password-settings":"Password","change-password-title":"Password","change-password-new-automated-login":"If the password is changed, the automatic login must be activated again!","change-password-old-password":"Old password","change-password-new-password1":"New password","change-password-new-password2":"Re-enter new password","change-password-submit":"Save","password-changed":"The password was updated!","registration-username-empty":"The username must not be empty.","registration-username-wrong-char":"The username may only consist of letters, numbers or the following characters: -_.&;()#!?$+\",","registration-username-already-taken":"The username is already assigned. Please choose another one.","registration-password-empty":"The password must not be empty.","registration-email-empty":"The email must not be empty.","registration-email-not-valid":"The email address is not a valid email address.","registration-email-already-taken":"There is already an account with the email address.","change-password-old-password-wrong":"The password is not correct!","user-roles-heading":"Roles from user","user-roles-list":"Current roles:","available-roles-list":"Available roles:","name":"Name","description":"Description"}
\ No newline at end of file
diff --git a/public/js/manifest.json b/public/js/manifest.json
deleted file mode 100755
index 395eb1e..0000000
--- a/public/js/manifest.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "name": "WordRotator",
- "short_name":"WordRotator",
- "icons": [
- {
- "src": "../img/icons/android-chrome-192x192.png",
- "sizes": "192x192",
- "type": "image/png"
- },
- {
- "src": "../img/icons/android-chrome-512x512.png",
- "sizes": "512x512",
- "type": "image/png"
- }
- ],
- "theme_color": "#ffffff",
- "background_color": "#ffffff",
- "display": "standalone",
- "start_url":"/"
-}
\ No newline at end of file
diff --git a/public/pwaAssets/html/fragment/tabbedFragment.html b/public/pwaAssets/html/fragment/tabbedFragment.html
deleted file mode 100755
index 5336041..0000000
--- a/public/pwaAssets/html/fragment/tabbedFragment.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/robots.txt b/public/robots.txt
deleted file mode 100644
index ca4ec54..0000000
--- a/public/robots.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-# robots.txt generated by https://seo-ranking-tools.de
-User-agent: *
-Disallow:
diff --git a/public/userManagement/html/403.html b/public/userManagement/html/403.html
deleted file mode 100755
index c845208..0000000
--- a/public/userManagement/html/403.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/userManagement/html/editUserRoles.html b/public/userManagement/html/editUserRoles.html
deleted file mode 100755
index 37ca445..0000000
--- a/public/userManagement/html/editUserRoles.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/userManagement/html/forgotPassword.html b/public/userManagement/html/forgotPassword.html
deleted file mode 100755
index 20fde2b..0000000
--- a/public/userManagement/html/forgotPassword.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/userManagement/html/fragments/passwordSettings.html b/public/userManagement/html/fragments/passwordSettings.html
deleted file mode 100755
index 76717b9..0000000
--- a/public/userManagement/html/fragments/passwordSettings.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/userManagement/html/fragments/userSettings.html b/public/userManagement/html/fragments/userSettings.html
deleted file mode 100755
index 8f723c4..0000000
--- a/public/userManagement/html/fragments/userSettings.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/userManagement/html/login.html b/public/userManagement/html/login.html
deleted file mode 100755
index d00992d..0000000
--- a/public/userManagement/html/login.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/userManagement/html/registration.html b/public/userManagement/html/registration.html
deleted file mode 100755
index 9dd54e6..0000000
--- a/public/userManagement/html/registration.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/userManagement/html/setNewPassword.html b/public/userManagement/html/setNewPassword.html
deleted file mode 100755
index 172b2a8..0000000
--- a/public/userManagement/html/setNewPassword.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/version/1/html/deleteLevels.html b/public/version/1/html/deleteLevels.html
deleted file mode 100644
index 0b1d2fb..0000000
--- a/public/version/1/html/deleteLevels.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/version/1/html/selectWords.html b/public/version/1/html/selectWords.html
deleted file mode 100644
index b19aa6e..0000000
--- a/public/version/1/html/selectWords.html
+++ /dev/null
@@ -1 +0,0 @@
-Noch nicht geprüft:
Gecheckt:
Unsicher:
Gelöscht:
\ No newline at end of file
diff --git a/public/version/1/listjs/list.min.js b/public/version/1/listjs/list.min.js
deleted file mode 100755
index 3cb2737..0000000
--- a/public/version/1/listjs/list.min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-/*! List.js v1.5.0 (http://listjs.com) by Jonny Strömberg (http://javve.com) */
-var List=function(t){function e(n){if(r[n])return r[n].exports;var i=r[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var r={};return e.m=t,e.c=r,e.i=function(t){return t},e.d=function(t,r,n){e.o(t,r)||Object.defineProperty(t,r,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var r=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(r,"a",r),r},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=11)}([function(t,e,r){function n(t){if(!t||!t.nodeType)throw new Error("A DOM element reference is required");this.el=t,this.list=t.classList}var i=r(4),s=/\s+/;Object.prototype.toString;t.exports=function(t){return new n(t)},n.prototype.add=function(t){if(this.list)return this.list.add(t),this;var e=this.array(),r=i(e,t);return~r||e.push(t),this.el.className=e.join(" "),this},n.prototype.remove=function(t){if(this.list)return this.list.remove(t),this;var e=this.array(),r=i(e,t);return~r&&e.splice(r,1),this.el.className=e.join(" "),this},n.prototype.toggle=function(t,e){return this.list?("undefined"!=typeof e?e!==this.list.toggle(t,e)&&this.list.toggle(t):this.list.toggle(t),this):("undefined"!=typeof e?e?this.add(t):this.remove(t):this.has(t)?this.remove(t):this.add(t),this)},n.prototype.array=function(){var t=this.el.getAttribute("class")||"",e=t.replace(/^\s+|\s+$/g,""),r=e.split(s);return""===r[0]&&r.shift(),r},n.prototype.has=n.prototype.contains=function(t){return this.list?this.list.contains(t):!!~i(this.array(),t)}},function(t,e,r){var n=window.addEventListener?"addEventListener":"attachEvent",i=window.removeEventListener?"removeEventListener":"detachEvent",s="addEventListener"!==n?"on":"",a=r(5);e.bind=function(t,e,r,i){t=a(t);for(var o=0;o0?setTimeout(function(){e(r,n,i)},1):(t.update(),n(i))};return e}},function(t,e){t.exports=function(t){return t.handlers.filterStart=t.handlers.filterStart||[],t.handlers.filterComplete=t.handlers.filterComplete||[],function(e){if(t.trigger("filterStart"),t.i=1,t.reset.filter(),void 0===e)t.filtered=!1;else{t.filtered=!0;for(var r=t.items,n=0,i=r.length;nv.page,a=new m(t[i],void 0,n),v.items.push(a),r.push(a)}return v.update(),r}},this.show=function(t,e){return this.i=t,this.page=e,v.update(),v},this.remove=function(t,e,r){for(var n=0,i=0,s=v.items.length;i-1&&r.splice(n,1),v},this.trigger=function(t){for(var e=v.handlers[t].length;e--;)v.handlers[t][e](v);return v},this.reset={filter:function(){for(var t=v.items,e=t.length;e--;)t[e].filtered=!1;return v},search:function(){for(var t=v.items,e=t.length;e--;)t[e].found=!1;return v}},this.update=function(){var t=v.items,e=t.length;v.visibleItems=[],v.matchingItems=[],v.templater.clear();for(var r=0;r=v.i&&v.visibleItems.lengthe},innerWindow:function(t,e,r){return t>=e-r&&t<=e+r},dotted:function(t,e,r,n,i,s,a){return this.dottedLeft(t,e,r,n,i,s)||this.dottedRight(t,e,r,n,i,s,a)},dottedLeft:function(t,e,r,n,i,s){return e==r+1&&!this.innerWindow(e,i,s)&&!this.right(e,n)},dottedRight:function(t,e,r,n,i,s,a){return!t.items[a-1].values().dotted&&(e==n&&!this.innerWindow(e,i,s)&&!this.right(e,n))}},a=function(e,r,n){i.bind(e,"click",function(){t.show((r-1)*n+1,n)})};return function(r){var n=new s(t.listContainer.id,{listClass:r.paginationClass||"pagination",item:" ",valueNames:["page","dotted"],searchClass:"pagination-search-that-is-not-supposed-to-exist",sortClass:"pagination-sort-that-is-not-supposed-to-exist"});t.on("updated",function(){e(n,r)}),e(n,r)}}},function(t,e,r){t.exports=function(t){var e=r(2)(t),n=function(t){for(var e=t.childNodes,r=[],n=0,i=e.length;n0?setTimeout(function(){s(e,r)},1):(t.update(),t.trigger("parseComplete"))};return t.handlers.parseComplete=t.handlers.parseComplete||[],function(){var e=n(t.list),r=t.valueNames;t.indexAsync?s(e,r):i(e,r)}}},function(t,e){t.exports=function(t){var e,r,n,i,s={resetList:function(){t.i=1,t.templater.clear(),i=void 0},setOptions:function(t){2==t.length&&t[1]instanceof Array?r=t[1]:2==t.length&&"function"==typeof t[1]?(r=void 0,i=t[1]):3==t.length?(r=t[1],i=t[2]):r=void 0},setColumns:function(){0!==t.items.length&&void 0===r&&(r=void 0===t.searchColumns?s.toArray(t.items[0].values()):t.searchColumns)},setSearchString:function(e){e=t.utils.toString(e).toLowerCase(),e=e.replace(/[-[\]{}()*+?.,\\^$|#]/g,"\\$&"),n=e},toArray:function(t){var e=[];for(var r in t)e.push(r);return e}},a={list:function(){for(var e=0,r=t.items.length;e-1))},reset:function(){t.reset.search(),t.searched=!1}},o=function(e){return t.trigger("searchStart"),s.resetList(),s.setSearchString(e),s.setOptions(arguments),s.setColumns(),""===n?a.reset():(t.searched=!0,i?i(n,r):a.list()),t.update(),t.trigger("searchComplete"),t.visibleItems};return t.handlers.searchStart=t.handlers.searchStart||[],t.handlers.searchComplete=t.handlers.searchComplete||[],t.utils.events.bind(t.utils.getByClass(t.listContainer,t.searchClass),"keyup",function(e){var r=e.target||e.srcElement,n=""===r.value&&!t.searched;n||o(r.value)}),t.utils.events.bind(t.utils.getByClass(t.listContainer,t.searchClass),"input",function(t){var e=t.target||t.srcElement;""===e.value&&o("")}),o}},function(t,e){t.exports=function(t){var e={els:void 0,clear:function(){for(var r=0,n=e.els.length;r]/g.exec(e)){var s=document.createElement("tbody");return s.innerHTML=e,s.firstChild}if(e.indexOf("<")!==-1){var a=document.createElement("div");return a.innerHTML=e,a.firstChild}var o=document.getElementById(t.item);if(o)return o}},this.get=function(e,n){r.create(e);for(var i={},s=0,a=n.length;s=1;)t.list.removeChild(t.list.firstChild)},n()};t.exports=function(t){return new r(t)}},function(t,e){t.exports=function(t,e){var r=t.getAttribute&&t.getAttribute(e)||null;if(!r)for(var n=t.attributes,i=n.length,s=0;s=48&&t<=57}function i(t,e){for(var r=(t+="").length,i=(e+="").length,s=0,l=0;s32)return!1;var o=i,l=function(){var t,r={};for(t=0;t=p;b--){var w=l[t.charAt(b-1)];if(0===g?y[b]=(y[b+1]<<1|1)&w:y[b]=(y[b+1]<<1|1)&w|((v[b+1]|v[b])<<1|1)|v[b+1],y[b]&f){var x=n(g,b-1);if(x<=u){if(u=x,c=b-1,!(c>o))break;p=Math.max(1,2*o-c)}}}if(n(g+1,o)>u)break;v=y}return!(c<0)}}]);
\ No newline at end of file
diff --git a/public/version/2/html/deleteLevels.html b/public/version/2/html/deleteLevels.html
deleted file mode 100644
index 0b1d2fb..0000000
--- a/public/version/2/html/deleteLevels.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/version/2/html/selectWords.html b/public/version/2/html/selectWords.html
deleted file mode 100644
index 41eb80f..0000000
--- a/public/version/2/html/selectWords.html
+++ /dev/null
@@ -1 +0,0 @@
-Noch nicht geprüft:
Gecheckt:
Unsicher:
Gelöscht:
Unbenutzt:
\ No newline at end of file
diff --git a/public/version/x/app.names.json b/public/version/x/app.names.json
deleted file mode 100644
index b8f30ba..0000000
--- a/public/version/x/app.names.json
+++ /dev/null
@@ -1 +0,0 @@
-{"vars":{"props":{"$_typeof":"t","$_get":"e","$_createClass":"n","$_asyncToGenerator":"r","$_possibleConstructorReturn":"i","$_inherits":"o","$_classCallCheck":"s","$InitPromise":"a","$AndroidBridge":"u","$MenuAction":"l","$OpenSubmenuAction":"c","$Menu":"h","$Submenu":"f","$TranslatorDB":"p","$Translator":"d","$Helper":"v","$SystemSettings":"m","$ThemeManager":"y","$CookieCompliance":"g","$ActionBarMenu":"k","$ViewInflater":"w","$Context":"_","$AbstractSite":"b","$SiteContainer":"x","$SiteManager":"O","$PauseSite":"L","$App":"P","$Dialog":"E","$FlashMessenger":"I","$MyDb":"S","$ScriptLoader":"C","$ShareButton":"j","$MultipleShareButton":"R","$ShareManager":"T","$SmsShareButton":"M","$TelegramShareButton":"A","$WhatsappShareButton":"q","$Fragment":"N","$Theme":"B","$Constants":"D","$DataManager":"X","$Form":"H","$SettingsManager":"F","$LocalStorageSettingsFragment":"z","$SmartColumn":"$","$ConstSmartColumn":"U","$DataSmartColumn":"G","$ImgConstSmartColumn":"V","$ListHelper":"J","$SettingsSite":"Z","$UserManager":"Q","$UserAction":"W","$NotAllowedSite":"Y","$UserSite":"K","$LoginForm":"tt","$RegistrationForm":"et","$UserFragment":"nt","$PasswordSettingsFragment":"rt","$UserSettingsFragment":"it","$EditUserRolesSite":"ot","$ForgotPasswordSite":"st","$LoginSite":"at","$RegistrationSite":"ut","$SetNewPasswordSite":"lt","$InstallManager":"ct","$Matomo":"ht","$MatomoShareButton":"ft","$ScaleHelper":"pt","$AudioChain":"dt","$SoundManager":"vt","$Code":"mt","$CodeSite":"yt","$ContactSite":"gt","$WordRotatorBaseSite":"kt","$TemplateContainer":"wt","$Segment":"_t","$LeafSegment":"bt","$ParentSegment":"xt","$Level":"Ot","$RowSegment":"Lt","$RowLevel":"Pt","$SimpleLevel":"Et","$RowLevel8":"It","$RowLevel10":"St","$TriangleSegment":"Ct","$SixWordsRowLevel":"jt","$SixWordsRowLevel8":"Rt","$SixWordsRowLevel12":"Tt","$FourWordsLevel":"Mt","$FourWordsLevel8":"At","$FourWordsLevel12":"qt","$LevelHelper":"Nt","$WordRotatorDb":"Bt","$EndSite":"Dt","$LevelSite":"Xt","$MainMenuLevel":"Ht","$ShareDialog":"Ft","$MenuSite":"zt","$PrivacyPolicySite":"$t","$CreditsSite":"Ut","$ChooseThemeDialog":"Gt","$ImpressumSite":"Vt","$WordRotatorSettingFragment":"Jt","$SelectWordsSite":"Zt","$DeleteWordsSite":"Qt","$basePath":"Wt","$app":"Yt"}},"props":{"props":{"$addPromise":"t","$mainPromise":"s","$promises":"i","$mainResolver":"o","$addDefinition":"l","$definitions":"h","$applyDefinitions":"u","$nonNull":"m","$callback":"p","$showFor":"g","$SHOW_FOR_MEDIUM":"S","$_liClass":"M","$_menu":"H","$_activated":"v","$_visible":"P","$maxId":"T","$_icon":"L","$_shouldTranslate":"A","$_copies":"C","$setTitle":"k","$setShouldTranslate":"F","$getShowFor":"B","$getTitle":"R","$getShouldTranslate":"D","$isNotNull":"I","$removeAction":"U","$getMenu":"W","$setMenu":"N","$getVisible":"O","$setVisible":"_","$redraw":"j","$getActivated":"V","$getIcon":"J","$setIcon":"q","$getId":"K","$updateAction":"G","$copy":"X","$redrawMenu":"$","$SHOW_ALWAYS":"Y","$SHOW_FOR_LARGE":"Z","$SHOW_NEVER":"tt","$getSubmenu":"et","$submenu":"nt","$setParentAction":"st","$actions":"it","$submenus":"rt","$parentElements":"ot","$addAction":"at","$includesNot":"lt","$draw":"ht","$sortActions":"ut","$renderAction":"ct","$_htmlElement":"dt","$_getOnClickListener":"pt","$makePersistentTranslation":"gt","$renderLiElement":"ft","$getParentElement":"St","$_getElementsForAction":"wt","$isNull":"Mt","$SHOW_FOR_SMEDIUM":"Ht","$parentAction":"yt","$_indexedDB":"vt","$_version":"Pt","$_dbPromise":"Tt","$_upgradeDb":"Lt","$setLanguage":"bt","$_openTransaction":"At","$saveTranslationsForLang":"Ct","$loadTranslationsForLang":"kt","$getLanguage":"Ft","$_translations":"xt","$_db":"Bt","$_currentLanguage":"Rt","$_supportedLanguages":"Dt","$supportedLanguages":"It","$_baseLanguage":"Ut","$baseLanguage":"Et","$_languageBasePath":"Wt","$languageBasePath":"Nt","$_markUntranslatedTranslations":"Ot","$markUntranslatedTranslations":"_t","$_markTranslations":"jt","$markTranslations":"Vt","$_initPromise":"Jt","$loadBaseLanguage":"zt","$loadUserLanguage":"qt","$_loadLanguage":"Kt","$basePath":"Gt","$getInstance":"Xt","$updateTranslations":"$t","$addDynamicTranslation":"Qt","$logMissingTranslations":"Yt","$generateChangeLanguageMenuAction":"Zt","$instance":"te","$currentLanguage":"ee","$translations":"ne","$heightMmToPxFactor":"se","$widthMmToPxFactor":"ie","$isSet":"re","$notEmpty":"oe","$buildQuery":"ae","$inflateElementsFromString":"le","$createLoadingSymbol":"he","$getBasePath":"ue","$isMobileApple":"ce","$isMobile":"de","$encodeToBase":"me","$decodeToBase":"pe","$toggleVisibility":"ge","$strftime":"fe","$cloneJson":"Se","$htmlspecialcharsDecode":"we","$formDataFromObject":"Me","$scaleContentRecursive":"He","$scaleDownContentRecursive":"ye","$convertChildrenToRelativeRecursive":"ve","$convertToRelative":"Pe","$isChrome":"Te","$getIndexedObject":"Le","$invertKeyValues":"be","$setBasePath":"Ae","$_basePath":"Ce","$_settings":"ke","$loadCurrentTheme":"Fe","$changeCurrentTheme":"xe","$themes":"Be","$_name":"Re","$_className":"De","$currentTheme":"Ie","$changeListeners":"Ue","$addTheme":"Ee","$generateChangeThemeMenuAction":"We","$showIfNeeded":"Ne","$cookieContainerId":"Oe","$dropCookie":"_e","$cookieDuration":"je","$cookieName":"Ve","$cookieValue":"Je","$checkCookie":"ze","$removeMe":"qe","$createCookie":"Ke","$eraseCookie":"Ge","$currentMenu":"Xe","$updateToggleButton":"$e","$queries":"Qe","$_getCurrentSize":"Ye","$filterVisibleElements":"Ze","$inflate":"tn","$_siteContent":"en","$firstStart":"nn","$inflatePromise":"sn","$inflatePromiseResolver":"in","$fragments":"rn","$inflateView":"on","$onConstruct":"an","$onStart":"ln","$onFirstStart":"hn","$isActive":"un","$onPause":"cn","$onDestroy":"dn","$addFragment":"mn","$findBy":"pn","$isVisible":"gn","$siteManager":"fn","$isFinishing":"Sn","$actionMenu":"wn","$deepLink":"Mn","$startArgs":"Hn","$getDefaultTitle":"yn","$element":"vn","$updateTitle":"Pn","$startStartsite":"Tn","$startSite":"Ln","$getStartSiteName":"bn","$setUrlFromParams":"An","$endSite":"Cn","$toForeground":"kn","$finishAndStartNext":"Fn","$createActionBarMenu":"xn","$getDefaultActions":"Bn","$setUrl":"Rn","$updateUrl":"Dn","$updateUrlParams":"In","$getUrl":"Un","$getFullUrl":"En","$onBackPressed":"Wn","$addKeyListener":"Nn","$addKeyAndEventListener":"On","$_site":"_n","$_pauseParameters":"jn","$_startParameters":"Vn","$_finishResolver":"Jn","$getSite":"zn","$setSite":"qn","$getSiteContent":"Kn","$setSiteContent":"Gn","$getPauseParameters":"Xn","$setPauseParameters":"$n","$getStartParameters":"Qn","$setStartParameters":"Yn","$getFinishResolver":"Zn","$setFinishResolver":"ts","$siteDiv":"es","$siteContainerStack":"ns","$currentSiteContainerToShow":"ss","$actionBarMenuSelector":"rs","$siteStartingPromise":"os","$defaultActions":"as","$startSiteName":"ls","$titleElement":"hs","$defaultTitle":"us","$setStartSiteName":"cs","$addDefaultAction":"ds","$getCurrentSite":"ms","$findSite":"ps","$buildActionBarMenu":"gs","$findContainerIndexBySite":"fs","$showAppEndedMessage":"Ss","$refreshCurrentSite":"ws","$redrawCurrentActionBar":"Ms","$findContainerBySite":"Hs","$_siteManager":"ys","$_actionBarMenuSelector":"vs","$_siteContentId":"Ps","$_deepLinks":"Ts","$_defaultActions":"Ls","$_addThemeAction":"bs","$_showCookieCompliance":"As","$_startSite":"Cs","$getSiteManager":"ks","$setAddThemeAction":"Fs","$getSiteContentId":"xs","$setSiteContentId":"Bs","$getActionBarMenuSelector":"Rs","$setActionBarMenuSelector":"Ds","$addDeepLink":"Is","$setShowCookieCompliance":"Us","$_resolveDeepLink":"Es","$_getDeepLink":"Ws","$_addDeepLinksListener":"Ns","$_extractParams":"Os","$removeDefaultAction":"_s","$_getStartParams":"js","$_cookieClosePromise":"Vs","$resolver":"Js","$backgroundElement":"zs","$translatable":"qs","$additionalClasses":"Ks","$setContent":"Gs","$setTranslatable":"Xs","$setAdditionalClasses":"$s","$setCancelable":"Qs","$contentPromise":"Ys","$addButton":"Zs","$addDefaultButton":"ti","$deleteMessage":"ei","$addMessage":"ni","$MESSAGE_TYPE_SUCCESS":"si","$messageCount":"ii","$defaultTimeToShow":"ri","$LENGTH_SHORT":"oi","$MESSAGE_TYPE_ERROR":"ai","$MESSAGE_TYPE_DEFAULT":"li","$MESSAGE_TYPE_INFO":"hi","$MESSAGE_TYPE_WARNING":"ui","$shimIndexedDB":"ci","$_conn":"di","$upgrade":"mi","$queryPromise":"pi","$openTransaction":"gi","$openStore":"fi","$saveObj":"Si","$saveMany":"wi","$loadAll":"Mi","$loadMany":"Hi","$removeMany":"yi","$removeWithIndex":"vi","$removeAll":"Pi","$loadScript":"Ti","$scriptPromises":"Li","$loadCss":"bi","$cssPromises":"Ai","$_deviceType":"Ci","$_callback":"ki","$shouldShowFor":"Fi","$getCallback":"xi","$TYPE_DESKTOP":"Bi","$TYPE_MOBILE_APPLE":"Ri","$TYPE_MOBILE_LEFTOVER":"Di","$TYPE_MOBILE":"Ii","$shareButtons":"Ui","$addShareButton":"Ei","$generateDefaultShareElement":"Wi","$generateShareElement":"Ni","$getDefaultGenerateCallback":"Oi","$generateDefaultShareElementForButtons":"_i","$generateShareElementForButtons":"ji","$getCurrentDeviceType":"Vi","$site":"Ji","$ActiveXObject":"zi","$SCRIPTS":"qi","$CKEDITOR":"Ki","$LIST_JS":"Gi","$cachePath":"Xi","$dataPath":"$i","$_load":"Qi","$loadStatic":"Yi","$formElem":"Zi","$isCachable":"tr","$isBusy":"er","$submitHandler":"nr","$submitCallback":"sr","$errorCallback":"ir","$setErrors":"rr","$doSubmit":"or","$onError":"ar","$setValues":"lr","$setIsBusy":"hr","$readonly":"ur","$onSubmit":"cr","$_instance":"dr","$_localStorageKey":"mr","$getSettings":"pr","$_loadSettings":"gr","$getSetting":"Sr","$deleteSetting":"wr","$_saveSettings":"Mr","$setSetting":"Hr","$date":"yr","$setSettings":"vr","$hasSetting":"Pr","$_label":"Tr","$_translateable":"Lr","$_sortable":"br","$_index":"Ar","$_clickListener":"Cr","$setClickListener":"kr","$setIndex":"Fr","$getName":"xr","$getLabel":"Br","$getHeadElement":"Rr","$_headElement":"Dr","$getValueName":"Ir","$prepareData":"Ur","$getItemElement":"Er","$_valueTranslatable":"Wr","$_tableElement":"Nr","$_options":"Or","$_values":"_r","$_columns":"jr","$prepareDataset":"Vr","$createTable":"Jr","$updateColumns":"zr","$getList":"qr","$updateItem":"Kr","$setBusy":"Gr","$template":"Xr","$settingsFragments":"$r","$addSettingsFragment":"Qr","$buildList":"Yr","$setAddSettingsSite":"Zr","$shouldAddSettingsSite":"to","$setTemplate":"eo","$settingsAction":"no","$shouldAddSettingsAction":"so","$getMeUrl":"io","$userData":"ro","$online":"oo","$fetchMePromise":"ao","$fetchMePromiseResolver":"lo","$fetchMe":"ho","$logOut":"uo","$hasAccess":"co","$addCurrentUserListener":"do","$addIsLoggedInListener":"mo","$isCurrentUser":"po","$isLoggedIn":"fo","$_access":"So","$getAccess":"wo","$checkPw":"Mo","$setUserRoles":"Ho","$setAvailableRoles":"yo","$setUsername":"vo","$loginAction":"Po","$logoutAction":"To","$addLoginAction":"Lo","$addLogoutAction":"bo","$setDeferredPrompt":"Ao","$deferredPromt":"Co","$canInstallListener":"ko","$setCanInstallListener":"Fo","$isTrackingPromise":"xo","$LOCAL_STORAGE_KEY":"Bo","$_askIsTracking":"Ro","$setTrack":"Do","$TRACK_SITE":"Io","$SIDE_ID":"Uo","$currentUrl":"Eo","$query":"Wo","$BASE_PATH":"No","$getTrackingPromise":"Oo","$trackEvent":"_o","$scaleTo":"jo","$_getNewFontSize":"Vo","$scaleToFull":"Jo","$shouldLoop":"zo","$chainFunction":"qo","$pauseTime":"Ko","$running":"Go","$setBuffer":"Xo","$setLooping":"$o","$channels":"Qo","$handleVisibilityChange":"Yo","$DEFAULT":"Zo","$CHANNELS":"ta","$audio":"ea","$loadedPromise":"na","$timeOffset":"sa","$MUSIC":"ia","$SOUND":"ra","$args":"oa","$isCacheable":"aa","$setIsCacheable":"la","$getIsCacheable":"ha","$activate":"ua","$DEEP_LINK":"ca","$leafTemplate":"da","$parentTemplate":"ma","$rowTemplate":"pa","$triangleTemplate":"ga","$copyLeafTemplate":"fa","$copyParentTemplate":"Sa","$copyRowTemplate":"wa","$copyTriangleTemplate":"Ma","$getCurrentRotations":"Ha","$sameAs":"ya","$setParent":"va","$getLevel":"Pa","$canRotate":"Ta","$isSolved":"La","$_updateElement":"ba","$applyRotations":"Aa","$applyLocks":"Ca","$getCurrentLocked":"ka","$getElement":"Fa","$leaf":"xa","$setLeaf":"Ba","$initListener":"Ra","$mouseDownTarget":"Da","$clickPosition":"Ia","$setIsRotatable":"Ua","$rotatable":"Ea","$class":"Wa","$touchendListener":"Na","$segmentClickedListener":"Oa","$mouseupListener":"_a","$getHasWon":"ja","$_updateRotationClass":"Va","$checkHasWon":"Ja","$setChildren":"za","$addChild":"qa","$_getLayer":"Ka","$rootSegment":"Ga","$startRotations":"Xa","$templateContainer":"$a","$hasWon":"Qa","$wonResolver":"Ya","$giveUpResolver":"Za","$wonPromise":"tl","$saveAsCurrentLevel":"el","$setLocks":"nl","$setId":"sl","$setRootSegment":"il","$setWords":"rl","$setStartRotations":"ol","$getWonPromise":"al","$getRootSegment":"ll","$createSegments":"hl","$getRotatableSegments":"ul","$_getRotatableSegmentsFrom":"cl","$setSegmentClickedListener":"dl","$_createLeafsForWord":"ml","$wordLength":"pl","$setLevelType":"gl","$getLevelClass":"fl","$inflateLevel":"Sl","$LEVEL":"wl","$OBJECT_STORE":"Ml","$saveManyLevels":"Hl","$loadLevel":"yl","$loadNextLevel":"vl","$saveLevelPlayed":"Pl","$coinAction":"Tl","$levelCounter":"Ll","$levelScaler":"bl","$wonParams":"Al","$aborted":"Cl","$coinCounterTimer":"kl","$coinPromise":"Fl","$nextLevel":"xl","$continueButtonScaler":"Bl","$wonTextScaler":"Rl","$wonText":"Dl","$levelCounterActionContainer":"Il","$levelCounterAction":"Ul","$levelNumberScaler":"El","$coinTemplate":"Wl","$coinContainer":"Nl","$help":"Ol","$loadLastLevel":"_l","$levelWon":"jl","$tutorial":"Vl","$RENDERER_TYPES":"Jl","$FIRST_LEVEL":"zl","$TUTORIAL":"ql","$SECOND_LEVEL":"Kl","$BIG_SEGMENT_LEVEL":"Gl","$loadLevelPromise":"Xl","$loadLevels":"$l","$startLevelSite":"Ql","$randomRotateTimeout":"Yl","$stats":"Zl","$setWord":"th"}}}
\ No newline at end of file
diff --git a/rollup.config.js b/rollup.config.js
deleted file mode 100755
index efcf3c7..0000000
--- a/rollup.config.js
+++ /dev/null
@@ -1,34 +0,0 @@
-// import pkg from './package.json';
-
-const pkg = require('./package');
-
-const externals = [
- // ...Object.keys(pkg.dependencies || {}),
- // ...Object.keys(pkg.peerDependencies || {}),
-];
-
-const makeExternalPredicate = (externalsArr => {
- if (externalsArr.length === 0) {
- return (() => false);
- }
- const externalPattern = new RegExp(`^(${externalsArr.join('|')})($|/)`);
- return (id => externalPattern.test(id));
-});
-const ex = {
- input: pkg.input,
- external
- :
- makeExternalPredicate(externals),
- output
- :
- [{
- format: 'es',
- file: pkg.output,
- nameFile: pkg.namesOutput,
- }],
-};
-if (typeof module !== 'undefined') {
- module.exports = ex;
- return;
-}
-// export default ex;
\ No newline at end of file
diff --git a/src/client/globals.d.ts b/src/client/globals.d.ts
new file mode 100644
index 0000000..71a1a90
--- /dev/null
+++ b/src/client/globals.d.ts
@@ -0,0 +1,8 @@
+declare var require: {
+ (path: string): T;
+ (paths: string[], callback: (...modules: any[]) => void): void;
+ ensure: (
+ paths: string[],
+ callback: (require: (path: string) => T) => void
+ ) => void;
+};
\ No newline at end of file
diff --git a/src/module/Application/pwa/public/html/application/dialog/chooseTheme.html b/src/client/html/dialog/chooseTheme.html
similarity index 100%
rename from src/module/Application/pwa/public/html/application/dialog/chooseTheme.html
rename to src/client/html/dialog/chooseTheme.html
diff --git a/src/module/Application/pwa/public/html/application/dialog/persist.html b/src/client/html/dialog/persist.html
similarity index 100%
rename from src/module/Application/pwa/public/html/application/dialog/persist.html
rename to src/client/html/dialog/persist.html
diff --git a/src/module/Application/pwa/public/html/application/dialog/share.html b/src/client/html/dialog/share.html
similarity index 100%
rename from src/module/Application/pwa/public/html/application/dialog/share.html
rename to src/client/html/dialog/share.html
diff --git a/src/client/html/fragment/settings.html b/src/client/html/fragment/settings.html
new file mode 100644
index 0000000..5bc1424
--- /dev/null
+++ b/src/client/html/fragment/settings.html
@@ -0,0 +1,57 @@
+
+
+
+
+ sound
+
+
+
+
+
+
+ music
+
+
+
+
+
+
+ credits
+ >
+
+
+ privacy-policy
+ >
+
+
+ impressum
+ >
+
+
+ contact
+ >
+
+
+ track
+
+
+
+
+
+
+
+ >
+
+
+
+ version-label
+
+
+
+
reset-levels
+
+
+
diff --git a/src/client/html/sites/contactSite.html b/src/client/html/sites/contactSite.html
new file mode 100644
index 0000000..bff7a6e
--- /dev/null
+++ b/src/client/html/sites/contactSite.html
@@ -0,0 +1,21 @@
+contact
+
+
+
\ No newline at end of file
diff --git a/src/client/html/sites/credits.html b/src/client/html/sites/credits.html
new file mode 100644
index 0000000..ca828eb
--- /dev/null
+++ b/src/client/html/sites/credits.html
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/src/module/Application/pwa/public/version/2/html/deleteLevels.html b/src/client/html/sites/deleteLevels.html
similarity index 100%
rename from src/module/Application/pwa/public/version/2/html/deleteLevels.html
rename to src/client/html/sites/deleteLevels.html
diff --git a/src/client/html/sites/end.html b/src/client/html/sites/end.html
new file mode 100644
index 0000000..75e1b38
--- /dev/null
+++ b/src/client/html/sites/end.html
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/src/module/Application/pwa/public/html/application/impressum.html b/src/client/html/sites/impressum.html
similarity index 73%
rename from src/module/Application/pwa/public/html/application/impressum.html
rename to src/client/html/sites/impressum.html
index d60f56c..2bcaa05 100644
--- a/src/module/Application/pwa/public/html/application/impressum.html
+++ b/src/client/html/sites/impressum.html
@@ -6,6 +6,6 @@
Deutschland
E-Mail: wordRotator@silas.link
- Kontaktformular
+ Kontaktformular
\ No newline at end of file
diff --git a/src/module/Application/pwa/public/html/application/level.html b/src/client/html/sites/level.html
old mode 100755
new mode 100644
similarity index 62%
rename from src/module/Application/pwa/public/html/application/level.html
rename to src/client/html/sites/level.html
index 227a4b8..68c0aea
--- a/src/module/Application/pwa/public/html/application/level.html
+++ b/src/client/html/sites/level.html
@@ -19,24 +19,24 @@
-
-
-
-
-
+
+
+
+
+
-
+
-
+
@@ -45,7 +45,7 @@
-
+
diff --git a/src/module/Application/pwa/public/html/application/menu.html b/src/client/html/sites/menu.html
similarity index 85%
rename from src/module/Application/pwa/public/html/application/menu.html
rename to src/client/html/sites/menu.html
index 946c75d..bc5639c 100644
--- a/src/module/Application/pwa/public/html/application/menu.html
+++ b/src/client/html/sites/menu.html
@@ -21,16 +21,16 @@
-
+
-
+
-
+
-
+
diff --git a/src/module/Application/pwa/public/html/application/privacyPolicy.html b/src/client/html/sites/privacyPolicy.html
similarity index 93%
rename from src/module/Application/pwa/public/html/application/privacyPolicy.html
rename to src/client/html/sites/privacyPolicy.html
index 4e09499..bb10707 100644
--- a/src/module/Application/pwa/public/html/application/privacyPolicy.html
+++ b/src/client/html/sites/privacyPolicy.html
@@ -16,7 +16,7 @@ Mariabrunnstraße 48
Deutschland
E-Mailadresse: wordRotator@silas.link
-Link zum Impressum: https://wordrotator.silas.link/impressum
+ Link zum Impressum:
https://wordrotator.silas.link/impressum
Arten der verarbeiteten Daten
- Bestandsdaten (z.B., Personen-Stammdaten, Namen oder Adressen).
@@ -116,15 +116,15 @@ Link zum Impressum: https://wordrotator.silas.link/impressum
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
Rechte der betroffenen Personen
Sie haben das Recht, eine Bestätigung darüber zu verlangen, ob betreffende Daten verarbeitet werden und auf
Auskunft über diese Daten sowie auf weitere Informationen und Kopie der Daten entsprechend den gesetzlichen
@@ -220,7 +220,7 @@ Die Logs mit den Daten der Nutzer werden nach spätestens einem Jahr gelöscht.<
-
+
diff --git a/src/module/Application/pwa/public/version/2/html/selectWords.html b/src/client/html/sites/selectWords.html
similarity index 100%
rename from src/module/Application/pwa/public/version/2/html/selectWords.html
rename to src/client/html/sites/selectWords.html
diff --git a/src/client/html/sites/settingsSite.html b/src/client/html/sites/settingsSite.html
new file mode 100644
index 0000000..773c83b
--- /dev/null
+++ b/src/client/html/sites/settingsSite.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/client/img/background.png b/src/client/img/background.png
new file mode 100644
index 0000000..db49ca0
Binary files /dev/null and b/src/client/img/background.png differ
diff --git a/src/client/img/background.xcf b/src/client/img/background.xcf
new file mode 100644
index 0000000..a059029
Binary files /dev/null and b/src/client/img/background.xcf differ
diff --git a/public/img/coin.png b/src/client/img/coin.png
similarity index 100%
rename from public/img/coin.png
rename to src/client/img/coin.png
diff --git a/public/img/coinTower.png b/src/client/img/coinTower.png
similarity index 100%
rename from public/img/coinTower.png
rename to src/client/img/coinTower.png
diff --git a/src/img/coinTower.xcf b/src/client/img/coinTower.xcf
similarity index 100%
rename from src/img/coinTower.xcf
rename to src/client/img/coinTower.xcf
diff --git a/public/img/help.png b/src/client/img/help.png
similarity index 100%
rename from public/img/help.png
rename to src/client/img/help.png
diff --git a/src/client/img/icon.png b/src/client/img/icon.png
new file mode 100644
index 0000000..7cf37a5
Binary files /dev/null and b/src/client/img/icon.png differ
diff --git a/src/client/img/icon1.png b/src/client/img/icon1.png
new file mode 100644
index 0000000..a7df790
Binary files /dev/null and b/src/client/img/icon1.png differ
diff --git a/src/client/img/icon1.xcf b/src/client/img/icon1.xcf
new file mode 100644
index 0000000..5533e46
Binary files /dev/null and b/src/client/img/icon1.xcf differ
diff --git a/src/client/img/icon10.png b/src/client/img/icon10.png
new file mode 100644
index 0000000..ae82cfd
Binary files /dev/null and b/src/client/img/icon10.png differ
diff --git a/src/client/img/icon10.xcf b/src/client/img/icon10.xcf
new file mode 100644
index 0000000..85b3631
Binary files /dev/null and b/src/client/img/icon10.xcf differ
diff --git a/src/client/img/icon11.png b/src/client/img/icon11.png
new file mode 100644
index 0000000..db3de25
Binary files /dev/null and b/src/client/img/icon11.png differ
diff --git a/src/client/img/icon11.xcf b/src/client/img/icon11.xcf
new file mode 100644
index 0000000..f58ebf9
Binary files /dev/null and b/src/client/img/icon11.xcf differ
diff --git a/src/client/img/icon12,.xcf b/src/client/img/icon12,.xcf
new file mode 100644
index 0000000..14c4e5d
Binary files /dev/null and b/src/client/img/icon12,.xcf differ
diff --git a/src/client/img/icon12.png b/src/client/img/icon12.png
new file mode 100644
index 0000000..2a21994
Binary files /dev/null and b/src/client/img/icon12.png differ
diff --git a/src/client/img/icon13.png b/src/client/img/icon13.png
new file mode 100644
index 0000000..c00e08a
Binary files /dev/null and b/src/client/img/icon13.png differ
diff --git a/src/client/img/icon13.xcf b/src/client/img/icon13.xcf
new file mode 100644
index 0000000..f4698a2
Binary files /dev/null and b/src/client/img/icon13.xcf differ
diff --git a/src/client/img/icon14.png b/src/client/img/icon14.png
new file mode 100644
index 0000000..7a7c661
Binary files /dev/null and b/src/client/img/icon14.png differ
diff --git a/src/client/img/icon14.xcf b/src/client/img/icon14.xcf
new file mode 100644
index 0000000..93c87a8
Binary files /dev/null and b/src/client/img/icon14.xcf differ
diff --git a/src/client/img/icon2.xcf b/src/client/img/icon2.xcf
new file mode 100644
index 0000000..b13cb9d
Binary files /dev/null and b/src/client/img/icon2.xcf differ
diff --git a/src/client/img/icon3.xcf b/src/client/img/icon3.xcf
new file mode 100644
index 0000000..8476e75
Binary files /dev/null and b/src/client/img/icon3.xcf differ
diff --git a/src/client/img/icon4.xcf b/src/client/img/icon4.xcf
new file mode 100644
index 0000000..7c363d9
Binary files /dev/null and b/src/client/img/icon4.xcf differ
diff --git a/src/client/img/icon5.xcf b/src/client/img/icon5.xcf
new file mode 100644
index 0000000..82878bb
Binary files /dev/null and b/src/client/img/icon5.xcf differ
diff --git a/src/client/img/icon5_round.xcf b/src/client/img/icon5_round.xcf
new file mode 100644
index 0000000..7630072
Binary files /dev/null and b/src/client/img/icon5_round.xcf differ
diff --git a/src/client/img/icon6.xcf b/src/client/img/icon6.xcf
new file mode 100644
index 0000000..0d136f3
Binary files /dev/null and b/src/client/img/icon6.xcf differ
diff --git a/src/client/img/icon6_round.png b/src/client/img/icon6_round.png
new file mode 100644
index 0000000..7bc7c6b
Binary files /dev/null and b/src/client/img/icon6_round.png differ
diff --git a/src/client/img/icon6_round.xcf b/src/client/img/icon6_round.xcf
new file mode 100644
index 0000000..819984d
Binary files /dev/null and b/src/client/img/icon6_round.xcf differ
diff --git a/src/client/img/icon7_round.png b/src/client/img/icon7_round.png
new file mode 100644
index 0000000..2571d91
Binary files /dev/null and b/src/client/img/icon7_round.png differ
diff --git a/src/client/img/icon7_round.xcf b/src/client/img/icon7_round.xcf
new file mode 100644
index 0000000..a800034
Binary files /dev/null and b/src/client/img/icon7_round.xcf differ
diff --git a/src/client/img/icon8_round.png b/src/client/img/icon8_round.png
new file mode 100644
index 0000000..622332d
Binary files /dev/null and b/src/client/img/icon8_round.png differ
diff --git a/src/client/img/icon8_round.xcf b/src/client/img/icon8_round.xcf
new file mode 100644
index 0000000..7630072
Binary files /dev/null and b/src/client/img/icon8_round.xcf differ
diff --git a/src/client/img/icon9_round.png b/src/client/img/icon9_round.png
new file mode 100644
index 0000000..41da62a
Binary files /dev/null and b/src/client/img/icon9_round.png differ
diff --git a/src/client/img/icon9_round.xcf b/src/client/img/icon9_round.xcf
new file mode 100644
index 0000000..d43ec7c
Binary files /dev/null and b/src/client/img/icon9_round.xcf differ
diff --git a/src/client/img/icon_round.png b/src/client/img/icon_round.png
new file mode 100644
index 0000000..1917100
Binary files /dev/null and b/src/client/img/icon_round.png differ
diff --git a/public/img/icons/android-chrome-192x192.png b/src/client/img/icons/android-chrome-192x192.png
similarity index 100%
rename from public/img/icons/android-chrome-192x192.png
rename to src/client/img/icons/android-chrome-192x192.png
diff --git a/public/img/icons/android-chrome-512x512.png b/src/client/img/icons/android-chrome-512x512.png
similarity index 100%
rename from public/img/icons/android-chrome-512x512.png
rename to src/client/img/icons/android-chrome-512x512.png
diff --git a/public/img/icons/apple-touch-icon.png b/src/client/img/icons/apple-touch-icon.png
similarity index 100%
rename from public/img/icons/apple-touch-icon.png
rename to src/client/img/icons/apple-touch-icon.png
diff --git a/public/img/icons/browserconfig.xml b/src/client/img/icons/browserconfig.xml
similarity index 100%
rename from public/img/icons/browserconfig.xml
rename to src/client/img/icons/browserconfig.xml
diff --git a/public/img/icons/favicon-16x16.png b/src/client/img/icons/favicon-16x16.png
similarity index 100%
rename from public/img/icons/favicon-16x16.png
rename to src/client/img/icons/favicon-16x16.png
diff --git a/public/img/icons/favicon-32x32.png b/src/client/img/icons/favicon-32x32.png
similarity index 100%
rename from public/img/icons/favicon-32x32.png
rename to src/client/img/icons/favicon-32x32.png
diff --git a/public/img/icons/favicon.ico b/src/client/img/icons/favicon.ico
similarity index 100%
rename from public/img/icons/favicon.ico
rename to src/client/img/icons/favicon.ico
diff --git a/public/img/icons/mstile-150x150.png b/src/client/img/icons/mstile-150x150.png
similarity index 100%
rename from public/img/icons/mstile-150x150.png
rename to src/client/img/icons/mstile-150x150.png
diff --git a/public/img/icons/safari-pinned-tab.svg b/src/client/img/icons/safari-pinned-tab.svg
similarity index 100%
rename from public/img/icons/safari-pinned-tab.svg
rename to src/client/img/icons/safari-pinned-tab.svg
diff --git a/src/client/img/logo.png b/src/client/img/logo.png
new file mode 100644
index 0000000..f2fc338
Binary files /dev/null and b/src/client/img/logo.png differ
diff --git a/public/img/music.svg b/src/client/img/music.svg
similarity index 100%
rename from public/img/music.svg
rename to src/client/img/music.svg
diff --git a/public/img/settings.png b/src/client/img/settings.png
similarity index 100%
rename from public/img/settings.png
rename to src/client/img/settings.png
diff --git a/public/img/share.svg b/src/client/img/share.svg
old mode 100755
new mode 100644
similarity index 100%
rename from public/img/share.svg
rename to src/client/img/share.svg
diff --git a/public/img/sms.svg b/src/client/img/sms.svg
old mode 100755
new mode 100644
similarity index 100%
rename from public/img/sms.svg
rename to src/client/img/sms.svg
diff --git a/public/img/speaker.svg b/src/client/img/speaker.svg
similarity index 100%
rename from public/img/speaker.svg
rename to src/client/img/speaker.svg
diff --git a/public/img/telegram.svg b/src/client/img/telegram.svg
old mode 100755
new mode 100644
similarity index 100%
rename from public/img/telegram.svg
rename to src/client/img/telegram.svg
diff --git a/public/img/whatsapp.svg b/src/client/img/whatsapp.svg
old mode 100755
new mode 100644
similarity index 100%
rename from public/img/whatsapp.svg
rename to src/client/img/whatsapp.svg
diff --git a/src/client/index.html b/src/client/index.html
new file mode 100644
index 0000000..a58de46
--- /dev/null
+++ b/src/client/index.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ WordRotator
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/client/js/Dialog/ChooseThemeDialog.js b/src/client/js/Dialog/ChooseThemeDialog.js
new file mode 100644
index 0000000..84ae9f7
--- /dev/null
+++ b/src/client/js/Dialog/ChooseThemeDialog.js
@@ -0,0 +1,32 @@
+// import {Dialog, Helper, ThemeManager, Translator, ViewInflater} from "../../../../../js/lib/pwa-lib";
+//
+// export class ChooseThemeDialog extends Dialog {
+//
+// constructor() {
+// let viewPromise = ViewInflater.inflate("html/application/Dialog/chooseTheme.html").then(view => {
+//
+// let template = view.querySelector("#choose-theme-template");
+// template.remove();
+// template.id = null;
+//
+// let themeTemplateContainer = view.querySelector("#theme-choose-container");
+//
+// for (let i = 0; i < ThemeManager.themes.length; i++) {
+// let themeElem = template.cloneNode(true);
+// let theme = ThemeManager.themes[i];
+// themeElem.querySelector(".name").appendChild(Translator.makePersistentTranslation(theme._name));
+// themeElem["dataset"]["theme"] = theme._name;
+//
+// themeElem.addEventListener("click", () => {
+// this.result = themeElem["dataset"]["theme"];
+// this.close()
+// });
+// themeTemplateContainer.appendChild(themeElem);
+// }
+//
+// return view;
+// });
+//
+// super(viewPromise, "choose-theme-Dialog-title");
+// }
+// }
\ No newline at end of file
diff --git a/src/client/js/Dialog/PersistDialog.js b/src/client/js/Dialog/PersistDialog.js
new file mode 100644
index 0000000..dcf1bbc
--- /dev/null
+++ b/src/client/js/Dialog/PersistDialog.js
@@ -0,0 +1,7 @@
+// import {ConfirmDialog, Dialog, Helper, ThemeManager, Translator, ViewInflater} from "../../../../../js/lib/pwa-lib";
+//
+// export class PersistDialog extends ConfirmDialog{
+// constructor() {
+// super(Helper.isChrome()?"persist-storage-Dialog-message":"persist-storage-Dialog-message-firefox", "persist-storage-Dialog-title");
+// }
+// }
\ No newline at end of file
diff --git a/src/module/Application/pwa/js/dialog/ShareDialog.js b/src/client/js/Dialog/ShareDialog.js
similarity index 54%
rename from src/module/Application/pwa/js/dialog/ShareDialog.js
rename to src/client/js/Dialog/ShareDialog.js
index 3906347..9701504 100644
--- a/src/module/Application/pwa/js/dialog/ShareDialog.js
+++ b/src/client/js/Dialog/ShareDialog.js
@@ -1,8 +1,12 @@
-import {Dialog, Helper, ShareManager, ThemeManager, Translator, ViewInflater} from "../../../../../js/lib/pwa-lib";
+import {Dialog} from "cordova-sites/dist/client/js/Dialog/Dialog";
+import {Helper} from "js-helper/dist/shared/Helper";
+import {ViewInflater} from "cordova-sites/dist/client/js/ViewInflater";
export class ShareDialog extends Dialog{
constructor() {
- let viewPromise = ViewInflater.inflate("html/application/dialog/share.html").then(view => {
+ let viewPromise = ViewInflater.getInstance().load("html/application/Dialog/share.html").then(view => {
+
+ //TODO [MIG] ShareManager
view.appendChild(ShareManager.generateDefaultShareElement(window.location.hostname + Helper.basePath("")));
let closeListener = () => {
this.close();
@@ -14,6 +18,6 @@ export class ShareDialog extends Dialog{
return view;
});
- super(viewPromise, "share-dialog");
+ super(viewPromise, "share-Dialog");
}
}
\ No newline at end of file
diff --git a/src/client/js/Fragment/WordRotatorSettingFragment.js b/src/client/js/Fragment/WordRotatorSettingFragment.js
new file mode 100644
index 0000000..683cd60
--- /dev/null
+++ b/src/client/js/Fragment/WordRotatorSettingFragment.js
@@ -0,0 +1,91 @@
+import {CreditsSite} from "../Sites/CreditsSite";
+import {PrivacyPolicySite} from "../Sites/PrivacyPolicySite";
+import {ImpressumSite} from "../Sites/ImpressumSite";
+import {NativeStoragePromise} from "cordova-sites/dist/client/js/NativeStoragePromise";
+import {AbstractFragment} from "cordova-sites/dist/client/js/Context/AbstractFragment";
+
+import view from "../../html/fragment/settings.html";
+import {LevelData} from "../../../shared/model/LevelData";
+import {LastSyncDates} from "cordova-sites-easy-sync/dist/client/LastSyncDates";
+import {SoundManager} from "cordova-sites/dist/client/js/Sound/SoundManager";
+import {Toast} from "cordova-sites/dist/client/js/Toast/Toast";
+import {Matomo} from "cordova-sites/dist/client/js/Legacy/Matomo";
+import {LevelPlayed} from "../model/LevelPlayed";
+import {ContactSite} from "../Sites/ContactSite";
+
+export class WordRotatorSettingFragment extends AbstractFragment {
+ constructor(site) {
+ super(site, view);
+ }
+
+ async onViewLoaded() {
+ let res = super.onViewLoaded();
+
+ this.findBy("#reset-levels").addEventListener("click", async () => {
+ await NativeStoragePromise.remove("currentLevel");
+ await NativeStoragePromise.remove("levelCounter");
+ await NativeStoragePromise.remove("tutorial-step");
+
+ await LevelPlayed.clear();
+ await LevelData.clear();
+ await LastSyncDates.clear();
+ });
+
+ if (location.hostname.includes("beta") || location.hostname.includes("127.0.0.1") || location.hostname.includes("localhost")) {
+ this.findBy("#reset-levels").classList.remove("hidden");
+ }
+
+ let playMusicButton = this.findBy("#play-music");
+ playMusicButton.checked = (await NativeStoragePromise.getItem("play-music", "1") === "1")
+ playMusicButton.addEventListener("change", async () => {
+ await NativeStoragePromise.setItem("play-music", (playMusicButton.checked) ? "1" : "0");
+ let soundManager = SoundManager.getInstance();
+ soundManager.set({muted: !playMusicButton.checked}, SoundManager.CHANNELS.MUSIC);
+ if (playMusicButton.checked) {
+ await soundManager.play(SoundManager.CHANNELS.MUSIC);
+ }
+
+ //TODO [MIG] Matomo
+ Matomo.push(["trackEvent", "MainMenu", "PlayMusic", "Play Music", (playMusicButton.checked) ? 1 : 0]);
+ });
+
+ let playSoundButton = this.findBy("#play-sound");
+ playSoundButton.checked = (await NativeStoragePromise.getItem("play-sound", "1") === "1");
+ playSoundButton.addEventListener("change", async () => {
+ await NativeStoragePromise.setItem("play-sound", (playSoundButton.checked) ? "1" : "0");
+ let soundManager = SoundManager.getInstance();
+ soundManager.set({muted: !playSoundButton.checked}, SoundManager.CHANNELS.SOUND);
+
+ //TODO [MIG] Matomo
+ Matomo.push(["trackEvent", "MainMenu", "PlaySound", "Play Sound", (playSoundButton.checked) ? 1 : 0]);
+ });
+
+ this.findBy("#track-switch").addEventListener("change", function (e) {
+ Matomo.setTrack(this.checked === true);
+ e.stopPropagation();
+ e.preventDefault();
+ });
+
+ this.findBy("#credits-button").addEventListener("click", () => {
+ this.getSite().startSite(CreditsSite);
+ });
+ this.findBy("#privacy-policy-button").addEventListener("click", () => {
+ this.getSite().startSite(PrivacyPolicySite);
+ });
+ this.findBy("#contact-button").addEventListener("click", () => {
+ // new Toast("contact site").show();
+ this.getSite().startSite(ContactSite);
+ });
+ this.findBy("#impressum-button").addEventListener("click", () => {
+ this.getSite().startSite(ImpressumSite);
+ });
+ this.findBy("#version-info").innerText = window["version"];
+
+ return res;
+ }
+
+ onStart() {
+ Matomo.update("Settings Sites");
+ super.onStart();
+ }
+}
\ No newline at end of file
diff --git a/src/client/js/Sites/ContactSite.js b/src/client/js/Sites/ContactSite.js
new file mode 100644
index 0000000..e9e3fee
--- /dev/null
+++ b/src/client/js/Sites/ContactSite.js
@@ -0,0 +1,41 @@
+
+import view from "../../html/sites/contactSite.html"
+import {App} from "cordova-sites/dist/client/js/App";
+import {Form} from "cordova-sites/dist/client/js/Form";
+import {DataManager} from "cordova-sites/dist/client/js/DataManager";
+import {Toast} from "cordova-sites/dist/client/js/Toast/Toast";
+import {Translator} from "cordova-sites/dist/client/js/Translator";
+import {MenuSite} from "cordova-sites/dist/client/js/Context/MenuSite";
+
+export class ContactSite extends MenuSite {
+ constructor(siteManager) {
+ super(siteManager, view);
+ }
+
+ onViewLoaded() {
+ let res = super.onViewLoaded();
+
+ this.findBy("#contactText").appendChild(Translator.makePersistentTranslation("contact text", [__CONTACT_EMAIL__]))
+
+ new Form(this.findBy("#contact-form"), async values => {
+
+ let result = await DataManager.send("contact", values);
+ if (result.success) {
+ new Toast("the message was sent").show();
+ this.finish();
+ } else {
+ if (result) {
+ new Toast(result.message).show();
+ } else {
+ new Toast("Es ist ein Fehler aufgetreten...").show();
+ }
+ }
+ });
+
+ return res;
+ }
+}
+
+App.addInitialization((app) => {
+ app.addDeepLink("contact", ContactSite);
+});
\ No newline at end of file
diff --git a/src/client/js/Sites/CreditsSite.js b/src/client/js/Sites/CreditsSite.js
new file mode 100644
index 0000000..1656613
--- /dev/null
+++ b/src/client/js/Sites/CreditsSite.js
@@ -0,0 +1,19 @@
+import {WordRotatorBaseSite} from "./WordRotatorBaseSite";
+
+import view from "../../html/sites/credits.html"
+import {App} from "cordova-sites/dist/client/js/App";
+
+export class CreditsSite extends WordRotatorBaseSite{
+ constructor(siteManager) {
+ super(siteManager, view);
+ }
+
+ onStart(args) {
+ // Matomo.update("Credits Sites");
+ return super.onStart(args);
+ }
+}
+
+App.addInitialization(app => {
+ app.addDeepLink("credits", CreditsSite);
+});
\ No newline at end of file
diff --git a/src/module/Application/pwa/js/site/DeleteWordsSite.js b/src/client/js/Sites/DeleteWordsSite.js
similarity index 64%
rename from src/module/Application/pwa/js/site/DeleteWordsSite.js
rename to src/client/js/Sites/DeleteWordsSite.js
index cb3b0ef..a5f4545 100644
--- a/src/module/Application/pwa/js/site/DeleteWordsSite.js
+++ b/src/client/js/Sites/DeleteWordsSite.js
@@ -1,10 +1,16 @@
-import {UserAction, UserSite} from "../../../../../js/lib/pwa-user-management";
-import {Helper, InitPromise} from "../../../../../js/lib/pwa-lib";
-import {DataManager} from "../../../../../js/lib/pwa-core";
+import {UserMenuAction, UserSite} from "cordova-sites-user-management/dist/client";
-export class DeleteWordsSite extends UserSite {
+import view from "../../html/sites/deleteLevels.html"
+import {WordRotatorBaseSite} from "./WordRotatorBaseSite";
+import {App} from "cordova-sites/dist/client/js/App";
+import {NavbarFragment} from "cordova-sites/dist/client/js/Context/Menu/NavbarFragment";
+import {DataManager} from "cordova-sites/dist/client/js/DataManager";
+
+
+export class DeleteWordsSite extends WordRotatorBaseSite {
constructor(siteManager) {
- super(siteManager, "version/2/html/deleteLevels.html", null, "admin");
+ super(siteManager, view);
+ this.addDelegate(new UserSite(this, "admin"))
}
async onConstruct(args) {
@@ -13,9 +19,8 @@ export class DeleteWordsSite extends UserSite {
return res;
}
-
- onFirstStart() {
- super.onFirstStart();
+ onViewLoaded() {
+ super.onViewLoaded();
let levelTemplate = this.findBy("#level-template");
let wordTemplate = this.findBy("#word-template");
@@ -28,19 +33,19 @@ export class DeleteWordsSite extends UserSite {
wordTemplate.remove();
for (let k in this.words) {
- let wordElem = Helper.cloneNode(wordTemplate);
+ let wordElem = wordTemplate.cloneNode(true);
wordElem.querySelector(".name").appendChild(document.createTextNode(k));
let levelContainer = wordElem.querySelector(".level-container");
for (let j = 0; j < this.words[k].length; j++) {
let level = this.words[k][j];
- let levelElem = Helper.cloneNode(levelTemplate);
+ let levelElem = levelTemplate.cloneNode(true);
levelElem.querySelector(".id").appendChild(document.createTextNode(level["id"]));
levelElem.querySelector(".words").appendChild(document.createTextNode(level["words"]));
levelElem.querySelector(".positions").appendChild(document.createTextNode(level["rotations"]));
levelElem.querySelector(".delete-button").addEventListener("click", async () => {
let res = await DataManager.send("deleteLevel", {"levelId": level["id"]});
- if (res["success"]){
+ if (res["success"]) {
levelElem.remove();
}
});
@@ -52,8 +57,8 @@ export class DeleteWordsSite extends UserSite {
}
}
-InitPromise.addPromise(app => {
- app.addDefaultAction(new UserAction("delete-levels", () => {
+App.addInitialization(app => {
+ NavbarFragment.defaultActions.push(new UserMenuAction("delete-levels", "admin", () => {
app.startSite(DeleteWordsSite);
- },null, null, "admin"))
+ }));
});
\ No newline at end of file
diff --git a/src/module/Application/pwa/js/site/EndSite.js b/src/client/js/Sites/EndSite.js
old mode 100755
new mode 100644
similarity index 58%
rename from src/module/Application/pwa/js/site/EndSite.js
rename to src/client/js/Sites/EndSite.js
index e2f9e03..2bcc2ad
--- a/src/module/Application/pwa/js/site/EndSite.js
+++ b/src/client/js/Sites/EndSite.js
@@ -1,13 +1,14 @@
import {WordRotatorBaseSite} from "./WordRotatorBaseSite";
-import {Matomo} from "../../../../../js/lib/pwa-assets";
+
+import view from "../../html/sites/end.html"
export class EndSite extends WordRotatorBaseSite{
constructor(siteManager) {
- super(siteManager, "html/application/end.html");
+ super(siteManager, view);
}
onStart(args) {
- Matomo.update("End Site");
+ // Matomo.update("End Sites");
return super.onStart(args);
}
}
\ No newline at end of file
diff --git a/src/module/Application/pwa/js/site/ImpressumSite.js b/src/client/js/Sites/ImpressumSite.js
similarity index 54%
rename from src/module/Application/pwa/js/site/ImpressumSite.js
rename to src/client/js/Sites/ImpressumSite.js
index 712f66e..22df41e 100644
--- a/src/module/Application/pwa/js/site/ImpressumSite.js
+++ b/src/client/js/Sites/ImpressumSite.js
@@ -1,12 +1,14 @@
import {WordRotatorBaseSite} from "./WordRotatorBaseSite";
-import {InitPromise} from "../../../../../js/lib/pwa-lib";
+
+import view from "../../html/sites/impressum.html"
+import {App} from "cordova-sites/dist/client/js/App";
export class ImpressumSite extends WordRotatorBaseSite{
constructor(siteManager) {
- super(siteManager, "html/application/impressum.html", "impressum");
+ super(siteManager, view);
}
}
-InitPromise.addPromise(app => {
+App.addInitialization(app => {
app.addDeepLink("impressum", ImpressumSite);
});
\ No newline at end of file
diff --git a/src/module/Application/pwa/js/site/LevelSite.js b/src/client/js/Sites/LevelSite.js
old mode 100755
new mode 100644
similarity index 54%
rename from src/module/Application/pwa/js/site/LevelSite.js
rename to src/client/js/Sites/LevelSite.js
index d055131..7f0e0ca
--- a/src/module/Application/pwa/js/site/LevelSite.js
+++ b/src/client/js/Sites/LevelSite.js
@@ -1,33 +1,64 @@
-import {FlashMessenger, Helper, Menu, MenuAction, SystemSettings} from "../../../../../js/lib/pwa-lib";
import {TemplateContainer} from "../wordrotator/Segment/TemplateContainer";
import {LevelHelper} from "../wordrotator/Level/LevelHelper";
-import {WordRotatorDb} from "../WordRotatorDb";
-import {Matomo, ScaleHelper, SoundManager} from "../../../../../js/lib/pwa-assets";
import {EndSite} from "./EndSite";
import {WordRotatorBaseSite} from "./WordRotatorBaseSite";
-import {SettingsManager} from "../../../../../js/lib/pwa-core";
-import {SimpleFourWordsLevel} from "../wordrotator/Level/SimpleFourWordsLevel";
+
+import helpIcon from "../../img/help.png";
+
+import {
+ MenuAction,
+ Toast,
+ ScaleHelper,
+ Matomo,
+ NativeStoragePromise,
+} from "cordova-sites/dist/client";
+
+import view from "../../html/sites/level.html"
+import {Helper} from "js-helper/dist/shared/Helper";
+import {LevelData} from "../../../shared/model/LevelData";
+import {LevelPlayed} from "../model/LevelPlayed";
+import {ViewHelper} from "js-helper/dist/client/ViewHelper";
+
+import coinSound from "../../sound/single_coin_fall_on_concrete_.mp3";
+import {SoundManager} from "cordova-sites/dist/client/js/Sound/SoundManager";
export class LevelSite extends WordRotatorBaseSite {
constructor(siteManager) {
- super(siteManager, "html/application/level.html");
+ super(siteManager, view);
+ this._navbarFragment.setBackgroundImage(null);
}
- createActionBarMenu(menu) {
- menu = super.createActionBarMenu(menu);
+ async onCreateMenu(navbar) {
+ super.onCreateMenu(navbar);
- let coinAction = new MenuAction(Helper.nonNull(localStorage.getItem("coins"), "0"), () => {
+ let coinAction = new MenuAction(Helper.nonNull(await NativeStoragePromise.getItem("coins"), "0"), () => {
}, MenuAction.SHOW_ALWAYS, 900);
- coinAction.setShouldTranslate(false);
+ coinAction._shouldTranslate = false;
coinAction._liClass = "coin-counter";
- menu.addAction(coinAction);
+ navbar.addAction(coinAction);
this.coinAction = coinAction;
- return menu;
+ let levelCounterAction = new MenuAction(Helper.nonNull(this.levelCounter, "1"), () => {
+ }, MenuAction.SHOW_ALWAYS, 900);
+ levelCounterAction._shouldTranslate = false;
+ levelCounterAction.setLiClass("level-counter");
+ navbar.addAction(levelCounterAction);
+ this.levelCounterAction = levelCounterAction;
+
+ let helpAction = new MenuAction("", () => {
+ this.help();
+ }, MenuAction.SHOW_ALWAYS, 900);
+ helpAction._shouldTranslate = false;
+ helpAction._icon = helpIcon;
+ helpAction.setLiClass("help-action show-while-playing");
+ navbar.addAction(helpAction);
+
+ return navbar;
}
- onConstruct(args) {
- this.levelCounter = Helper.nonNull(localStorage.getItem("levelCounter"), 1);
+ async onConstruct(args) {
+ this.levelCounter = Helper.nonNull(await NativeStoragePromise.getItem("levelCounter"), 1);
+ // this.levelCounter = 987;
this.levelScaler = () => {
};
this.wonParams = {
@@ -36,11 +67,10 @@ export class LevelSite extends WordRotatorBaseSite {
};
this.coinPromise = Promise.resolve();
- let settingsManager = SettingsManager.getInstance();
let soundManager = SoundManager.getInstance();
soundManager.set({
- audio: "sound/single_coin_fall_on_concrete_.mp3",
- muted: (settingsManager.getSetting("play-sound", "1") !== "1"),
+ audio: coinSound,
+ muted: (NativeStoragePromise.getItem("play-sound", "1") !== "1"),
volume: 0.7
}, SoundManager.CHANNELS.SOUND);
@@ -49,8 +79,8 @@ export class LevelSite extends WordRotatorBaseSite {
return super.onConstruct(args);
}
- async onFirstStart() {
- super.onFirstStart();
+ async onViewLoaded() {
+ let res = super.onViewLoaded();
let leafSegmentTemplate = this.findBy("#segment-leaf-template");
let parentSegmentTemplate = this.findBy("#segment-parent-template");
let rowSegmentTemplate = this.findBy("#segment-row-template");
@@ -82,45 +112,39 @@ export class LevelSite extends WordRotatorBaseSite {
this.wonText = wonText;
this.wonText.style.fontSize = "0";
- //Benutze Document, da Element außerhalb von Seite (eigentlich unschön!)
- this.levelCounterActionContainer = document.getElementById("level-number-container");
- this.levelCounterAction = document.getElementById("level-number");
- this.levelCounterAction.innerText = this.levelCounter;
- this.levelNumberScaler = await scaleHelper.scaleToFull(this.levelCounterAction, this.levelCounterActionContainer, false, false, 4);
- this.levelCounterActionContainer.classList.add("visible");
this.templateContainer = new TemplateContainer(leafSegmentTemplate, parentSegmentTemplate, rowSegmentTemplate, triangleTemplate, columnTemplate);
this.coinTemplate = this.findBy("#coin-template");
this.coinContainer = this.findBy("#coin-container");
this.coinTemplate.id = null;
- this.coinContainer.removeAllChildren();
+ ViewHelper.removeAllChildren(this.coinContainer);
- this.findBy("#help-button").addEventListener("click", () => {
- this.help();
- });
+ // this.findBy("#help-button").addEventListener("click", () => {
+ // this.help();
+ // });
await this.loadLastLevel();
+
+ return res;
}
async loadLastLevel() {
try {
- let currentLevelInfo = localStorage.getItem("currentLevel");
+ let currentLevelInfo = await NativeStoragePromise.getItem("currentLevel");
if (Helper.isNotNull(currentLevelInfo)) {
currentLevelInfo = JSON.parse(currentLevelInfo);
- const db = await WordRotatorDb.getInstance();
- const levelJson = await db.loadLevel(currentLevelInfo["id"]);
+ let levelData = await LevelData.findById(currentLevelInfo["id"]);
- if (levelJson === null) {
+ if (Helper.isNull(levelData)) {
return this.nextLevel();
}
- let level = LevelHelper.inflateLevel(levelJson, this.templateContainer);
+ let level = LevelHelper.inflateLevel(levelData, this.templateContainer);
level.setStartRotations(currentLevelInfo["rotations"]);
- const self = this;
level.getWonPromise().then(() => {
- self.levelWon(level);
+ this.levelWon(level);
});
level.createSegments();
@@ -130,15 +154,15 @@ export class LevelSite extends WordRotatorBaseSite {
level.saveAsCurrentLevel();
let levelSegment = this.findBy("#level");
- levelSegment.removeAllChildren().appendChild(level.getRootSegment().getElement());
+ ViewHelper.removeAllChildren(levelSegment).appendChild(level.getRootSegment().getElement());
let scaleHelper = new ScaleHelper();
this.levelScaler = await scaleHelper.scaleToFull(levelSegment, levelSegment.parentElement, false, false, 1, level.words[0].length * 1.5, null, 0);
this.level = level;
- let res = this.tutorial();
+ // let res = this.tutorial();
Matomo.push(["trackEvent", "LevelSite", "LoadLastLevel"]);
this.level.checkHasWon();
- return res;
+ return;
}
} catch (e) {
console.error(e);
@@ -151,27 +175,38 @@ export class LevelSite extends WordRotatorBaseSite {
this.finish();
}
- async nextLevel(loadingElement) {
- loadingElement = Helper.nonNull(loadingElement, Helper.createLoadingSymbol());
- this._siteContent.replaceWith(loadingElement);
+ updateLevelCounter() {
+ this.levelCounterAction.setName(this.levelCounter);
+ if (this.levelCounter >= 10 && this.levelCounter <= 99) {
+ this.levelCounterAction.setLiClass("num-10 level-counter");
+ } else if (this.levelCounter >= 100 && this.levelCounter <= 999) {
+ this.levelCounterAction.setLiClass("num-100 level-counter");
+ } else if (this.levelCounter >= 1000) {
+ this.levelCounterAction.setLiClass("num-1000 level-counter");
+ } else {
+ this.levelCounterAction.setLiClass("level-counter");
+ }
+ }
+ async nextLevel() {
+ this.showLoadingSymbol();
try {
- const db = await WordRotatorDb.getInstance();
- const nextLevelJson = await db.loadNextLevel(LevelSite.RENDERER_TYPES);
+ let levelData = await LevelPlayed.getNextLevelData(LevelSite.RENDERER_TYPES);
- console.log("nextLevelJson", nextLevelJson);
- if (nextLevelJson === null) {
+ if (Helper.isNull(levelData)) {
this.startEndSite();
return;
}
- const level = LevelHelper.inflateLevel(nextLevelJson, this.templateContainer);
+
+ const level = LevelHelper.inflateLevel(levelData, this.templateContainer);
//Waiting for Level to be done
if (this.level && level.id === this.level.id) {
console.log("Level is the same as before! reload!");
await new Promise((resolve) => setTimeout(resolve, 50));
// return;
- return this.nextLevel(loadingElement);
+ debugger;
+ return this.nextLevel();
}
level.getWonPromise().then(() => {
@@ -184,21 +219,20 @@ export class LevelSite extends WordRotatorBaseSite {
level.saveAsCurrentLevel();
let levelSegment = this.findBy("#level");
- levelSegment.removeAllChildren().appendChild(level.getRootSegment().getElement());
+ ViewHelper.removeAllChildren(levelSegment).appendChild(level.getRootSegment().getElement());
- this._siteContent.classList.remove('won');
+ this._view.classList.remove('won');
this.wonText.style.fontSize = "0";
- loadingElement.replaceWith(this._siteContent);
+ this.removeLoadingSymbol();
let scaleHelper = new ScaleHelper();
this.levelScaler = await scaleHelper.scaleToFull(levelSegment, levelSegment.parentElement, false, false, 1, level.words[0].length * 1.5, null, 0);
this.level = level;
- this.levelCounterAction.innerText = this.levelCounter;
- this.levelNumberScaler();
+ this.updateLevelCounter();
- this.coinAction.setTitle(Helper.nonNull(localStorage.getItem("coins"), "0"));
- this.coinAction.redraw();
+ this.coinAction.setName(Helper.nonNull(await NativeStoragePromise.getItem("coins"), "0"));
+ // this.coinAction.redraw();
this.wonParams.aborted = true;
clearTimeout(this.wonParams.coinCounterTimer);
@@ -209,96 +243,94 @@ export class LevelSite extends WordRotatorBaseSite {
return this.tutorial();
} catch (e) {
- // loadingElement.replaceWith(this._siteContent);
console.log("Fehler!");
console.error(e);
this.startEndSite();
}
}
- onStart(args) {
- Matomo.update("Level Site");
+ async onStart(args) {
+ Matomo.update("Level Sites");
let res = super.onStart(args);
if (this.levelCounterAction) {
-
- this.levelCounterAction.innerText = this.levelCounter;
- this.levelCounterActionContainer.classList.add("visible");
+ this.updateLevelCounter();
}
this.levelScaler();
- let settingsManager = SettingsManager.getInstance();
+ //TODO Sound
let soundManager = SoundManager.getInstance();
soundManager.set({
- audio: "sound/single_coin_fall_on_concrete_.mp3",
- muted: (settingsManager.getSetting("play-sound", "1") !== "1"),
+ audio: coinSound,
+ muted: (await NativeStoragePromise.getItem("play-sound", "1") !== "1"),
volume: 0.7
}, SoundManager.CHANNELS.SOUND);
+ await this.tutorial();
+
return res;
}
- onPause(args) {
- super.onPause(args);
- this.levelCounterActionContainer.classList.remove("visible");
- }
-
async levelWon(level) {
try {
- const db = await WordRotatorDb.getInstance();
- const savePromise = db.saveLevelPlayed(level.getId());
+ const savePromise = LevelPlayed.setPlayed(level.getLevelData());
- savePromise.then((r) => console.log("levelSaved!", r)).then(() => {
- return db.loadLevel(level.id);
- }).then(level => console.log("saved level", level));
+ savePromise.then((r) => console.log("levelSaved!", r));
this.levelCounter++;
- localStorage.setItem("levelCounter", this.levelCounter);
+ await NativeStoragePromise.setItem("levelCounter", this.levelCounter);
- this._siteContent.classList.add('won');
- localStorage.removeItem("currentLevel");
+ //Todo richtiges Element aufrufen?
+ this._view.classList.add('won');
+ await NativeStoragePromise.remove("currentLevel");
let continueButton = this.findBy("#continue-button");
continueButton.style.transition = "none";
continueButton.style.opacity = 0;
- this.coinContainer.removeAllChildren();
- let coinsPerLevel = SystemSettings.get("coinsPerLevel", 5);
+ ViewHelper.removeAllChildren(this.coinContainer);
+ let coinsPerLevel = await NativeStoragePromise.getItem("coinsPerLevel", 5);
let coinsBefore = 0;
let soundManager = SoundManager.getInstance();
let audioOptions = soundManager.get(SoundManager.CHANNELS.SOUND);
- this.coinPromise = this.coinPromise.then(() => {
- coinsBefore = parseInt(Helper.nonNull(localStorage.getItem("coins"), "0"));
- localStorage.setItem("coins", coinsBefore + parseInt(coinsPerLevel));
- }).then(() => {
+ this.coinPromise = this.coinPromise.then(async () => {
+ coinsBefore = parseInt(Helper.nonNull(await NativeStoragePromise.getItem("coins"), "0"));
+ await NativeStoragePromise.setItem("coins", coinsBefore + parseInt(coinsPerLevel));
+ }).then(async () => {
return Promise.all([new Promise((r) => {
setTimeout(() => {
- r(continueButton.fadeIn());
+ //TODO animationen einbauen
+ continueButton.style.opacity = 1;
+ r();
}, 500)
- }), audioOptions.loadedPromise.catch(e => {
- console.error(e)
- })]);
+ }),
+ audioOptions.loadedPromise.catch(e => {
+ console.error(e)
+ })
+ ]);
});
this.wonParams.aborted = false;
for (let i = 0; i < coinsPerLevel; i++) {
- let coinElem = Helper.cloneNode(this.coinTemplate);
+ let coinElem = this.coinTemplate.cloneNode(true);
this.coinContainer.appendChild(coinElem);
this.coinPromise = this.coinPromise.then(() => {
return new Promise(r => {
let timeout = 350;
if (!this.wonParams.aborted) {
- coinElem.fadeIn(timeout / 1000);
+ //TODO animationen einbauen
+ coinElem.style.opacity = 1;
+ // coinElem.fadeIn(timeout / 1000);
soundManager.play(SoundManager.CHANNELS.SOUND);
this.wonParams.coinCounterTimer = setTimeout(() => {
if (!this.wonParams.aborted) {
- this.coinAction.setTitle(++coinsBefore);
- this.coinAction.redraw();
+ this.coinAction.setName(++coinsBefore);
+ // this.coinAction.redraw();
}
}, timeout / 2);
} else {
@@ -318,7 +350,14 @@ export class LevelSite extends WordRotatorBaseSite {
this.continueButtonScaler();
this.levelScaler();
- Matomo.push(["trackEvent", "LevelSite", "LevelWon", "Coins", parseInt(Helper.nonNull(localStorage.getItem("coins"), "0"))]);
+ Matomo.push(["trackEvent", "LevelSite", "LevelWon", "Coins", parseInt(Helper.nonNull(await NativeStoragePromise.getItem("coins"), "0"))]);
+
+ let leafs = level.getLeafSegments();
+ leafs.forEach((leaf, i) => {
+ let elem = leaf.getElement();
+ elem.style.animationDelay = i*50+"ms";
+ elem.classList.add("jump-animation");
+ })
await savePromise;
} catch (e) {
@@ -326,15 +365,14 @@ export class LevelSite extends WordRotatorBaseSite {
}
}
- help() {
- let cost = SystemSettings.get("costForHelp", 25);
- let currentCoins = parseInt(Helper.nonNull(localStorage.getItem("coins"), 0));
+ async help() {
+ let cost = await NativeStoragePromise.getItem("costForHelp", 25);
+ let currentCoins = parseInt(Helper.nonNull(await NativeStoragePromise.getItem("coins"), 0));
if (currentCoins >= cost) {
currentCoins -= cost;
- localStorage.setItem("coins", currentCoins);
- this.coinAction.title = currentCoins;
- this.coinAction.redraw();
+ await NativeStoragePromise.setItem("coins", currentCoins);
+ this.coinAction.setName(currentCoins);
let rotatables = this.level.getRotatableSegments();
rotatables = rotatables.filter((segment) => {
@@ -350,26 +388,26 @@ export class LevelSite extends WordRotatorBaseSite {
segmentToHelp.setIsRotatable(false);
this.level.saveAsCurrentLevel();
- Matomo.push(["trackEvent", "LevelSite", "Help", "Coins", parseInt(Helper.nonNull(localStorage.getItem("coins"), "0"))]);
+ // Matomo.push(["trackEvent", "LevelSite", "Help", "Coins", parseInt(Helper.nonNull(localStorage.getItem("coins"), "0"))]);
} else {
- FlashMessenger.addMessage("not-enough-coins");
- Matomo.push(["trackEvent", "LevelSite", "Help", "Not enough Coins", parseInt(Helper.nonNull(localStorage.getItem("coins"), "0"))]);
+ new Toast("not-enough-coins").show();
+ // Matomo.push(["trackEvent", "LevelSite", "Help", "Not enough Coins", parseInt(Helper.nonNull(localStorage.getItem("coins"), "0"))]);
}
}
async tutorial() {
if (this.level.id === LevelSite.TUTORIAL.FIRST_LEVEL) {
- let currentStep = Helper.nonNull(localStorage.getItem("tutorial-step"), "1");
+ let currentStep = Helper.nonNull(await NativeStoragePromise.getItem("tutorial-step"), "1");
let scaleHelper = new ScaleHelper();
- this._siteContent.classList.add("tutorial");
- this._siteContent.classList.add("step-" + currentStep);
+ this._view.classList.add("tutorial");
+ this._view.classList.add("step-" + currentStep);
switch (currentStep) {
case "1": {
- this.level.setSegmentClickedListener(() => {
- this._siteContent.classList.remove("step-1");
- localStorage.setItem("tutorial-step", "2");
+ this.level.setSegmentClickedListener(async () => {
+ this._view.classList.remove("step-1");
+ await NativeStoragePromise.setItem("tutorial-step", "2");
this.tutorial();
});
@@ -383,15 +421,15 @@ export class LevelSite extends WordRotatorBaseSite {
case "2": {
this.level.setSegmentClickedListener(() => {
});
- this.level.getWonPromise().then(() => {
- this._siteContent.classList.remove("tutorial");
- this._siteContent.classList.remove("step-2");
- localStorage.removeItem("tutorial-step");
- this.coinPromise = this.coinPromise.then(() => {
- FlashMessenger.addMessage("extra-coins-after-first-level");
- localStorage.setItem("coins", parseInt(Helper.nonNull(localStorage.getItem("coins"), "0")) + 50);
- this.coinAction.setTitle(Helper.nonNull(localStorage.getItem("coins"), "0"));
- this.coinAction.redraw();
+ this.level.getWonPromise().then(async () => {
+ this._view.classList.remove("tutorial");
+ this._view.classList.remove("step-2");
+ await NativeStoragePromise.remove("tutorial-step");
+ this.coinPromise = this.coinPromise.then(async () => {
+ new Toast("extra-coins-after-first-level").show();
+ await NativeStoragePromise.setItem("coins", parseInt(Helper.nonNull(await NativeStoragePromise.getItem("coins"), "0")) + 50);
+ this.coinAction.setName(Helper.nonNull(await NativeStoragePromise.getItem("coins"), "0"));
+ // this.coinAction.redraw();
});
// this.levelScaler();
});
@@ -404,27 +442,27 @@ export class LevelSite extends WordRotatorBaseSite {
break;
}
default: {
- this._siteContent.classList.remove("tutorial");
+ this._view.classList.remove("tutorial");
}
}
} else if (this.level.id === LevelSite.TUTORIAL.SECOND_LEVEL) {
- let currentStep = Helper.nonNull(localStorage.getItem("tutorial-step"), "3");
+ let currentStep = Helper.nonNull(await NativeStoragePromise.getItem("tutorial-step"), "3");
switch (currentStep) {
case "3": {
let scaleHelper = new ScaleHelper();
- this._siteContent.classList.add("tutorial");
- this._siteContent.classList.add("step-" + currentStep);
+ this._view.classList.add("tutorial");
+ this._view.classList.add("step-" + currentStep);
- let eventListener = () => {
- this._siteContent.classList.remove("tutorial");
- this._siteContent.classList.remove("step-3");
- localStorage.setItem("tutorial-step", "4");
- this.findBy("#help-button").removeEventListener("click", eventListener);
+ let eventListener = async () => {
+ this._view.classList.remove("tutorial");
+ this._view.classList.remove("step-3");
+ await NativeStoragePromise.setItem("tutorial-step", "4");
+ // this.findBy("#help-button").removeEventListener("click", eventListener);
this.levelScaler();
};
- this.findBy("#help-button").addEventListener("click", eventListener);
+ this.findBy(".help-action").addEventListener("click", eventListener);
let textElem = this.findBy(".tutorial-text .step-3");
@@ -433,33 +471,31 @@ export class LevelSite extends WordRotatorBaseSite {
break;
}
default: {
- this._siteContent.classList.remove("tutorial");
+ this._view.classList.remove("tutorial");
}
}
} else if (this.level.id === LevelSite.TUTORIAL.BIG_SEGMENT_LEVEL) {
- let currentStep = Helper.nonNull(localStorage.getItem("tutorial-step"), "4");
+ let currentStep = Helper.nonNull(await NativeStoragePromise.getItem("tutorial-step"), "4");
switch (currentStep) {
case "4": {
let scaleHelper = new ScaleHelper();
- this._siteContent.classList.add("tutorial");
- this._siteContent.classList.add("step-" + currentStep);
+ this._view.classList.add("tutorial");
+ this._view.classList.add("step-" + currentStep);
let rotatableSegments = this.level.getRotatableSegments();
let firstSegment = rotatableSegments[2];
- console.log(firstSegment);
let pointer = this.findBy("#tutorial-pointer");
pointer.remove();
firstSegment.element.appendChild(pointer);
- this.level.setSegmentClickedListener((segment) => {
- console.log("clicked Segment", segment);
+ this.level.setSegmentClickedListener(async (segment) => {
if (firstSegment === segment) {
- this._siteContent.classList.remove("tutorial");
- this._siteContent.classList.remove("step-4");
- localStorage.setItem("tutorial-step", "5");
+ this._view.classList.remove("tutorial");
+ this._view.classList.remove("step-4");
+ await NativeStoragePromise.setItem("tutorial-step", "5");
this.levelScaler();
}
});
@@ -472,7 +508,7 @@ export class LevelSite extends WordRotatorBaseSite {
break;
}
default: {
- this._siteContent.classList.remove("tutorial");
+ this._view.classList.remove("tutorial");
}
}
}
@@ -480,6 +516,7 @@ export class LevelSite extends WordRotatorBaseSite {
}
LevelSite.RENDERER_TYPES = [20, 40, 60, 80, 81, 82, 83, 100, 110, 111, 112, 120, 140, 160];
+// LevelSite.RENDERER_TYPES = [120, 140, 160];
LevelSite.TUTORIAL = {
FIRST_LEVEL: 67,
SECOND_LEVEL: 15,
diff --git a/src/module/Application/pwa/js/site/MenuSite.js b/src/client/js/Sites/MainMenuSite.js
similarity index 67%
rename from src/module/Application/pwa/js/site/MenuSite.js
rename to src/client/js/Sites/MainMenuSite.js
index cdf5258..beb6d87 100644
--- a/src/module/Application/pwa/js/site/MenuSite.js
+++ b/src/client/js/Sites/MainMenuSite.js
@@ -1,22 +1,43 @@
import {WordRotatorBaseSite} from "./WordRotatorBaseSite";
+import {App, Toast, DataManager, ScaleHelper} from "cordova-sites/dist/client";
+import {Helper} from "js-helper/dist/shared";
import {LevelSite} from "./LevelSite";
-import {Matomo, ScaleHelper, SoundManager} from "../../../../../js/lib/pwa-assets";
import {TemplateContainer} from "../wordrotator/Segment/TemplateContainer";
import {MainMenuLevel} from "../wordrotator/Level/MainMenuLevel";
-import {FlashMessenger, Helper, InitPromise, ShareManager} from "../../../../../js/lib/pwa-lib";
-import {DataManager, SettingsManager} from "../../../../../js/lib/pwa-core";
-import {WordRotatorDb} from "../WordRotatorDb";
-import {ShareDialog} from "../dialog/ShareDialog";
+import view from "../../html/sites/menu.html"
+import {NativeStoragePromise} from "cordova-sites/dist/client";
+import {ViewHelper} from "js-helper/dist/client/ViewHelper";
+import {LevelPlayed} from "../model/LevelPlayed";
+import {SyncJob} from "cordova-sites-easy-sync/dist/client/SyncJob";
+import {LevelData} from "../../../shared/model/LevelData";
+import {ShareManager} from "cordova-sites/dist/client/js/ShareManager/ShareManager";
+import {Translator} from "cordova-sites/dist/client/js/Translator";
+import {SoundManager} from "cordova-sites/dist/client/js/Sound/SoundManager";
+import {Matomo} from "cordova-sites/dist/client/js/Legacy/Matomo";
+import {MenuAction} from "cordova-sites/dist/client/js/Context/Menu/MenuAction/MenuAction";
+import {SettingsSite} from "./SettingsSite";
-export class MenuSite extends WordRotatorBaseSite {
+import settingsIcon from "../../img/settings.png";
+
+export class MainMenuSite extends WordRotatorBaseSite {
constructor(siteManager) {
- super(siteManager, "html/application/menu.html");
- this.loadLevelPromise = this.loadLevels();
+ super(siteManager, view);
+ this.loadLevelPromise = new SyncJob().sync([LevelData]).catch(e => console.error(e));
this.listener = null;
+ this._navbarFragment.setCanGoBack(false);
}
- onStart(args) {
- Matomo.update("Menu Site");
+ onCreateMenu(navbar) {
+ super.onCreateMenu(navbar);
+ let settingsAction = new MenuAction("", () => {
+ this.startSite(SettingsSite);
+ }, MenuAction.SHOW_ALWAYS, null, settingsIcon);
+ navbar.addAction(settingsAction);
+ return navbar;
+ }
+
+ async onStart(args) {
+ // Matomo.update("Menu Sites");
let res = super.onStart(args);
let level = new MainMenuLevel(this.templateContainer);
@@ -24,7 +45,7 @@ export class MenuSite extends WordRotatorBaseSite {
level.createSegments();
level.getWonPromise().then(() => {
- Matomo.push(["trackEvent", "MainMenu", "levelSolved"]);
+ // Matomo.push(["trackEvent", "MainMenu", "levelSolved"]);
this.startLevelSite();
});
@@ -32,7 +53,7 @@ export class MenuSite extends WordRotatorBaseSite {
segment._updateElement();
let levelSegment = this.findBy("#level");
- levelSegment.removeAllChildren().appendChild(segment.getElement());
+ ViewHelper.removeAllChildren(levelSegment).appendChild(segment.getElement());
let rotationsSegments = level.getRotatableSegments();
@@ -67,14 +88,13 @@ export class MenuSite extends WordRotatorBaseSite {
this.listener = async () => {
let playButton = this.findBy("#play-button");
let levelNumber = this.findBy("#level-number");
- levelNumber.innerText = Helper.nonNull(localStorage.getItem("levelCounter"), 1);
+ levelNumber.innerText = Helper.nonNull(await NativeStoragePromise.getItem("levelCounter"), 1);
let levelSegment = this.findBy("#level");
let scaleHelper = new ScaleHelper();
await scaleHelper.scaleToFull(levelSegment, levelSegment.parentElement, false, false, 2, 8, null, false);
- // debugger;
let levelStyle = getComputedStyle(levelSegment);
playButton.style.width = levelStyle.getPropertyValue("width");
scaleHelper.scaleToFull(playButton.children[0], playButton, null, null, null, 4, null, false);
@@ -83,25 +103,26 @@ export class MenuSite extends WordRotatorBaseSite {
scaleHelper.scaleToFull(levelNumber, levelNumber.parentElement, false, false, 8, null, null, false);
};
- this.listener();
+ // this.listener();
window.addEventListener("resize", this.listener);
+ setTimeout(this.listener, 50);
//Musikbuttons update, falls in den Einstellungen umgestellt
- let settingsManager = SettingsManager.getInstance();
+ // let settingsManager = SettingsManager.getInstance();
let playSoundButton = this.findBy("#play-sound");
- playSoundButton.checked = (settingsManager.getSetting("play-sound", "1") === "1");
+ playSoundButton.checked = (await NativeStoragePromise.getItem("play-sound", "1") === "1");
let playMusicButton = this.findBy("#play-music");
- playMusicButton.checked = (settingsManager.getSetting("play-music", "1") === "1");
+ playMusicButton.checked = (await NativeStoragePromise.getItem("play-music", "1") === "1");
return res;
}
async startLevelSite() {
SoundManager.getInstance().resumeContext();
+
this.startSite(LevelSite, Promise.race([this.loadLevelPromise, new Promise(async resolve => {
- const db = await WordRotatorDb.getInstance();
- let level = await db.loadNextLevel(LevelSite.RENDERER_TYPES);
- if (level !== null) {
+ let levelData = await LevelPlayed.getNextLevelData(LevelSite.RENDERER_TYPES);
+ if (levelData !== null) {
resolve();
}
})]));
@@ -112,7 +133,7 @@ export class MenuSite extends WordRotatorBaseSite {
let playButton = this.findBy("#play-button");
playButton.addEventListener("click", () => {
- Matomo.push(["trackEvent", "MainMenu", "startButton"]);
+ // Matomo.push(["trackEvent", "MainMenu", "startButton"]);
this.startLevelSite();
});
@@ -133,38 +154,41 @@ export class MenuSite extends WordRotatorBaseSite {
this.templateContainer = new TemplateContainer(leafSegmentTemplate, parentSegmentTemplate, rowSegmentTemplate, triangleTemplate);
- if (Helper.nonNull(MenuSite.app._cookieClosePromise)) {
- MenuSite.app._cookieClosePromise.then(() => {
+ if (Helper.nonNull(MainMenuSite.app._cookieClosePromise)) {
+ MainMenuSite.app._cookieClosePromise.then(() => {
if (this.listener) {
this.listener();
}
});
}
- let settingsManager = SettingsManager.getInstance();
let soundManager = SoundManager.getInstance();
let playMusicButton = this.findBy("#play-music");
- playMusicButton.checked = (settingsManager.getSetting("play-music", "1") === "1");
- playMusicButton.addEventListener("change", () => {
- settingsManager.setSetting("play-music", (playMusicButton.checked) ? "1" : "0");
+ playMusicButton.checked = (await NativeStoragePromise.getItem("play-music", "1") === "1");
+ playMusicButton.addEventListener("change", async () => {
+ await NativeStoragePromise.setItem("play-music", (playMusicButton.checked) ? "1" : "0");
soundManager.set({muted: !playMusicButton.checked}, SoundManager.CHANNELS.MUSIC);
if (playMusicButton.checked) {
soundManager.play(SoundManager.CHANNELS.MUSIC);
}
+
+ //TODO [MIG] Matomo
Matomo.push(["trackEvent", "MainMenu", "PlayMusic", "Play Music", (playMusicButton.checked) ? 1 : 0]);
});
let playSoundButton = this.findBy("#play-sound");
- playSoundButton.checked = (settingsManager.getSetting("play-sound", "1") === "1");
- playSoundButton.addEventListener("change", () => {
- settingsManager.setSetting("play-sound", (playSoundButton.checked) ? "1" : "0");
+ playSoundButton.checked = (await NativeStoragePromise.getItem("play-sound", "1") === "1");
+ playSoundButton.addEventListener("change", async () => {
+ await NativeStoragePromise.setItem("play-sound", (playSoundButton.checked) ? "1" : "0");
soundManager.set({muted: !playSoundButton.checked}, SoundManager.CHANNELS.SOUND);
+
+ //TODO [MIG] Matomo
Matomo.push(["trackEvent", "MainMenu", "PlaySound", "Play Sound", (playSoundButton.checked) ? 1 : 0]);
});
this.findBy("#share-button").addEventListener("click", () => {
- new ShareDialog().show();
+ new ShareManager().share(Translator.getInstance().translate("share-text", [window.location]));
});
// this.findBy("#share-buttons").appendChild(ShareManager.generateDefaultShareElement("https://wordrotator.silas.link"));
}
@@ -172,7 +196,7 @@ export class MenuSite extends WordRotatorBaseSite {
onPause(args) {
clearTimeout(this.randomRotateTimeout);
window.removeEventListener("resize", this.listener);
- super.onPause(args);
+ return super.onPause(args);
}
async loadLevels() {
@@ -192,7 +216,7 @@ export class MenuSite extends WordRotatorBaseSite {
}));
if (!res["success"]) {
if (await db.loadNextLevel(LevelSite.RENDERER_TYPES) === null) {
- FlashMessenger.addMessage("sync-error", null, 6000);
+ new Toast("sync-error", 6000).show();
}
newLastSync = null;
break;
@@ -214,20 +238,20 @@ export class MenuSite extends WordRotatorBaseSite {
await db.saveManyLevels(levels);
if (newLastSync != null && newLastSync !== "null") {
- localStorage.setItem("date-last-sync", newLastSync);
+ await NativeStoragePromise.setItem("date-last-sync", newLastSync);
db.saveDateLastSync(newLastSync);
}
}
catch(e){
// if (await db.loadNextLevel(LevelSite.RENDERER_TYPES) === null) {
- FlashMessenger.addMessage("sync-error", null, 6000);
+ new Toast("sync-error", 6000);
// }
console.error(e);
}
}
}
-MenuSite.app = null;
-InitPromise.addPromise(app => {
- MenuSite.app = app;
+MainMenuSite.app = null;
+App.addInitialization(app => {
+ MainMenuSite.app = app;
});
\ No newline at end of file
diff --git a/src/module/Application/pwa/js/site/PrivacyPolicySite.js b/src/client/js/Sites/PrivacyPolicySite.js
similarity index 53%
rename from src/module/Application/pwa/js/site/PrivacyPolicySite.js
rename to src/client/js/Sites/PrivacyPolicySite.js
index 5d8508c..9abb4d6 100644
--- a/src/module/Application/pwa/js/site/PrivacyPolicySite.js
+++ b/src/client/js/Sites/PrivacyPolicySite.js
@@ -1,13 +1,15 @@
import {WordRotatorBaseSite} from "./WordRotatorBaseSite";
-import {Helper, InitPromise} from "../../../../../js/lib/pwa-lib";
-import {Matomo} from "../../../../../js/lib/pwa-assets";
+
+import view from "../../html/sites/privacyPolicy.html"
+import {App} from "cordova-sites/dist/client/js/App";
+import {Matomo} from "cordova-sites/dist/client/js/Legacy/Matomo";
export class PrivacyPolicySite extends WordRotatorBaseSite {
constructor(siteManager) {
- super(siteManager, "html/application/privacyPolicy.html", "privacyPolicy");
+ super(siteManager,view);
}
- onFirstStart() {
+ async onViewLoaded() {
let trackSwitch =this.findBy("#track-switch");
trackSwitch.addEventListener("change", function (e) {
@@ -15,19 +17,18 @@ export class PrivacyPolicySite extends WordRotatorBaseSite {
e.stopPropagation();
e.preventDefault();
});
- super.onFirstStart();
+ return super.onViewLoaded();
}
- onStart(args) {
+ async onStart(args) {
let trackSwitch =this.findBy("#track-switch");
- let shouldTrack = (Helper.nonNull(localStorage.getItem("matomoShouldTrack"), "1") === "1");
- trackSwitch.checked = shouldTrack;
+ trackSwitch.checked = ((await Matomo.getTrackingPromise()) === "1");
- Matomo.update("Privacy Policy Site");
+ // Matomo.update("Privacy Policy Sites");
return super.onStart(args);
}
}
-InitPromise.addPromise(app => {
+App.addInitialization(app => {
app.addDeepLink("privacyPolicy", PrivacyPolicySite);
});
\ No newline at end of file
diff --git a/src/module/Application/pwa/js/site/SelectWordsSite.js b/src/client/js/Sites/SelectWordsSite.js
similarity index 69%
rename from src/module/Application/pwa/js/site/SelectWordsSite.js
rename to src/client/js/Sites/SelectWordsSite.js
index ffafec2..45abf5e 100644
--- a/src/module/Application/pwa/js/site/SelectWordsSite.js
+++ b/src/client/js/Sites/SelectWordsSite.js
@@ -1,11 +1,17 @@
-import {Helper, InitPromise} from "../../../../../js/lib/pwa-lib";
-import {UserAction, UserSite} from "../../../../../js/lib/pwa-user-management";
-import {DataManager} from "../../../../../js/lib/pwa-core";
-export class SelectWordsSite extends UserSite{
+import view from "../../html/sites/selectWords.html"
+import {WordRotatorBaseSite} from "./WordRotatorBaseSite";
+import {UserMenuAction, UserSite} from "cordova-sites-user-management/dist/client";
+import {NavbarFragment} from "cordova-sites/dist/client/js/Context/Menu/NavbarFragment";
+import {App} from "cordova-sites/dist/client/js/App";
+import {DataManager} from "cordova-sites/dist/dist/client/js/DataManager";
+import {ViewHelper} from "js-helper/dist/client/ViewHelper";
+
+export class SelectWordsSite extends WordRotatorBaseSite{
constructor(siteManager) {
- super(siteManager, "version/2/html/selectWords.html", null, "select-words");
+ super(siteManager, view);
+ this.addDelegate(new UserSite("select-words"))
}
async onConstruct(args) {
@@ -16,8 +22,8 @@ export class SelectWordsSite extends UserSite{
return res;
}
- onFirstStart() {
- super.onFirstStart();
+ async onViewLoaded() {
+ let res = super.onViewLoaded();
this.findBy("#not-checked").appendChild(document.createTextNode(this.stats["wordsNotChecked"]));
this.findBy("#checked").appendChild(document.createTextNode(this.stats["wordsChecked"]));
this.findBy("#not-sure").appendChild(document.createTextNode(this.stats["wordsUnsure"]));
@@ -32,7 +38,7 @@ export class SelectWordsSite extends UserSite{
let numWords = this.words.length;
for (let i = 0; i < numWords; i++) {
- let wordElement = Helper.cloneNode(template);
+ let wordElement = template.cloneNode(true);
wordElement.dataset["id"] = -1;
this.setWord(wordElement, this.words[i]);
container.appendChild(wordElement);
@@ -61,16 +67,17 @@ export class SelectWordsSite extends UserSite{
this.setWord(wordElement, newWord[0]);
});
}
+ return res;
}
setWord(wordElement, word){
- wordElement.querySelector(".word").removeAllChildren().appendChild(document.createTextNode(word["word"]));
+ ViewHelper.removeAllChildren(wordElement.querySelector(".word")).appendChild(document.createTextNode(word["word"]));
wordElement.dataset["id"] = word["id"];
}
}
-InitPromise.addPromise(app => {
- app.addDefaultAction(new UserAction("select-words", () => {
+App.addInitialization(app => {
+ NavbarFragment.defaultActions.push(new UserMenuAction("select-words", "select-words", () => {
app.startSite(SelectWordsSite);
- }, null, null, "select-words"));
+ }));
});
\ No newline at end of file
diff --git a/src/client/js/Sites/SettingsSite.js b/src/client/js/Sites/SettingsSite.js
new file mode 100644
index 0000000..289923c
--- /dev/null
+++ b/src/client/js/Sites/SettingsSite.js
@@ -0,0 +1,17 @@
+
+import view from "../../html/sites/settingsSite.html"
+import {MenuSite} from "cordova-sites/dist/client/js/Context/MenuSite";
+import {WordRotatorSettingFragment} from "../Fragment/WordRotatorSettingFragment";
+import {App} from "cordova-sites/dist/client/js/App";
+
+export class SettingsSite extends MenuSite {
+
+ constructor(siteManager) {
+ super(siteManager, view);
+ this.addFragment("#wordRotatorSettings", new WordRotatorSettingFragment(this));
+ }
+}
+
+App.addInitialization((app) => {
+ app.addDeepLink("settings", SettingsSite);
+});
\ No newline at end of file
diff --git a/src/client/js/Sites/WordRotatorBaseSite.js b/src/client/js/Sites/WordRotatorBaseSite.js
new file mode 100644
index 0000000..a959d2a
--- /dev/null
+++ b/src/client/js/Sites/WordRotatorBaseSite.js
@@ -0,0 +1,12 @@
+import {MenuSite} from "cordova-sites/dist/client";
+
+export class WordRotatorBaseSite extends MenuSite {
+
+ async onViewLoaded() {
+ let res = super.onViewLoaded();
+ await this.onFirstStart();
+ return res;
+ }
+
+ async onFirstStart(){}
+}
\ No newline at end of file
diff --git a/src/js/beta.settings.js b/src/client/js/beta.settings.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/js/beta.settings.js
rename to src/client/js/beta.settings.js
diff --git a/src/client/js/model/LevelPlayed.ts b/src/client/js/model/LevelPlayed.ts
new file mode 100644
index 0000000..959b23d
--- /dev/null
+++ b/src/client/js/model/LevelPlayed.ts
@@ -0,0 +1,78 @@
+import {BaseModel} from "cordova-sites-database/dist/BaseModel";
+import {BaseDatabase} from "cordova-sites-database/dist/cordova-sites-database";
+import {LevelData} from "../../../shared/model/LevelData";
+import {Helper} from "js-helper/dist/shared/Helper";
+
+export class LevelPlayed extends BaseModel {
+
+ levelData: LevelData;
+ played: boolean;
+
+ static getColumnDefinitions() {
+ let columns = super.getColumnDefinitions();
+ columns["played"] = {type: BaseDatabase.TYPES.BOOLEAN, default: true};
+ return columns;
+ }
+
+ static getRelationDefinitions() {
+ let relations = super.getRelationDefinitions();
+ relations["levelData"] = {
+ target: LevelData.getSchemaName(),
+ type: "one-to-one",
+ joinColumn: true,
+ cascade: true,
+ };
+ return relations;
+ }
+
+ static async setPlayed(levelData, played?){
+ played = Helper.nonNull(played, true);
+ let levelPlayed = new LevelPlayed();
+ levelPlayed.levelData = levelData;
+ levelPlayed.played = played;
+
+ return await levelPlayed.save();
+ }
+
+ static async getNextLevelData(renderer){
+ let qb = await this._database.createQueryBuilder(LevelData);
+
+ qb = qb.select("COUNT(*) as count, difficulty")
+ .leftJoin(LevelPlayed, "levelPlayed", "levelPlayed.levelData = LevelData.id")
+ .where("(deleted = 0 OR deleted = 'false')")
+ .andWhere("renderer IN ("+renderer.join(",")+")")
+ .andWhere("(levelPlayed.id IS NULL OR levelPlayed.played = 0)")
+ .groupBy("difficulty")
+ .orderBy("difficulty, LevelData.id");
+
+ let countRes = await qb.getRawMany();
+
+ let difficulty = null;
+ let offset = null;
+
+ if (!countRes.some(res => {
+ if (res["count"] > 0){
+ difficulty = res["difficulty"];
+ offset = Math.floor(Math.random() * Math.floor(res["count"]));
+ return true;
+ }
+ return false;
+ })){
+ return null;
+ }
+
+ qb = await this._database.createQueryBuilder(LevelData);
+ qb = qb
+ .leftJoin(LevelPlayed, "levelPlayed", "levelPlayed.levelData = LevelData.id")
+ .where("(deleted = 0 OR deleted = 'false')")
+ .andWhere("difficulty = "+difficulty)
+ .andWhere("renderer IN ("+renderer.join(",")+")")
+ .andWhere("(levelPlayed.id IS NULL OR levelPlayed.played = 0)")
+ .orderBy("LevelData.id")
+ .limit(1)
+ .offset(offset);
+
+ return await qb.getOne();
+ }
+}
+BaseDatabase.addModel(LevelPlayed);
\ No newline at end of file
diff --git a/src/client/js/model/migration/ClientSetup.ts b/src/client/js/model/migration/ClientSetup.ts
new file mode 100644
index 0000000..ca3136b
--- /dev/null
+++ b/src/client/js/model/migration/ClientSetup.ts
@@ -0,0 +1,14 @@
+import {MigrationInterface, QueryRunner, Table} from "typeorm";
+import {MigrationHelper} from "js-helper/dist/shared";
+import {LevelPlayed} from "../LevelPlayed";
+
+export class ClientSetup1000000002001 implements MigrationInterface {
+
+ async up(queryRunner: QueryRunner): Promise {
+ await MigrationHelper.addTableFromModelClass(LevelPlayed, queryRunner);
+ }
+
+ down(queryRunner: QueryRunner): Promise {
+ return undefined;
+ }
+}
\ No newline at end of file
diff --git a/src/js/prod.settings.js b/src/client/js/prod.settings.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/js/prod.settings.js
rename to src/client/js/prod.settings.js
diff --git a/src/client/js/script.js b/src/client/js/script.js
new file mode 100644
index 0000000..9678f7c
--- /dev/null
+++ b/src/client/js/script.js
@@ -0,0 +1,109 @@
+import translationGerman from '../translations/de.json';
+import translationEn from '../translations/en.json';
+import {App, Translator, DataManager, Toast} from "cordova-sites/dist/client";
+
+
+import "cordova-sites-user-management/dist/client/js/translationInit"
+import "cordova-sites/dist/client/js/translationInit"
+
+import {LoginSite, RegistrationSite, UserManager} from "cordova-sites-user-management/dist/client";
+
+import {BaseDatabase} from "cordova-sites-database/dist/cordova-sites-database";
+import {DeleteUserManagement1000000000000} from "cordova-sites-user-management/dist/shared//migrations/DeleteUserManagement";
+import {SetupUserManagement1000000001000} from "cordova-sites-user-management/dist/shared/migrations/SetupUserManagement";
+import {Setup1000000002000} from "../../shared/model/migration/shared/Setup";
+import {SetupEasySync1000000000500} from "cordova-sites-easy-sync/dist/client";
+import {MainMenuSite} from "./Sites/MainMenuSite";
+import {ClientSetup1000000002001} from "./model/migration/ClientSetup";
+import {EasySyncClientDb} from "cordova-sites-easy-sync/dist/client/EasySyncClientDb";
+import {NavbarFragment} from "cordova-sites/dist/client/js/Context/Menu/NavbarFragment";
+import {NativeStoragePromise} from "cordova-sites/dist/client/js/NativeStoragePromise";
+
+import music from "../sound/brightAndBeautifull__.mp3";
+import {SoundManager} from "cordova-sites/dist/client/js/Sound/SoundManager";
+
+window["JSObject"] = Object;
+
+//Disable Google Analytics for VideoJS
+window["HELP_IMPROVE_VIDEOJS"] = false;
+
+LoginSite.ADD_LOGIN_ACTION = false;
+RegistrationSite.ADD_REGISTRATION_ACTION = false;
+
+App.addInitialization(async () => {
+ Translator.init({
+ translations: {
+ "de": translationGerman,
+ "en": translationEn
+ },
+ fallbackLanguage: "de",
+ // markTranslations: true,
+ markUntranslatedTranslations: true,
+ });
+
+ //Setting Title
+ NavbarFragment.title = "WordRotator";
+
+ let soundManager = SoundManager.getInstance();
+ soundManager.play(SoundManager.CHANNELS.MUSIC, {
+ audio: music,
+ loop: true,
+ volume: 0.6,
+ muted: (await NativeStoragePromise.getItem("play-music", "1") !== "1")
+ }).catch(e => console.error(e));
+
+ await UserManager.getInstance().getMe().catch(e => console.error(e));
+
+ UserManager.getInstance().addLoginChangeCallback(async (isLoggedIn) => {
+ if (isLoggedIn) {
+ // await new SyncJob().sync([UserManager.syncParamFor(Definition), UserManager.syncParamFor(ExerciseProgress), UserManager.syncParamFor(WrongAnswer)]).catch(e => console.error(e));
+ }
+ });
+});
+
+DataManager._basePath = __HOST_ADDRESS__;
+DataManager.onlineCallback = isOnline => {
+ if (!isOnline){
+ new Toast("not online!").show();
+ }
+};
+
+Object.assign(BaseDatabase.CONNECTION_OPTIONS, {
+ logging: ["error",],
+ synchronize: false,
+ migrationsRun: true,
+ migrations: [
+ DeleteUserManagement1000000000000,
+ SetupEasySync1000000000500,
+ SetupUserManagement1000000001000,
+ Setup1000000002000,
+ ClientSetup1000000002001,
+ ]
+});
+
+let app = new App();
+app.start(MainMenuSite).catch(e => console.error(e)).then(async () => {
+ window["queryDb"] = async (sql) => {
+ // SELECT name FROM my_db.sqlite_master WHERE type='table';
+
+
+ // console.log("DB", EasySyncClientDb.getInstance());
+ let res = await EasySyncClientDb.getInstance().rawQuery(sql);
+ console.log(res);
+ return res;
+ }
+});
+app.ready(() => {
+ console.log("initialisation over", new Date());
+
+ if (device.platform === "browser"){
+ // Check that service workers are supported
+ if ('serviceWorker' in navigator) {
+ // Use the window load event to keep the page load performant
+ window.addEventListener('load', () => {
+ navigator.serviceWorker.register('service-worker.js');
+ });
+ }
+ }
+
+});
diff --git a/src/client/js/sw.js b/src/client/js/sw.js
new file mode 100644
index 0000000..a7f38c7
--- /dev/null
+++ b/src/client/js/sw.js
@@ -0,0 +1,5 @@
+import {precacheAndRoute} from "workbox-precaching";
+
+const precacheManifest = self.__WB_MANIFEST;
+
+precacheAndRoute(precacheManifest || []);
diff --git a/src/module/Application/pwa/js/wordrotator/Level/BigSegmentsLevels.js b/src/client/js/wordrotator/Level/BigSegmentsLevels.js
similarity index 100%
rename from src/module/Application/pwa/js/wordrotator/Level/BigSegmentsLevels.js
rename to src/client/js/wordrotator/Level/BigSegmentsLevels.js
diff --git a/src/module/Application/pwa/js/wordrotator/Level/FourWordsLevel.js b/src/client/js/wordrotator/Level/FourWordsLevel.js
old mode 100755
new mode 100644
similarity index 98%
rename from src/module/Application/pwa/js/wordrotator/Level/FourWordsLevel.js
rename to src/client/js/wordrotator/Level/FourWordsLevel.js
index 4c3e622..7ca1e27
--- a/src/module/Application/pwa/js/wordrotator/Level/FourWordsLevel.js
+++ b/src/client/js/wordrotator/Level/FourWordsLevel.js
@@ -1,6 +1,5 @@
import {Level} from "./Level";
import {RowSegment} from "../Segment/RowSegment";
-import {TriangleSegment} from "../Segment/TriangleSegment";
import {ParentSegment} from "../Segment/ParentSegment";
export class FourWordsLevel extends Level {
diff --git a/src/module/Application/pwa/js/wordrotator/Level/FourWordsLevel12.js b/src/client/js/wordrotator/Level/FourWordsLevel12.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/module/Application/pwa/js/wordrotator/Level/FourWordsLevel12.js
rename to src/client/js/wordrotator/Level/FourWordsLevel12.js
diff --git a/src/module/Application/pwa/js/wordrotator/Level/FourWordsLevel8.js b/src/client/js/wordrotator/Level/FourWordsLevel8.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/module/Application/pwa/js/wordrotator/Level/FourWordsLevel8.js
rename to src/client/js/wordrotator/Level/FourWordsLevel8.js
diff --git a/src/client/js/wordrotator/Level/Level.js b/src/client/js/wordrotator/Level/Level.js
new file mode 100644
index 0000000..5e2570e
--- /dev/null
+++ b/src/client/js/wordrotator/Level/Level.js
@@ -0,0 +1,218 @@
+import {LeafSegment} from "../Segment/LeafSegment";
+import {ParentSegment} from "../Segment/ParentSegment";
+import {Helper} from "js-helper/dist/shared/Helper";
+import {NativeStoragePromise} from "cordova-sites/dist/client";
+import {Random} from "js-helper";
+
+export class Level {
+ constructor(templateContainer) {
+ this.rootSegment = null;
+ this.words = [];
+ this.startRotations = [];
+ this.templateContainer = templateContainer;
+
+ this.levelData = null;
+
+ this.hasWon = false;
+ this.id = null;
+
+ this.wonResolver = null;
+ this.giveUpResolver = null;
+
+ this._shakeLeafs = true;
+ this._shakeLeafsTimeout = null;
+ this._lastRotation = 0;
+
+ this.wonPromise = new Promise((resolve, reject) => {
+ this.wonResolver = resolve;
+ this.giveUpResolver = reject;
+ });
+
+ this.segmentClickedListener = () => {
+ console.log("clicked")
+ };
+ }
+
+ getLevelData() {
+ return this.levelData;
+ }
+
+ setLevelData(levelData) {
+ this.levelData = levelData;
+ }
+
+ async saveAsCurrentLevel() {
+ let rotations = this.getCurrentRotations();
+ let locked = this.getCurrentLocked();
+ await NativeStoragePromise.setItem("currentLevel", JSON.stringify({
+ "id": this.id,
+ "rotations": rotations,
+ "locks": locked
+ }));
+ }
+
+ getCurrentLocked() {
+ if (this.rootSegment !== null) {
+ return this.rootSegment.getCurrentLocked([]);
+ }
+ return [];
+ }
+
+ getCurrentRotations() {
+ if (this.rootSegment !== null) {
+ return this.rootSegment.getCurrentRotations([]);
+ }
+ return [];
+ }
+
+ setLocks(locks) {
+ if (this.rootSegment !== null) {
+ this.rootSegment.applyLocks(locks);
+ }
+ }
+
+ setId(id) {
+ this.id = id;
+ }
+
+ getId() {
+ return this.id;
+ }
+
+ getLevel() {
+ return this;
+ }
+
+ setRootSegment(rootSegment) {
+ this.rootSegment = rootSegment;
+ this.rootSegment.setParent(this);
+ if (this.startRotations) {
+ this.applyRotations();
+ }
+ }
+
+ setWords(words) {
+ this.words = [];
+ for (let i = 0, n = words.length; i < n; i++) {
+ this.words.push(words[i].replace(/ß/g, "ẞ").toUpperCase());
+ }
+ }
+
+ setStartRotations(rotations) {
+ this.startRotations = rotations;
+ }
+
+ applyRotations(rotations) {
+ if (this.rootSegment) {
+ rotations = Helper.nonNull(rotations, this.startRotations);
+ this.rootSegment.applyRotations(rotations);
+ }
+ }
+
+ getHasWon() {
+ return this.hasWon;
+ }
+
+ checkHasWon(delayPromise) {
+ if (this.rootSegment.isSolved()) {
+ this.hasWon = true;
+ const self = this;
+ Promise.resolve(delayPromise).then(() => {
+ self.wonResolver(true);
+ });
+ return true;
+ }
+ this.saveAsCurrentLevel();
+ return false;
+ }
+
+ getWonPromise() {
+ return this.wonPromise;
+ }
+
+ getRootSegment() {
+ return this.rootSegment;
+ }
+
+ createSegments() {
+ };
+
+ getRotatableSegments() {
+ return Level._getRotatableSegmentsFrom(this.rootSegment);
+ }
+
+ segmentClicked(segment) {
+ if (this.segmentClickedListener) {
+ this.segmentClickedListener(segment);
+ }
+
+ this._lastRotation = new Date().getTime();
+ clearTimeout(this._shakeLeafsTimeout);
+ if (this._shakeLeafs) {
+ this._shakeLeafsTimeout = setTimeout(() => {
+ this.shakeLeafs();
+ }, Random.getIntRandom(5000) + 25000);
+ }
+ }
+
+ setSegmentClickedListener(listener) {
+ this.segmentClickedListener = listener;
+ }
+
+ getLeafSegments() {
+ return Level._getLeafSegmentsFrom(this.rootSegment);
+ }
+
+ static _getRotatableSegmentsFrom(segment) {
+ let rotatable = [];
+ if (segment.canRotate()) {
+ rotatable.push(segment);
+ }
+ if (segment instanceof ParentSegment) {
+ for (let i = 0; i < segment.children.length; i++) {
+ rotatable.push.apply(rotatable, Level._getRotatableSegmentsFrom(segment.children[i]));
+ }
+ }
+ return rotatable;
+ }
+
+ shakeLeafs() {
+ clearTimeout(this._shakeLeafsTimeout);
+ if (this._shakeLeafs && !this.hasWon) {
+
+ const leafs = this.getLeafSegments();
+ if (leafs.length > 0) {
+ const index = Random.getIntRandom(leafs.length-1);
+ const leaf = leafs[index];
+
+ leaf.getElement().classList.add("shake");
+ setTimeout(() => {
+ leaf.getElement().classList.remove("shake");
+ }, Random.getIntRandom(350)+650);
+ }
+ this._shakeLeafsTimeout = setTimeout(() => {
+ this.shakeLeafs();
+ }, Random.getIntRandom(2000) + 5000);
+ }
+ }
+
+ static _createLeafsForWord(word, leafSegmentTemplate) {
+ let leafSegments = [];
+ for (let i = 0, n = word.length; i < n; i++) {
+ leafSegments.push(new LeafSegment(leafSegmentTemplate.cloneNode(true), word.charAt(i)));
+ }
+ return leafSegments;
+ }
+
+ static _getLeafSegmentsFrom(segment) {
+ let leafs = [];
+ if (segment instanceof LeafSegment) {
+ leafs.push(segment);
+ } else if (segment instanceof ParentSegment) {
+ for (let i = 0; i < segment.children.length; i++) {
+ leafs.push(...Level._getLeafSegmentsFrom(segment.children[i]));
+ }
+ }
+ return leafs;
+ }
+}
\ No newline at end of file
diff --git a/src/module/Application/pwa/js/wordrotator/Level/LevelHelper.js b/src/client/js/wordrotator/Level/LevelHelper.js
old mode 100755
new mode 100644
similarity index 72%
rename from src/module/Application/pwa/js/wordrotator/Level/LevelHelper.js
rename to src/client/js/wordrotator/Level/LevelHelper.js
index 48b4f3e..7a3fdba
--- a/src/module/Application/pwa/js/wordrotator/Level/LevelHelper.js
+++ b/src/client/js/wordrotator/Level/LevelHelper.js
@@ -22,18 +22,20 @@ export class LevelHelper {
return LevelHelper.types[type];
}
- static inflateLevel(jsonLevel, templateContainer) {
- let level = new (LevelHelper.types[jsonLevel["rendererType"]])(templateContainer);
- level.setWords(jsonLevel["words"]);
- level.setId(jsonLevel["id"]);
+ static inflateLevel(levelData, templateContainer) {
+ let level = new (LevelHelper.types[levelData["renderer"]])(templateContainer);
+ level.setWords(JSON.parse(levelData["words"].replace(/"/g, '"')));
+ level.setId(levelData["id"]);
+ level.setLevelData(levelData);
- for (let i = 0, n = jsonLevel["rotations"].length; i < n; i++) {
- if (jsonLevel["rotations"][i] <= 4) {
- jsonLevel["rotations"][i] = 90 * jsonLevel["rotations"][i];
+ levelData["positions"] = JSON.parse(levelData["positions"]);
+ for (let i = 0, n = levelData["positions"].length; i < n; i++) {
+ if (levelData["positions"][i] <= 4) {
+ levelData["positions"][i] = 90 * levelData["positions"][i];
}
}
- level.setStartRotations(jsonLevel["rotations"]);
+ level.setStartRotations(levelData["positions"]);
return level;
}
}
diff --git a/src/module/Application/pwa/js/wordrotator/Level/MainMenuLevel.js b/src/client/js/wordrotator/Level/MainMenuLevel.js
similarity index 100%
rename from src/module/Application/pwa/js/wordrotator/Level/MainMenuLevel.js
rename to src/client/js/wordrotator/Level/MainMenuLevel.js
diff --git a/src/module/Application/pwa/js/wordrotator/Level/RowLevel.js b/src/client/js/wordrotator/Level/RowLevel.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/module/Application/pwa/js/wordrotator/Level/RowLevel.js
rename to src/client/js/wordrotator/Level/RowLevel.js
diff --git a/src/module/Application/pwa/js/wordrotator/Level/RowLevel10.js b/src/client/js/wordrotator/Level/RowLevel10.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/module/Application/pwa/js/wordrotator/Level/RowLevel10.js
rename to src/client/js/wordrotator/Level/RowLevel10.js
diff --git a/src/module/Application/pwa/js/wordrotator/Level/RowLevel8.js b/src/client/js/wordrotator/Level/RowLevel8.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/module/Application/pwa/js/wordrotator/Level/RowLevel8.js
rename to src/client/js/wordrotator/Level/RowLevel8.js
diff --git a/src/module/Application/pwa/js/wordrotator/Level/SimpleFourWordsLevel.js b/src/client/js/wordrotator/Level/SimpleFourWordsLevel.js
similarity index 100%
rename from src/module/Application/pwa/js/wordrotator/Level/SimpleFourWordsLevel.js
rename to src/client/js/wordrotator/Level/SimpleFourWordsLevel.js
diff --git a/src/module/Application/pwa/js/wordrotator/Level/SimpleFourWordsLevel10_0.js b/src/client/js/wordrotator/Level/SimpleFourWordsLevel10_0.js
similarity index 100%
rename from src/module/Application/pwa/js/wordrotator/Level/SimpleFourWordsLevel10_0.js
rename to src/client/js/wordrotator/Level/SimpleFourWordsLevel10_0.js
diff --git a/src/module/Application/pwa/js/wordrotator/Level/SimpleFourWordsLevel10_1.js b/src/client/js/wordrotator/Level/SimpleFourWordsLevel10_1.js
similarity index 100%
rename from src/module/Application/pwa/js/wordrotator/Level/SimpleFourWordsLevel10_1.js
rename to src/client/js/wordrotator/Level/SimpleFourWordsLevel10_1.js
diff --git a/src/module/Application/pwa/js/wordrotator/Level/SimpleFourWordsLevel10_2.js b/src/client/js/wordrotator/Level/SimpleFourWordsLevel10_2.js
similarity index 100%
rename from src/module/Application/pwa/js/wordrotator/Level/SimpleFourWordsLevel10_2.js
rename to src/client/js/wordrotator/Level/SimpleFourWordsLevel10_2.js
diff --git a/src/module/Application/pwa/js/wordrotator/Level/SimpleFourWordsLevel10_3.js b/src/client/js/wordrotator/Level/SimpleFourWordsLevel10_3.js
similarity index 100%
rename from src/module/Application/pwa/js/wordrotator/Level/SimpleFourWordsLevel10_3.js
rename to src/client/js/wordrotator/Level/SimpleFourWordsLevel10_3.js
diff --git a/src/module/Application/pwa/js/wordrotator/Level/SimpleLevel.js b/src/client/js/wordrotator/Level/SimpleLevel.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/module/Application/pwa/js/wordrotator/Level/SimpleLevel.js
rename to src/client/js/wordrotator/Level/SimpleLevel.js
diff --git a/src/module/Application/pwa/js/wordrotator/Level/SixWordsRowLevel.js b/src/client/js/wordrotator/Level/SixWordsRowLevel.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/module/Application/pwa/js/wordrotator/Level/SixWordsRowLevel.js
rename to src/client/js/wordrotator/Level/SixWordsRowLevel.js
diff --git a/src/module/Application/pwa/js/wordrotator/Level/SixWordsRowLevel12.js b/src/client/js/wordrotator/Level/SixWordsRowLevel12.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/module/Application/pwa/js/wordrotator/Level/SixWordsRowLevel12.js
rename to src/client/js/wordrotator/Level/SixWordsRowLevel12.js
diff --git a/src/module/Application/pwa/js/wordrotator/Level/SixWordsRowLevel8.js b/src/client/js/wordrotator/Level/SixWordsRowLevel8.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/module/Application/pwa/js/wordrotator/Level/SixWordsRowLevel8.js
rename to src/client/js/wordrotator/Level/SixWordsRowLevel8.js
diff --git a/src/module/Application/pwa/js/wordrotator/Level/TwoSegmentFourWordsLevel10_0_2.js b/src/client/js/wordrotator/Level/TwoSegmentFourWordsLevel10_0_2.js
similarity index 100%
rename from src/module/Application/pwa/js/wordrotator/Level/TwoSegmentFourWordsLevel10_0_2.js
rename to src/client/js/wordrotator/Level/TwoSegmentFourWordsLevel10_0_2.js
diff --git a/src/module/Application/pwa/js/wordrotator/Level/TwoSegmentFourWordsLevel10_0_3.js b/src/client/js/wordrotator/Level/TwoSegmentFourWordsLevel10_0_3.js
similarity index 100%
rename from src/module/Application/pwa/js/wordrotator/Level/TwoSegmentFourWordsLevel10_0_3.js
rename to src/client/js/wordrotator/Level/TwoSegmentFourWordsLevel10_0_3.js
diff --git a/src/module/Application/pwa/js/wordrotator/Level/TwoSegmentFourWordsLevel10_1_3.js b/src/client/js/wordrotator/Level/TwoSegmentFourWordsLevel10_1_3.js
similarity index 100%
rename from src/module/Application/pwa/js/wordrotator/Level/TwoSegmentFourWordsLevel10_1_3.js
rename to src/client/js/wordrotator/Level/TwoSegmentFourWordsLevel10_1_3.js
diff --git a/src/module/Application/pwa/js/wordrotator/Segment/ColumnSegment.js b/src/client/js/wordrotator/Segment/ColumnSegment.js
similarity index 92%
rename from src/module/Application/pwa/js/wordrotator/Segment/ColumnSegment.js
rename to src/client/js/wordrotator/Segment/ColumnSegment.js
index 8234944..f81f497 100644
--- a/src/module/Application/pwa/js/wordrotator/Segment/ColumnSegment.js
+++ b/src/client/js/wordrotator/Segment/ColumnSegment.js
@@ -1,10 +1,11 @@
import {RowSegment} from "./RowSegment";
+import {ViewHelper} from "js-helper/dist/client/ViewHelper";
export class ColumnSegment extends RowSegment{
_updateElement() {
const childContainer = this.element.querySelector(".child-container");
- childContainer.removeAllChildren();
+ ViewHelper.removeAllChildren(childContainer);
this._updateRotationClass();
@@ -56,7 +57,7 @@ export class ColumnSegment extends RowSegment{
//
// _updateElement() {
// const childContainer = this.element.querySelector(".child-container");
- // childContainer.removeAllChildren();
+ // ViewHelper.removeAllChildren(childContainer);
//
// this._updateRotationClass();
//
diff --git a/src/module/Application/pwa/js/wordrotator/Segment/LeafSegment.js b/src/client/js/wordrotator/Segment/LeafSegment.js
old mode 100755
new mode 100644
similarity index 65%
rename from src/module/Application/pwa/js/wordrotator/Segment/LeafSegment.js
rename to src/client/js/wordrotator/Segment/LeafSegment.js
index 86ef663..51b69f7
--- a/src/module/Application/pwa/js/wordrotator/Segment/LeafSegment.js
+++ b/src/client/js/wordrotator/Segment/LeafSegment.js
@@ -1,5 +1,6 @@
import {Segment} from "./Segment";
-import {Helper} from "../../../../../../js/lib/pwa-lib";
+import {Helper} from "js-helper/dist/shared/Helper";
+import {ViewHelper} from "js-helper/dist/client/ViewHelper";
export class LeafSegment extends Segment {
@@ -21,6 +22,6 @@ export class LeafSegment extends Segment {
}
_updateElement() {
- this.element.querySelector(".leaf-element").removeAllChildren().appendChild(document.createTextNode(this.leaf));
+ ViewHelper.removeAllChildren(this.element.querySelector(".leaf-element")).appendChild(document.createTextNode(this.leaf));
}
}
\ No newline at end of file
diff --git a/src/module/Application/pwa/js/wordrotator/Segment/ParentSegment.js b/src/client/js/wordrotator/Segment/ParentSegment.js
old mode 100755
new mode 100644
similarity index 86%
rename from src/module/Application/pwa/js/wordrotator/Segment/ParentSegment.js
rename to src/client/js/wordrotator/Segment/ParentSegment.js
index e57bf78..3f79e4d
--- a/src/module/Application/pwa/js/wordrotator/Segment/ParentSegment.js
+++ b/src/client/js/wordrotator/Segment/ParentSegment.js
@@ -1,9 +1,11 @@
import {Segment} from "./Segment";
-import {Helper} from "../../../../../../js/lib/pwa-lib";
+import {Helper} from "js-helper/dist/shared/Helper";
+import {ViewHelper} from "js-helper/dist/client/ViewHelper";
export class ParentSegment extends Segment {
static initListener() {
window.addEventListener("mousedown", (e) => {
+ console.log("mousedown");
ParentSegment.mouseDownTarget = e.target;
ParentSegment.clickPosition = {x: e.pageX, y: e.pageY};
});
@@ -17,10 +19,6 @@ export class ParentSegment extends Segment {
ParentSegment.mouseDownTarget = e.targetTouches[0].target;
ParentSegment.clickPosition = {x: e.targetTouches[0].pageX, y: e.targetTouches[0].pageY};
}
- // else if (Array.isArray(e.path) && e.path.length >= 1) {
- // ParentSegment.mouseDownTarget = e.path[0];
- // ParentSegment.clickPosition = null;
- // }
});
window.addEventListener("touchend", (e) => {
ParentSegment.mouseDownTarget = null;
@@ -42,11 +40,9 @@ export class ParentSegment extends Segment {
this.userRotationDelta = 100;
this.lastUserRotation = 0;
- let self = this;
- this.touchendListener = function (e) {
+ this.touchendListener = (e) => {
let now = new Date().getTime();
- // console.log("touchendListener", e,now, self.lastUserRotation);
let target = null;
let position = null;
@@ -54,34 +50,34 @@ export class ParentSegment extends Segment {
target = document.elementFromPoint(e.changedTouches[0].pageX, e.changedTouches[0].pageY);
position = {x: e.changedTouches[0].pageX, y: e.changedTouches[0].pageY};
}
- if (target != null && e.targetTouches.length === 0 && self.element.contains(ParentSegment.mouseDownTarget) && self.element.contains(target)) {
+ if (target != null && e.targetTouches.length === 0 && this.element.contains(ParentSegment.mouseDownTarget) && this.element.contains(target)) {
e.stopPropagation();
e.preventDefault();
- if (self.lastUserRotation+self.userRotationDelta > now){
+ if (this.lastUserRotation + this.userRotationDelta > now) {
return;
}
- self.getLevel().segmentClickedListener(self);
- self.rotate(ParentSegment.mouseDownTarget, target, ParentSegment.clickPosition, position);
+ this.getLevel().segmentClicked(this);
+ this.rotate(ParentSegment.mouseDownTarget, target, ParentSegment.clickPosition, position);
// console.log("touchendListener stopped event", e);
- self.lastUserRotation = new Date().getTime();
+ this.lastUserRotation = new Date().getTime();
}
};
- this.mouseupListener = function (e) {
+ this.mouseupListener = (e) => {
let now = new Date().getTime();
- // console.log("mouseupListener", e,now, self.lastUserRotation);
- if (ParentSegment.mouseDownTarget !== null && self.element.contains(ParentSegment.mouseDownTarget) && self.element.contains(e.target)) {
+ console.log("mouseup", ParentSegment.mouseDownTarget);
+ if (ParentSegment.mouseDownTarget !== null && this.element.contains(ParentSegment.mouseDownTarget) && this.element.contains(e.target)) {
let position = {x: e.pageX, y: e.pageY};
e.stopPropagation();
e.preventDefault();
- if (self.lastUserRotation+self.userRotationDelta > now){
+ if (this.lastUserRotation + this.userRotationDelta > now) {
return;
}
- self.getLevel().segmentClickedListener(self);
- self.rotate(ParentSegment.mouseDownTarget, e.target, ParentSegment.clickPosition, position);
+ this.getLevel().segmentClicked(this);
+ this.rotate(ParentSegment.mouseDownTarget, e.target, ParentSegment.clickPosition, position);
// console.log("mouseupListener stopped event", e);
- self.lastUserRotation = new Date().getTime();
+ this.lastUserRotation = new Date().getTime();
}
};
}
@@ -246,7 +242,7 @@ export class ParentSegment extends Segment {
}
const childContainer = this.element.querySelector(".child-container");
- childContainer.removeAllChildren();
+ ViewHelper.removeAllChildren(childContainer);
this._updateRotationClass();
diff --git a/src/module/Application/pwa/js/wordrotator/Segment/RowSegment.js b/src/client/js/wordrotator/Segment/RowSegment.js
old mode 100755
new mode 100644
similarity index 92%
rename from src/module/Application/pwa/js/wordrotator/Segment/RowSegment.js
rename to src/client/js/wordrotator/Segment/RowSegment.js
index b504a1f..058cd67
--- a/src/module/Application/pwa/js/wordrotator/Segment/RowSegment.js
+++ b/src/client/js/wordrotator/Segment/RowSegment.js
@@ -1,4 +1,5 @@
import {ParentSegment} from "./ParentSegment";
+import {ViewHelper} from "js-helper/dist/client/ViewHelper";
export class RowSegment extends ParentSegment{
constructor(element) {
@@ -37,7 +38,7 @@ export class RowSegment extends ParentSegment{
_updateElement() {
const childContainer = this.element.querySelector(".child-container");
- childContainer.removeAllChildren();
+ ViewHelper.removeAllChildren(childContainer);
this._updateRotationClass();
diff --git a/src/module/Application/pwa/js/wordrotator/Segment/Segment.js b/src/client/js/wordrotator/Segment/Segment.js
old mode 100755
new mode 100644
similarity index 99%
rename from src/module/Application/pwa/js/wordrotator/Segment/Segment.js
rename to src/client/js/wordrotator/Segment/Segment.js
index dec2a00..dec2abe
--- a/src/module/Application/pwa/js/wordrotator/Segment/Segment.js
+++ b/src/client/js/wordrotator/Segment/Segment.js
@@ -1,5 +1,4 @@
-
export class Segment{
constructor(element){
this.rotation = 0;
diff --git a/src/module/Application/pwa/js/wordrotator/Segment/TemplateContainer.js b/src/client/js/wordrotator/Segment/TemplateContainer.js
old mode 100755
new mode 100644
similarity index 62%
rename from src/module/Application/pwa/js/wordrotator/Segment/TemplateContainer.js
rename to src/client/js/wordrotator/Segment/TemplateContainer.js
index a935f75..cbc82e7
--- a/src/module/Application/pwa/js/wordrotator/Segment/TemplateContainer.js
+++ b/src/client/js/wordrotator/Segment/TemplateContainer.js
@@ -1,4 +1,4 @@
-import {Helper} from "../../../../../../js/lib/pwa-lib";
+import {Helper} from "js-helper/dist/shared/Helper";
export class TemplateContainer{
constructor(leafTemplate, parentTemplate, rowTemplate, triangleTemplate, columnTemplate){
@@ -11,25 +11,25 @@ export class TemplateContainer{
copyLeafTemplate()
{
- return Helper.cloneNode(this.leafTemplate);
+ return this.leafTemplate.cloneNode(true);
}
copyParentTemplate()
{
- return Helper.cloneNode(this.parentTemplate);
+ return this.parentTemplate.cloneNode(true);
}
copyRowTemplate()
{
- return Helper.cloneNode(this.rowTemplate);
+ return this.rowTemplate.cloneNode(true);
}
copyTriangleTemplate()
{
- return Helper.cloneNode(this.triangleTemplate);
+ return this.triangleTemplate.cloneNode(true);
}
copyColumnTemplate(){
- return Helper.cloneNode(this.columnTemplate);
+ return this.columnTemplate.cloneNode(true);
}
}
\ No newline at end of file
diff --git a/src/module/Application/pwa/js/wordrotator/Segment/TriangleSegment.js b/src/client/js/wordrotator/Segment/TriangleSegment.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/module/Application/pwa/js/wordrotator/Segment/TriangleSegment.js
rename to src/client/js/wordrotator/Segment/TriangleSegment.js
diff --git a/src/client/sass/_animations.scss b/src/client/sass/_animations.scss
new file mode 100644
index 0000000..63ba424
--- /dev/null
+++ b/src/client/sass/_animations.scss
@@ -0,0 +1,45 @@
+@keyframes jump-animation {
+ 0% {
+ //transform: rotate(#{$startDegree}deg);
+ transform: scale(1);
+ }
+ 50% {
+ transform: scale(2);
+ }
+ 100% {
+ transform: scale(1);
+ }
+}
+
+.jump-animation {
+ animation-name: jump-animation;
+ animation-duration: 0.4s;
+ animation-fill-mode: none;
+ animation-timing-function: linear;
+}
+
+$deg: 10deg;
+
+@keyframes shake {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 33% {
+ transform: rotate(-$deg);
+ }
+ 66% {
+ transform: rotate($deg);
+ }
+ 100% {
+ transform: rotate(0deg);
+ }
+}
+
+.shake .leaf-element {
+
+ /* Start the shake animation and make the animation last for 0.5 seconds */
+ animation: shake 0.15s;
+
+ /* When the animation is finished, start again */
+ animation-iteration-count: infinite;
+}
\ No newline at end of file
diff --git a/src/client/sass/_foundationSettings.scss b/src/client/sass/_foundationSettings.scss
new file mode 100644
index 0000000..ee68ceb
--- /dev/null
+++ b/src/client/sass/_foundationSettings.scss
@@ -0,0 +1,870 @@
+// Foundation for Sites Settings
+// -----------------------------
+//
+// Table of Contents:
+//
+// 1. Global
+// 2. Breakpoints
+// 3. The Grid
+// 4. Base Typography
+// 5. Typography Helpers
+// 6. Abide
+// 7. Accordion
+// 8. Accordion Menu
+// 9. Badge
+// 10. Breadcrumbs
+// 11. Button
+// 12. Button Group
+// 13. Callout
+// 14. Card
+// 15. Close Button
+// 16. Drilldown
+// 17. Dropdown
+// 18. Dropdown Menu
+// 19. Flexbox Utilities
+// 20. Forms
+// 21. Label
+// 22. Media Object
+// 23. Menu
+// 24. Meter
+// 25. Off-canvas
+// 26. Orbit
+// 27. Pagination
+// 28. Progress Bar
+// 29. Prototype Arrow
+// 30. Prototype Border-Box
+// 31. Prototype Border-None
+// 32. Prototype Bordered
+// 33. Prototype Display
+// 34. Prototype Font-Styling
+// 35. Prototype List-Style-Type
+// 36. Prototype Overflow
+// 37. Prototype Position
+// 38. Prototype Rounded
+// 39. Prototype Separator
+// 40. Prototype Shadow
+// 41. Prototype Sizing
+// 42. Prototype Spacing
+// 43. Prototype Text-Decoration
+// 44. Prototype Text-Transformation
+// 45. Prototype Text-Utilities
+// 46. Responsive Embed
+// 47. Reveal
+// 48. Slider
+// 49. Switch
+// 50. Table
+// 51. Tabs
+// 52. Thumbnail
+// 53. Title Bar
+// 54. Tooltip
+// 55. Top Bar
+// 56. Xy Grid
+
+//@import 'util/util';
+
+// 1. Global
+// ---------
+
+$global-font-size: 100%;
+$global-width: rem-calc(1200);
+$global-lineheight: 1.5;
+$foundation-palette: (
+ primary: #1779ba,
+ secondary: #767676,
+ success: #3adb76,
+ warning: #ffae00,
+ alert: #cc4b37,
+);
+$light-gray: #e6e6e6;
+$medium-gray: #cacaca;
+$dark-gray: #8a8a8a;
+$black: #0a0a0a;
+$white: #fefefe;
+$body-background: $white;
+$body-font-color: $black;
+$body-font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;
+$body-antialiased: true;
+$global-margin: 1rem;
+$global-padding: 1rem;
+$global-position: 1rem;
+$global-weight-normal: normal;
+$global-weight-bold: bold;
+$global-radius: 0;
+$global-menu-padding: 0.7rem 1rem;
+$global-menu-nested-margin: 1rem;
+$global-text-direction: ltr;
+$global-flexbox: true;
+$global-prototype-breakpoints: false;
+$global-button-cursor: auto;
+$global-color-pick-contrast-tolerance: 0;
+$print-transparent-backgrounds: true;
+
+@include add-foundation-colors;
+$print-hrefs: true;
+
+// 2. Breakpoints
+// --------------
+
+$breakpoints: (
+ small: 0,
+ smedium: 400px,
+ medium: 640px,
+ large: 1024px,
+ xlarge: 1200px,
+ xxlarge: 1440px,
+);
+$print-breakpoint: large;
+$breakpoint-classes: (small smedium medium large);
+
+// 3. The Grid
+// -----------
+
+$grid-row-width: $global-width;
+$grid-column-count: 12;
+$grid-column-gutter: (
+ small: 20px,
+ medium: 30px,
+);
+$grid-column-align-edge: true;
+$grid-column-alias: 'columns';
+$block-grid-max: 8;
+
+// 4. Base Typography
+// ------------------
+
+$header-font-family: $body-font-family;
+$header-font-weight: $global-weight-normal;
+$header-font-style: normal;
+$font-family-monospace: Consolas, 'Liberation Mono', Courier, monospace;
+$header-color: inherit;
+$header-lineheight: 1.4;
+$header-margin-bottom: 0.5rem;
+$header-styles: (
+ small: (
+ 'h1': ('font-size': 24),
+ 'h2': ('font-size': 20),
+ 'h3': ('font-size': 19),
+ 'h4': ('font-size': 18),
+ 'h5': ('font-size': 17),
+ 'h6': ('font-size': 16),
+ ),
+ medium: (
+ 'h1': ('font-size': 48),
+ 'h2': ('font-size': 40),
+ 'h3': ('font-size': 31),
+ 'h4': ('font-size': 25),
+ 'h5': ('font-size': 20),
+ 'h6': ('font-size': 16),
+ ),
+);
+$header-text-rendering: optimizeLegibility;
+$small-font-size: 80%;
+$header-small-font-color: $medium-gray;
+$paragraph-lineheight: 1.6;
+$paragraph-margin-bottom: 1rem;
+$paragraph-text-rendering: optimizeLegibility;
+$code-color: $black;
+$code-font-family: $font-family-monospace;
+$code-font-weight: $global-weight-normal;
+$code-background: $light-gray;
+$code-border: 1px solid $medium-gray;
+$code-padding: rem-calc(2 5 1);
+$anchor-color: $primary-color;
+$anchor-color-hover: scale-color($anchor-color, $lightness: -14%);
+$anchor-text-decoration: none;
+$anchor-text-decoration-hover: none;
+$hr-width: $global-width;
+$hr-border: 1px solid $medium-gray;
+$hr-margin: rem-calc(20) auto;
+$list-lineheight: $paragraph-lineheight;
+$list-margin-bottom: $paragraph-margin-bottom;
+$list-style-type: disc;
+$list-style-position: outside;
+$list-side-margin: 1.25rem;
+$list-nested-side-margin: 1.25rem;
+$defnlist-margin-bottom: 1rem;
+$defnlist-term-weight: $global-weight-bold;
+$defnlist-term-margin-bottom: 0.3rem;
+$blockquote-color: $dark-gray;
+$blockquote-padding: rem-calc(9 20 0 19);
+$blockquote-border: 1px solid $medium-gray;
+$cite-font-size: rem-calc(13);
+$cite-color: $dark-gray;
+$cite-pseudo-content: '\2014 \0020';
+$keystroke-font: $font-family-monospace;
+$keystroke-color: $black;
+$keystroke-background: $light-gray;
+$keystroke-padding: rem-calc(2 4 0);
+$keystroke-radius: $global-radius;
+$abbr-underline: 1px dotted $black;
+
+// 5. Typography Helpers
+// ---------------------
+
+$lead-font-size: $global-font-size * 1.25;
+$lead-lineheight: 1.6;
+$subheader-lineheight: 1.4;
+$subheader-color: $dark-gray;
+$subheader-font-weight: $global-weight-normal;
+$subheader-margin-top: 0.2rem;
+$subheader-margin-bottom: 0.5rem;
+$stat-font-size: 2.5rem;
+
+// 6. Abide
+// --------
+
+$abide-inputs: true;
+$abide-labels: true;
+$input-background-invalid: get-color(alert);
+$form-label-color-invalid: get-color(alert);
+$input-error-color: get-color(alert);
+$input-error-font-size: rem-calc(12);
+$input-error-font-weight: $global-weight-bold;
+
+// 7. Accordion
+// ------------
+
+$accordion-background: $white;
+$accordion-plusminus: true;
+$accordion-title-font-size: rem-calc(12);
+$accordion-item-color: $primary-color;
+$accordion-item-background-hover: $light-gray;
+$accordion-item-padding: 1.25rem 1rem;
+$accordion-content-background: $white;
+$accordion-content-border: 1px solid $light-gray;
+$accordion-content-color: $body-font-color;
+$accordion-content-padding: 1rem;
+
+// 8. Accordion Menu
+// -----------------
+
+$accordionmenu-padding: $global-menu-padding;
+$accordionmenu-nested-margin: $global-menu-nested-margin;
+$accordionmenu-submenu-padding: $accordionmenu-padding;
+$accordionmenu-arrows: true;
+$accordionmenu-arrow-color: $primary-color;
+$accordionmenu-item-background: null;
+$accordionmenu-border: null;
+$accordionmenu-submenu-toggle-background: null;
+$accordion-submenu-toggle-border: $accordionmenu-border;
+$accordionmenu-submenu-toggle-width: 40px;
+$accordionmenu-submenu-toggle-height: $accordionmenu-submenu-toggle-width;
+$accordionmenu-arrow-size: 6px;
+
+// 9. Badge
+// --------
+
+$badge-background: $primary-color;
+$badge-color: $white;
+$badge-color-alt: $black;
+$badge-palette: $foundation-palette;
+$badge-padding: 0.3em;
+$badge-minwidth: 2.1em;
+$badge-font-size: 0.6rem;
+
+// 10. Breadcrumbs
+// ---------------
+
+$breadcrumbs-margin: 0 0 $global-margin 0;
+$breadcrumbs-item-font-size: rem-calc(11);
+$breadcrumbs-item-color: $primary-color;
+$breadcrumbs-item-color-current: $black;
+$breadcrumbs-item-color-disabled: $medium-gray;
+$breadcrumbs-item-margin: 0.75rem;
+$breadcrumbs-item-uppercase: true;
+$breadcrumbs-item-separator: true;
+$breadcrumbs-item-separator-item: '/';
+$breadcrumbs-item-separator-item-rtl: '\\';
+$breadcrumbs-item-separator-color: $medium-gray;
+
+// 11. Button
+// ----------
+
+$button-font-family: inherit;
+$button-padding: 0.85em 1em;
+$button-margin: 0 0 $global-margin 0;
+$button-fill: solid;
+$button-background: $primary-color;
+$button-background-hover: scale-color($button-background, $lightness: -15%);
+$button-color: $white;
+$button-color-alt: $black;
+$button-radius: $global-radius;
+$button-hollow-border-width: 1px;
+$button-sizes: (
+ tiny: 0.6rem,
+ small: 0.75rem,
+ default: 0.9rem,
+ large: 1.25rem,
+);
+$button-palette: $foundation-palette;
+$button-opacity-disabled: 0.25;
+$button-background-hover-lightness: -20%;
+$button-hollow-hover-lightness: -50%;
+$button-transition: background-color 0.25s ease-out, color 0.25s ease-out;
+$button-responsive-expanded: false;
+
+// 12. Button Group
+// ----------------
+
+$buttongroup-margin: 1rem;
+$buttongroup-spacing: 1px;
+$buttongroup-child-selector: '.button';
+$buttongroup-expand-max: 6;
+$buttongroup-radius-on-each: true;
+
+// 13. Callout
+// -----------
+
+$callout-background: $white;
+$callout-background-fade: 85%;
+$callout-border: 1px solid rgba($black, 0.25);
+$callout-margin: 0 0 1rem 0;
+$callout-padding: 1rem;
+$callout-font-color: $body-font-color;
+$callout-font-color-alt: $body-background;
+$callout-radius: $global-radius;
+$callout-link-tint: 30%;
+
+// 14. Card
+// --------
+
+$card-background: $white;
+$card-font-color: $body-font-color;
+$card-divider-background: $light-gray;
+$card-border: 1px solid $light-gray;
+$card-shadow: none;
+$card-border-radius: $global-radius;
+$card-padding: $global-padding;
+$card-margin-bottom: $global-margin;
+
+// 15. Close Button
+// ----------------
+
+$closebutton-position: right top;
+$closebutton-offset-horizontal: (
+ small: 0.66rem,
+ medium: 1rem,
+);
+$closebutton-offset-vertical: (
+ small: 0.33em,
+ medium: 0.5rem,
+);
+$closebutton-size: (
+ small: 1.5em,
+ medium: 2em,
+);
+$closebutton-lineheight: 1;
+$closebutton-color: $dark-gray;
+$closebutton-color-hover: $black;
+
+// 16. Drilldown
+// -------------
+
+$drilldown-transition: transform 0.15s linear;
+$drilldown-arrows: true;
+$drilldown-padding: $global-menu-padding;
+$drilldown-nested-margin: 0;
+$drilldown-background: $white;
+$drilldown-submenu-padding: $drilldown-padding;
+$drilldown-submenu-background: $white;
+$drilldown-arrow-color: $primary-color;
+$drilldown-arrow-size: 6px;
+
+// 17. Dropdown
+// ------------
+
+$dropdown-padding: 1rem;
+$dropdown-background: $body-background;
+$dropdown-border: 1px solid $medium-gray;
+$dropdown-font-size: 1rem;
+$dropdown-width: 300px;
+$dropdown-radius: $global-radius;
+$dropdown-sizes: (
+ tiny: 100px,
+ small: 200px,
+ large: 400px,
+);
+
+// 18. Dropdown Menu
+// -----------------
+
+$dropdownmenu-arrows: true;
+$dropdownmenu-arrow-color: $anchor-color;
+$dropdownmenu-arrow-size: 6px;
+$dropdownmenu-arrow-padding: 1.5rem;
+$dropdownmenu-min-width: 200px;
+$dropdownmenu-background: null;
+$dropdownmenu-submenu-background: $white;
+$dropdownmenu-padding: $global-menu-padding;
+$dropdownmenu-nested-margin: 0;
+$dropdownmenu-submenu-padding: $dropdownmenu-padding;
+$dropdownmenu-border: 1px solid $medium-gray;
+$dropdown-menu-item-color-active: get-color(primary);
+$dropdown-menu-item-background-active: transparent;
+
+// 19. Flexbox Utilities
+// ---------------------
+
+$flex-source-ordering-count: 6;
+$flexbox-responsive-breakpoints: true;
+
+// 20. Forms
+// ---------
+
+$fieldset-border: 1px solid $medium-gray;
+$fieldset-padding: rem-calc(20);
+$fieldset-margin: rem-calc(18 0);
+$legend-padding: rem-calc(0 3);
+$form-spacing: rem-calc(16);
+$helptext-color: $black;
+$helptext-font-size: rem-calc(13);
+$helptext-font-style: italic;
+$input-prefix-color: $black;
+$input-prefix-background: $light-gray;
+$input-prefix-border: 1px solid $medium-gray;
+$input-prefix-padding: 1rem;
+$form-label-color: $black;
+$form-label-font-size: rem-calc(14);
+$form-label-font-weight: $global-weight-normal;
+$form-label-line-height: 1.8;
+$select-background: $white;
+$select-triangle-color: $dark-gray;
+$select-radius: $global-radius;
+$input-color: $black;
+$input-placeholder-color: $medium-gray;
+$input-font-family: inherit;
+$input-font-size: rem-calc(16);
+$input-font-weight: $global-weight-normal;
+$input-line-height: $global-lineheight;
+$input-background: $white;
+$input-background-focus: $white;
+$input-background-disabled: $light-gray;
+$input-border: 1px solid $medium-gray;
+$input-border-focus: 1px solid $dark-gray;
+$input-padding: $form-spacing / 2;
+$input-shadow: inset 0 1px 2px rgba($black, 0.1);
+$input-shadow-focus: 0 0 5px $medium-gray;
+$input-cursor-disabled: not-allowed;
+$input-transition: box-shadow 0.5s, border-color 0.25s ease-in-out;
+$input-number-spinners: true;
+$input-radius: $global-radius;
+$form-button-radius: $global-radius;
+
+// 21. Label
+// ---------
+
+$label-background: $primary-color;
+$label-color: $white;
+$label-color-alt: $black;
+$label-palette: $foundation-palette;
+$label-font-size: 0.8rem;
+$label-padding: 0.33333rem 0.5rem;
+$label-radius: $global-radius;
+
+// 22. Media Object
+// ----------------
+
+$mediaobject-margin-bottom: $global-margin;
+$mediaobject-section-padding: $global-padding;
+$mediaobject-image-width-stacked: 100%;
+
+// 23. Menu
+// --------
+
+$menu-margin: 0;
+$menu-nested-margin: $global-menu-nested-margin;
+$menu-items-padding: $global-menu-padding;
+$menu-simple-margin: 1rem;
+$menu-item-color-active: $white;
+$menu-item-background-active: get-color(primary);
+$menu-icon-spacing: 0.25rem;
+$menu-state-back-compat: true;
+$menu-centered-back-compat: true;
+$menu-icons-back-compat: true;
+
+// 24. Meter
+// ---------
+
+$meter-height: 1rem;
+$meter-radius: $global-radius;
+$meter-background: $medium-gray;
+$meter-fill-good: $success-color;
+$meter-fill-medium: $warning-color;
+$meter-fill-bad: $alert-color;
+
+// 25. Off-canvas
+// --------------
+
+$offcanvas-sizes: (
+ small: 250px,
+);
+$offcanvas-vertical-sizes: (
+ small: 250px,
+);
+$offcanvas-background: $light-gray;
+$offcanvas-shadow: 0 0 10px rgba($black, 0.7);
+$offcanvas-inner-shadow-size: 20px;
+$offcanvas-inner-shadow-color: rgba($black, 0.25);
+$offcanvas-overlay-zindex: 11;
+$offcanvas-push-zindex: 12;
+$offcanvas-overlap-zindex: 13;
+$offcanvas-reveal-zindex: 12;
+$offcanvas-transition-length: 0.5s;
+$offcanvas-transition-timing: ease;
+$offcanvas-fixed-reveal: true;
+$offcanvas-exit-background: rgba($white, 0.25);
+$maincontent-class: 'off-canvas-content';
+
+// 26. Orbit
+// ---------
+
+$orbit-bullet-background: $medium-gray;
+$orbit-bullet-background-active: $dark-gray;
+$orbit-bullet-diameter: 1.2rem;
+$orbit-bullet-margin: 0.1rem;
+$orbit-bullet-margin-top: 0.8rem;
+$orbit-bullet-margin-bottom: 0.8rem;
+$orbit-caption-background: rgba($black, 0.5);
+$orbit-caption-padding: 1rem;
+$orbit-control-background-hover: rgba($black, 0.5);
+$orbit-control-padding: 1rem;
+$orbit-control-zindex: 10;
+
+// 27. Pagination
+// --------------
+
+$pagination-font-size: rem-calc(14);
+$pagination-margin-bottom: $global-margin;
+$pagination-item-color: $black;
+$pagination-item-padding: rem-calc(3 10);
+$pagination-item-spacing: rem-calc(1);
+$pagination-radius: $global-radius;
+$pagination-item-background-hover: $light-gray;
+$pagination-item-background-current: $primary-color;
+$pagination-item-color-current: $white;
+$pagination-item-color-disabled: $medium-gray;
+$pagination-ellipsis-color: $black;
+$pagination-mobile-items: false;
+$pagination-mobile-current-item: false;
+$pagination-arrows: true;
+
+// 28. Progress Bar
+// ----------------
+
+$progress-height: 1rem;
+$progress-background: $medium-gray;
+$progress-margin-bottom: $global-margin;
+$progress-meter-background: $primary-color;
+$progress-radius: $global-radius;
+
+// 29. Prototype Arrow
+// -------------------
+
+$prototype-arrow-directions: (
+ down,
+ up,
+ right,
+ left
+);
+$prototype-arrow-size: 0.4375rem;
+$prototype-arrow-color: $black;
+
+// 30. Prototype Border-Box
+// ------------------------
+
+$prototype-border-box-breakpoints: $global-prototype-breakpoints;
+
+// 31. Prototype Border-None
+// -------------------------
+
+$prototype-border-none-breakpoints: $global-prototype-breakpoints;
+
+// 32. Prototype Bordered
+// ----------------------
+
+$prototype-bordered-breakpoints: $global-prototype-breakpoints;
+$prototype-border-width: rem-calc(1);
+$prototype-border-type: solid;
+$prototype-border-color: $medium-gray;
+
+// 33. Prototype Display
+// ---------------------
+
+$prototype-display-breakpoints: $global-prototype-breakpoints;
+$prototype-display: (
+ inline,
+ inline-block,
+ block,
+ table,
+ table-cell
+);
+
+// 34. Prototype Font-Styling
+// --------------------------
+
+$prototype-font-breakpoints: $global-prototype-breakpoints;
+$prototype-wide-letter-spacing: rem-calc(4);
+$prototype-font-normal: $global-weight-normal;
+$prototype-font-bold: $global-weight-bold;
+
+// 35. Prototype List-Style-Type
+// -----------------------------
+
+$prototype-list-breakpoints: $global-prototype-breakpoints;
+$prototype-style-type-unordered: (
+ disc,
+ circle,
+ square
+);
+$prototype-style-type-ordered: (
+ decimal,
+ lower-alpha,
+ lower-latin,
+ lower-roman,
+ upper-alpha,
+ upper-latin,
+ upper-roman
+);
+
+// 36. Prototype Overflow
+// ----------------------
+
+$prototype-overflow-breakpoints: $global-prototype-breakpoints;
+$prototype-overflow: (
+ visible,
+ hidden,
+ scroll
+);
+
+// 37. Prototype Position
+// ----------------------
+
+$prototype-position-breakpoints: $global-prototype-breakpoints;
+$prototype-position: (
+ static,
+ relative,
+ absolute,
+ fixed
+);
+$prototype-position-z-index: 975;
+
+// 38. Prototype Rounded
+// ---------------------
+
+$prototype-rounded-breakpoints: $global-prototype-breakpoints;
+$prototype-border-radius: rem-calc(3);
+
+// 39. Prototype Separator
+// -----------------------
+
+$prototype-separator-breakpoints: $global-prototype-breakpoints;
+$prototype-separator-align: center;
+$prototype-separator-height: rem-calc(2);
+$prototype-separator-width: 3rem;
+$prototype-separator-background: $primary-color;
+$prototype-separator-margin-top: $global-margin;
+
+// 40. Prototype Shadow
+// --------------------
+
+$prototype-shadow-breakpoints: $global-prototype-breakpoints;
+$prototype-box-shadow: 0 2px 5px 0 rgba(0, 0, 0, .16),
+0 2px 10px 0 rgba(0, 0, 0, .12);
+
+// 41. Prototype Sizing
+// --------------------
+
+$prototype-sizing-breakpoints: $global-prototype-breakpoints;
+$prototype-sizing: (
+ width,
+ height
+);
+$prototype-sizes: (
+ 25: 25%,
+ 50: 50%,
+ 75: 75%,
+ 100: 100%
+);
+
+// 42. Prototype Spacing
+// ---------------------
+
+$prototype-spacing-breakpoints: $global-prototype-breakpoints;
+$prototype-spacers-count: 3;
+
+// 43. Prototype Text-Decoration
+// -----------------------------
+
+$prototype-decoration-breakpoints: $global-prototype-breakpoints;
+$prototype-text-decoration: (
+ overline,
+ underline,
+ line-through,
+);
+
+// 44. Prototype Text-Transformation
+// ---------------------------------
+
+$prototype-transformation-breakpoints: $global-prototype-breakpoints;
+$prototype-text-transformation: (
+ lowercase,
+ uppercase,
+ capitalize
+);
+
+// 45. Prototype Text-Utilities
+// ----------------------------
+
+$prototype-utilities-breakpoints: $global-prototype-breakpoints;
+$prototype-text-overflow: ellipsis;
+
+// 46. Responsive Embed
+// --------------------
+
+$responsive-embed-margin-bottom: rem-calc(16);
+$responsive-embed-ratios: (
+ default: 4 by 3,
+ widescreen: 16 by 9,
+);
+
+// 47. Reveal
+// ----------
+
+$reveal-background: $white;
+$reveal-width: 600px;
+$reveal-max-width: $global-width;
+$reveal-padding: $global-padding;
+$reveal-border: 1px solid $medium-gray;
+$reveal-radius: $global-radius;
+$reveal-zindex: 1005;
+$reveal-overlay-background: rgba($black, 0.45);
+
+// 48. Slider
+// ----------
+
+$slider-width-vertical: 0.5rem;
+$slider-transition: all 0.2s ease-in-out;
+$slider-height: 0.5rem;
+$slider-background: $light-gray;
+$slider-fill-background: $medium-gray;
+$slider-handle-height: 1.4rem;
+$slider-handle-width: 1.4rem;
+$slider-handle-background: $primary-color;
+$slider-opacity-disabled: 0.25;
+$slider-radius: $global-radius;
+
+// 49. Switch
+// ----------
+
+$switch-background: $medium-gray;
+$switch-background-active: $primary-color;
+$switch-height: 2rem;
+$switch-height-tiny: 1.5rem;
+$switch-height-small: 1.75rem;
+$switch-height-large: 2.5rem;
+$switch-radius: $global-radius;
+$switch-margin: $global-margin;
+$switch-paddle-background: $white;
+$switch-paddle-offset: 0.25rem;
+$switch-paddle-radius: $global-radius;
+$switch-paddle-transition: all 0.25s ease-out;
+
+// 50. Table
+// ---------
+
+$table-background: $white;
+$table-color-scale: 5%;
+$table-border: 1px solid smart-scale($table-background, $table-color-scale);
+$table-padding: rem-calc(8 10 10);
+$table-hover-scale: 2%;
+$table-row-hover: darken($table-background, $table-hover-scale);
+$table-row-stripe-hover: darken($table-background, $table-color-scale + $table-hover-scale);
+$table-is-striped: true;
+$table-striped-background: smart-scale($table-background, $table-color-scale);
+$table-stripe: even;
+$table-head-background: smart-scale($table-background, $table-color-scale / 2);
+$table-head-row-hover: darken($table-head-background, $table-hover-scale);
+$table-foot-background: smart-scale($table-background, $table-color-scale);
+$table-foot-row-hover: darken($table-foot-background, $table-hover-scale);
+$table-head-font-color: $body-font-color;
+$table-foot-font-color: $body-font-color;
+$show-header-for-stacked: false;
+$table-stack-breakpoint: medium;
+
+// 51. Tabs
+// --------
+
+$tab-margin: 0;
+$tab-background: $white;
+$tab-color: $primary-color;
+$tab-background-active: $light-gray;
+$tab-active-color: $primary-color;
+$tab-item-font-size: rem-calc(12);
+$tab-item-background-hover: $white;
+$tab-item-padding: 1.25rem 1.5rem;
+$tab-content-background: $white;
+$tab-content-border: $light-gray;
+$tab-content-color: $body-font-color;
+$tab-content-padding: 1rem;
+
+// 52. Thumbnail
+// -------------
+
+$thumbnail-border: 4px solid $white;
+$thumbnail-margin-bottom: $global-margin;
+$thumbnail-shadow: 0 0 0 1px rgba($black, 0.2);
+$thumbnail-shadow-hover: 0 0 6px 1px rgba($primary-color, 0.5);
+$thumbnail-transition: box-shadow 200ms ease-out;
+$thumbnail-radius: $global-radius;
+
+// 53. Title Bar
+// -------------
+
+$titlebar-background: $black;
+$titlebar-color: $white;
+$titlebar-padding: 0.5rem;
+$titlebar-text-font-weight: bold;
+$titlebar-icon-color: $white;
+$titlebar-icon-color-hover: $medium-gray;
+$titlebar-icon-spacing: 0.25rem;
+
+// 54. Tooltip
+// -----------
+
+$has-tip-cursor: help;
+$has-tip-font-weight: $global-weight-bold;
+$has-tip-border-bottom: dotted 1px $dark-gray;
+$tooltip-background-color: $black;
+$tooltip-color: $white;
+$tooltip-padding: 0.75rem;
+$tooltip-max-width: 10rem;
+$tooltip-font-size: $small-font-size;
+$tooltip-pip-width: 0.75rem;
+$tooltip-pip-height: $tooltip-pip-width * 0.866;
+$tooltip-radius: $global-radius;
+
+// 55. Top Bar
+// -----------
+
+$topbar-padding: 0.5rem;
+$topbar-background: $light-gray;
+$topbar-submenu-background: $topbar-background;
+$topbar-title-spacing: 0.5rem 1rem 0.5rem 0;
+$topbar-input-width: 200px;
+$topbar-unstack-breakpoint: medium;
+
+// 56. Xy Grid
+// -----------
+
+$xy-grid: true;
+$grid-container: $global-width;
+$grid-columns: 12;
+$grid-margin-gutters: (
+ small: 20px,
+ medium: 30px
+);
+$grid-padding-gutters: $grid-margin-gutters;
+$grid-container-padding: $grid-padding-gutters;
+$grid-container-max: $global-width;
+$xy-block-grid-max: 8;
+
diff --git a/log/gitFile.txt b/src/client/sass/_mainMenu.scss
similarity index 100%
rename from log/gitFile.txt
rename to src/client/sass/_mainMenu.scss
diff --git a/src/client/sass/_settings.scss b/src/client/sass/_settings.scss
new file mode 100644
index 0000000..3c67625
--- /dev/null
+++ b/src/client/sass/_settings.scss
@@ -0,0 +1,313 @@
+@import "lib/coreSettings";
+@import "foundationSettings";
+
+$defaultThemeValues: (
+ class: "",
+ //themeColor: #383838,
+ themeColor: #ffffff,
+ lightThemeColor: #353535,
+ linkColor: #000,
+ spinnerColor: #000,
+ navBarTextColor: inherit,
+ textColor: #000,
+ textColor2: #555555,
+ lightLinkColor: #fff,
+ linkBorderBottom: none,
+ linkHoverColor: #4e4e4e,
+ lightLinkHoverColor: #cacaca,
+ background: #fff,
+ background-gradient: linear-gradient(#3b3b3b, #191919),
+ highlight: #D56B52,
+ textColorOne: #bcbbbb,
+ colorOne: #F3F1F1,
+ colorTwo: #3B3B3B,
+ colorThree: #FFF,
+ buttonBorder: none,
+ buttonColor: white,
+);
+
+$themes: (
+ black:(
+ class: black,
+ //themeColor: #000000,
+ themeColor: #ffffff,
+ lightThemeColor: #353535,
+ linkColor: #000,
+ spinnerColor: #000,
+ navBarTextColor: inherit,
+ textColor: #000,
+ textColor2: #555555,
+ lightLinkColor: #fff,
+ linkBorderBottom: none,
+ linkHoverColor: #4e4e4e,
+ lightLinkHoverColor: #cacaca,
+ background: #fff,
+ background-gradient: linear-gradient(#3b3b3b, #191919),
+ highlight: #D56B52,
+ textColorOne: #bcbbbb,
+ colorOne: #F3F1F1,
+ colorTwo: #3B3B3B,
+ colorThree: #FFF,
+ buttonBorder: 1px solid black,
+ buttonColor: black,
+ ),
+ red:(
+ class: red,
+ themeColor: #ff0000,
+ lightThemeColor: #870015,
+ linkColor: #ff3d00,
+ spinnerColor: #b71c1a,
+ navBarTextColor: #fff,
+ textColor: #000,
+ textColor2: #555555,
+ lightLinkColor: #ff3d00,
+ linkBorderBottom: none,
+ linkHoverColor: #ff3d00,
+ lightLinkHoverColor: #ff3d00,
+ background: #fff
+ ),
+ blue:(
+ class: blue,
+ themeColor: #2c58ae,
+ lightThemeColor: #1a3062,
+ linkColor: #546cfe,
+ spinnerColor: #673AB7,
+ navBarTextColor: #fff,
+ textColor: #000,
+ textColor2: #555555,
+ lightLinkColor: #546cfe,
+ linkBorderBottom: none,
+ linkHoverColor: #546cfe,
+ lightLinkHoverColor: #546cfe,
+ background: #fff
+ ),
+ green:(
+ class: green,
+ themeColor: #008000,
+ lightThemeColor: #003613,
+ linkColor: #009829,
+ spinnerColor: #008000,
+ navBarTextColor: #fff,
+ textColor: #000,
+ textColor2: #555555,
+ lightLinkColor: #009829,
+ linkBorderBottom: none,
+ linkHoverColor: #009829,
+ lightLinkHoverColor: #009829,
+ background: #fff
+ ),
+ pink:(
+ class: pink,
+ themeColor: #ff69b4,
+ lightThemeColor: #70374a,
+ linkColor: #fe64af,
+ spinnerColor: #ff69b4,
+ navBarTextColor: #fff,
+ textColor: #000,
+ textColor2: #555555,
+ lightLinkColor: #fe64af,
+ linkBorderBottom: none,
+ linkHoverColor: #fe64af,
+ lightLinkHoverColor: #fe64af,
+ background: #fff
+ ),
+ dark: (
+ class: dark,
+ themeColor: #373737,
+ lightThemeColor: #4b4b4b,
+ linkColor: #fff,
+ spinnerColor: #ffffff,
+ navBarTextColor: #fff,
+ textColor: #ffffff,
+ textColor2: #9b9b9b,
+ lightLinkColor: #ffffff,
+ linkBorderBottom: 1px solid #ffffff,
+ linkHoverColor: #ffffff,
+ lightLinkHoverColor: #ffffff,
+ background: #000000
+ )
+);
+
+$themes: (
+ red:(
+ class: red,
+ themeColor: #ff0000,
+ lightThemeColor: #870015,
+ linkColor: #ff3d00,
+ spinnerColor: #b71c1a,
+ navBarTextColor: #fff,
+ textColor: #000,
+ textColor2: #555555,
+ lightLinkColor: #ff3d00,
+ linkBorderBottom: none,
+ linkHoverColor: #ff3d00,
+ lightLinkHoverColor: #ff3d00,
+ background: #fff
+ ),
+ blue:(
+ class: blue,
+ themeColor: #2c58ae,
+ lightThemeColor: #1a3062,
+ linkColor: #546cfe,
+ spinnerColor: #673AB7,
+ navBarTextColor: #fff,
+ textColor: #000,
+ textColor2: #555555,
+ lightLinkColor: #546cfe,
+ linkBorderBottom: none,
+ linkHoverColor: #546cfe,
+ lightLinkHoverColor: #546cfe,
+ background: #fff
+ ),
+ green:(
+ class: green,
+ themeColor: #008000,
+ lightThemeColor: #003613,
+ linkColor: #009829,
+ spinnerColor: #008000,
+ navBarTextColor: #fff,
+ textColor: #000,
+ textColor2: #555555,
+ lightLinkColor: #009829,
+ linkBorderBottom: none,
+ linkHoverColor: #009829,
+ lightLinkHoverColor: #009829,
+ background: #fff
+ ),
+ pink:(
+ class: pink,
+ themeColor: #ff69b4,
+ lightThemeColor: #70374a,
+ linkColor: #fe64af,
+ spinnerColor: #ff69b4,
+ navBarTextColor: #fff,
+ textColor: #000,
+ textColor2: #555555,
+ lightLinkColor: #fe64af,
+ linkBorderBottom: none,
+ linkHoverColor: #fe64af,
+ lightLinkHoverColor: #fe64af,
+ background: #fff
+ ),
+ black:(
+ class: black,
+ themeColor: #000,
+ lightThemeColor: #353535,
+ linkColor: #000,
+ spinnerColor: #000,
+ navBarTextColor: #fff,
+ textColor: #000,
+ textColor2: #555555,
+ lightLinkColor: #fff,
+ linkBorderBottom: 1px solid #000000,
+ linkHoverColor: #4e4e4e,
+ lightLinkHoverColor: #cacaca,
+ background: #fff
+ ),
+ default:(
+ class: "default",
+ themeColor: #000,
+ lightThemeColor: #353535,
+ navbarColor: rgba(0, 205, 0, 0.5), //TODO benutzen
+ linkColor: #000,
+ spinnerColor: #000,
+ navBarTextColor: #fff,
+ textColor: #000,
+ textColor2: #555555,
+ lightLinkColor: #fff,
+ linkBorderBottom: 1px solid #000000,
+ linkHoverColor: #4e4e4e,
+ lightLinkHoverColor: #cacaca,
+ background: transparent,
+ //background: #fefefe,
+ ),
+ dark: (
+ class: dark,
+ themeColor: #373737,
+ lightThemeColor: #4b4b4b,
+ linkColor: #fff,
+ spinnerColor: #ffffff,
+ navBarTextColor: #fff,
+ textColor: #ffffff,
+ textColor2: #9b9b9b,
+ lightLinkColor: #ffffff,
+ linkBorderBottom: 1px solid #ffffff,
+ linkHoverColor: #ffffff,
+ lightLinkHoverColor: #ffffff,
+ background: #000000
+ )
+);
+
+$themes: map-merge($themes, (dark: (
+ class: dark,
+ themeColor: #373737,
+ lightThemeColor: #4b4b4b,
+ linkColor: #fff,
+ spinnerColor: #ffffff,
+ navBarTextColor: #fff,
+ textColor: #ffffff,
+ textColor2: #9b9b9b,
+ lightLinkColor: #ffffff,
+ linkBorderBottom: 1px solid #ffffff,
+ linkHoverColor: #ffffff,
+ lightLinkHoverColor: #ffffff,
+ background: #000000
+)));
+
+@function recursive-map-merge($parent-map, $child-map) {
+ $result: $parent-map;
+ @each $key, $value in $child-map {
+ @if (not map-has-key($result, $key)) or (type-of(map-get($result, $key)) != type-of($value)) or (not (type-of(map-get($result, $key)) == map and type-of($value) == map)) {
+ $result: map-merge($result, ($key: $value));
+ } @else {
+ $result: map-merge($result, ($key: non-destructive-map-merge(map-get($result, $key), $value)));
+ }
+ }
+ @return $result;
+}
+
+@each $theme, $values in $themes {
+ $themeMap : recursive-map-merge($defaultThemeValues, $values);
+ $themes: map-merge($themes, ($theme: $themeMap))
+}
+
+$breakpoints: (
+ small: 0,
+ smedium: 400px,
+ medium: 640px,
+ large: 1024px,
+ xlarge: 1200px,
+ xxlarge: 1440px,
+);
+
+$margins: (
+ small: 0.625rem,
+ //smedium: 0.625rem,
+ medium: 0.9375rem,
+ //large: 0.9375rem,
+ //xlarge: 0.9375rem,
+ //xxlarge: 0.9375rem,
+);
+
+$rotationDegrees: (90 180 270 360);
+$animationDuration: .25s;
+
+//$degreeMatrix: (
+// //0:matrix(1, 0, 0, 1, 0, 0),
+// 0:rotate(0deg),
+// 90:matrix(0, 1, -1, 0, 0, 0),
+// 180:matrix(-1, 0, 0, -1, 0, 0),
+// 270:matrix(0, -1, 1, 0, 0, 0),
+// //360:matrix(0.99999, 0, 0, 0.99999, 0, 0),
+// //450:matrix(0, 1, -1, 0, 0, 0),
+// 360:rotate(360deg),
+// 450:rotate(450deg),
+//);
+$degreeMatrix: (
+ 0:rotate(0deg),
+ 90:rotate(90deg),
+ 180:rotate(180deg),
+ 270:rotate(270deg),
+ 360:rotate(360deg),
+ 450:rotate(450deg),
+);
\ No newline at end of file
diff --git a/src/scss/_tutorial.scss b/src/client/sass/_tutorial.scss
similarity index 92%
rename from src/scss/_tutorial.scss
rename to src/client/sass/_tutorial.scss
index 33fafee..a74dbf7 100644
--- a/src/scss/_tutorial.scss
+++ b/src/client/sass/_tutorial.scss
@@ -16,7 +16,7 @@
right: 0;
z-index: 9001;
- background: rgba(98, 98, 98, 0.51);
+ background: rgba(55, 55, 55, 0.51);
}
.tutorial {
@@ -67,12 +67,18 @@
position: relative;
}
- #help-button {
- position: relative;
+ .top-bar{
z-index: 9900 !important;
+ }
+
+ .help-action {
+ margin-top: 0;
+ padding-top: 10px;
+
+ position: relative;
+ //z-index: 9900 !important;
overflow: visible;
margin-right: 10px;
- margin-top: 10px;
box-shadow: 0 0 10px 5px #fff;
}
}
diff --git a/src/scss/_wordRotator.scss b/src/client/sass/_wordRotator_old.scss
old mode 100755
new mode 100644
similarity index 94%
rename from src/scss/_wordRotator.scss
rename to src/client/sass/_wordRotator_old.scss
index bbb5b3b..347de71
--- a/src/scss/_wordRotator.scss
+++ b/src/client/sass/_wordRotator_old.scss
@@ -1,4 +1,19 @@
-@import "imports";
+@import "settings";
+@import "lib/_actionBar.scss";
+@import "lib/_form.scss";
+@import "lib/_listjs.scss";
+@import "lib/_modal.scss";
+@import "lib/_rotate.scss";
+@import "lib/_share.scss";
+@import "lib/_tabs.scss";
+@import "lib/_core.scss";
+@import "lib/_flashMessenger.scss";
+@import "lib/_framework.scss";
+@import "lib/_pwaAssets.scss";
+@import "lib/_settingsSite.scss";
+@import "lib/_style.scss";
+@import "lib/_theme.scss";
+
@import "tutorial";
@import "wordrotatorTheme";
diff --git a/src/scss/_wordrotatorTheme.scss b/src/client/sass/_wordrotatorTheme.scss
similarity index 70%
rename from src/scss/_wordrotatorTheme.scss
rename to src/client/sass/_wordrotatorTheme.scss
index bc9205e..656451c 100644
--- a/src/scss/_wordrotatorTheme.scss
+++ b/src/client/sass/_wordrotatorTheme.scss
@@ -1,5 +1,3 @@
-
-
@mixin addThemeDefinition($theme) {
#tutorial-pointer {
background: #{map-get($theme, themeColor)};
@@ -13,15 +11,20 @@
}
.segment.segment-parent {
border-color: #{map-get($theme, textColor2)};
+
&.layer-2 {
border-color: #{map-get($theme, textColor)};
}
}
- #site-content > :not(.won) .segment.locked {
+ #site > :not(.won) .segment.locked {
+ cursor: default;
border-color: #{map-get($theme, lightThemeColor)};
background-color: #{map-get($theme, themeColor)} !important;
+
> .child-container > .segment-leaf {
+ cursor: default;
+
//border-color: #{map-get($theme, lightThemeColor)};
//background-color:#{map-get($theme, themeColor)} !important;
}
@@ -30,6 +33,7 @@
@for $i from 1 through length($rotationDegrees) {
&.rotate-#{nth($rotationDegrees, $i)} {
background-color: #{map-get($theme, background)};;
+
> .child-container {
> .segment {
background-color: #{map-get($theme, background)};;
@@ -68,50 +72,89 @@ body {
}
}
- &.dark{
- .switch {
- input:checked + .slider{
- border-color:black;
+ &.default {
+ background: url('../img/background.png');
+ background-size: cover;
+ background-position: center;
+
+ #level-number-container {
+ &.in-main-menu {
+ background: #fff !important;
}
+ }
+
+ .segment.segment-parent {
+ &:not(.layer-2) {
+ border-color: #005d07;
+ background: rgba(109, 255, 127, 0.2) !important;
+ }
+
+ //background: rgba(90, 164, 61, 1) !important;
+ }
+
+ #site > :not(.won) .segment.locked {
+ background-color: transparent !important;
+ border-color: #42ff4a !important;
+
+ > .child-container > .segment-leaf {
+ background-color: transparent !important;
+ }
+ }
+ }
+
+ &.dark {
+ .switch {
+ input:checked + .slider {
+ border-color: black;
+ }
+
.slider {
border: solid 1px white;
background-color: inherit;
padding: 1px;
+ margin-bottom: 0;
+ margin-top: 0;
}
}
- #site-content > :not(.won) .segment.locked.layer-2 {
+
+ #site > :not(.won) .segment.locked.layer-2 {
border-color: #565656;
}
- .modal{
+
+ .modal {
+ background-color: #fefefe;
border: 1px solid white;
border-radius: 2px;
}
}
- &.black{
- #site-content > :not(.won) .segment.locked {
+
+ &.black {
+ #site > :not(.won) .segment.locked {
background-color: #9d9d9d !important;
border-color: #6e6e6e !important;
+
> .child-container > .segment-leaf {
background-color: transparent !important;
}
}
- #logo{
+ #logo {
border: 1px solid grey;
border-radius: 50%;
}
}
- label{
- font-size: 1em !important;
+ label {
+ font-size: 1em !important;
}
- .setting-row:not(.hidden){
+
+ .setting-row:not(.hidden) {
line-height: 1;
padding-top: 0.5em;
padding-bottom: 0.5em;
width: 100%;
cursor: pointer;
background: rgba(195, 195, 195, 0.13);
- display: inline-block;
+ //display: inline-block;
}
}
diff --git a/src/scss/foundation.scss b/src/client/sass/foundation.scss
old mode 100755
new mode 100644
similarity index 100%
rename from src/scss/foundation.scss
rename to src/client/sass/foundation.scss
diff --git a/src/client/sass/index.scss b/src/client/sass/index.scss
new file mode 100644
index 0000000..e4fce1d
--- /dev/null
+++ b/src/client/sass/index.scss
@@ -0,0 +1,192 @@
+@import "../../../node_modules/foundation-sites/scss/foundation";
+
+//Settings nach foundation für mixins in settings
+@import "wordRotator";
+@import "animations";
+
+//Include foundation before other styles, so that other one can override foundation
+@include foundation-everything;
+
+//From framework
+@import "../../../node_modules/cordova-sites/cordova-sites";
+@import "../../../node_modules/cordova-sites-user-management/cordova-sites-user-management";
+
+//Anderes nach Settings, damit Settings bereits angewendet werden
+
+.translation{}
+
+@keyframes rotate {
+ from {
+ transform: rotate(0);
+ }
+ to {
+ transform: rotate(450deg);
+ }
+}
+
+@keyframes line {
+ 0% {
+ stroke-dasharray: 2, 85.964;
+ transform: rotate(0);
+ }
+ 50% {
+ stroke-dasharray: 65.973, 21.9911;
+ stroke-dashoffset: 0;
+ }
+ 100% {
+ stroke-dasharray: 2, 85.964;
+ stroke-dashoffset: -65.973;
+ transform: rotate(90deg);
+ }
+}
+
+html, body {
+ min-height: 100%;
+ width: 100%;
+ height: 100%;
+ letter-spacing: 1px;
+ overscroll-behavior: none;
+}
+
+
+a, a:hover {
+ color: #ffca00;
+}
+
+#site {
+ position: relative;
+ max-height: 100%;
+ max-width: 100%;
+ //overflow: auto;
+ height: 100%;
+ width: 100%;
+ //display: inline-block;
+}
+
+.right {
+ float: right
+}
+
+.grow {
+ flex: 1;
+}
+
+.loader {
+ left: 50%;
+ top: 50%;
+ position: fixed;
+ -webkit-transform: translate(-50%, -50%);
+ transform: translate(-50%, -50%);
+ text-align: center;
+
+ &.overlay {
+ left: 0;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(192, 192, 192, 0.5);
+ transform: none;
+ z-index: 10000;
+
+ svg {
+ left: 50%;
+ top: 50%;
+ position: fixed;
+ -webkit-transform: translate(-50%, -50%);
+ transform: translate(-50%, -50%);
+ text-align: center;
+ }
+ }
+
+ &.inline {
+ left: initial;
+ top: initial;
+ position: initial;
+ -webkit-transform: initial;
+ transform: initial;
+ text-align: center;
+ display: inline;
+ }
+
+ &.small .spinner {
+ transform: scale(0.5);
+ }
+
+ .spinner {
+ box-sizing: border-box;
+ //stroke: #b71c1a;
+ stroke: #000;
+ stroke-width: 3px;
+ transform-origin: 50%;
+ animation: line 1.6s cubic-bezier(0.4, 0, 0.2, 1) infinite, rotate 1.6s linear infinite;
+ }
+}
+
+.overflow-auto {
+ overflow: auto;
+}
+.overflow-hidden{
+ overflow: hidden;
+}
+
+.height-100 {
+ height: 100%;
+}
+
+.hidden {
+ display: none;
+}
+
+//ViewInflater
+.injected-span {
+}
+
+.vertical-middle {
+ display: flex;
+ align-items: center;
+}
+
+.vertical-bottom {
+ display: flex;
+ align-items: end;
+}
+
+.horizontal-center {
+ display: flex;
+ justify-content: center;
+}
+
+.width-100 {
+ width: 100%;
+}
+
+@for $i from 1 through 6 {
+ h#{$i}.inline {
+ display: inline-block;
+ }
+}
+
+img.back-button {
+ cursor: pointer;
+ max-height: 1.1rem;
+ margin-right: 0.2rem;
+ margin-bottom: 0.65rem;
+}
+
+a.hidden-link {
+ color: inherit;
+}
+
+#main-content-container {
+ overflow: auto;
+ width: 100%;
+
+ #main-content {
+ padding-top: 0;
+ padding-bottom: 0;
+ }
+}
+
+body{
+ //background-image: url("../img/background.png");
+}
\ No newline at end of file
diff --git a/src/client/sass/lib/_actionBar.scss b/src/client/sass/lib/_actionBar.scss
new file mode 100644
index 0000000..917fa2d
--- /dev/null
+++ b/src/client/sass/lib/_actionBar.scss
@@ -0,0 +1,250 @@
+@import "../../../node_modules/foundation-sites/scss/foundation";
+
+nav.top-bar.title-bar {
+ padding: 0.3rem 0.6rem 0;
+}
+
+#logo {
+ max-width: 2rem;
+ transition: none;
+}
+
+.menu, .dropdown.menu {
+ a {
+ padding: 0.2rem 0.5rem;
+ }
+ > li > a {
+ background-color: transparent;
+ padding: 0.2rem 0.7rem;
+ }
+}
+
+.top-bar-title
+{
+ white-space: nowrap;
+}
+
+#action-bar {
+ .close-listener {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: transparent;
+ z-index: 9000;
+ }
+ #responsive-menu {
+ .top-bar-right {
+ position: relative;
+ text-align: right;
+ width: 100%;
+ }
+
+ }
+ .top-bar-right {
+ width: auto;
+
+
+
+ .menu {
+ &.action-bar {
+ a {
+ img + span {
+ display: none;
+ }
+ }
+ .action {
+ position: relative;
+ z-index: 9000;
+ &.is-dropdown-submenu-parent{
+ z-index: 9001;
+ }
+
+ &.hidden {
+ display: none;
+ }
+ @include breakpoint(small down) {
+ &.smedium {
+ display: none;
+ }
+ }
+ @include breakpoint(smedium down) {
+ li {
+ display: table-cell;
+ }
+ &.medium {
+ display: none;
+ }
+ }
+ @include breakpoint(medium down) {
+ &.large {
+ display: none;
+ }
+ }
+ &.never {
+ display: none;
+ }
+ }
+
+ &.hidden {
+ display: inline-block;
+ //float: right;
+ position: absolute;
+ z-index: 9000;
+ border: 1px solid rgb(202, 202, 202);
+ padding: 0.2rem;
+ transform: translateX(-100%);
+ text-align: left;
+
+ .action {
+ &.hidden {
+ display: none;
+ }
+ &.is-dropdown-submenu-parent {
+ z-index: 9001;
+ ul.is-dropdown-submenu {
+ top: auto;
+ > li.action, > .close-listener {
+ z-index: 9001;
+ }
+ }
+ > a:after {
+ display: block;
+ width: 0;
+ height: 0;
+ border: 6px inset;
+ content: "";
+ border-bottom-width: 0;
+ border-top-style: solid;
+ border-color: #ffffff transparent transparent;
+ right: 5px;
+ left: auto;
+ margin-top: -3px;
+ }
+ }
+ a {
+ white-space: nowrap;
+ img {
+ display: none;
+ + span {
+ display: inherit;
+ }
+ }
+ }
+ @include breakpoint(medium) {
+ &.medium {
+ display: none;
+ }
+ }
+ @include breakpoint(smedium) {
+ &.smedium {
+ display: none;
+ }
+ }
+ @include breakpoint(large) {
+ &.large {
+ display: none;
+ }
+ }
+
+ @include breakpoint(small down) {
+ &.smedium {
+ display: block;
+ &.hidden {
+ display: none;
+ }
+ }
+ }
+ @include breakpoint(smedium down) {
+ &.medium {
+ display: block;
+ &.hidden {
+ display: none;
+ }
+ }
+ }
+ @include breakpoint(medium down) {
+ &.large {
+ display: block;
+ &.hidden {
+ display: none;
+ }
+ }
+ }
+ &.never {
+ display: block;
+ &.hidden {
+ display: none;
+ }
+ }
+ &.always {
+ display: none;
+ }
+ }
+ }
+ }
+
+ .action {
+ z-index: 100;
+ @include breakpoint(smedium down) {
+ a {
+ width: 100%;
+ //text-align: left;
+ }
+ }
+
+ @include breakpoint(smedium down) {
+ a {
+ padding-left: 0.68rem;
+ }
+ }
+ @include breakpoint(small down) {
+ a {
+ padding-left: 0.236rem;
+ }
+ }
+
+ &:not(.is-dropdown-submenu-parent) {
+ @include breakpoint(smedium down) {
+ a {
+ padding-right: 0.68rem;
+ }
+ }
+ @include breakpoint(small down) {
+ a {
+ padding-right: 0.236rem;
+ }
+ }
+ }
+
+ &.img a {
+ padding-top: 0;
+ padding-bottom: 0;
+ img {
+ vertical-align: inherit;
+ max-height: 1.8rem;
+ }
+ }
+
+ }
+ > li > ul.is-dropdown-submenu {
+ min-width: 0;
+ .action {
+ display: inherit;
+ }
+ }
+ > li.opens-right > ul.is-dropdown-submenu {
+ right: auto;
+ left: auto;
+ a {
+ text-align: left;
+ }
+ }
+ }
+ }
+}
+
+.dropdown.menu > li.is-dropdown-submenu-parent > a:after {
+ border-color: #ffffff transparent transparent;
+}
\ No newline at end of file
diff --git a/src/client/sass/lib/_core.scss b/src/client/sass/lib/_core.scss
new file mode 100644
index 0000000..03ea1ac
--- /dev/null
+++ b/src/client/sass/lib/_core.scss
@@ -0,0 +1,367 @@
+//@import "../../../node_modules/foundation-sites/scss/foundation";
+
+*, :after, :before {
+ box-sizing: inherit;
+}
+
+html {
+ min-height: 100%;
+ width: 100%;
+ height: 100%;
+ font-size: 18px;
+ letter-spacing: 1px;
+}
+
+.max-height {
+ height: 100%;
+ min-height: 100%;
+}
+
+body {
+ margin: 0;
+ padding: 0;
+ height: 100%;
+ width: 100%;
+ font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif;
+ font-weight: 400;
+ line-height: 1.5;
+ display: flex;
+ flex-direction: column;
+
+ background: #fefefe;
+ color: #0a0a0a;
+}
+
+footer {
+ border-top: #d8d8d8 solid 1px;
+ text-align: center;
+}
+
+.top-bar .top-bar-title strong {
+ //margin-top: 7px;
+ vertical-align: middle;
+ display: inline-block;
+ /*margin-left: 8px;*/
+}
+
+nav.top-bar {
+
+ color: #FFF;
+ //background: #3F51B5;
+ //background: red;
+ font-size: 20px;
+ box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 2px 9px 1px rgba(0, 0, 0, 0.12), 0 4px 2px -2px rgba(0, 0, 0, 0.2);
+ padding: 0.6rem;
+ display: block;
+}
+
+button.button, a.button {
+ border-radius: 2px;
+ //background-color: red;
+ &.disabled, &.disabled:hover, &.disabled:focus {
+ //background-color: red;
+ }
+ &:focus, &:hover {
+ //background-color: #e00000;
+ }
+}
+
+.fill-me {
+ display: flex;
+ flex-direction: column;
+ &.vertical {
+ flex-direction: row;
+ }
+ .grow {
+ flex: 1;
+ }
+}
+
+.flex-center {
+ flex-direction: column;
+ justify-content: center;
+ //justify-content: space-around;
+ display: flex;
+ //margin: auto;
+ align-items: center;
+ > * {
+ max-height: 100%;
+ }
+}
+
+.menu a, .dropdown.menu a {
+ padding: .4rem .5rem
+}
+
+svg path {
+ fill: currentColor;
+}
+
+div.mainContainer {
+ position: relative;
+ max-height: 100%;
+ max-width: 100%;
+ overflow: auto;
+ flex: 1;
+ margin: 0.5rem;
+ > .row, #main-content, #site {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ //left: .625rem;
+ right: 0;
+ //right: .625rem;
+ }
+}
+
+.inline-block {
+ display: inline-block;
+}
+
+.right {
+ float: right;
+}
+
+#logo-img {
+ max-height: 2.2rem;
+}
+
+a {
+ text-decoration: none;
+ cursor: pointer;
+ color: inherit;
+}
+
+a.hidden-link {
+ text-decoration: none;
+ color: inherit;
+}
+
+label {
+ cursor: pointer;
+}
+
+.align-right {
+ text-align: right;
+}
+
+.view-panel {
+ display: none;
+}
+
+.loader {
+ left: 50%;
+ top: 50%;
+ position: fixed;
+ -webkit-transform: translate(-50%, -50%);
+ transform: translate(-50%, -50%);
+ text-align: center;
+
+ &.inline {
+ left: initial;
+ top: initial;
+ position: initial;
+ -webkit-transform: initial;
+ transform: initial;
+ text-align: center;
+ display: inline;
+ }
+
+ &.small #spinner {
+
+ transform: scale(0.5);
+ }
+
+ #spinner {
+ box-sizing: border-box;
+ stroke: #b71c1a;
+ stroke-width: 3px;
+ transform-origin: 50%;
+ animation: line 1.6s cubic-bezier(0.4, 0, 0.2, 1) infinite, rotate 1.6s linear infinite;
+ }
+}
+
+@keyframes rotate {
+ from {
+ transform: rotate(0);
+ }
+ to {
+ transform: rotate(450deg);
+ }
+}
+
+@keyframes line {
+ 0% {
+ stroke-dasharray: 2, 85.964;
+ transform: rotate(0);
+ }
+ 50% {
+ stroke-dasharray: 65.973, 21.9911;
+ stroke-dashoffset: 0;
+ }
+ 100% {
+ stroke-dasharray: 2, 85.964;
+ stroke-dashoffset: -65.973;
+ transform: rotate(90deg);
+ }
+}
+
+#print-content {
+ display: none;
+}
+
+.action-button {
+ max-height: 1.7rem;
+ margin-left: 0.4rem;
+ margin-right: 0.4rem;
+ &:hover {
+ background: $hoverColorDark;
+ }
+}
+
+.vcenter-container {
+ width: 100%;
+ height: 100%;
+ display: table;
+ //display: flex;
+ //justify-content: center;
+ //flex-wrap: wrap;
+
+ .vcenter {
+ //display: flex;
+ vertical-align: middle;
+ display: table-cell;
+ flex-direction: column;
+ justify-content: center;
+ }
+}
+
+.max-width {
+ width: 100%;
+}
+
+input, button {
+ letter-spacing: 1px !important;
+}
+
+.no-padding {
+ padding: 0;
+ border: 0;
+}
+
+.center {
+ text-align: center;
+}
+
+@media print {
+ nav, .mainContainer, footer, #styles {
+ display: none !important;
+ }
+ #print-content {
+ display: block !important;
+ }
+}
+
+.overflow-y-auto {
+ overflow-y: auto !important;
+}
+
+.row.no-after:after {
+ content: initial;
+}
+
+.margin-bottom {
+ margin-bottom: 1rem;
+ @include breakpoint(smedium) {
+ margin-bottom: 2rem;
+ }
+ @include breakpoint(medium) {
+ margin-bottom: 3rem;
+ }
+ @include breakpoint(large) {
+ margin-bottom: 4rem;
+ }
+ @include breakpoint(xlarge) {
+ margin-bottom: 5rem;
+ }
+}
+
+.font-small {
+ font-size: 0.7em;
+}
+
+.border-bottom {
+ border-bottom: 1px solid $prototype-border-color;
+}
+
+.border-right {
+ border-right: 1px solid $prototype-border-color;
+}
+
+.border-left {
+ border-left: 1px solid $prototype-border-color;
+}
+
+img.logo {
+ vertical-align: inherit;
+ display: inline-block;
+ height: auto;
+ max-width: 1.1rem;
+ margin-right: 2px;
+}
+
+.align-center {
+ text-align: center;
+}
+
+hr.separator {
+ margin: 1rem 0;
+}
+
+.button-line {
+ display: flex;
+ .button {
+ flex: 1;
+ margin-left: 1px;
+ margin-right: 1px;
+ padding: 0.5rem 0.77rem;
+ }
+}
+
+.small-small {
+ @include breakpoint(small down) {
+ font-size: small;
+ }
+}
+
+select {
+ border: 0;
+ padding: 0.3rem 0.3rem;
+}
+
+.hidden {
+ display: none;
+}
+
+.no-transition {
+ transition: none !important;
+}
+
+img.action-image {
+ max-height: 1.4rem;
+ cursor: pointer;
+}
+
+img.back-button {
+ max-height: 0.6rem;
+ margin-right: 0.2rem;
+ cursor: pointer;
+ vertical-align: inherit;
+}
+
+.no-margin-bottom {
+ margin-bottom: 0;
+}
\ No newline at end of file
diff --git a/src/client/sass/lib/_coreSettings.scss b/src/client/sass/lib/_coreSettings.scss
new file mode 100644
index 0000000..fb896f6
--- /dev/null
+++ b/src/client/sass/lib/_coreSettings.scss
@@ -0,0 +1,96 @@
+
+$hoverColor: #f2f2f2;
+$hoverColorDark: #e8e8e8;
+
+$themes: (
+ red:(
+ class: red,
+ themeColor: #ff0000,
+ lightThemeColor: #870015,
+ linkColor: #ff3d00,
+ spinnerColor: #b71c1a,
+ navBarTextColor: #fff,
+ textColor: #000,
+ textColor2: #555555,
+ lightLinkColor: #ff3d00,
+ linkBorderBottom: none,
+ linkHoverColor: #ff3d00,
+ lightLinkHoverColor: #ff3d00,
+ background: #fff
+ ),
+ blue:(
+ class: blue,
+ themeColor: #2c58ae,
+ lightThemeColor: #1a3062,
+ linkColor: #546cfe,
+ spinnerColor: #673AB7,
+ navBarTextColor: #fff,
+ textColor: #000,
+ textColor2: #555555,
+ lightLinkColor: #546cfe,
+ linkBorderBottom: none,
+ linkHoverColor: #546cfe,
+ lightLinkHoverColor: #546cfe,
+ background: #fff
+ ),
+ green:(
+ class: green,
+ themeColor: #008000,
+ lightThemeColor: #003613,
+ linkColor: #009829,
+ spinnerColor: #008000,
+ navBarTextColor: #fff,
+ textColor: #000,
+ textColor2: #555555,
+ lightLinkColor: #009829,
+ linkBorderBottom: none,
+ linkHoverColor: #009829,
+ lightLinkHoverColor: #009829,
+ background: #fff
+ ),
+ pink:(
+ class: pink,
+ themeColor: #ff69b4,
+ lightThemeColor: #70374a,
+ linkColor: #fe64af,
+ spinnerColor: #ff69b4,
+ navBarTextColor: #fff,
+ textColor: #000,
+ textColor2: #555555,
+ lightLinkColor: #fe64af,
+ linkBorderBottom: none,
+ linkHoverColor: #fe64af,
+ lightLinkHoverColor: #fe64af,
+ background: #fff
+ ),
+ black:(
+ class: black,
+ themeColor: #000,
+ lightThemeColor: #353535,
+ linkColor: #000,
+ spinnerColor: #000,
+ navBarTextColor: #fff,
+ textColor: #000,
+ textColor2: #555555,
+ lightLinkColor: #fff,
+ linkBorderBottom: 1px solid #000000,
+ linkHoverColor: #4e4e4e,
+ lightLinkHoverColor: #cacaca,
+ background: #fff
+ ),
+ dark: (
+ class: dark,
+ themeColor: #373737,
+ lightThemeColor: #4b4b4b,
+ linkColor: #fff,
+ spinnerColor: #ffffff,
+ navBarTextColor: #fff,
+ textColor: #ffffff,
+ textColor2: #9b9b9b,
+ lightLinkColor: #ffffff,
+ linkBorderBottom: 1px solid #ffffff,
+ linkHoverColor: #ffffff,
+ lightLinkHoverColor: #ffffff,
+ background: #000000
+ )
+);
\ No newline at end of file
diff --git a/src/client/sass/lib/_flashMessenger.scss b/src/client/sass/lib/_flashMessenger.scss
new file mode 100644
index 0000000..6d2013a
--- /dev/null
+++ b/src/client/sass/lib/_flashMessenger.scss
@@ -0,0 +1,59 @@
+div.flashMessage {
+ font-size: 0.8rem;
+ border-radius: 25px;
+ letter-spacing: 0;
+
+ z-index: 1001;
+ max-width: 100%;
+ display: inline-block;
+ position: relative;
+ box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.28);
+
+ border: 1px solid #626262;
+ background-color: #6b6b6b;
+ padding: .3em .6em;
+ text-align:center;
+
+ color: white;
+ //opacity: .9;
+
+ &:hover {
+ opacity: .4;
+ cursor: pointer;
+ }
+
+ &:before, &:after
+ {
+ display: block;
+ content: "";
+ }
+}
+
+span.flashMessage {
+ float: right;
+ cursor: pointer
+}
+
+div.success {
+ //background-color: #adeca1
+}
+
+div.default {
+ background-color: #1a9cc8
+}
+
+#flashMessageContainer {
+ text-align: center;
+ position: absolute
+}
+
+#flashMessageContainer, #flashMessageContainerAbsoulte {
+ height: 0 !important;
+ width: 100%;
+ overflow: visible !important
+}
+
+#flashMessageContainerAbsoulte {
+ margin: 5px 0;
+ position: relative
+}
\ No newline at end of file
diff --git a/src/client/sass/lib/_form.scss b/src/client/sass/lib/_form.scss
new file mode 100644
index 0000000..8518925
--- /dev/null
+++ b/src/client/sass/lib/_form.scss
@@ -0,0 +1,86 @@
+
+form {
+ position: relative;
+}
+
+.sending {
+ .sending-loader {
+ position: absolute;
+ background-color: rgba(125, 125, 125, 0.3);
+ display: block;
+ pointer-events: all;
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ z-index: 10;
+ .loader {
+ position: absolute
+ }
+ border-radius: 2px;
+ }
+}
+
+.sending-loader {
+ display: none;
+}
+
+//input.notEmpty:invalid {
+// background-color: lightcoral;
+//}
+
+label {
+ position: relative;
+ [type='text'], [type='password'], [type='date'], [type='datetime'], [type='datetime-local'], [type='month'], [type='week'], [type='email'], [type='number'], [type='search'], [type='tel'], [type='time'], [type='url'], [type='color'], textarea, input[type=text], input:not([type]) {
+ display: block;
+ width: 100%;
+ height: 2.4375rem;
+ padding: 0.5rem;
+ box-shadow: none !important;
+ font-size: 1rem;
+ font-weight: normal;
+ line-height: 1.5;
+ border: none;
+ //border-bottom: solid black;
+ outline: 0;
+ margin: 0 0 15px;
+
+ &:focus {
+ border: none;
+ box-shadow: none !important;
+ //border-bottom: solid black;
+ }
+
+ &:focus, &.notEmpty:not(:focus) {
+ ~ span {
+ top: -11px;
+ left: 0;
+ bottom: 0;
+ font-size: 11px;
+ opacity: 1;
+ //color: black;
+ }
+ }
+ ~ span {
+ position: absolute;
+ pointer-events: none;
+ left: 10px;
+ bottom: 10px;
+ top: 7px;
+ transition: 0.2s ease all;
+ //color: #626262;
+ }
+ }
+ textarea {
+ height: 10rem;
+ //border: 1px solid rgba(136, 136, 136, 0.31);
+ //box-shadow: 0 0 3px 2px hsla(0, 0%, 53%, .31) !important;
+ border-top-right-radius: 3px;
+ border-top-left-radius: 3px;
+ }
+ [type="checkbox"].before-text {
+ margin-bottom: 0;
+ }
+}
diff --git a/src/client/sass/lib/_foundationSettings.scss b/src/client/sass/lib/_foundationSettings.scss
new file mode 100644
index 0000000..e122f0f
--- /dev/null
+++ b/src/client/sass/lib/_foundationSettings.scss
@@ -0,0 +1,621 @@
+// Foundation for Sites Settings
+// -----------------------------
+//
+// Table of Contents:
+//
+// 1. Global
+// 2. Breakpoints
+// 3. The Grid
+// 4. Base Typography
+// 5. Typography Helpers
+// 6. Abide
+// 7. Accordion
+// 8. Accordion Menu
+// 9. Badge
+// 10. Breadcrumbs
+// 11. Button
+// 12. Button Group
+// 13. Callout
+// 14. Card
+// 15. Close Button
+// 16. Drilldown
+// 17. Dropdown
+// 18. Dropdown Menu
+// 19. Forms
+// 20. Label
+// 21. Media Object
+// 22. Menu
+// 23. Meter
+// 24. Off-canvas
+// 25. Orbit
+// 26. Pagination
+// 27. Progress Bar
+// 28. Responsive Embed
+// 29. Reveal
+// 30. Slider
+// 31. Switch
+// 32. Table
+// 33. Tabs
+// 34. Thumbnail
+// 35. Title Bar
+// 36. Tooltip
+// 37. Top Bar
+
+@import '../../../node_modules/foundation-sites/scss/util/util';
+
+// 1. Global
+// ---------
+
+$global-font-size: 100%;
+$global-width: rem-calc(1200);
+$global-lineheight: 1.5;
+$foundation-palette: (
+ primary: #1779ba,
+ secondary: #767676,
+ success: #3adb76,
+ warning: #ffae00,
+ alert: #cc4b37,
+);
+$light-gray: #e6e6e6;
+$medium-gray: #cacaca;
+$dark-gray: #8a8a8a;
+$black: #0a0a0a;
+$white: #fefefe;
+$body-background: $white;
+$body-font-color: $black;
+$body-font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;
+$body-antialiased: true;
+$global-margin: 1rem;
+$global-padding: 1rem;
+$global-weight-normal: normal;
+$global-weight-bold: bold;
+$global-radius: 0;
+$global-text-direction: ltr;
+$global-flexbox: false;
+$print-transparent-backgrounds: true;
+
+@include add-foundation-colors;
+
+// 2. Breakpoints
+// --------------
+
+$breakpoints: (
+ small:0,
+ smedium: 400px,
+ medium: 640px,
+ large: 1024px,
+ xlarge: 1200px,
+ xxlarge: 1440px,
+);
+$print-breakpoint: large;
+$breakpoint-classes: (small smedium medium large);
+
+// 3. The Grid
+// -----------
+
+$grid-row-width: $global-width;
+$grid-column-count: 12;
+$grid-column-gutter: (
+ small: 20px,
+ medium: 30px,
+);
+$grid-column-align-edge: true;
+$block-grid-max: 8;
+
+// 4. Base Typography
+// ------------------
+
+$header-font-family: $body-font-family;
+$header-font-weight: $global-weight-normal;
+$header-font-style: normal;
+$font-family-monospace: Consolas, 'Liberation Mono', Courier, monospace;
+$header-color: inherit;
+$header-lineheight: 1.4;
+$header-margin-bottom: 0.5rem;
+$header-styles: (
+ small: (
+ 'h1': ('font-size': 24),
+ 'h2': ('font-size': 20),
+ 'h3': ('font-size': 19),
+ 'h4': ('font-size': 18),
+ 'h5': ('font-size': 17),
+ 'h6': ('font-size': 16),
+ ),
+ medium: (
+ 'h1': ('font-size': 48),
+ 'h2': ('font-size': 40),
+ 'h3': ('font-size': 31),
+ 'h4': ('font-size': 25),
+ 'h5': ('font-size': 20),
+ 'h6': ('font-size': 16),
+ ),
+);
+$header-text-rendering: optimizeLegibility;
+$small-font-size: 80%;
+$header-small-font-color: $medium-gray;
+$paragraph-lineheight: 1.6;
+$paragraph-margin-bottom: 1rem;
+$paragraph-text-rendering: optimizeLegibility;
+$code-color: $black;
+$code-font-family: $font-family-monospace;
+$code-font-weight: $global-weight-normal;
+$code-background: $light-gray;
+$code-border: 1px solid $medium-gray;
+$code-padding: rem-calc(2 5 1);
+$anchor-color: $primary-color;
+$anchor-color-hover: scale-color($anchor-color, $lightness: -14%);
+$anchor-text-decoration: none;
+$anchor-text-decoration-hover: none;
+$hr-width: $global-width;
+$hr-border: 1px solid $medium-gray;
+$hr-margin: rem-calc(20) auto;
+$list-lineheight: $paragraph-lineheight;
+$list-margin-bottom: $paragraph-margin-bottom;
+$list-style-type: disc;
+$list-style-position: outside;
+$list-side-margin: 1.25rem;
+$list-nested-side-margin: 1.25rem;
+$defnlist-margin-bottom: 1rem;
+$defnlist-term-weight: $global-weight-bold;
+$defnlist-term-margin-bottom: 0.3rem;
+$blockquote-color: $dark-gray;
+$blockquote-padding: rem-calc(9 20 0 19);
+$blockquote-border: 1px solid $medium-gray;
+$cite-font-size: rem-calc(13);
+$cite-color: $dark-gray;
+$cite-pseudo-content: '\2014 \0020';
+$keystroke-font: $font-family-monospace;
+$keystroke-color: $black;
+$keystroke-background: $light-gray;
+$keystroke-padding: rem-calc(2 4 0);
+$keystroke-radius: $global-radius;
+$abbr-underline: 1px dotted $black;
+
+// 5. Typography Helpers
+// ---------------------
+
+$lead-font-size: $global-font-size * 1.25;
+$lead-lineheight: 1.6;
+$subheader-lineheight: 1.4;
+$subheader-color: $dark-gray;
+$subheader-font-weight: $global-weight-normal;
+$subheader-margin-top: 0.2rem;
+$subheader-margin-bottom: 0.5rem;
+$stat-font-size: 2.5rem;
+
+// 6. Abide
+// --------
+
+$abide-inputs: true;
+$abide-labels: true;
+$input-background-invalid: get-color(alert);
+$form-label-color-invalid: get-color(alert);
+$input-error-color: get-color(alert);
+$input-error-font-size: rem-calc(12);
+$input-error-font-weight: $global-weight-bold;
+
+// 7. Accordion
+// ------------
+
+$accordion-background: $white;
+$accordion-plusminus: true;
+$accordion-title-font-size: rem-calc(12);
+$accordion-item-color: $primary-color;
+$accordion-item-background-hover: $light-gray;
+$accordion-item-padding: 1.25rem 1rem;
+$accordion-content-background: $white;
+$accordion-content-border: 1px solid $light-gray;
+$accordion-content-color: $body-font-color;
+$accordion-content-padding: 1rem;
+
+// 8. Accordion Menu
+// -----------------
+
+$accordionmenu-arrows: true;
+$accordionmenu-arrow-color: $primary-color;
+$accordionmenu-arrow-size: 6px;
+
+// 9. Badge
+// --------
+
+$badge-background: $primary-color;
+$badge-color: $white;
+$badge-color-alt: $black;
+$badge-palette: $foundation-palette;
+$badge-padding: 0.3em;
+$badge-minwidth: 2.1em;
+$badge-font-size: 0.6rem;
+
+// 10. Breadcrumbs
+// ---------------
+
+$breadcrumbs-margin: 0 0 $global-margin 0;
+$breadcrumbs-item-font-size: rem-calc(11);
+$breadcrumbs-item-color: $primary-color;
+$breadcrumbs-item-color-current: $black;
+$breadcrumbs-item-color-disabled: $medium-gray;
+$breadcrumbs-item-margin: 0.75rem;
+$breadcrumbs-item-uppercase: true;
+$breadcrumbs-item-slash: true;
+
+// 11. Button
+// ----------
+
+$button-padding: 0.85em 1em;
+$button-margin: 0 0 $global-margin 0;
+$button-fill: solid;
+$button-background: $primary-color;
+$button-background-hover: scale-color($button-background, $lightness: -15%);
+$button-color: $white;
+$button-color-alt: $black;
+$button-radius: $global-radius;
+$button-sizes: (
+ tiny: 0.6rem,
+ small: 0.75rem,
+ default: 0.9rem,
+ large: 1.25rem,
+);
+$button-palette: $foundation-palette;
+$button-opacity-disabled: 0.25;
+$button-background-hover-lightness: -20%;
+$button-hollow-hover-lightness: -50%;
+$button-transition: background-color 0.25s ease-out, color 0.25s ease-out;
+
+// 12. Button Group
+// ----------------
+
+$buttongroup-margin: 1rem;
+$buttongroup-spacing: 1px;
+$buttongroup-child-selector: '.button';
+$buttongroup-expand-max: 6;
+$buttongroup-radius-on-each: true;
+
+// 13. Callout
+// -----------
+
+$callout-background: $white;
+$callout-background-fade: 85%;
+$callout-border: 1px solid rgba($black, 0.25);
+$callout-margin: 0 0 1rem 0;
+$callout-padding: 1rem;
+$callout-font-color: $body-font-color;
+$callout-font-color-alt: $body-background;
+$callout-radius: $global-radius;
+$callout-link-tint: 30%;
+
+// 14. Card
+// --------
+
+$card-background: $white;
+$card-font-color: $body-font-color;
+$card-divider-background: $light-gray;
+$card-border: 1px solid $light-gray;
+$card-shadow: none;
+$card-border-radius: $global-radius;
+$card-padding: $global-padding;
+$card-margin: $global-margin;
+
+// 15. Close Button
+// ----------------
+
+$closebutton-position: right top;
+$closebutton-offset-horizontal: (
+ small: 0.66rem,
+ medium: 1rem,
+);
+$closebutton-offset-vertical: (
+ small: 0.33em,
+ medium: 0.5rem,
+);
+$closebutton-size: (
+ small: 1.5em,
+ medium: 2em,
+);
+$closebutton-lineheight: 1;
+$closebutton-color: $dark-gray;
+$closebutton-color-hover: $black;
+
+// 16. Drilldown
+// -------------
+
+$drilldown-transition: transform 0.15s linear;
+$drilldown-arrows: true;
+$drilldown-arrow-color: $primary-color;
+$drilldown-arrow-size: 6px;
+$drilldown-background: $white;
+
+// 17. Dropdown
+// ------------
+
+$dropdown-padding: 1rem;
+$dropdown-background: $body-background;
+$dropdown-border: 1px solid $medium-gray;
+$dropdown-font-size: 1rem;
+$dropdown-width: 300px;
+$dropdown-radius: $global-radius;
+$dropdown-sizes: (
+ tiny: 100px,
+ small: 200px,
+ large: 400px,
+);
+
+// 18. Dropdown Menu
+// -----------------
+
+$dropdownmenu-arrows: true;
+$dropdownmenu-arrow-color: $anchor-color;
+$dropdownmenu-arrow-size: 6px;
+$dropdownmenu-min-width: 200px;
+$dropdownmenu-background: $white;
+$dropdownmenu-border: 1px solid $medium-gray;
+
+// 19. Forms
+// ---------
+
+$fieldset-border: 1px solid $medium-gray;
+$fieldset-padding: rem-calc(20);
+$fieldset-margin: rem-calc(18 0);
+$legend-padding: rem-calc(0 3);
+$form-spacing: rem-calc(16);
+$helptext-color: $black;
+$helptext-font-size: rem-calc(13);
+$helptext-font-style: italic;
+$input-prefix-color: $black;
+$input-prefix-background: $light-gray;
+$input-prefix-border: 1px solid $medium-gray;
+$input-prefix-padding: 1rem;
+$form-label-color: $black;
+$form-label-font-size: rem-calc(14);
+$form-label-font-weight: $global-weight-normal;
+$form-label-line-height: 1.8;
+$select-background: $white;
+$select-triangle-color: $dark-gray;
+$select-radius: $global-radius;
+$input-color: $black;
+$input-placeholder-color: $medium-gray;
+$input-font-family: inherit;
+$input-font-size: rem-calc(16);
+$input-font-weight: $global-weight-normal;
+$input-background: $white;
+$input-background-focus: $white;
+$input-background-disabled: $light-gray;
+$input-border: 1px solid $medium-gray;
+$input-border-focus: 1px solid $dark-gray;
+$input-shadow: inset 0 1px 2px rgba($black, 0.1);
+$input-shadow-focus: 0 0 5px $medium-gray;
+$input-cursor-disabled: not-allowed;
+$input-transition: box-shadow 0.5s, border-color 0.25s ease-in-out;
+$input-number-spinners: true;
+$input-radius: $global-radius;
+$form-button-radius: $global-radius;
+
+// 20. Label
+// ---------
+
+$label-background: $primary-color;
+$label-color: $white;
+$label-color-alt: $black;
+$label-palette: $foundation-palette;
+$label-font-size: 0.8rem;
+$label-padding: 0.33333rem 0.5rem;
+$label-radius: $global-radius;
+
+// 21. Media Object
+// ----------------
+
+$mediaobject-margin-bottom: $global-margin;
+$mediaobject-section-padding: $global-padding;
+$mediaobject-image-width-stacked: 100%;
+
+// 22. Menu
+// --------
+
+$menu-margin: 0;
+$menu-margin-nested: 1rem;
+$menu-item-padding: 0.7rem 1rem;
+$menu-item-color-active: $white;
+$menu-item-background-active: get-color(primary);
+$menu-icon-spacing: 0.25rem;
+$menu-item-background-hover: $light-gray;
+$menu-border: $light-gray;
+
+// 23. Meter
+// ---------
+
+$meter-height: 1rem;
+$meter-radius: $global-radius;
+$meter-background: $medium-gray;
+$meter-fill-good: $success-color;
+$meter-fill-medium: $warning-color;
+$meter-fill-bad: $alert-color;
+
+// 24. Off-canvas
+// --------------
+
+$offcanvas-size: 250px;
+$offcanvas-vertical-size: 250px;
+$offcanvas-background: $light-gray;
+$offcanvas-shadow: 0 0 10px rgba($black, 0.7);
+$offcanvas-push-zindex: 1;
+$offcanvas-overlap-zindex: 10;
+$offcanvas-reveal-zindex: 1;
+$offcanvas-transition-length: 0.5s;
+$offcanvas-transition-timing: ease;
+$offcanvas-fixed-reveal: true;
+$offcanvas-exit-background: rgba($white, 0.25);
+$maincontent-class: 'off-canvas-content';
+
+// 25. Orbit
+// ---------
+
+$orbit-bullet-background: $medium-gray;
+$orbit-bullet-background-active: $dark-gray;
+$orbit-bullet-diameter: 1.2rem;
+$orbit-bullet-margin: 0.1rem;
+$orbit-bullet-margin-top: 0.8rem;
+$orbit-bullet-margin-bottom: 0.8rem;
+$orbit-caption-background: rgba($black, 0.5);
+$orbit-caption-padding: 1rem;
+$orbit-control-background-hover: rgba($black, 0.5);
+$orbit-control-padding: 1rem;
+$orbit-control-zindex: 10;
+
+// 26. Pagination
+// --------------
+
+$pagination-font-size: rem-calc(14);
+$pagination-margin-bottom: $global-margin;
+$pagination-item-color: $black;
+$pagination-item-padding: rem-calc(3 10);
+$pagination-item-spacing: rem-calc(1);
+$pagination-radius: $global-radius;
+$pagination-item-background-hover: $light-gray;
+$pagination-item-background-current: $primary-color;
+$pagination-item-color-current: $white;
+$pagination-item-color-disabled: $medium-gray;
+$pagination-ellipsis-color: $black;
+$pagination-mobile-items: false;
+$pagination-mobile-current-item: false;
+$pagination-arrows: true;
+
+// 27. Progress Bar
+// ----------------
+
+$progress-height: 1rem;
+$progress-background: $medium-gray;
+$progress-margin-bottom: $global-margin;
+$progress-meter-background: $primary-color;
+$progress-radius: $global-radius;
+
+// 28. Responsive Embed
+// --------------------
+
+$responsive-embed-margin-bottom: rem-calc(16);
+$responsive-embed-ratios: (
+ default: 4 by 3,
+ widescreen: 16 by 9,
+);
+
+// 29. Reveal
+// ----------
+
+$reveal-background: $white;
+$reveal-width: 600px;
+$reveal-max-width: $global-width;
+$reveal-padding: $global-padding;
+$reveal-border: 1px solid $medium-gray;
+$reveal-radius: $global-radius;
+$reveal-zindex: 1005;
+$reveal-overlay-background: rgba($black, 0.45);
+
+// 30. Slider
+// ----------
+
+$slider-width-vertical: 0.5rem;
+$slider-transition: all 0.2s ease-in-out;
+$slider-height: 0.5rem;
+$slider-background: $light-gray;
+$slider-fill-background: $medium-gray;
+$slider-handle-height: 1.4rem;
+$slider-handle-width: 1.4rem;
+$slider-handle-background: $primary-color;
+$slider-opacity-disabled: 0.25;
+$slider-radius: $global-radius;
+
+// 31. Switch
+// ----------
+
+$switch-background: $medium-gray;
+$switch-background-active: $primary-color;
+$switch-height: 2rem;
+$switch-height-tiny: 1.5rem;
+$switch-height-small: 1.75rem;
+$switch-height-large: 2.5rem;
+$switch-radius: $global-radius;
+$switch-margin: $global-margin;
+$switch-paddle-background: $white;
+$switch-paddle-offset: 0.25rem;
+$switch-paddle-radius: $global-radius;
+$switch-paddle-transition: all 0.25s ease-out;
+
+// 32. Table
+// ---------
+
+$table-background: $white;
+$table-color-scale: 5%;
+$table-border: 1px solid smart-scale($table-background, $table-color-scale);
+$table-padding: rem-calc(8 10 10);
+$table-hover-scale: 2%;
+$table-row-hover: darken($table-background, $table-hover-scale);
+$table-row-stripe-hover: darken($table-background, $table-color-scale + $table-hover-scale);
+$table-is-striped: true;
+$table-striped-background: smart-scale($table-background, $table-color-scale);
+$table-stripe: even;
+$table-head-background: smart-scale($table-background, $table-color-scale / 2);
+$table-head-row-hover: darken($table-head-background, $table-hover-scale);
+$table-foot-background: smart-scale($table-background, $table-color-scale);
+$table-foot-row-hover: darken($table-foot-background, $table-hover-scale);
+$table-head-font-color: $body-font-color;
+$table-foot-font-color: $body-font-color;
+$show-header-for-stacked: false;
+
+// 33. Tabs
+// --------
+
+$tab-margin: 0;
+$tab-background: $white;
+$tab-color: $primary-color;
+$tab-background-active: $light-gray;
+$tab-active-color: $primary-color;
+$tab-item-font-size: rem-calc(12);
+$tab-item-background-hover: $white;
+$tab-item-padding: 1.25rem 1.5rem;
+$tab-expand-max: 6;
+$tab-content-background: $white;
+$tab-content-border: $light-gray;
+$tab-content-color: $body-font-color;
+$tab-content-padding: 1rem;
+
+// 34. Thumbnail
+// -------------
+
+$thumbnail-border: solid 4px $white;
+$thumbnail-margin-bottom: $global-margin;
+$thumbnail-shadow: 0 0 0 1px rgba($black, 0.2);
+$thumbnail-shadow-hover: 0 0 6px 1px rgba($primary-color, 0.5);
+$thumbnail-transition: box-shadow 200ms ease-out;
+$thumbnail-radius: $global-radius;
+
+// 35. Title Bar
+// -------------
+
+$titlebar-background: $black;
+$titlebar-color: $white;
+$titlebar-padding: 0.5rem;
+$titlebar-text-font-weight: bold;
+$titlebar-icon-color: $white;
+$titlebar-icon-color-hover: $medium-gray;
+$titlebar-icon-spacing: 0.25rem;
+
+// 36. Tooltip
+// -----------
+
+$has-tip-font-weight: $global-weight-bold;
+$has-tip-border-bottom: dotted 1px $dark-gray;
+$tooltip-background-color: $black;
+$tooltip-color: $white;
+$tooltip-padding: 0.75rem;
+$tooltip-font-size: $small-font-size;
+$tooltip-pip-width: 0.75rem;
+$tooltip-pip-height: $tooltip-pip-width * 0.866;
+$tooltip-radius: $global-radius;
+
+// 37. Top Bar
+// -----------
+
+$topbar-padding: 0.5rem;
+$topbar-background: $light-gray;
+$topbar-submenu-background: $topbar-background;
+$topbar-title-spacing: 0.5rem 1rem 0.5rem 0;
+$topbar-input-width: 200px;
+$topbar-unstack-breakpoint: medium;
diff --git a/src/client/sass/lib/_framework.scss b/src/client/sass/lib/_framework.scss
new file mode 100644
index 0000000..4d2764c
--- /dev/null
+++ b/src/client/sass/lib/_framework.scss
@@ -0,0 +1,4 @@
+
+.relative{
+ position: relative;
+}
\ No newline at end of file
diff --git a/src/client/sass/lib/_listjs.scss b/src/client/sass/lib/_listjs.scss
new file mode 100644
index 0000000..4ce14ee
--- /dev/null
+++ b/src/client/sass/lib/_listjs.scss
@@ -0,0 +1,54 @@
+.listjs {
+ position: relative;
+
+ label {
+ display: inline-block;
+ input {
+ margin-bottom: 0;
+ }
+ }
+
+ table {
+ border-collapse: collapse;
+ thead, tfoot {
+ tr th {
+ text-align: left;
+ &.sort{
+ cursor: pointer;
+ }
+ }
+ }
+ tbody.list {
+ tr:first-child td {
+ border-top: solid 1px #696969;
+ }
+ tr:last-child td {
+ border-bottom: solid 1px #696969;
+ }
+
+ tr td {
+ border-top: solid 1px #c8c8c8;
+ padding: 0.3rem;
+ }
+ }
+ }
+ ul.pagination {
+ float: right;
+ display: inline-block;
+ margin: 0;
+ li {
+ display: inline-block;
+ padding-left: 5px;
+ padding-right: 5px;
+ text-decoration: underline;
+
+ &.active, &.disabled {
+ text-decoration: none;
+ }
+
+ a.page {
+
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/client/sass/lib/_modal.scss b/src/client/sass/lib/_modal.scss
new file mode 100644
index 0000000..1a84c9d
--- /dev/null
+++ b/src/client/sass/lib/_modal.scss
@@ -0,0 +1,91 @@
+
+.background {
+ position: fixed;
+ z-index: 1000000;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ overflow: auto;
+ //background-color: rgb(0, 0, 0); /* Fallback color */
+ background-color: rgba(55, 55, 55, 0.6);
+
+ .modal {
+ position: relative;
+ top: 50%;
+ //left: 10%;
+ //right: 10%;
+ margin: auto;
+ width: 80%;
+
+ //background-color: #fefefe;
+
+ transform: translateY(-50%);
+ padding: 0.5rem;
+ display: flex;
+ flex-direction: column;
+ max-height: 80%;
+ max-width: nth(nth($breakpoints, 4),2);
+
+ &.small-margin {
+ @include breakpoint(medium down) {
+ width: 90%;
+ }
+ @include breakpoint(small down) {
+ width: 95%;
+ }
+ }
+
+ @each $size in $breakpoints
+ {
+ &.max-#{nth($size, 1)}
+ {
+ max-width: nth($size, 2);
+ }
+ }
+
+ .title {
+ font-weight: bold;
+ padding-bottom: 0.5rem;
+ }
+
+ .content-container {
+ overflow-y: auto;
+ max-height: 100%;
+
+ .loader{
+ position:static;
+ transform: none;
+ }
+ }
+
+ .close {
+ text-align: right;
+ //color: #aaa;
+ float: right;
+ font-size: 28px;
+ font-weight: bold;
+ line-height: 1;
+
+ &:hover,
+ &:focus {
+ //color: black;
+ text-decoration: none;
+ cursor: pointer;
+ }
+ }
+
+ .modal-button-container {
+ padding-top: 0.5rem;
+ .button {
+ margin-left: 0.2rem;
+ margin-bottom: 0 !important;
+ padding: 0.6em 0.8em;
+ @include breakpoint(small down) {
+ margin-left: 0.1rem;
+ padding: 0.3em 0.5em;
+ }
+ }
+ }
+ }
+}
diff --git a/src/client/sass/lib/_pwaAssets.scss b/src/client/sass/lib/_pwaAssets.scss
new file mode 100644
index 0000000..4dd9dfc
--- /dev/null
+++ b/src/client/sass/lib/_pwaAssets.scss
@@ -0,0 +1,7 @@
+
+.no-transition{
+ transition: none !important;
+ * {
+ transition: none !important;
+ }
+}
\ No newline at end of file
diff --git a/src/client/sass/lib/_rotate.scss b/src/client/sass/lib/_rotate.scss
new file mode 100644
index 0000000..85e1936
--- /dev/null
+++ b/src/client/sass/lib/_rotate.scss
@@ -0,0 +1,10 @@
+.rotated{
+ transform-origin: bottom center;
+ height: 50%;
+ //display: inline-block;
+ position: absolute;
+ top:0;
+ bottom:0;
+ left:0;
+ right:0;
+}
\ No newline at end of file
diff --git a/src/client/sass/lib/_settingsSite.scss b/src/client/sass/lib/_settingsSite.scss
new file mode 100644
index 0000000..154e04c
--- /dev/null
+++ b/src/client/sass/lib/_settingsSite.scss
@@ -0,0 +1,97 @@
+//@import "../../../node_modules/foundation-sites/scss/foundation";
+
+.settings-container {
+ border: 1px solid black;
+ border-radius: 2px;
+ padding: 0.3rem;
+
+ #settings-fragments-container {
+ @include breakpoint(medium) {
+ border-left: 1px solid $prototype-border-color;
+ }
+
+ #settings-fragments {
+ > * {
+ display: none;
+ &.active {
+ display: block;
+ }
+ }
+ }
+ }
+}
+
+.switch {
+ position: relative;
+ display: inline-block;
+
+ @include breakpoint(small down){
+ font-size: 0.6em;
+ }
+ @include breakpoint(smedium down){
+ font-size: 0.7em;
+ }
+ input {
+
+ display: none;
+ &:checked + .slider{
+ //background-color: #2196F3;
+ &:before{
+ transform: translateX(1.5em);
+ }
+ }
+ &:focus + .slider{
+ //box-shadow: 0 0 1px #2196F3;
+ }
+ }
+ .slider {
+ display: inline-block;
+ position: relative;
+ cursor: pointer;
+ width: 3em;
+ height: 1.5em;
+ border-radius: 1.5em;
+ background-color: #ccc;
+ transition: .4s;
+ margin-bottom: 0;
+ margin-top: 0;
+ &:before{
+ position: absolute;
+ content: "";
+ height: 1.1em;
+ width: 1.1em;
+ left: 0.15em;
+ bottom: 0.15em;
+ background-color: white;
+ transition: .4s;
+ border-radius: 50%;
+ }
+ }
+ img, svg{
+ width: 1.4em;
+ display: inline;
+ vertical-align: initial;
+ path{
+ stroke-color: inherit;
+ }
+ }
+}
+label{
+ font-size: 1em !important;
+
+}
+.setting-row:not(.hidden){
+ line-height: 1;
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
+ width: 100%;
+ cursor: pointer;
+ background: rgba(195, 195, 195, 0.13);
+ //display: inline-block;
+
+ input[type=checkbox]
+ {
+ margin: 0;
+ }
+}
+
diff --git a/src/client/sass/lib/_share.scss b/src/client/sass/lib/_share.scss
new file mode 100644
index 0000000..03eed92
--- /dev/null
+++ b/src/client/sass/lib/_share.scss
@@ -0,0 +1,10 @@
+.share-icon {
+ width: 1.5rem;
+ max-width: 1.5rem;
+ margin: 0.1rem;
+
+ svg{
+ width: 1.5rem;
+ max-width: 1.5rem;
+ }
+}
diff --git a/src/client/sass/lib/_style.scss b/src/client/sass/lib/_style.scss
new file mode 100644
index 0000000..868476c
--- /dev/null
+++ b/src/client/sass/lib/_style.scss
@@ -0,0 +1,135 @@
+.zf-green {
+ color: #68b604
+}
+
+.column:last-child:not(:first-child), .columns:last-child:not(:first-child) {
+ float: left
+}
+
+input[type=checkBox].form-control {
+ height: 24px;
+ height: 1.5rem;
+ width: 100%
+}
+
+[type=submit] {
+ display: block;
+ box-sizing: border-box;
+ width: 100%;
+ height: 39px;
+ height: 2.4375rem;
+ padding: 8px;
+ padding: .5rem;
+ border: 1px solid #cacaca;
+ margin: 0 0 16px;
+ margin: 0 0 1rem;
+ font-family: inherit;
+ font-size: 16px;
+ font-size: 1rem;
+ color: #0a0a0a;
+ background-color: #fefefe;
+ box-shadow: inset 0 1px 2px hsla(0, 0%, 4%, .1);
+ border-radius: 0;
+ transition: box-shadow .5s, border-color .25s ease-in-out;
+ -webkit-appearance: none;
+ -moz-appearance: none
+}
+
+form ul li {
+ color: red;
+ font-size: 12.8px;
+ font-size: .8rem
+}
+
+.button-dropdown:after {
+ border-color: #000 transparent transparent;
+ border-width: .4em;
+ border-style: solid;
+ content: "";
+ position: absolute;
+ top: .4em;
+ display: block;
+ height: 0;
+ width: 0;
+ right: 1em
+}
+
+.button-dropdown {
+ position: relative;
+ display: block;
+ padding-right: 2em
+}
+
+.button-dropdown.open:after {
+ border-color: transparent transparent #000;
+ top: 0
+}
+
+a.ui-datepicker-next, a.ui-datepicker-prev {
+ height: 100% !important
+}
+
+div.container a.navbar-brand > img {
+ display: inline;
+ margin-right: 4px
+}
+
+ul.menu.plain li.active a {
+ background-color: #ededed;
+ color: #000
+}
+
+ul.menu.plain li a {
+ color: #000
+}
+
+ul.menu.plain li a:hover {
+ color: #525252
+}
+
+ul.submenu {
+ border-top: 1px solid #bcbcbc;
+ border-bottom: 1px solid #bcbcbc;
+ margin-left: 10px
+}
+
+#cookie-compliance {
+ line-height: 1.2;
+ font-size: 0.8rem;
+ width: 100%;
+ margin: 0 0;
+ padding: 0.3rem 0;
+ #close-cookie-msg {
+ float: right;
+ margin-bottom: 0;
+ margin-right: 3px;
+ padding: 0.4rem 0.8rem;
+ }
+}
+
+.menu-container .button
+{
+ text-align: center;
+ width: 100%;
+}
+
+@for $i from 1 through 20 {
+ $factor: $i/20;
+ $value: percentage($factor);
+ .height-#{$factor*100} {
+ height: $value;
+ }
+ .max-height-#{$factor*100} {
+ max-height: $value;
+ }
+ .width-#{$factor*100} {
+ width: $value;
+ }
+ .max-width-#{$factor*100} {
+ max-width: $value;
+ }
+}
+
+.text-right {
+ text-align: right;
+}
\ No newline at end of file
diff --git a/src/client/sass/lib/_tabs.scss b/src/client/sass/lib/_tabs.scss
new file mode 100644
index 0000000..8567b45
--- /dev/null
+++ b/src/client/sass/lib/_tabs.scss
@@ -0,0 +1,18 @@
+.tab-header-container{
+ //border-bottom: 1px solid #b0b0b0;
+ //margin-bottom: -1px;
+
+ .tab-header{
+ display:inline-block;
+ background-color: #eeeeee;
+ border: 1px solid #b0b0b0;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ padding: 0 5px;
+
+ &.active{
+ border-bottom: 0;
+ background-color: #FFF;
+ }
+ }
+}
diff --git a/src/client/sass/lib/_theme.scss b/src/client/sass/lib/_theme.scss
new file mode 100644
index 0000000..406c34d
--- /dev/null
+++ b/src/client/sass/lib/_theme.scss
@@ -0,0 +1,117 @@
+* {
+ //transition: background-color .25s ease-out, color .25s ease-out;
+ transition: .25s ease-out, color .25s ease-out;
+}
+
+@mixin defineTheme($theme) {
+ background: map-get($theme, background);
+ color: map-get($theme, textColor);
+
+ #cookie-compliance {
+ background-color: map-get($theme, lightThemeColor);
+ color: map-get($theme, navBarTextColor);
+ a.link {
+ color: map-get($theme, lightLinkColor);
+ border-bottom-color: map-get($theme, lightLinkColor);
+ &:hover {
+ color: map-get($theme, lightLinkHoverColor);
+ border-bottom-color: map-get($theme, lightLinkHoverColor);
+ }
+ }
+ }
+ a.link {
+ text-decoration: none;
+ color: map-get($theme, linkColor);
+ border-bottom: map-get($theme, linkBorderBottom);
+ &:hover {
+ color: map-get($theme, linkHoverColor);
+ border-bottom-color: map-get($theme, linkHoverColor);
+ }
+ }
+ .loader #spinner {
+ stroke: map-get($theme, spinnerColor);
+ }
+
+ nav.top-bar {
+ color: map-get($theme, navBarTextColor);
+ background: map-get($theme, themeColor);
+ }
+ .top-bar {
+ ul {
+ background: map-get($theme, themeColor) !important;
+ a {
+ color: map-get($theme, navBarTextColor);
+ }
+ }
+ }
+ button.button, a.button {
+ background-color: map-get($theme, themeColor);
+ &.disabled, &.disabled:hover, &.disabled:focus, &:hover {
+ background-color: map-get($theme, themeColor);
+ }
+ }
+ .switch {
+ input {
+ &:checked + .slider {
+ background-color: map-get($theme, themeColor);
+ }
+ &:focus + .slider {
+ box-shadow: 0 0 1px map-get($theme, themeColor);
+ }
+ }
+ }
+ label {
+ color: #{map-get($theme, textColor)};
+ }
+ .background .modal {
+ background-color: #fefefe;
+ }
+
+ svg {
+ .fill-color, &.fill-color{
+ fill: currentColor;
+ }
+ .fill-background, &.fill-background{
+ fill: #fefefe;
+ }
+ }
+
+ //Forms
+ label {
+ [type='text'], [type='password'], [type='date'], [type='datetime'], [type='datetime-local'], [type='month'], [type='week'], [type='email'], [type='number'], [type='search'], [type='tel'], [type='time'], [type='url'], [type='color'], textarea, input[type=text], input:not([type]) {
+ border-bottom: solid #{map-get($theme, textColor)};
+ background: #{map-get($theme, background)};
+ color:#{map-get($theme, textColor)};
+
+ &:focus {
+ border-bottom: solid #{map-get($theme, textColor)};
+ }
+ &:focus, &.notEmpty:not(:focus) {
+ ~ span {
+ color: #{map-get($theme, textColor)};
+ }
+ }
+ ~ span {
+ color: #{adjust_color( map-get($theme, textColor), $alpha: -0.35)};
+ }
+ }
+ textarea {
+ box-shadow: 0 0 3px 2px hsla(0, 0%, 53%, .31) !important;
+ }
+ }
+ input.notEmpty:invalid {
+ background-color: #{adjust_color( map-get($theme, themeColor), $alpha: -0.35)};
+ }
+}
+
+body {
+ @each $theme, $values in $themes {
+ @if (map-get($values, class) == "") {
+ @include defineTheme($values)
+ } @else {
+ &.#{map-get($values, class)} {
+ @include defineTheme($values)
+ }
+ }
+ }
+}
diff --git a/src/scss/wordRotator.scss b/src/client/sass/wordRotator.scss
old mode 100755
new mode 100644
similarity index 86%
rename from src/scss/wordRotator.scss
rename to src/client/sass/wordRotator.scss
index e1a873c..8f1e8e6
--- a/src/scss/wordRotator.scss
+++ b/src/client/sass/wordRotator.scss
@@ -1,7 +1,32 @@
-@import "imports";
+@import "settings";
+@import "lib/_rotate.scss";
+@import "lib/_share.scss";
+@import "lib/_tabs.scss";
+@import "lib/_core.scss";
+@import "lib/_flashMessenger.scss";
+@import "lib/_framework.scss";
+@import "lib/_pwaAssets.scss";
+@import "lib/_settingsSite.scss";
+@import "lib/_style.scss";
+@import "lib/_theme.scss";
@import "tutorial";
@import "wordrotatorTheme";
+
+$text-shadow: /*
+ 0 0 3px #787878,
+ 0 0 10px #000000;
+*/
+
+ /*
+ 0 3px 3px #787878,
+ 15px 15px 8px #000000
+ */
+ 0 0.2rem 0.2rem #464646, 0.6rem 0.8rem 0.4rem #00000090;
+
+
+
+
//ActionBar
nav.top-bar.title-bar {
padding: 0.3rem 0.6rem 0;
@@ -14,6 +39,7 @@ nav.top-bar.title-bar {
#action-bar .top-bar-right .menu .action.img a {
padding-bottom: 0;
+
img {
max-height: 1.8rem;
}
@@ -27,31 +53,57 @@ nav.top-bar.title-bar {
.relative-level-number {
position: relative;
+
#level-number-container {
top: 50%;
transform: translate(-50%, -50%);
}
}
-#level-number-container {
+//body.default .won .level-counter {
+// transition-duration: 1s;
+// background: #06bd06;
+// border-color: #c10000;
+// //> a {
+// // color: black;
+// //}
+//}
+
+#level-number-container, .level-counter {
z-index: 1;
- transition: none;
+ //transition: none;
position: absolute;
left: 50%;
transform: translate(-50%);
border: 3px solid white;
border-radius: 50%;
- visibility: hidden;
+ //visibility: hidden;
display: table-cell;
- height: 35px;
- width: 35px;
+
+ height: 40px;
+ width: 40px;
text-align: center;
vertical-align: middle;
- &.visible {
- visibility: visible;
+ &.level-counter {
+ position: fixed !important;
+ font-size: 2rem;
+
+ &.num-10 {
+ font-size: 1.4rem;
+ }
+
+ &.num-100 {
+ font-size: 1rem;
+ }
+
+ &.num-1000 {
+ font-size: 0.7rem;
+ }
+
}
+
&.in-main-menu {
background: white;
border-color: black;
@@ -64,7 +116,11 @@ nav.top-bar.title-bar {
max-width: 1em;
}
- #level-number {
+ a {
+ width: initial !important;
+ }
+
+ #level-number, a {
transition: none;
position: absolute;
left: 50%;
@@ -96,6 +152,7 @@ $coinTowerDimension: 28px;
#coin-container {
line-height: 1;
+
.coin {
margin-left: 3px;
margin-right: 3px;
@@ -170,6 +227,7 @@ $coinTowerDimension: 28px;
&.reverse {
//animation-name: rotate-reverse-#{(nth($rotationDegrees, $i))%360+90};
animation-name: rotate-reverse-#{nth($rotationDegrees, $i)};
+
> .child-container {
> .segment {
//animation-name: rotate-reverse-#{360- (nth($rotationDegrees, $i)%360)};
@@ -194,6 +252,7 @@ $coinTowerDimension: 28px;
transform: #{map-get($degreeMatrix, nth($rotationDegrees, $i))};
background-color: inherit;
z-index: 1;
+
> .child-container {
> .segment {
//transform: rotate(#{360- nth($rotationDegrees, $i)}deg);
@@ -243,6 +302,7 @@ $coinTowerDimension: 28px;
* {
transition: none;
}
+
overflow-y: visible;
}
@@ -269,6 +329,7 @@ $coinTowerDimension: 28px;
&.segment-column {
padding-top: 4px;
+
> .child-container > .segment {
display: block;
width: 100%;
@@ -279,11 +340,13 @@ $coinTowerDimension: 28px;
background-color: transparent !important;
min-width: 1em;
padding: 0.8em;
+
&:before {
content: " ";
display: block;
padding-top: 100%;
}
+
.leaf-element {
position: absolute;
width: 100%;
@@ -291,6 +354,9 @@ $coinTowerDimension: 28px;
line-height: 1.5em;
top: 0;
left: 0;
+
+ text-shadow: $text-shadow;
+
}
}
@@ -315,7 +381,7 @@ $coinTowerDimension: 28px;
}
//Won-screen
-#site-content > :not(.won) {
+#site > :not(.won) {
.show-when-won {
display: none;
}
@@ -330,12 +396,19 @@ $coinTowerDimension: 28px;
.level-container {
//height: 60%;
}
+
.show-when-won {
//visibility: initial;
}
+
.show-while-playing {
display: none;
}
+
+ #won-text{
+ text-shadow: $text-shadow;
+ }
+
}
.text-right {
@@ -375,7 +448,7 @@ body {
user-select: none;
}
-#site-content {
+#site {
overflow: visible;
}
@@ -396,8 +469,17 @@ div.mainContainer {
#share-button {
overflow: hidden;
+
svg {
cursor: pointer;
max-width: 1.5rem;
}
}
+
+svg {
+ color: black;
+
+ .fill-background {
+ fill: white;
+ }
+}
\ No newline at end of file
diff --git a/public/sound/brightAndBeautifull__.mp3 b/src/client/sound/brightAndBeautifull__.mp3
similarity index 100%
rename from public/sound/brightAndBeautifull__.mp3
rename to src/client/sound/brightAndBeautifull__.mp3
diff --git a/src/sound/brightAndBeautifull__.wav b/src/client/sound/brightAndBeautifull__.wav
similarity index 100%
rename from src/sound/brightAndBeautifull__.wav
rename to src/client/sound/brightAndBeautifull__.wav
diff --git a/public/sound/single_coin_fall_on_concrete_.mp3 b/src/client/sound/single_coin_fall_on_concrete_.mp3
similarity index 100%
rename from public/sound/single_coin_fall_on_concrete_.mp3
rename to src/client/sound/single_coin_fall_on_concrete_.mp3
diff --git a/src/module/Application/pwa/translations/de.json b/src/client/translations/de.json
old mode 100755
new mode 100644
similarity index 83%
rename from src/module/Application/pwa/translations/de.json
rename to src/client/translations/de.json
index e6cc9bc..7cab480
--- a/src/module/Application/pwa/translations/de.json
+++ b/src/client/translations/de.json
@@ -36,5 +36,17 @@
"already-persisted-dialog-title":"Daten werden dauerhaft gespeichert!",
"persist-storage-dialog-message-firefox":"Damit dein Fortschritt dauerhaft gespeichert wird, musst du zulassen, dass Daten dauerhaft gespeichert werden.",
"warning-data-not-persistent":"Achtung! Dein Fortschritt kann verloren gehen! Gehe die Einstellungen für mehr Infos.",
- "version-label": "Version:"
+ "version-label": "Version:",
+ "share-text": "Schau dir diese coole App an:\n{0}",
+ "share": "Teilen",
+
+ "document-title": "WordRotator",
+ "document-title-empty": "WordRotator",
+ "contact": "Kontakt",
+ "contact text": "Du möchtest Kontakt mit uns aufnehmen? Kein Problem, nutze einfach das Kontaktformular oder sende uns eine E-Mail an {0} .\n Egal, ob du uns eine E-Mail sendest oder das Kontaktformular benutzt, akzeptierst du unsere Datenschutzbestimmung",
+ "e-mail": "E-Mailadresse",
+ "privacy policy accepted": " akzeptiert",
+ "message": "Nachricht",
+ "send": "Senden",
+ "the message was sent": "Die Nachricht wurde gesendet."
}
\ No newline at end of file
diff --git a/src/client/translations/en.json b/src/client/translations/en.json
new file mode 100644
index 0000000..f4b3873
--- /dev/null
+++ b/src/client/translations/en.json
@@ -0,0 +1,53 @@
+{
+ "won":"Won!",
+ "continue":"Continue",
+
+ "help": "?",
+ "not-enough-coins":"You have to few coins!",
+ "sync-error": "Es gab einen Fehler beim Aktualisieren der Level. Bitte stelle sicher, dass du eine aktive Internetverbindung hast und versuche es später erneut.",
+ "game-ended": "Oh nein! Es sieht so aus, als ob du schon alle Level gespielt hast... Schau später noch einmal rein, evtl gibt es dann neue Level.",
+ "play": "Spielen!",
+ "tutorial-step-1": "Klicke auf ein Feld, um dieses rotieren zu lassen!",
+ "tutorial-step-2": "Um zu gewinnen, drehe die Segmente so, dass du zwei Wörter lesen kannst.",
+ "tutorial-step-3": "Die Hilfe löst ein Segment, kostet aber 25 Münzen. Probiere jetzt die Hilfe aus.",
+ "tutorial-step-4": "Große Segmente drehst du, indem du diese ziehst.",
+ "extra-coins-after-first-level": "Für das erste Level gibt es 50 extra Münzen!",
+ "dark": "Dunkel",
+ "theme": "Theme:",
+ "sound": "Sound:",
+ "music": "Musik:",
+ "credits": "Credits",
+ "privacy-policy": "Datenschutzbestimmungen",
+ "impressum": "Impressum",
+ "track": "Anonymisierte Nutzungsdaten senden:",
+ ">": ">",
+ "choose-theme-dialog-title": "Theme auswählen:",
+ "install": "Installieren",
+ "share-dialog": "Teilen:",
+ "credits-sister-text": "Ich danke meiner Lieblingsschwester, denn ohne Sie würde diese App nicht so aussehen, wie sie aussieht (wahrscheinlich eher schlechter :p)",
+ "credits-coin-text": "Sound: Der Münz-Sound ist von der Webseite {0} . Alle Rechte für diesen Münz-Sound gehören {0} .",
+ "credits-music-text": "Musik: Bright And Beautiful - GEMAfreie Musik von {0} Licensed under Creative Commons: By Attribution 4.0 International (CC BY 4.0){1} Angepasst (geschnitten) für diese App",
+ "storage-info": "Fortschritt {0} dauerhaft gespeichert",
+ "storage-permission-not-get": "Der Browser gibt nicht die Erlaubnis zur dauerhaften Speicherung...",
+ "storage-permission-get": "Die Daten sind nun dauerhaft gespeichert",
+ "persist-storage-dialog-title": "Daten dauerhaft speichern?",
+ "persist-storage-dialog-message": "Der Fortschritt und die Level dieser WebApp sind nur temporär gespeichert. Damit die Daten dauerhaft gespeichert werden, muss eins von drei Kriterien erfüllt sein: 1) Die Seite muss als Lesezeichen gespeichert werden (und maximal 5 Lesezeichen ingsesamt). 2) Die Seite muss mit die meistbenutzte Seite sein. 3) Benachrichtigungen müssen erlaubt werden. Damit die Daten dieser Webseite nicht gelöscht werden, erlaube bitte Benachrichtigungen. Alternativ kannst du die Seite auch als Lesezeichen speichern.",
+ "notification-permission-denied":"Die Berechtigung für Benachrichtigungen wurde verwährt",
+ "already-persisted-dialog-message":"Damit die Daten dauerhaft gespeichert werden, muss eins von drei Kriterien erfüllt sein: 1) Die Seite muss als Lesezeichen gespeichert werden (und maximal 5 Lesezeichen ingsesamt). 2) Die Seite muss mit die meistbenutzte Seite sein. 3) Benachrichtigungen müssen erlaubt werden. Du erfüllst schon ein Kriterium und daher wird dein Fortschritt dauerhaft gespeichert (außer du löscht sie)",
+ "already-persisted-dialog-title":"Daten werden dauerhaft gespeichert!",
+ "persist-storage-dialog-message-firefox":"Damit dein Fortschritt dauerhaft gespeichert wird, musst du zulassen, dass Daten dauerhaft gespeichert werden.",
+ "warning-data-not-persistent":"Achtung! Dein Fortschritt kann verloren gehen! Gehe die Einstellungen für mehr Infos.",
+ "version-label": "Version:",
+ "share-text": "Schau dir diese coole App an: {0}",
+ "share": "Teilen",
+
+ "document-title": "WordRotator",
+ "document-title-empty": "WordRotator",
+ "contact": "Kontakt",
+ "contact text": "Du möchtest Kontakt mit uns aufnehmen? Kein Problem, nutze einfach das Kontaktformular oder sende uns eine E-Mail an {0} .\n Egal, ob du uns eine E-Mail sendest oder das Kontaktformular benutzt, akzeptierst du unsere Datenschutzbestimmung",
+ "e-mail": "E-Mailadresse",
+ "privacy policy accepted": " akzeptiert",
+ "message": "Nachricht",
+ "send": "Senden",
+ "the message was sent": "Die Nachricht wurde gesendet."
+}
\ No newline at end of file
diff --git a/src/js/init.js b/src/js/init.js
deleted file mode 100755
index 0072752..0000000
--- a/src/js/init.js
+++ /dev/null
@@ -1,127 +0,0 @@
-import {
- AndroidBridge,
- App, applyPolyfills, FlashMessenger, Helper,
- InitPromise, MenuAction,
- ShareManager,
- SmsShareButton, TelegramShareButton,
- Theme,
- ThemeManager,
- Translator,
- WhatsappShareButton
-} from "./lib/pwa-lib";
-import {LoginSite, RegistrationSite, UserManager} from "./lib/pwa-user-management";
-
-import "./lib/pwa-lib"
-import "./lib/pwa-core"
-import "./lib/pwa-assets"
-import "./lib/pwa-code-management"
-import "./lib/pwa-user-management"
-import "./lib/pwa-contact"
-
-import {SettingsManager, SettingsSite} from "./lib/pwa-core";
-
-import {
- InstallManager,
- Matomo,
- MatomoShareButton,
- MyStorageManager,
- SoundManager
-} from "./lib/pwa-assets";
-import {MenuSite} from "../module/Application/pwa/js/site/MenuSite";
-import {WordRotatorSettingFragment} from "../module/Application/pwa/js/Fragment/WordRotatorSettingFragment";
-
-import {PrivacyPolicySite} from "../module/Application/pwa/js/site/PrivacyPolicySite";
-import {CreditsSite} from "../module/Application/pwa/js/site/CreditsSite";
-import {SelectWordsSite} from "../module/Application/pwa/js/site/SelectWordsSite";
-import {DeleteWordsSite} from "../module/Application/pwa/js/site/DeleteWordsSite";
-
-import './settings'
-
-window.onerror = (e, u, l) => {
- console.error(e, u, l);
-};
-
-applyPolyfills();
-
-ThemeManager.addTheme(new Theme('red', 'red'));
-ThemeManager.addTheme(new Theme("blue", "blue"));
-ThemeManager.addTheme(new Theme("black", "black"));
-ThemeManager.addTheme(new Theme("green", "green"));
-ThemeManager.addTheme(new Theme("pink", "pink"));
-ThemeManager.addTheme(new Theme("dark", "dark"));
-
-ShareManager.addShareButton(new MatomoShareButton(new WhatsappShareButton('img/whatsapp.svg'), "whatsapp", true));
-ShareManager.addShareButton(new MatomoShareButton(new SmsShareButton('img/sms.svg'), "sms", true));
-ShareManager.addShareButton(new MatomoShareButton(new TelegramShareButton('img/telegram.svg'), "telegram", true));
-// ShareManager.addShareButton(new CopyShareButton('img/copy.svg'));
-
-let app = new App();
-
-AndroidBridge.addDefinition(() => {
- window["app"] = app;
- window["app"]["pause"] = app.pause;
- window["app"]["resume"] = app.resume;
- window["app"]["setAppEndListener"] = app.setAppEndListener;
-});
-
-SettingsSite.setTemplate("html/application/setting-template.html");
-// SettingsSite.shouldAddSettingsAction = false;
-
-RegistrationSite.addAction = false;
-LoginSite.addLoginAction = false;
-UserManager.waitForData = false;
-
-InitPromise.resolve(app).then(async function () {
- SettingsSite.settingsAction.showFor = MenuAction.SHOW_ALWAYS;
-
- let settingsManager = SettingsManager.getInstance();
-
- let soundManager = SoundManager.getInstance();
- soundManager.play(SoundManager.CHANNELS.MUSIC, {
- audio: "sound/brightAndBeautifull__.mp3",
- loop: true,
- volume: 0.6,
- muted: (settingsManager.getSetting("play-music", "1") !== "1")
- }).catch(e => console.error(e));
-
- app.start(MenuSite);
- Translator.setLanguage("de");
-
- InstallManager.setCanInstallListener(e => {});
- let storageManager = MyStorageManager.getInstance();
- if (InstallManager.isInstalled()){
- storageManager.persist();
- }
-
- window["applyAndroidBridge"] = AndroidBridge.applyDefinitions;
-
- let wasOpened = (Helper.nonNull(localStorage.getItem('was-open'), "0") === "1");
- if (wasOpened && storageManager.canPersist()){
- Promise.all([storageManager.isPersistent(), navigator["serviceWorker"]["ready"]]).then(res => {
- if (!res[0]){
- FlashMessenger.addMessage("warning-data-not-persistent");
- }
- });
- }
- else{
- localStorage.setItem("was-open", "1");
- }
-});
-
-// console.log("trying push... 1");
-// navigator.serviceWorker["ready"].then(function (registration) {
-// console.log("trying push... 2");
-// registration["pushManager"]["subscribe"]({
-// "userVisibleOnly": true,
-// "applicationServerKey": new Uint8Array([0x4, 0x53, 0xb7, 0x8d, 0xc6, 0xd1, 0x1a, 0xd4, 0x8b, 0xb2, 0xeb, 0x82, 0xf0, 0x9e, 0x12, 0xf6, 0xd, 0x32, 0x18, 0xa, 0x35, 0xf, 0x2d, 0x4c, 0x5, 0x29, 0x15, 0x95, 0x23, 0xb1, 0xd3, 0xab, 0x87, 0x88, 0x85, 0x1d, 0xc0, 0x98, 0x6e, 0x65, 0xe3, 0xcb, 0xa2, 0x28, 0x63, 0x7, 0x34, 0x9b, 0xfa, 0x46, 0x9a, 0x49, 0xcc, 0x70, 0x7a, 0xdd, 0xbe, 0x1e, 0xfc, 0xde, 0xcc, 0xb3, 0x5b, 0xcb, 0xf4])
-// }).then(function (sub) {
-// console.log("trying push... 3");
-// console.log("Subscription", sub);
-// }).catch(function (e) {
-// // if ('Notification' in window && Notification.permission === 'denied') {
-// // console.warn('Permission for notifications was denied');
-// // } else {
-// // console.error('Unable to subscribe to push', e);
-// // }
-// });
-// });
\ No newline at end of file
diff --git a/src/js/lib/pwa-assets.js b/src/js/lib/pwa-assets.js
deleted file mode 100755
index 738550c..0000000
--- a/src/js/lib/pwa-assets.js
+++ /dev/null
@@ -1,680 +0,0 @@
-import { Helper, InitPromise, MultipleShareButton, AndroidBridge, PauseSite, Fragment, Translator } from './pwa-lib.js';
-
-class DelayPromise extends Promise {
- static async delay(delay) {
- return new Promise((resolve) => {
- setTimeout(resolve, delay);
- });
- }
-}
-
-class MyStorageManager {
- static getInstance() {
- if (Helper.isNull(MyStorageManager.instance)) {
- MyStorageManager.instance = new MyStorageManager();
- }
- return MyStorageManager.instance;
- }
-
- async estimate() {
- if ('storage' in navigator && 'estimate' in navigator["storage"]) {
- // We've got the real thing! Return its response.
- return navigator["storage"]["estimate"]();
- }
-
- if ('webkitTemporaryStorage' in navigator &&
- 'queryUsageAndQuota' in navigator["webkitTemporaryStorage"]) {
- // Return a promise-based wrapper that will follow the expected interface.
- return new Promise(function (resolve, reject) {
- navigator["webkitTemporaryStorage"]["queryUsageAndQuota"](
- function (usage, quota) {
- resolve({"usage": usage, "quota": quota});
- },
- );
- });
- }
- // If we can't estimate the values, return a Promise that resolves with NaN.
- return Promise.resolve({"usage": NaN, "quota": NaN});
- }
-
- async isPersistent(){
- if (this.canPersist()){
- return navigator["storage"]["persisted"]();
- }
- return Promise.resolve(false);
- }
-
- canEstimateStorage() {
- return ('storage' in navigator && 'estimate' in navigator["storage"]|| 'webkitTemporaryStorage' in navigator &&
- 'queryUsageAndQuota' in navigator["webkitTemporaryStorage"]);
- }
-
- canPersist() {
- return (navigator["storage"] && navigator["storage"]["persist"]);
- }
-
- persist(){
- if (this.canPersist()){
- return navigator["storage"]["persist"]();
- }
- return Promise.resolve(false);
- }
-}
-
-MyStorageManager.instance = null;
-
-class InstallManager {
- static init() {
- window.addEventListener('beforeinstallprompt', e => {
- e.preventDefault();
- this.setDeferredPrompt(e);
- });
- }
-
- static setDeferredPrompt(e){
- this.deferredPromt = e;
- if (this.canInstallListener) {
- this.canInstallListener(this.deferredPromt);
- }
- }
-
- static async prompt(){
- if (Helper.isNotNull(this.deferredPromt)){
- this.deferredPromt["prompt"]();
- return this.deferredPromt["userChoice"].then(r => {
- MyStorageManager.getInstance().persist();
- return r;
- });
- }
- return Promise.resolve({
- "outcome":"dismissed",
- "platform":""
- });
- }
-
- static isInstalled(){
- return matchMedia("(display-mode: standalone)").matches;
- }
-
- static setCanInstallListener(listener, callIfCanInstall) {
- this.canInstallListener = listener;
- callIfCanInstall = Helper.nonNull(callIfCanInstall, true);
-
- if (callIfCanInstall && Helper.nonNull(this.deferredPromt)) {
- this.canInstallListener(this.deferredPromt);
- }
- }
-}
-
-InstallManager.init();
-
-class Matomo {
-
- static init() {
- Matomo.isTrackingPromise = new Promise(async (resolve) => {
- let shouldTrack = Helper.nonNull(localStorage.getItem(Matomo.LOCAL_STORAGE_KEY), "1");
- if (Helper.isNull(shouldTrack)) {
- shouldTrack = await Matomo._askIsTracking();
- localStorage.setItem(Matomo.LOCAL_STORAGE_KEY, shouldTrack);
- }
- else {
- shouldTrack = (shouldTrack === "1");
- Matomo.setTrack(shouldTrack);
- }
- resolve(shouldTrack);
- });
- Matomo.isTrackingPromise.then(() => {
- Matomo.push(['trackPageView'], true);
- Matomo.push(['enableLinkTracking'], true);
- Matomo.push(['setTrackerUrl', Matomo.TRACK_SITE + '/piwik.php'], true);
- Matomo.push(['setSiteId', Matomo.SIDE_ID + ""], true);
-
- let d = document, g = d.createElement('script'), s = d.getElementsByTagName('head')[0];
- g.type = 'text/javascript';
- g.async = true;
- g.defer = true;
- g.src = Matomo.TRACK_SITE + '/piwik.js';
- s.appendChild(g);
- });
- }
-
- static update(title) {
- if (Helper.nonNull(Matomo.currentUrl)) {
- Matomo.push(['setReferrerUrl', Matomo.currentUrl]);
- }
- Matomo.currentUrl = window.location.pathname + window.location.search;
- Matomo.push(['setCustomUrl', Matomo.currentUrl]);
- Matomo.push(['setDocumentTitle', title]);
-
- // remove all previously assigned custom variables, requires Matomo (formerly Piwik) 3.0.2
- Matomo.push(['deleteCustomVariables', 'page']);
- Matomo.push(['setGenerationTimeMs', 0]);
- Matomo.push(['trackPageView']);
-
- // make Matomo aware of newly added content
- var content = document.getElementById('site-content');
- Matomo.push(['MediaAnalytics::scanForMedia', content]);
- Matomo.push(['FormAnalytics::scanForForms', content]);
- Matomo.push(['trackContentImpressionsWithinNode', content]);
- Matomo.push(['enableLinkTracking']);
- }
-
- static async _askIsTracking() {
- Matomo.isTrackingPromise = new Promise(resolve => {
- Matomo.push([function () {
- resolve(!this["isUserOptedOut"]());
- }]);
- Matomo.push([function () {
- resolve(!this["isUserOptedOut"]());
- }]);
- });
- return Matomo.isTrackingPromise;
- }
-
- static async query(method) {
- return fetch(Matomo.TRACK_SITE + Matomo.BASE_PATH + method, {
- "mode": "cors",
- "credentials": "include",
- }).then(res => res.text()).then(text => (new window.DOMParser()).parseFromString(text, "text/xml"));
- }
-
- static getTrackingPromise() {
- return Matomo.isTrackingPromise;
- }
-
- static async setTrack(shouldTrack) {
- Matomo.isTrackingPromise = Promise.resolve(shouldTrack);
- localStorage.setItem(Matomo.LOCAL_STORAGE_KEY, (shouldTrack === true) ? "1" : "0");
-
- if (shouldTrack) {
- Matomo.push(["forgetUserOptOut"], true);
- }
- else {
- Matomo.push(["optUserOut"], true);
- }
- }
-
- static async trackEvent(event, name, label, value){
- let ev = ["trackEvent", event, name];
- if (Helper.isNotNull(label)){
- ev.push(label);
- }
- if (Helper.isNotNull(value) && !isNaN(parseFloat(value)) && isFinite(value)){
- ev.push(value);
- }
-
- return this.push(ev);
- }
-
- static async push(arr, force) {
-
- if (!Array.isArray(arr)) {
- arr = [arr];
- }
- window["_paq"].push(arr);
- }
-}
-
-Matomo.currentUrl = null;
-
-Matomo.LOCAL_STORAGE_KEY = "matomoShouldTrack";
-Matomo.TRACK_SITE = "//matomo.silas.link";
-Matomo.BASE_PATH = "/index.php?module=API&method=AjaxOptOut.";
-Matomo.SIDE_ID = "1";
-
-InitPromise.addPromise(() => {
- window["_paq"] = window["_paq"] || [];
- Matomo.init();
-});
-
-class MatomoShareButton extends MultipleShareButton{
-
- constructor(baseButton, platform, shouldLoadImg) {
- super([baseButton, (url) => {
- Matomo.trackEvent("shared", url, platform);
- }], shouldLoadImg);
- }
-}
-
-AndroidBridge.addDefinition("MatomoShareButton", MatomoShareButton);
-
-class RotateHelper {
- rotate(element, degrees){
- let rotateText = element.innerText;
- element.removeAllChildren();
-
- let partDegree = degrees/rotateText.length;
- for(let i = 0; i < rotateText.length; i++){
- let child = document.createElement("span");
- child.innerText = rotateText.charAt(i);
- child.style.transform ="rotate("+(partDegree*i)+"deg)";
- child.classList.add("rotated");
- element.appendChild(child);
- }
- }
-}
-
-class ScaleHelper {
- async scaleTo(scale, fontElement, container, ignoreHeight, ignoreWidth, margin, fontWeight, animationDelay, addListener) {
-
- addListener = Helper.nonNull(addListener, true);
- animationDelay = Helper.nonNull(animationDelay, 0);
-
- let newFontSize = await this._getNewFontSize(scale, fontElement, container, ignoreHeight, ignoreWidth, margin, fontWeight, animationDelay === 0);
-
- if (animationDelay > 0) {
- await new Promise(r => {
- setTimeout(r, animationDelay);
- fontElement.style.fontSize = newFontSize + "px";
- });
- }
-
- let self = this;
- let listener = function () {
- return new Promise(resolve => {
- let timeout = (typeof addListener === 'number') ? addListener : 255;
- setTimeout(() => {
- resolve(self.scaleTo(scale, fontElement, container, ignoreHeight, ignoreWidth, margin, fontWeight, animationDelay, false));
- }, timeout);
- });
- };
- if (addListener !== false) {
- window.addEventListener("resize", listener);
- }
- return listener;
- }
-
- async scaleToFull(fontElement, container, ignoreHeight, ignoreWidth, margin, fontWeight, animDelay, addListener) {
- return this.scaleTo(1, fontElement, container, ignoreHeight, ignoreWidth, margin, fontWeight, animDelay, addListener);
- }
-
- async _getNewFontSize(scale, fontElement, container, ignoreHeight, ignoreWidth, margin, fontWeight, setFontSize) {
- margin = Helper.nonNull(margin, 10);
- ignoreHeight = Helper.nonNull(ignoreHeight, false);
- ignoreWidth = Helper.nonNull(ignoreWidth, false);
- fontWeight = Helper.nonNull(fontWeight, fontElement.innerHTML.length);
- setFontSize = Helper.nonNull(setFontSize, true);
-
- let hasNoTransitionClass = container.classList.contains("no-transition");
-
- if (!hasNoTransitionClass) {
- container.classList.add("no-transition");
- }
-
- const numChanged = 5;
- let oldDiffIndex = 0;
- let oldDiff = [];
-
- for (let i = 0; i < numChanged; i++) {
- oldDiff.push(0);
- }
-
- let beforeFontSize = fontElement.style.fontSize;
- let currentFontSize = 1;
- let widthDiff = 0;
- let heightDiff = 0;
- let containerWidth = 0;
- let containerHeight = 0;
- do {
- currentFontSize += oldDiff[oldDiffIndex] / (fontWeight + 1);
- fontElement.style.fontSize = currentFontSize + 'px';
-
- let containerStyle = window.getComputedStyle(container);
-
- containerWidth = containerStyle.getPropertyValue("width").replace('px', '');
- containerHeight = containerStyle.getPropertyValue("height").replace('px', '');
-
- widthDiff = containerWidth - fontElement.offsetWidth;
- heightDiff = containerHeight - fontElement.offsetHeight;
-
- oldDiffIndex = (oldDiffIndex+1)%numChanged;
- let newDiff = (ignoreWidth ? heightDiff : (ignoreHeight ? widthDiff : Math.min(widthDiff, heightDiff)));
- if (newDiff === oldDiff[(oldDiffIndex+1)%numChanged]) {
- break;
- }
- oldDiff[oldDiffIndex] = newDiff;
- } while ((widthDiff > (1 - scale) * containerWidth || ignoreWidth) && (heightDiff > (1 - scale) * containerHeight || ignoreHeight));
-
- currentFontSize -= margin;
- fontElement.style.fontSize = ((setFontSize) ? currentFontSize + "px" : beforeFontSize);
-
- if (!hasNoTransitionClass) {
- await new Promise((r) => {
- setTimeout(r, 50);
- });
- container.classList.remove("no-transition");
- }
-
- return currentFontSize;
- }
-}
-
-class AudioChain {
-
- constructor(context, sourceBuffer, chainFunction) {
- this.buffer = sourceBuffer;
- this.shouldLoop = false;
- this.loopStart = null;
- this.loopEnd = null;
- this.chainFunction = chainFunction;
- this.context = context;
-
- this.startTime = null;
- this.pauseTime = null;
- this.source = null;
-
- this.running = false;
- }
-
- setBuffer(buffer) {
- this.buffer = buffer;
- }
-
- setLooping(shouldLoop, loopStart, loopEnd) {
- this.shouldLoop = shouldLoop;
-
- if (Helper.isNotNull(loopStart)) {
- this.loopStart = loopStart;
- }
- if (Helper.isNotNull(loopEnd)) {
- this.loopEnd = loopEnd;
- }
- }
-
- async start(delay, offset, duration) {
- //sind sonst null, schmeißt in Android 5 einen fehler
- delay = Helper.nonNull(delay, 0);
- offset = Helper.nonNull(offset, 0);
- //Duration darf nicht gesetzt werden
- // duration = Helper.nonNull(duration, -1);
-
- let source = this.context.createBufferSource();
-
- source.loop = this.shouldLoop;
- if (Helper.isNotNull(this.loopStart)) {
- source.loopStart = this.loopStart;
- }
- if (Helper.isNotNull(this.loopEnd)) {
- source.loopEnd = this.loopEnd;
- }
- source.buffer = this.buffer;
- await this.chainFunction(source);
-
- if (Helper.isNull(duration)){
- source.start(delay, offset);
- }
- else{
- source.start(delay, offset, duration);
- }
- this.startTime = (new Date()).getTime() - (Helper.nonNull(offset, 0) * 1000);
- this.source = source;
- this.running = true;
- }
-
- async stop(delay) {
- if (Helper.isNotNull(this.source)) {
- delay = Helper.nonNull(delay, 0);
-
- this.pauseTime = ((new Date()).getTime()) - this.startTime;
- this.running = false;
- return this.source.stop(delay);
- }
- return null;
- }
-
- async resume() {
-
- if (!this.running) {
- return this.start(null, Helper.nonNull(this.pauseTime, 0) / 1000.0);
- }
- }
-}
-
-class SoundManager {
- static getInstance() {
- if (Helper.isNull(SoundManager.instance)) {
- SoundManager.instance = new SoundManager();
- }
- return SoundManager.instance;
- }
-
- constructor() {
- this.channels = {};
- if ('AudioContext' in window){
- this.context = new AudioContext();
- }
- else if ('webkitAudioContext' in window){
- this.context = new webkitAudioContext();
- }
- else {
- throw new Error("No audio context found!");
- }
- this.context.onstatechange = function () {
- console.log("stateChange from context", arguments);
- };
- this.context.oncomplete = function () {
- console.log("onComplete from context", arguments);
- };
-
- window.addEventListener("visibilitychange", (e) => {
- // console.log("visibility Change event", e);
- this.handleVisibilityChange();
- });
- //For safari
- let checkVisibility = ()=>{
- this.handleVisibilityChange();
- setTimeout(checkVisibility, 500);
- };
- checkVisibility();
- }
-
- isNotSuspended(){
- // return false;
- return this.context.state !== "suspended";
- }
-
- set(options, channel) {
- channel = Helper.nonNull(channel, SoundManager.CHANNELS.DEFAULT);
- let audioObject = Helper.nonNull(this.channels[channel], {});
-
- if (typeof options === "string") {
- options = {audio: options};
- }
-
- let audio = options.audio;
- if (Helper.isNotNull(audio)) {
- audioObject.loadedPromise = fetch(audio).then(res => res.arrayBuffer()).then(arrayBuffer => {
- return new Promise((r) => this.context.decodeAudioData(arrayBuffer, r));
- }).catch(e => console.error(e));
- this.stop(channel);
- }
- audioObject.muted = Helper.nonNull(options.muted, audioObject.muted, false);
- audioObject.volume = Helper.nonNull(options.volume, audioObject.volume, 1);
- audioObject.loop = Helper.nonNull(options.loop, audioObject.loop, false);
- audioObject.timeOffset = Helper.nonNull(options.timeOffset, audioObject.timeOffset, 0);
- this.channels[channel] = audioObject;
-
- if (audioObject.muted) {
- this.stop(channel);
- }
-
- return this.channels[channel];
- }
-
- async resumeContext(){
- if (typeof this.context.resume === "function") {
- return this.context.resume();
- }
- }
-
- async play(channel, audioOrOptions) {
- this.resumeContext();
- channel = Helper.nonNull(channel, SoundManager.CHANNELS.DEFAULT);
- if (Helper.isNull(audioOrOptions)) {
- audioOrOptions = {};
- } else if (!(typeof audioOrOptions === "object")) {
- audioOrOptions = {
- audio: audioOrOptions
- };
- }
- audioOrOptions.timeOffset = Helper.nonNull(audioOrOptions.timeOffset, 0);
-
- this.stop(channel);
- this.set(audioOrOptions, channel);
-
- if (!this.channels[channel].muted) {
- let buffer = await this.channels[channel].loadedPromise;
- let source = new AudioChain(this.context, buffer, (sourceNode) => {
- let gain = this.context.createGain();
- gain.gain.value = this.channels[channel].volume;
-
- sourceNode.connect(gain);
- gain.connect(this.context.destination);
- });
-
- source.setBuffer(buffer);
-
- //to prevent gap in mp3-files
- source.setLooping(this.channels[channel].loop, 0.3, buffer.duration - 0.3);
-
- this.channels[channel].source = source;
- await source.start();
- }
- return this.channels[channel];
- }
-
- stop(channel) {
- channel = Helper.nonNull(channel, SoundManager.CHANNELS.DEFAULT);
-
-
- let oldAudio = this.channels[channel];
- if (Helper.isNotNull(oldAudio) && Helper.isNotNull(oldAudio.source)) {
- oldAudio.source.stop();
- }
- }
-
- get(channel) {
- channel = Helper.nonNull(channel, SoundManager.CHANNELS.DEFAULT);
- return this.channels[channel];
- }
-
- async resume(channel) {
- channel = Helper.nonNull(channel, SoundManager.CHANNELS.DEFAULT);
- if (Helper.isNotNull(this.channels[channel]) && !this.channels[channel].muted && Helper.isNotNull(this.channels[channel].source)) {
- return this.channels[channel].source.resume();
- }
- }
-
- stopAll(){
- for (let k in this.channels) {
- if (Helper.isNotNull(this.channels[k].source)) {
- this.channels[k].source.stop();
- }
- }
- }
-
- resumeAllIfNotMuted(){
- for (let k in this.channels) {
- if (Helper.isNotNull(this.channels[k]) && !this.channels[k].muted && Helper.isNotNull(this.channels[k].source)) {
- this.channels[k].source.resume();
- }
- }
- }
-
- handleVisibilityChange() {
- if (document.hidden) {
- this.stopAll();
- }
- else {
- this.resumeAllIfNotMuted();
- }
- }
-}
-
-SoundManager.CHANNELS = {
- MUSIC: "music",
- SOUND: "sound",
- DEFAULT: "default"
-};
-
-InitPromise.addPromise(() => {
- PauseSite.onPauseListeners.push(() => {
- SoundManager.getInstance().stopAll();
- });
- PauseSite.onStartListeners.push(() => {
- SoundManager.getInstance().resumeAllIfNotMuted();
- });
-});
-
-// AndroidBridge.addDefinition(() => {
- // window["soundManagerInstance"] = SoundManager.getInstance();
- // window["soundManagerInstance"]["stopAll"] = window["soundManagerInstance"].stopAll;
- // window["soundManagerInstance"]["resumeAllIfNotMuted"] = window["soundManagerInstance"].resumeAllIfNotMuted;
-// });
-
-class TabbedFragment extends Fragment {
- constructor(site) {
- super(site, 'pwaAssets/html/fragment/tabbedFragment.html');
- this.fragments = {};
- this.tabHeadingTemplate = null;
- this.tabHeadingContainer = null;
- this.tabContainer = null;
- this.tabKeys = [];
- this.currentTabIndex = 0;
- }
-
- onFirstStart() {
- super.onFirstStart();
- this.tabContainer = this.findBy(".tab-container");
- this.showTab(0);
- }
-
- addFragment(name, fragment, translationArgs, isTranslatable) {
- isTranslatable = Helper.nonNull(isTranslatable, true);
- if (translationArgs === false) {
- isTranslatable = false;
- }
-
- this.fragments[name] = fragment;
- const tabIndex = this.tabKeys.length;
- this.tabKeys.push(name);
-
- const _self = this;
- this.inflatePromise = this.inflatePromise.then(function (siteContent) {
- if (Helper.isNull(_self.tabHeadingTemplate)) {
- _self.tabHeadingTemplate = siteContent.querySelector(".tab-header-template");
- }
- const newTabHeader = Helper.cloneNode(_self.tabHeadingTemplate);
- newTabHeader.classList.add("tab-" + tabIndex);
- newTabHeader.querySelector(".tab-name").appendChild((isTranslatable) ? Translator.makePersistentTranslation(name, translationArgs) : document.createTextNode(name));
- newTabHeader.addEventListener("click", function(){
- _self.showTab(tabIndex);
- });
-
- if (Helper.isNull(_self.tabHeadingContainer)) {
- _self.tabHeadingContainer = siteContent.querySelector(".tab-header-container");
- }
- _self.tabHeadingContainer.appendChild(newTabHeader);
- return siteContent;
- });
- }
-
- showTab(index) {
- if (index >= 0 && index < this.tabKeys.length) {
- this.findBy(".tab-" + this.currentTabIndex).classList.remove("active");
- this.findBy(".tab-" + index).classList.add("active");
- this.tabContainer.removeAllChildren().appendChild(Helper.createLoadingSymbol());
-
- this.currentTabIndex = index;
-
- const _self = this;
- this.fragments[this.tabKeys[index]].inflatePromise.then(tabView => {
- if (_self.currentTabIndex === index) {
- _self.tabContainer.removeAllChildren().appendChild(tabView);
- }
- });
- }
- }
-}
-
-export { DelayPromise, InstallManager, Matomo, MatomoShareButton, MyStorageManager, RotateHelper, ScaleHelper, AudioChain, SoundManager, TabbedFragment };
diff --git a/src/js/lib/pwa-code-management.js b/src/js/lib/pwa-code-management.js
deleted file mode 100755
index 9904525..0000000
--- a/src/js/lib/pwa-code-management.js
+++ /dev/null
@@ -1,63 +0,0 @@
-import { DataManager } from './pwa-core.js';
-import { AbstractSite, FlashMessenger, Helper, InitPromise, Translator } from './pwa-lib.js';
-
-class Code {
- constructor(args) {
- if (typeof args === "string") {
- args = {
- "code": args
- };
- }
- this.args = args;
- this.isCacheable = false;
- }
-
- setIsCacheable(isCacheable) {
- this.isCacheable = isCacheable;
- }
-
- getIsCacheable() {
- return this.isCacheable;
- }
-
- activate() {
- return DataManager.send("c/code", this.args);
- }
-}
-
-class CodeSite extends AbstractSite {
- constructor(siteManager) {
- super(siteManager, "core/html/load.html", "code");
- }
-
- onConstruct(args) {
- super.onConstruct(args);
- console.log(args);
-
- let resPromise = Promise.resolve();
- if (Helper.isNotNull(args["code"])) {
- let code = args["code"];
- let isCachable = Helper.nonNull(args["cachable"], false);
-
- let codeObject = new Code(code);
- codeObject.setIsCacheable(isCachable);
-
- let self = this;
- resPromise = codeObject.activate().then(function (res) {
- if (!res["success"]) {
- FlashMessenger.addMessage(FlashMessenger.MESSAGE_TYPE_SUCCESS, Translator.translate(res["errors"][0]));
- }
- else {
- FlashMessenger.addMessage(FlashMessenger.MESSAGE_TYPE_SUCCESS, Translator.translate(Helper.nonNull(res["result"]["successMessage"], "code-activated")));
- }
- self.finish();
- });
- }
- }
-}
-
-InitPromise.addPromise(function (app) {
- app.addDeepLink("code", CodeSite);
-});
-
-export { Code, CodeSite };
diff --git a/src/js/lib/pwa-contact.js b/src/js/lib/pwa-contact.js
deleted file mode 100644
index d5b9ecf..0000000
--- a/src/js/lib/pwa-contact.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import { AbstractSite, FlashMessenger, InitPromise } from './pwa-lib.js';
-import { Form } from './pwa-core.js';
-
-class ContactSite extends AbstractSite{
- constructor(siteManager) {
- super(siteManager, 'contact/html/contact.html', ContactSite.DEEP_LINK);
- }
-
- onFirstStart() {
- new Form(this.findBy("#contact-form"), "contact", "post").onSubmit((d) => {
- FlashMessenger.addMessage("contact-message-sent");
- this.finish();
- });
-
- super.onFirstStart();
- }
-}
-ContactSite.DEEP_LINK = "contactMe";
-
-InitPromise.addPromise((app) => {
- if (ContactSite.DEEP_LINK){
- app.addDeepLink(ContactSite.DEEP_LINK, ContactSite);
- }
-});
-
-export { ContactSite };
diff --git a/src/js/lib/pwa-core.js b/src/js/lib/pwa-core.js
deleted file mode 100755
index 9e62ddf..0000000
--- a/src/js/lib/pwa-core.js
+++ /dev/null
@@ -1,959 +0,0 @@
-import { MenuAction, Helper, Dialog, Translator, Fragment, ViewInflater, AbstractSite, InitPromise, ThemeManager as ThemeManager$1 } from './pwa-lib.js';
-
-class ConditionAction extends MenuAction
-{
- constructor(title, callback, condition, showFor, order) {
- super(title, callback, showFor, order);
- this.condition = condition;
- }
-
- getVisible() {
- return (super.getVisible() && this.condition(this));
- }
-}
-
-class Constants{}
-Constants.SCRIPTS = {
- CKEDITOR:"version/2/ckeditor/ckeditor.js",
- LIST_JS: "version/1/listjs/list.min.js"
-};
-
-class DataManager {
- static async load(url, isCachable, raw) {
- isCachable = Helper.nonNull(isCachable, false);
- raw = Helper.nonNull(raw, false);
- let fullUrl = (isCachable) ? Helper.basePath(DataManager.cachePath + url) : Helper.basePath(DataManager.dataPath + url);
-
- return this._load(fullUrl, raw);
- }
-
- static async _load(url, raw) {
- return fetch(url, {"credentials": "same-origin"}).then(function (res) {
- if (raw) {
- return res.text();
- }
- return res.json();
- }).catch(function (e) {
- if (!raw) {
- return {
- "success": false,
- "errors": [
- "not-online"
- ]
- }
- }
- });
- }
-
- static async loadStatic(url, raw) {
- raw = Helper.nonNull(raw, false);
- let fullUrl = Helper.basePath(url);
-
- return this._load(fullUrl, raw);
- }
-
- static async send(url, params) {
- let fullUrl = Helper.basePath(DataManager.dataPath + url);
-
- if (!(params instanceof FormData)) {
- let newParams = new FormData();
- for (let k in params) {
- newParams.append(k, params[k]);
- }
- params = newParams;
- }
-
- return fetch(fullUrl, {
- "credentials": "same-origin",
- "method": "POST",
- "body": params
- }).then(function (res) {
- return res.json();
- }).catch(function (e) {
- console.error("error", e);
- return {
- "success": false,
- "errors": [
- "not-online"
- ]
- }
- });
- }
-
- static buildQuery(values) {
- return Helper.buildQuery(values);
- }
-}
-
-DataManager.dataPath = "data/";
-DataManager.cachePath = "cached/";
-
-class Form {
- constructor(formElem, url, method, isCachable) {
- this.formElem = formElem;
- this.method = Helper.nonNull(method, Helper.nonNull(formElem["method"], "POST"));
- this.isCachable = (Helper.nonNull(isCachable, this.method.toLowerCase() === "get") === true);
-
- this.isBusy = false;
-
- if (typeof url === "string")
- {
- this.submitHandler = function(values){
- if (self.method.toLowerCase() === "get") {
- return (DataManager.load(url + DataManager.buildQuery(values), self.isCachable));
- }
- else {
- return (DataManager.send(url, values));
- }
- };
- }
- else {
- this.submitHandler = url;
- }
-
- let self = this;
-
- this.submitCallback = null;
- this.errorCallback = async function (errors) {
- await self.setErrors(errors);
- };
-
- formElem.addEventListener("submit", async function (e) {
- console.log("submitting!", e);
- e.preventDefault();
- await self.doSubmit(e);
- });
-
- for (let i = 0, n = formElem.elements.length; i < n; i++) {
- let elem = formElem.elements[i];
- elem.addEventListener("change", function () {
- if (this.value.trim() !== "") {
- this.classList.add("notEmpty");
- }
- else {
- this.classList.remove("notEmpty");
- }
- this.setCustomValidity("");
- });
- elem.addEventListener("keydown", function () {
- this.setCustomValidity("");
- });
- }
- }
-
- onError(errorHandler, ownHandlerForOptimisticLocking){
- ownHandlerForOptimisticLocking = Helper.nonNull(ownHandlerForOptimisticLocking, true);
- let callback = null;
-
- if (ownHandlerForOptimisticLocking){
- callback = function(errors){
- if (Array.isArray(errors) && errors.indexOf("optimistic-locking-exception") >= 0){
- let dialog = new Dialog("optimistic-locking-dialog", "optimistic-locking-dialog-title");
- dialog.addDefaultButton();
- dialog.show();
- }
- else
- {
- errorHandler(errors);
- }
- };
- }
- else
- {
- callback = errorHandler;
- }
- this.errorCallback = callback;
- }
-
- doSubmit() {
- if (!this.isBusy) {
- let self = this;
- return this.submit().then(function (res) {
- if (res["success"]) {
- if (self.submitCallback !== null) {
- return self.submitCallback(res["result"]);
- }
- }
- else if (Helper.isNotNull(self.errorCallback)) {
- return self.errorCallback(res["errors"]);
- }
- });
- }
- }
-
- load(url, isCached) {
- this.setValues(DataManager.load(url, isCached).then(function (values) {
- if (values["success"]) {
- return values["result"];
- }
- return {};
- }));
- return this;
- }
-
- setValues(valuePromise) {
- this.setIsBusy(true);
-
- let self = this;
- return Promise.resolve(valuePromise).then(function (values) {
- self.setIsBusy(false);
- for (let k in values) {
- if (Helper.isNotNull(self.formElem.elements[k])) {
- if (Helper.isNotNull(self.formElem.elements[k].options) && Helper.isNotNull(values[k+"Options"]))
- {
- let options = self.formElem.elements[k].options;
- for (let val in values[k+"Options"])
- {
- let option = document.createElement("option");
- option.value = val;
- option.innerText = values[k+"Options"][val];
- options.add(option);
- }
- }
-
- self.formElem.elements[k].value = Helper.htmlspecialcharsDecode(values[k]);
- if (Helper.isNotNull(values[k]) && (""+values[k]).trim() !== "") {
- self.formElem.elements[k].classList.add("notEmpty");
- }
- else {
- self.formElem.elements[k].classList.remove("notEmpty");
- }
- }
- }
- return self;
- });
- }
-
- async setErrors(errors) {
- let hasElem = false;
- let firstError = null;
-
- for (let k in errors) {
- if (Helper.isNotNull(this.formElem.elements[k]) && this.formElem.elements[k].type !== "hidden"
- && Helper.isNull(this.formElem.elements[k].readonly) && (
- Helper.isNull(this.formElem.elements[k].disabled) || !this.formElem.elements[k].disabled)
- ) {
- this.formElem.elements[k].setCustomValidity(Translator.translate(Helper.nonNull(errors[k], "form-default-error")));
- hasElem = true;
- }
- if (Helper.isNull(firstError)) {
- firstError = Helper.nonNull(errors[k], "form-default-error");
- }
- }
- if (!hasElem && Helper.isNotNull(firstError)) {
- for (let k in this.formElem.elements) {
- if (this.formElem.elements[k].type !== "hidden") {
- this.formElem.elements[k].setCustomValidity(Translator.translate(firstError));
- hasElem = true;
- break;
- }
- }
- }
-
- if (hasElem) {
- this.formElem.querySelector("input[type=submit]").click();
- }
- }
-
- setIsBusy(isBusy) {
- this.isBusy = isBusy;
- if (this.isBusy) {
- this.formElem.classList.add("sending");
- }
- else {
- this.formElem.classList.remove("sending");
- }
- }
-
- submit() {
- let self = this;
- return new Promise(function (resolve) {
- self.setIsBusy(true);
- let values = new FormData(self.formElem);
- resolve(self.submitHandler(values));
- }).then(function (data) {
- self.setIsBusy(false);
- return data;
- });
- }
-
- onSubmit(callback) {
- this.submitCallback = callback;
- }
-}
-
-class SettingsManager {
- static getInstance() {
- if (SettingsManager._instance === null) {
- SettingsManager._instance = new SettingsManager();
- }
- return SettingsManager._instance;
- }
-
- constructor() {
- this._settings = null;
- this._localStorageKey = "settings";
- }
-
- getSettings() {
- if (Helper.isNull(this._settings)) {
- this._loadSettings();
- }
- return this._settings;
- }
-
- getSetting(name, defaultValue) {
- const settings = this.getSettings();
-
- if (Helper.isNotNull(settings[name])) {
- return settings[name].value;
- }
- else {
- return defaultValue;
- }
- }
-
- deleteSetting(name) {
- this.getSettings();
- delete this._settings[name];
- this._saveSettings();
- }
-
- setSetting(name, value) {
- this.getSettings();
- this._settings[name] = {
- date: new Date().getTime(),
- value: value
- };
- this._saveSettings();
- }
-
- setSettings(settingsObject) {
- this.getSettings();
- for (const k in settingsObject) {
- this._settings[k] = settingsObject[k];
- }
- this._saveSettings();
- }
-
- hasSetting(name)
- {
- return Helper.nonNull(this._settings[name]);
- }
-
- _loadSettings() {
- this._settings = localStorage.getItem(this._localStorageKey);
- console.log("settings", this._settings);
- if (this._settings === null) {
- this._settings = {};
- }
- else {
- this._settings = JSON.parse(this._settings);
- }
- }
-
- _saveSettings() {
- if (this._settings !== null) {
- localStorage.setItem(this._localStorageKey, JSON.stringify(this._settings));
- }
- }
-}
-
-SettingsManager._instance = null;
-
-class LocalStorageSettingsFragment extends Fragment {
- onFirstStart() {
- let res = super.onFirstStart();
- let settings = this.findBy(".setting", true);
- const settingsManager = SettingsManager.getInstance();
-
- for (let i = 0; i < settings.length; i++) {
- let setting = settings[i];
- const name = setting.name;
- let value;
- if (!setting["dataset"]["raw"]) {
- value = settingsManager.getSetting(name);
- } else {
- value = localStorage.getItem(name);
- }
-
- let isCheckable = false;
- if (setting instanceof HTMLInputElement && (setting.type === 'checkbox' || setting.type === 'radio')) {
- isCheckable = true;
- }
- if (((!setting["dataset"]["raw"] && !settingsManager.hasSetting(name)) || (setting["dataset"]["raw"] && value === null))
- && Helper.isNotNull(settings[i]["dataset"]["default"])) {
- value = setting["dataset"]["default"];
- if (Helper.isNotNull(setting["dataset"]["defaultTranslateable"])) {
-
- setting["dataset"]["translation"] = "";
- setting["dataset"]["translationValue"] = value;
- value = Translator.translate(value);
- }
- }
-
- if (Helper.isNotNull(value)) {
- if (isCheckable) {
- setting.checked = (value === setting.value);
- }
- else {
- setting.value = value;
- }
- if (value !== "") {
- setting.classList.add("notEmpty");
- }
- }
-
- setting.addEventListener("change", function () {
- let value = this.value;
- if (isCheckable && !this.checked) {
- value = null;
- }
- if (!setting["dataset"]["raw"]) {
- settingsManager.setSetting(name, value);
- } else {
- localStorage.setItem(name, value);
- }
- delete setting["dataset"]["translationValue"];
- delete setting["dataset"]["translation"];
- });
- }
- return res;
- }
-
- onStart() {
- let res = super.onStart();
- let settings = this.findBy(".setting", true);
- const settingsManager = SettingsManager.getInstance();
-
- for (let i = 0; i < settings.length; i++) {
- let setting = settings[i];
- const name = setting.name;
- let value;
- if (!setting["dataset"]["raw"]) {
- value = settingsManager.getSetting(name);
- } else {
- value = localStorage.getItem(name);
- }
-
- let isCheckable = false;
- if (setting instanceof HTMLInputElement && (setting.type === 'checkbox' || setting.type === 'radio')) {
- isCheckable = true;
- }
-
- if (Helper.isNotNull(value)) {
- if (isCheckable) {
- setting.checked = (value === setting.value);
- }
- else {
- setting.value = value;
- }
- if (value !== "") {
- setting.classList.add("notEmpty");
- }
- }
- }
- return res;
- }
-}
-
-class SmartColumn{
- constructor(name, label, translateable){
- this._name = name;
- this._label = label;
- this._translateable = Helper.nonNull(translateable, true);
- this._sortable = true;
-
- this._index = -1;
-
- this._clickListener = null;
- }
-
- setClickListener(listener)
- {
- this._clickListener = listener;
- return this;
- }
-
- setIndex(index)
- {
- this._index = index;
- }
-
- getName()
- {
- return this._name;
- }
-
- getLabel()
- {
- return this._label;
- }
-
- getHeadElement()
- {
- const headElement = document.createElement("th");
- headElement.appendChild((this._translateable)?Translator.makePersistentTranslation(this._label):document.createTextNode(this._label));
-
- if (this._sortable)
- {
- headElement.classList.add("sort");
- headElement["dataset"]["sort"] = this._name;
- }
-
- headElement["dataset"]["column"] = this._index;
-
- this._headElement = headElement;
- return this._headElement;
- }
-
- getValueName(){
- return this._name;
- }
-
- prepareData(myData, rowData)
- {
- return myData;
- }
-
- getItemElement(){
- const element = document.createElement("td");
- element.classList.add(this._name);
- element["dataset"]["column"] = this._index;
-
- if (Helper.isNotNull(this._clickListener))
- {
- element.classList.add("clickable");
- }
-
- return element;
- }
-
- click(tableCell, table, event){
- if (Helper.isNotNull(this._clickListener))
- {
- this._clickListener(tableCell, table, event);
- }
- }
-}
-
-class ImgSmartColumn extends SmartColumn{
- getValueName() {
- return {
- "name":this._name,
- "attr":"src"
- };
- }
-
- getItemElement() {
- const element = super.getItemElement();
- element.classList.remove(this._name);
-
- const imgElement = document.createElement("img");
- imgElement.classList.add(this._name);
-
- element.appendChild(imgElement);
- return element;
- }
-}
-
-class AliasImgSmartColumn extends ImgSmartColumn{
- constructor(name, label, translatable, aliases) {
-
- if (typeof translatable === 'object' && Helper.isNull(aliases))
- {
- aliases = translatable;
- translatable = null;
- }
-
- super(name, label, translatable);
- this.aliases = aliases;
- this.reverseAliases = Helper.invertKeyValues(aliases);
- }
-
- prepareData(myData)
- {
- if (Helper.isNotNull(this.aliases[myData]))
- {
- return this.aliases[myData];
- }
- return myData;
- }
-
- getAlias(value)
- {
- if (Helper.isNotNull(this.reverseAliases[value]))
- {
- return this.reverseAliases[value];
- }
- return null;
- }
-}
-
-class ConstSmartColumn extends SmartColumn{
- constructor(name, label, translatable, valueTranslatable) {
- super(name, label, translatable);
- this._sortable = false;
- this._valueTranslatable = Helper.nonNull(valueTranslatable, false);
- }
-
- getValueName() {
- return null;
- }
-
- getItemElement(){
- const element = super.getItemElement();
- element.classList.remove(this._name);
- element.appendChild((this._valueTranslatable)?Translator.makePersistentTranslation(this._name):document.createTextNode(this._name));
- return element;
- }
-}
-
-class DataSmartColumn extends SmartColumn{
- constructor(name, label, translateable) {
- translateable = Helper.nonNull(translateable, false);
- super(name, label, translateable);
- }
-
- getHeadElement() {
- return document.createTextNode("");
- }
-
- getValueName() {
- return {
- "data":[this._name]
- };
- }
-
- getItemElement() {
- return document.createTextNode("");
- }
-}
-
-class ImgConstSmartColumn extends ConstSmartColumn{
- constructor(name, label, translateable) {
- super(name, label, translateable);
- this._valueTranslatable = false;
- }
-
- getItemElement() {
- const element = super.getItemElement();
- const imgElement = document.createElement("img");
- imgElement["src"] = this._name;
-
- element.removeAllChildren().appendChild(imgElement);
- return element;
- }
-}
-
-class ListHelper {
- constructor(id, options, values) {
- this._tableElement = id;
- this._options = Helper.nonNull(options, {});
- this._values = values;
-
- if (typeof this._tableElement === "string") {
- this._tableElement = document.getElementById(this._tableElement);
- }
-
- this._columns = [];
- if (Array.isArray(options)) {
- this._columns = options;
- }
- else if (Helper.isNotNull(options["columns"])) {
- this._columns = options["columns"];
- }
- }
-
- prepareData(data) {
- console.log("prepareData", data);
- if (Helper.isNotNull(data)) {
- for (let i = 0, n = data.length; i < n; i++) {
- data[i] = this.prepareDataset(data[i]);
- }
- }
- return data;
- }
-
- prepareDataset(dataset) {
- console.log("prepareDataset", dataset);
- for (let i = 0, n = this._columns.length; i < n; i++) {
- if (Helper.isNotNull(dataset[this._columns[i].getName()])) {
- dataset[this._columns[i].getName()] = this._columns[i].prepareData(dataset[this._columns[i].getName()], dataset);
- }
- }
- return dataset;
- }
-
- createTable() {
- if (Helper.isNotNull(this._columns)) {
- this.updateColumns();
- }
-
- let id = this._tableElement;
- let options = this._options;
- let values = this._values;
-
- options["item"] = Helper.nonNull(options["item"], id["id"] + "-template-item");
- options["page"] = Helper.nonNull(options["page"], 5);
- options["pagination"] = Helper.nonNull(options["pagination"], {
- "outerWindow": 1,
- "innerWindow": 1
- });
-
- let template = document.getElementById(options["item"]);
- if (template) {
- options["item"] = template.outerHTML;
- template.remove();
- }
-
- values = this.prepareData(values);
-
- const list = new List(id, options, values);
- let self = this;
- id.querySelector("." + Helper.nonNull(options["listClass"], "list")).addEventListener("click", function (e) {
- let columnElem = e.target.closest("td[data-column]");
- const column = parseInt(columnElem["dataset"]["column"]);
- if (self._columns.length > column) {
- self._columns[column].click(columnElem, list, e);
- }
- });
- this.list = list;
-
- return list;
- }
-
- updateColumns() {
- const head = document.createElement("tr");
- const item = document.createElement("tr");
- const valueNames = [];
-
- for (let i = 0, n = this._columns.length; i < n; i++) {
- this._columns[i].setIndex(i);
-
- head.appendChild(this._columns[i].getHeadElement());
- item.appendChild(this._columns[i].getItemElement());
-
- const valueName = this._columns[i].getValueName();
- if (Helper.isNotNull(valueName)) {
- valueNames.push(valueName);
- }
- }
- const header = this._tableElement.querySelector("thead");
- const footer = this._tableElement.querySelector("tfoot");
-
- if (Helper.isNotNull(header)) {
- header.removeAllChildren().appendChild(head);
- }
- if (Helper.isNotNull(footer)) {
- footer.removeAllChildren().appendChild(Helper.cloneNode(head));
- }
-
-
- this._options["item"] = item.outerHTML;
- this._options["valueNames"] = valueNames;
- }
-
- getList() {
- return this.list;
- }
-
- updateItem(valueName, value, newValues) {
- const items = this.list.get(valueName, value);
- if (Helper.isNotNull(items) && items.length >= 1) {
- newValues = this.prepareDataset(newValues);
- items[0].values(newValues);
- }
- }
-
- setBusy(isBusy) {
- if (isBusy) {
- this._tableElement.classList.add("sending");
- }
- else {
- this._tableElement.classList.remove("sending");
- }
- }
-}
-
-class ChooseThemeDialog extends Dialog {
-
- constructor() {
- let viewPromise = ViewInflater.inflate("core/html/dialog/chooseTheme.html").then(view => {
-
- let template = view.querySelector("#choose-theme-template");
- template.remove();
- template.id = null;
-
- let themeTemplateContainer = view.querySelector("#theme-choose-container");
-
- for (let i = 0; i < ThemeManager.themes.length; i++) {
- let themeElem = Helper.cloneNode(template);
- let theme = ThemeManager.themes[i];
- themeElem.querySelector(".name").appendChild(Translator.makePersistentTranslation(theme._name));
- themeElem["dataset"]["theme"] = theme._name;
-
- themeElem.addEventListener("click", () => {
- this.result = themeElem["dataset"]["theme"];
- this.close();
- });
- themeTemplateContainer.appendChild(themeElem);
- }
-
- return view;
- });
-
- super(viewPromise, "choose-theme-dialog-title");
- }
-}
-
-class SettingsSite extends AbstractSite {
- constructor(siteManager) {
- super(siteManager, SettingsSite.template, "settings");
- for (let k in SettingsSite.settingsFragments) {
- this.addSettingsFragment(k, new SettingsSite.settingsFragments[k](this));
- }
- this.active = null;
- }
-
- addSettingsFragment(name, settingsFragment) {
- this.addFragment("#settings-fragments", settingsFragment);
- delete this.fragments["#settings-fragments"];
- this.fragments[name] = settingsFragment;
- }
-
- onStart() {
- let res = super.onStart();
- if (Helper.isNotNull(this.active) && !this.fragments[this.active].isActive()) {
- this.setActive(null);
- }
-
- this.buildList();
- return res;
- }
-
- setActive(name) {
- if (Helper.isNotNull(this.active)) {
- this.fragments[this.active].inflatePromise.then(function (view) {
- view.classList.remove("active");
- });
- this.findBy("#show-fragment-" + this.active).classList.remove("active");
- }
- this.active = name;
- if (Helper.isNotNull(this.active)) {
- this.fragments[this.active].inflatePromise.then(function (view) {
- view.classList.add("active");
- });
- this.findBy("#show-fragment-" + this.active).classList.add("active");
- }
- }
-
- buildList() {
- let listNameElem = this.findBy("#settings-fragment-list");
- listNameElem.removeAllChildren();
-
- let self = this;
- for (let k in this.fragments) {
- if (this.fragments[k].isActive()) {
-
- let liElement = document.createElement("li");
- liElement.id = "show-fragment-" + k;
- liElement.appendChild(Translator.makePersistentTranslation(k, null, "a"));
- liElement.addEventListener("click", function () {
- self.setActive(k);
- });
- listNameElem.appendChild(liElement);
-
- if (Helper.isNull(this.active)) {
- this.setActive(k);
- }
- }
- }
- }
-
- static addSettingsFragment(name, settingsFragment) {
- SettingsSite.settingsFragments[name] = settingsFragment;
- }
-
- static setAddSettingsSite(addLink) {
- SettingsSite.shouldAddSettingsSite = addLink;
- }
-
- static setTemplate(template) {
- SettingsSite.template = template;
- }
-}
-
-SettingsSite.template = 'core/html/settings.html';
-SettingsSite.settingsFragments = {};
-SettingsSite.shouldAddSettingsSite = true;
-SettingsSite.settingsAction = null;
-SettingsSite.shouldAddSettingsAction = true;
-
-InitPromise.addPromise(function (app) {
- if (SettingsSite.shouldAddSettingsSite) {
- app.addDeepLink("settings", SettingsSite);
-
- if (Helper.isNull(SettingsSite.settingsAction)) {
- let settingsAction = new MenuAction("settings", async () => {
- let currentSite = app.getCurrentSite();
- if (currentSite instanceof SettingsSite) {
- currentSite.finish();
- }
- else {
- let settingsSite = await app.findSite((site) => {
- return (site instanceof SettingsSite);
- });
- if (Helper.isNotNull(settingsSite)) {
- settingsSite.toForeground();
- }
- else {
- app.startSite(SettingsSite);
- }
- }
- }, MenuAction.SHOW_FOR_LARGE, 10000);
- settingsAction.setIcon("img/settings.png");
- SettingsSite.settingsAction = settingsAction;
- }
- if (SettingsSite.shouldAddSettingsAction) {
- app.addDefaultAction(SettingsSite.settingsAction);
- }
- }
-});
-
-class GeneralSettingsFragment extends LocalStorageSettingsFragment {
-
- constructor(site) {
- super(site, "core/html/fragment/generalSettingsFragment.html");
- }
-
- onFirstStart() {
- this.addThemeListener();
- return super.onFirstStart();
- }
-
- addThemeListener(){
- let currentThemeName = ThemeManager$1.currentTheme._name;
- SettingsManager.getInstance().setSetting("theme", currentThemeName);
-
- let themeNameElem = this.findBy("#theme-name");
- themeNameElem.removeAllChildren().appendChild(Translator.makePersistentTranslation(currentThemeName));
- this.findBy("#theme-chooser").addEventListener("click", async () => {
- let newTheme = await (new ChooseThemeDialog()).show();
- if (Helper.isNotNull(newTheme)) {
- SettingsManager.getInstance().setSetting("theme", newTheme);
- ThemeManager$1.changeCurrentTheme(newTheme);
- themeNameElem.removeAllChildren().appendChild(Translator.makePersistentTranslation(newTheme));
- }
- });
- }
-}
-
-GeneralSettingsFragment.addFragment = false;
-InitPromise.addPromise(function () {
- if (GeneralSettingsFragment.addFragment) {
- SettingsSite.addSettingsFragment("general-settings-fragment", GeneralSettingsFragment);
- }
-});
-
-export { ConditionAction, Constants, DataManager, Form, LocalStorageSettingsFragment, SettingsManager, AliasImgSmartColumn, ConstSmartColumn, DataSmartColumn, ImgConstSmartColumn, ImgSmartColumn, ListHelper, SmartColumn, ChooseThemeDialog, GeneralSettingsFragment, SettingsSite };
diff --git a/src/js/lib/pwa-cronjob.js b/src/js/lib/pwa-cronjob.js
deleted file mode 100755
index 8b13789..0000000
--- a/src/js/lib/pwa-cronjob.js
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/src/js/lib/pwa-lib.js b/src/js/lib/pwa-lib.js
deleted file mode 100755
index dedc5e6..0000000
--- a/src/js/lib/pwa-lib.js
+++ /dev/null
@@ -1,4515 +0,0 @@
-class InitPromise
-{
- static addPromise(promise)
- {
- if (typeof promise === 'function')
- {
- let func = promise;
- promise = InitPromise.mainPromise.then(function(app){
- return (func(app));
- });
- }
- InitPromise.promises.push(promise);
- }
-
- static resolve(app)
- {
- InitPromise.mainResolver(app);
- return InitPromise.mainPromise.then(function(){
- return Promise.all(InitPromise.promises);
- });
- }
-}
-
-InitPromise.promises = [];
-InitPromise.mainPromise = new Promise(function(resolver){
- InitPromise.mainResolver = resolver;
-});
-
-class AndroidBridge {
-
- static addDefinition(definition, object) {
- if (typeof definition !== "function") {
- if (typeof definition === "string"){
- let parts = definition.split(".");
- for (let i = parts.length-1; i >= 1; i--) {
- let newObject = {};
- newObject[parts[i]] = object;
- object = newObject;
- }
- definition = parts[0];
- // console.log("parts for", definition, parts, object);
- }
- let textDefinition = definition;
- definition = () => {
- // console.log("defining", textDefinition, object);
- window[textDefinition] = object;
- };
- }
- AndroidBridge.definitions.push(definition);
- }
-
- static applyDefinitions() {
- for (let i = 0; i < AndroidBridge.definitions.length; i++) {
- AndroidBridge.definitions[i]();
- }
- return Promise.resolve();
- }
-}
-
-AndroidBridge.definitions = [];
-AndroidBridge.addDefinition("InitPromise.addPromise", InitPromise.addPromise);
-
-class MenuAction {
- constructor(title, callback, showFor, order) {
- this.title = Helper.nonNull(title, null);
- this.callback = callback;
- this.showFor = Helper.nonNull(showFor, MenuAction.SHOW_FOR_MEDIUM);
- this.order = Helper.nonNull(order, 1000);
- this._liClass = "";
-
- this._menu = null;
- this._activated = true;
- this._visible = true;
- this.id = MenuAction.maxId++;
- this._icon = null;
- this._shouldTranslate = true;
- this._copies = [];
- }
-
- setTitle(title)
- {
- this.title = title;
- }
-
- setShouldTranslate(shouldTranslate)
- {
- this._shouldTranslate = shouldTranslate;
- }
-
- getShowFor(){
- return this.showFor;
- }
-
- getTitle()
- {
- return this.title;
- }
-
- getShouldTranslate()
- {
- return this._shouldTranslate;
- }
-
- remove(removeCopies) {
- removeCopies = Helper.nonNull(removeCopies, false);
- if (Helper.isNotNull(this._menu)) {
- console.log(this._menu);
- this._menu.removeAction(this);
- this._menu = null;
- }
- if (removeCopies)
- {
- for (let i = 0; i < this._copies.length; i++) {
- this._copies[i].remove();
- }
- }
- }
-
- getMenu() {
- return this._menu;
- }
-
- setMenu(value) {
- this._menu = value;
- }
-
- getVisible() {
- return this._visible;
- }
-
- setVisible(value) {
- if (value !== this._visible) {
- this._visible = value;
- this.redraw();
- }
- }
-
- getActivated() {
- return this._activated;
- }
-
- getIcon() {
- return this._icon;
- }
-
- setIcon(value) {
- this._icon = value;
- }
-
- getId()
- {
- return this.id;
- }
-
- redraw() {
- if (Helper.isNotNull(this._menu)) {
- this._menu.updateAction(this);
- }
- }
- copy(instance){
- let copy = Helper.nonNull(instance, new MenuAction());
- copy.title = this.title;
- copy.callback = this.callback;
- copy.showFor = this.showFor;
- copy.order = this.order;
- copy._liClass = this._liClass;
-
- copy._activated = this._activated;
- copy._visible = this._visible;
- copy._icon = this._icon;
- copy._shouldTranslate = this._shouldTranslate;
-
- copy._menu = null;
- copy.id = MenuAction.maxId++;
- this._copies.push(copy);
- return copy;
- }
-
- redrawMenu()
- {
- if (Helper.isNotNull(this._menu)) {
- this._menu.redraw();
- }
- }
-}
-MenuAction.maxId = 0;
-
-MenuAction.SHOW_ALWAYS = "always";
-MenuAction.SHOW_FOR_MEDIUM = "medium";
-MenuAction.SHOW_FOR_LARGE = "large";
-MenuAction.SHOW_NEVER = "never";
-
-class OpenSubmenuAction extends MenuAction {
- constructor(title, menu, showFor, order) {
- super(title, function (action) {
- action.getSubmenu().toggle();
- action.redraw();
- }, showFor, order);
-
- this.submenu = menu;
- menu.setParentAction(this);
- }
-
- getSubmenu() {
- return this.submenu;
- }
-
- copy(instance) {
- instance = super.copy(Helper.nonNull(instance, new OpenSubmenuAction(null, this.submenu.copy())));
- return instance;
- }
-}
-
-class Menu {
- constructor(parentElementSelector) {
- this.actions = [];
- this.submenus = [];
- if (typeof parentElementSelector === 'string') {
- this.parentElements = document.querySelectorAll(parentElementSelector);
- }
- else if (Array.isArray(parentElementSelector)) {
- this.parentElements = parentElementSelector;
- }
- else {
- this.parentElements = [parentElementSelector];
- }
- }
-
- copy(instance) {
- instance = Helper.nonNull(instance, new Menu([]));
-
- instance.actions = [];
- for (let i = 0, n = this.actions.length; i < n; i++) {
- instance.actions.push(this.actions[i].copy());
- }
-
- instance.submenus = [];
- for (let i = 0, n = this.submenus.length; i < n; i++) {
- instance.submenus.push(this.submenus[i].copy());
- }
-
- return instance;
- }
-
- addAction(action) {
- if (Helper.includesNot(this.actions, action)) {
- this.actions.push(action);
- this.redraw();
- action.setMenu(this);
- if (action instanceof OpenSubmenuAction) {
- this.submenus.push(action.getSubmenu());
- }
- }
- }
-
- draw() {
- if (Helper.isNotNull(this.parentElements)) {
- this.sortActions();
-
- let actionElements = [];
- for (let i = 0; i < this.actions.length; i++) {
- let element = this.renderAction(this.actions[i]);
- this.actions[i]._htmlElement = element;
- actionElements.push(element);
- }
- for (let i = 0, n = this.parentElements.length; i < n; i++) {
- this.parentElements[i].removeAllChildren();
- for (let i2 = 0, n2 = actionElements.length; i2 < n2; i2++) {
- this.parentElements[i].appendChild(Helper.cloneNode(actionElements[i2]));
- }
- this.parentElements[i].onclick = this._getOnClickListener();
- }
- }
- }
-
- _getOnClickListener() {
- let menu = this;
- return function (event) {
- let _element = event.target;
- if (_element.matches('.action') || _element.matches('.action *')) {
- // while (!_element.matches('.action > a')) {
- // _element = _element.parentNode;
- // }
- _element = _element.closest(".action");
- let actionId = parseInt(_element.dataset["id"]);
- for (let i = 0, n = menu.actions.length; i < n; i++) {
- if (menu.actions[i].id === actionId) {
- if (typeof menu.actions[i].callback === 'function' && menu.actions[i].getActivated()) {
- menu.actions[i].callback(menu.actions[i], event);
- }
- return menu.actions[i];
- }
- }
- for (let i = 0, n = menu.submenus.length; i < n; i++) {
- if (menu.submenus[i].click(actionId, event)) {
- return menu.submenus[i];
- }
- }
- }
- return null;
- };
- }
-
- /** @protected */
- renderAction(action) {
- let aElement = document.createElement("a");
- if (typeof action.callback === 'string') {
- aElement.href = action.callback;
- }
-
- if (Helper.isNotNull(action.getIcon())) {
- let iconElement = document.createElement("img");
- iconElement.src = action.getIcon();
- iconElement.classList.add('action-image');
- if (action.getShouldTranslate()) {
- iconElement.dataset["translationTitle"] = action.title;
- }
- aElement.appendChild(iconElement);
- }
- let title = action.getTitle();
- if (action.getShouldTranslate()) {
- title = Translator.makePersistentTranslation(title);
- }
- else {
- title = document.createTextNode(title);
- }
- aElement.appendChild(title);
-
- return this.renderLiElement(aElement, action)
- }
-
- /** @protected */
- renderLiElement(aElement, action) {
- let liElement = document.createElement("li");
- liElement.classList.add('action');
- if (action._liClass.trim() !== "") {
- liElement.classList.add(action._liClass);
- }
- liElement.appendChild(aElement);
- liElement.dataset["id"] = action.id;
- if (Helper.isNotNull(action.getIcon())) {
- liElement.classList.add("img");
- }
-
- if (!action.getVisible()) {
- liElement.classList.add("hidden");
- }
-
- if (action instanceof OpenSubmenuAction) {
- action.getSubmenu().draw();
- liElement.appendChild(action.getSubmenu().getParentElement());
- liElement.classList.add("is-dropdown-submenu-parent");
- liElement.classList.add("opens-right");
- }
- return liElement;
- }
-
- /** @private */
- sortActions() {
- this.actions = this.actions.sort(function (first, second) {
- return first.order - second.order;
- });
- }
-
- _getElementsForAction(action) {
- let elements = [];
- for (let i = 0; i < this.parentElements.length; i++) {
- let elem = this.parentElements[i].querySelector("[data-id=\"" + action.getId() + "\"]");
- Helper.isNull(elem) || elements.push(elem);
- }
- return elements
- }
-
- updateAction(action) {
- let oldElements = this._getElementsForAction(action);
- if (oldElements.length === 0) {
- return;
- }
-
- let element = this.renderAction(action);
- action._htmlElement = element;
-
- for (let i = 0; i < oldElements.length; i++) {
- oldElements[i].replaceWith(Helper.cloneNode(element));
- }
- }
-
- removeAction(action) {
- let index = this.actions.indexOf(action);
- if (index > 0) {
- this.actions.splice(index, 1);
- let oldElements = this._getElementsForAction(action);
- for (let i = 0, n = oldElements.length; i < n; i++) {
- oldElements[i].remove();
- }
- if (action instanceof OpenSubmenuAction) {
- let index = this.submenus.indexOf(action.getSubmenu());
- this.submenus.splice(index, 1);
- }
- }
- }
-
- redraw() {
- this.draw();
- }
-}
-
-Menu.SHOW_ALWAYS = "always";
-Menu.SHOW_FOR_MEDIUM = "medium";
-Menu.SHOW_FOR_SMEDIUM = "smedium";
-Menu.SHOW_FOR_LARGE = "large";
-Menu.SHOW_NEVER = "never";
-
-class Submenu extends Menu
-{
- constructor()
- {
- let menuElement = document.createElement("ul");
- menuElement.classList.add("menu");
- menuElement.classList.add("vertical");
- menuElement.classList.add("submenu");
- menuElement.classList.add("is-dropdown-submenu");
- menuElement.classList.add("first-sub");
- super(menuElement);
-
- this.parentAction = null;
- this.isOpen = false;
- }
-
-
-
- copy(instance)
- {
- instance = super.copy(Helper.nonNull(instance, new Submenu()));
- instance.parentElements = [];
- for (let i = 0, n = this.parentElements.length; i < n; i++) {
- instance.parentElements.push(Helper.cloneNode(this.parentElements[i]));
- }
- instance.parentAction = this.parentAction;
- instance.isOpen = this.isOpen;
- return instance;
- }
-
- setParentAction(action)
- {
- this.parentAction = action;
- }
-
- draw()
- {
- super.draw();
- if (Helper.isNotNull(this.parentElements))
- {
- let self = this;
- for (let i = 0; i < this.parentElements.length; i++) {
- let closeListener = document.createElement("div");
- closeListener.classList.add("close-listener");
- closeListener.onclick = function(e){
- console.log(e);
- self.close();
- };
- this.parentElements[i].insertBefore(closeListener, this.parentElements[i].firstElementChild);
- }
- }
- }
-
- getParentElement()
- {
- return this.parentElements[0];
- }
-
- _getOnClickListener()
- {
- return function () {};
- }
-
- click(actionId, event)
- {
- for (let i = 0, n = this.actions.length; i < n; i++) {
- if (this.actions[i].id === actionId)
- {
- if (typeof this.actions[i].callback === 'function' && this.actions[i].getActivated()) {
- this.actions[i].callback(this.actions[i], event);
- }
- this.close();
- return true;
- }
- }
- return false;
- }
-
- toggle()
- {
- if (this.isOpen)
- {
- this.close();
- }
- else
- {
- this.open();
- }
- }
-
- open()
- {
- this.isOpen = true;
- for (let i = 0, n = this.parentElements.length; i < n; i++) {
- this.parentElements[i].classList.add("js-dropdown-active");
- }
- if (Helper.isNotNull(this.parentAction))
- {
- this.parentAction.redraw();
- }
- }
- close()
- {
- this.isOpen = false;
- for (let i = 0, n = this.parentElements.length; i < n; i++) {
- this.parentElements[i].classList.remove("js-dropdown-active");
- }
- if (Helper.isNotNull(this.parentAction))
- {
- this.parentAction.redraw();
- }
- }
-}
-
-class TranslatorDB {
- constructor() {
- this._indexedDB = indexedDB || mozIndexedDB || webkitIndexedDB || msIndexedDB;
- this._version = 3;
-
- let self = this;
- this._dbPromise = new Promise(function (resolve, reject) {
- let request = self._indexedDB.open("Translator", self._version);
- request.onupgradeneeded = function (event) {
- let db = event.target.result;
- self._upgradeDb(db);
- };
- request.onsuccess = function (event) {
- let db = event.target.result;
- resolve(db);
- };
- request.onerror = function (event) {
- reject(event);
- };
- }).catch(function(e){
- console.error(e);
- });
- }
-
- _upgradeDb(db) {
- try {
- db.deleteObjectStore("currentLang");
- db.deleteObjectStore("translations");
- }
- catch (e) {
- console.warn(e);
- }
- let currentLangObjectStore = db.createObjectStore("currentLang", {"keyPath": "id"});
- let translationsObjectStore = db.createObjectStore("translations", {"keyPath": ["lang","key"]});
- translationsObjectStore.createIndex("lang", "lang", {"unique": false});
- }
-
- setLanguage(lang) {
- this._dbPromise.then(function (db) {
- let transaction = TranslatorDB._openTransaction(["currentLang"], "readwrite", db);
- let currentLangObjectStore = transaction.objectStore("currentLang");
- currentLangObjectStore.put({"id": 1, "lang": lang});
- }).catch(function(e){
- console.error(e);
- });
- }
-
- saveTranslationsForLang(lang, translations) {
- return this._dbPromise.then(function (db) {
- return new Promise(function (resolve) {
- let transaction = TranslatorDB._openTransaction(["translations"], "readwrite", db);
- let translationsObjectStore = transaction.objectStore("translations");
- for (let k in translations) {
- translationsObjectStore.put({"lang": lang, "key": k, "translation": translations[k]});
- }
- transaction.oncomplete = function () {
- resolve();
- };
- });
- }).catch(function(e){
- // console.error(e);
- });
- }
-
- loadTranslationsForLang(lang) {
- return this._dbPromise.then(function (db) {
- return new Promise(function (resolve) {
- let transaction = TranslatorDB._openTransaction(["translations"], "readonly", db);
- let translationsObjectStore = transaction.objectStore("translations");
- let index = translationsObjectStore.index("lang");
- let request = index.openCursor(IDBKeyRange.only(lang));
-
- let translations = {};
- request.onsuccess = function (e) {
- let cursor = e.target.result;
- if (cursor) {
-
- let translation = cursor.value;
- translations[translation["key"]] = translation["translation"];
- cursor.continue();
- }
- };
- transaction.oncomplete = function(){
- resolve(translations);
- };
- });
- }).catch(function(e){
- console.error(e);
- return {};
- });
- }
-
- getLanguage() {
- return this._dbPromise.then(function (db) {
- return new Promise(function (resolve) {
- let transaction = TranslatorDB._openTransaction(["currentLang"], "readonly", db);
- let currentLangObjectStore = transaction.objectStore("currentLang");
- let req = currentLangObjectStore.get(1);
- req.onsuccess = function (e) {
- let data = e.currentTarget.result;
- if (data)
- {
- resolve(data["lang"]);
- }
- else
- {
- resolve(null);
- }
- };
- req.onerror = function (e) {
- resolve(null);
- };
- });
- }).catch(function(e){
- // console.error(e);
- });
- }
-
- static _openTransaction(name, transactionMode, db) {
- let transaction = null;
- try {
- transaction = db.transaction(name, transactionMode);
- }
- catch (e) {
- console.warn(e);
- transaction = db.transaction(name);
- }
- return transaction;
- }
-}
-
-class Translator {
- constructor() {
- this._translations = [];
- this._db = new TranslatorDB();
- this._currentLanguage = null;
- this._supportedLanguages = Translator.supportedLanguages;
- this._baseLanguage = Translator.baseLanguage;
- this._languageBasePath = Translator.languageBasePath;
- this._markUntranslatedTranslations = Translator.markUntranslatedTranslations;
- this._markTranslations = Translator.markTranslations;
-
- let self = this;
- this._initPromise = this.loadBaseLanguage().then(function () {
- return self.loadUserLanguage();
- });
- }
-
- _loadLanguage(language) {
- let self = this;
- return fetch(Helper.basePath(this._languageBasePath + language + ".json")).then(function (result) {
- return result.json();
- }).then(function (res) {
- self._translations[language] = Object.assign(res, self._translations[language]);
- self._db.saveTranslationsForLang(language, self._translations[language]);
- }).catch(function (err) {
- console.error("could not load lang " + language + " because of error: ", err);
- });
- }
-
- loadBaseLanguage() {
- let self = this;
- return this._loadLanguage(this._baseLanguage).then(function () {
- self._currentLanguage = self._baseLanguage;
- if (typeof document !== 'undefined') {
- document.getElementsByTagName("html")[0].setAttribute("lang", self._baseLanguage);
- }
- });
- };
-
- static setLanguage(language) {
- let instance = Translator.getInstance();
- if (instance) {
- return instance.setLanguage(language);
- }
- }
-
- setLanguage(language) {
- if (this._currentLanguage === language) {
- this.updateTranslations();
- return Promise.resolve();
- }
-
- if (this._supportedLanguages.indexOf(language) === -1) {
- return Promise.resolve();
- }
-
- this._currentLanguage = language;
- if (typeof localStorage !== 'undefined') {
- localStorage.setItem("language", language);
- }
- this._db.setLanguage(language);
-
- let self = this;
- return this._loadLanguage(language).then(function () {
- if (typeof document !== 'undefined') {
- document.getElementsByTagName("html")[0].setAttribute("lang", language);
- }
- self.updateTranslations();
- });
- }
-
- static translate(key, args) {
- let instance = Translator.getInstance();
- if (instance) {
- return instance.translate(key, args);
- }
- return "";
- }
-
- translate(key, args) {
- if (typeof key === 'object' && Helper.isNotNull(key)) {
- key = this.addDynamicTranslation(key);
- }
-
- let translation = null;
- if (Helper.isNotNull(this._translations[this._currentLanguage]) && Helper.isNotNull(this._translations[this._currentLanguage][key])) {
- translation = this._translations[this._currentLanguage][key];
- }
-
- if (Helper.isNull(translation)) {
- if (Translator.logMissingTranslations) {
- console.warn("missing translation for language " + this._currentLanguage + " and key " + key);
- }
- if (Helper.isNotNull(this._translations[this._baseLanguage])) {
- translation = this._translations[this._baseLanguage][key];
- }
-
- if (Helper.isNull(translation)) {
- if (Translator.logMissingTranslations) {
- console.error("missing base translation for key " + key + ". FIX IT");
- }
- translation = key;
- }
- if (this._markUntranslatedTranslations) {
- translation = ">>" + translation + "<<";
- }
- }
-
- if (this._markTranslations) {
- translation = "$" + translation + "$";
- }
-
- if (args !== undefined) {
- translation = translation.format(args);
- }
-
- return translation;
- }
-
- static addDynamicTranslation(trans) {
- let instance = Translator.getInstance();
- if (instance) {
- return instance.addDynamicTranslation(trans);
- }
- }
-
- addDynamicTranslation(trans) {
- let key = trans["key"];
- delete trans["key"];
- for (let lang in trans) {
- if (trans.hasOwnProperty(lang)) {
- if (Helper.isNull(this._translations[lang])) {
- this._translations[lang] = {};
- }
- this._translations[lang][key] = trans[lang];
- }
- }
- return key;
- }
-
- updateTranslations() {
- if (typeof document !== 'undefined') {
- let elements = document.querySelectorAll("[data-translation]");
- for (let i = 0, max = elements.length; i < max; i++) {
- if (elements[i].dataset["translation"] != "") {
- try {
- elements[i].innerHTML = this.translate(elements[i].dataset["translation"], (elements[i].dataset["translationArgs"] !== undefined) ? JSON.parse(elements[i].dataset["translationArgs"]) : undefined);
- }
- catch (err) {
- console.error("wrong configured translation: " + err);
- }
- }
- for (let k in elements[i].dataset) {
- if (k.startsWith("translation") && !k.endsWith("Args")) {
- try {
- elements[i][k.substr(11).toLowerCase()] = this.translate(elements[i].dataset[k], (elements[i].dataset[k + "Args"] !== undefined) ? JSON.parse(elements[i].dataset[k + "Args"]) : undefined);
- }
- catch (err) {
- console.error("wrong configured translation: " + err);
- }
- }
- }
- }
- }
- }
-
- loadUserLanguage() {
- let userLanguage = localStorage.getItem("language");
- if (Helper.isNull(userLanguage) || this._supportedLanguages.indexOf(userLanguage) === -1) {
- let userLanguages = [];
- if (Helper.isNotNull(navigator.languages)) {
- userLanguages = navigator.languages.slice(0); //.slice(0) klont das Array. Behebt einen Bug in Firefox
- }
-
- if (navigator.language !== undefined) {
- userLanguages.push(navigator.language);
- }
- //sicherstellen, dass überhaupt eine Sprache gefunden wird
- userLanguages.push(this._baseLanguage);
-
- if (userLanguages !== undefined) {
- for (let i = 0, numLanguages = userLanguages.length; i < numLanguages; i++) {
- if (this._supportedLanguages.indexOf(userLanguages[i]) !== -1) {
- userLanguage = userLanguages[i];
- break;
- }
- }
- }
- }
- return this.setLanguage(userLanguage.toLowerCase())
- }
-
- static makePersistentTranslation(key, args, tag) {
- tag = Helper.nonNull(tag, "span");
- if (typeof key === 'object') {
- key = Translator.addDynamicTranslation(key);
- }
-
- if (typeof document !== 'undefined') {
- let htmlElem = document.createElement(tag);
- htmlElem.dataset["translation"] = key;
- if (args !== undefined) {
- htmlElem.dataset["translationArgs"] = JSON.stringify(args);
- }
- htmlElem.innerHTML = Translator.translate(key, args);
- return htmlElem;
- }
- }
-
- static generateChangeLanguageMenuAction() {
- let submenu = new Submenu();
- submenu.addAction(new MenuAction("en", function () {
- Translator.getInstance().setLanguage("en");
- }));
- submenu.addAction(new MenuAction("de", function () {
- Translator.getInstance().setLanguage("de");
- }));
- return new OpenSubmenuAction("current-lang", submenu, Menu.SHOW_ALWAYS)
- }
-
- static init() {
- Translator.instance = new Translator();
- // Translator.loadBaseLanguage().then(function () {
- // Translator.loadUserLanguage();
- // });
- }
-
- static getInstance() {
- return Translator.instance;
- }
-}
-Translator.logMissingTranslations = false;
-
-Translator.instance = null;
-
-Translator.baseLanguage = "en";
-Translator.supportedLanguages = [
- "de",
- "en"
-];
-Translator.markUntranslatedTranslations = true;
-Translator.markTranslations = false;
-Translator.languageBasePath = "js/lang/";
-Translator.currentLanguage = null;
-Translator.translations = {};
-
-
-AndroidBridge.addDefinition("Translator.setLanguage", Translator.setLanguage);
-
-class Helper {
- static init() {
- Helper.heightMmToPxFactor = null;
- Helper.widthMmToPxFactor = null;
- }
-
- static includesNot(array, value, fromIndex) {
- return -1 === array.indexOf(value, fromIndex);
- }
-
- static includes(array, value, fromIndex) {
- return !Helper.includesNot(array, value, fromIndex);
- }
-
- static isSet() {
- if (arguments.length > 0) {
- const object = arguments[0];
- let keys = Array.prototype.slice.call(arguments, 1);
- return (Helper.isNotNull(object) && (keys.length === 0 || Helper.isSet.apply(null, [object[keys[0]]].concat(keys.slice(1)))));
- }
- return false;
- }
-
- static isNull(variable) {
- return (variable === null || variable === undefined);
- }
-
- static isNotNull(variable) {
- return !Helper.isNull(variable);
- }
-
- static nonNull(val1, val2) {
- for (let i = 0; i < arguments.length; i++) {
- if (Helper.isNotNull(arguments[i])) {
- return arguments[i];
- }
- }
- return null;
- }
-
- static notEmpty(value) {
- return !Helper.empty(value);
- }
-
- static buildQuery(values) {
- let queryStrings = [];
- for (let k in values) {
- queryStrings.push(encodeURIComponent(k) + "=" + encodeURIComponent(values[k]));
- }
- return "?" + queryStrings.join("&");
- }
-
- static empty(value) {
- return (Helper.isNull(value) || (typeof value === 'string' && value.trim() === ""))
- }
-
- static inflateElementsFromString(string) {
- let template = document.createElement('template');
- template.innerHTML = string;
- return template.content.childNodes;
- }
-
- static createLoadingSymbol() {
- let svgNS = "http://www.w3.org/2000/svg";
-
- let loader = document.createElement("div");
- loader.className = 'loader';
-
- let svg = document.createElementNS(svgNS, "svg");
- svg.setAttribute('viewBox', "0 0 32 32");
- svg.setAttribute("widh", "32");
- svg.setAttribute("height", "32");
-
- let circle = document.createElementNS(svgNS, "circle");
- circle.setAttribute("id", "spinner");
- circle.setAttribute("cx", "16");
- circle.setAttribute("cy", "16");
- circle.setAttribute("r", "14");
- circle.setAttribute("fill", "none");
-
- svg.appendChild(circle);
- loader.appendChild(svg);
-
- return loader;
- }
-
- static basePath(url) {
- return SystemSettings.getBasePath() + url;
- }
-
- static isMobileApple() {
- return navigator.userAgent.match(/iPhone|iPad|iPod/i);
- }
-
- static isMobile() {
- return (navigator.userAgent.match(/Android|BlackBerry|Opera Mini|IEMobile/i) !== null || Helper.isMobileApple() || (typeof window.orientation !== "undefined" || window.orientation === false || window.orientation === null));
- }
-
- static select(e) {
- let range = document.createRange();
- range.selectNodeContents(e);
- let sel = window.getSelection();
- sel.removeAllRanges();
- sel.addRange(range);
- }
-
- static format(number, leadingZeros) {
- number = "" + number;
- while (number.length < leadingZeros) {
- number = "0" + number;
- }
- return number;
- }
-
- static cloneNode(srcNode) {
- let destNode = srcNode.cloneNode(true);
- destNode.onclick = srcNode.onclick;
- return destNode;
- }
-
- static encodeToBase(stringToEncode, base) {
- let encodedString = "";
- let charlength = Math.floor(Math.log(265) / Math.log(base));
- for (let i = 0; i < stringToEncode.length; i++) {
- let value = stringToEncode.charCodeAt(i).toString(base);
- let joinLength = value.length % charlength;
- if (joinLength > 0) {
- let joinArray = new Array(charlength + 1 - (joinLength)); //+1, da join nur zwischen elemente einfügt
- value = joinArray.join("0") + value;
- }
- encodedString += value;
- }
- return encodedString;
- }
-
- static decodeToBase(stringToDecode, base) {
- let charlength = Math.floor(Math.log(265) / Math.log(base));
- let values = stringToDecode.match(new RegExp(".{1," + charlength + "}", "g")) || [];
- let encodedString = "";
- for (let i = 0, n = values.length; i < n; i++) {
- encodedString += String.fromCharCode(parseInt(values[i], base));
- }
- return encodedString;
- }
-
- static toggleVisibility(elem) {
- if (elem.style.display === "none") {
- elem.style.display = "";
- return true;
- }
- else {
- elem.style.display = "none";
- return false;
- }
- }
-
- static print(content) {
- let printContent = document.getElementById("print-content");
- if (content instanceof Element) {
- printContent.removeAllChildren();
- printContent.appendChild(content);
- }
- else {
- printContent.innerHTML = content;
- }
- window.print();
- }
-
- static strftime(sFormat, date, useUTC) {
- if (!(date instanceof Date)) date = new Date(date);
- useUTC = Helper.nonNull(useUTC, false);
- let nDay = (useUTC) ? date.getUTCDay() : date.getDay(),
- nDate = (useUTC) ? date.getUTCDate() : date.getDate(),
- nMonth = (useUTC) ? date.getUTCMonth() : date.getMonth(),
- nYear = (useUTC) ? date.getUTCFullYear() : date.getFullYear(),
- nHour = (useUTC) ? date.getUTCHours() : date.getHours(),
- aDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
- aMonths = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
- aDayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
- isLeapYear = function () {
- if ((nYear & 3) !== 0) return false;
- return nYear % 100 !== 0 || nYear % 400 === 0;
- },
- getThursday = function () {
- let target = new Date(date);
- target.setDate(nDate - ((nDay + 6) % 7) + 3);
- return target;
- },
- zeroPad = function (nNum, nPad) {
- return ('' + (Math.pow(10, nPad) + nNum)).slice(1);
- };
-
- return sFormat.replace(/%[a-z]/gi, function (sMatch) {
- return {
- '%a': Translator.makePersistentTranslation(aDays[nDay].slice(0, 3)).outerHTML,
- '%A': Translator.makePersistentTranslation(aDays[nDay]).outerHTML,
- '%b': Translator.makePersistentTranslation(aMonths[nMonth].slice(0, 3)).outerHTML,
- '%B': Translator.makePersistentTranslation(aMonths[nMonth]).outerHTML,
- '%c': date.toUTCString(),
- '%C': Math.floor(nYear / 100),
- '%d': zeroPad(nDate, 2),
- '%e': nDate,
- '%f': zeroPad(date.getTime() % 1000, 4),
- '%F': date.toISOString().slice(0, 10),
- '%G': getThursday().getFullYear(),
- '%g': ('' + getThursday().getFullYear()).slice(2),
- '%H': zeroPad(nHour, 2),
- '%I': zeroPad((nHour + 11) % 12 + 1, 2),
- '%j': zeroPad(aDayCount[nMonth] + nDate + ((nMonth > 1 && isLeapYear()) ? 1 : 0), 3),
- '%k': '' + nHour,
- '%l': (nHour + 11) % 12 + 1,
- '%m': zeroPad(nMonth + 1, 2),
- '%M': zeroPad(date.getMinutes(), 2),
- '%p': (nHour < 12) ? 'AM' : 'PM',
- '%P': (nHour < 12) ? 'am' : 'pm',
- '%s': Math.round(date.getTime() / 1000),
- '%S': zeroPad(date.getSeconds(), 2),
- '%u': nDay || 7,
- '%V': (function () {
- let target = getThursday(),
- n1stThu = target.valueOf();
- target.setMonth(0, 1);
- let nJan1 = target.getDay();
- if (nJan1 !== 4) target.setMonth(0, 1 + ((4 - nJan1) + 7) % 7);
- return zeroPad(1 + Math.ceil((n1stThu - target) / 604800000), 2);
- })(),
- '%w': '' + nDay,
- '%x': date.toLocaleDateString(),
- '%X': date.toLocaleTimeString(),
- '%y': ('' + nYear).slice(2),
- '%Y': nYear,
- '%z': date.toTimeString().replace(/.+GMT([+-]\d+).+/, '$1'),
- '%Z': date.toTimeString().replace(/.+\((.+?)\)$/, '$1')
- }[sMatch] || sMatch;
- });
- }
-
- static cloneJson(obj) {
- // https://stackoverflow.com/questions/4120475/how-to-create-and-clone-a-json-object/17502990#17502990
- let i;
-
- // basic type deep copy
- if (Helper.isNull(obj) || typeof obj !== 'object') {
- return obj
- }
- // array deep copy
- if (obj instanceof Array) {
- let cloneA = [];
- for (i = 0; i < obj.length; ++i) {
- cloneA[i] = Helper.cloneJson(obj[i]);
- }
- return cloneA;
- }
- if (obj instanceof Date)
- {
- return new Date(obj.getTime());
- }
- // object deep copy
- let cloneO = {};
- for (i in obj) {
- cloneO[i] = Helper.cloneJson(obj[i]);
- }
- return cloneO;
- }
-
- static htmlspecialcharsDecode(text) {
- const map = {
- '&': '&',
- '&': "&",
- '<': '<',
- '>': '>',
- '"': '"',
- ''': "'",
- '’': "’",
- '‘': "‘",
- '–': "–",
- '—': "—",
- '…': "…",
- '”': '”'
- };
-
- if (Helper.isNotNull(text) && typeof text.replace === "function") {
- return text.replace(/\&[\w\d\#]{2,5}\;/g, function (m) {
- return map[m];
- });
- }
- return text;
- }
-
- static formDataFromObject(obj) {
- let formData = new FormData();
- for (let k in obj) {
- formData.set(k, obj[k]);
- }
- return formData;
- }
-
- static scaleContentRecursive(element, content) {
-
- let elementStyle = window.getComputedStyle(element);
- let contentStyle = window.getComputedStyle(content);
-
- if (contentStyle.height > elementStyle.height || contentStyle.width > elementStyle.width) {
- return Helper.scaleDownContentRecursive(element, content);
- }
- }
-
- static scaleDownContentRecursive(element, content) {
- Helper.convertChildrenToRelativeRecursive(element);
-
- let elementStyle = window.getComputedStyle(element);
- let contentStyle = window.getComputedStyle(content);
-
- let runs = 0;
- let fontSize = parseFloat(contentStyle.getPropertyValue("font-size"));
- let width = contentStyle.width;
- let height = contentStyle.height;
- while (contentStyle.height > elementStyle.height || contentStyle.width > elementStyle.width) {
- fontSize *= 0.95;
-
- if (height > elementStyle.height) {
- height *= 0.95;
- }
- if (width > contentStyle.width) {
- width *= 0.95;
- }
- content.style["font-size"] = fontSize + "px";
- content.style["max-height"] = height + "px";
- content.style["max-width"] = width + "px";
-
- runs++;
- if (runs > 2000) {
- console.log("breaked");
- break;
- }
- }
- Helper.convertToRelative(content);
-
- contentStyle = window.getComputedStyle(content);
- content.style["font-size"] = (parseFloat(contentStyle.getPropertyValue("font-size")) / parseFloat(document.documentElement.clientHeight) * 100) + "vh";
- }
-
- static convertChildrenToRelativeRecursive(element) {
- let children = element.childNodes;
- for (let i = 0, n = children.length; i < n; i++) {
- if (children[i] instanceof Element) {
- Helper.convertToRelative(children[i]);
- Helper.convertChildrenToRelativeRecursive(children[i]);
- }
- }
- }
-
- static convertToRelative(element) {
- let hasTransitionClass = (element.classList.contains("no-transtition"));
-
- element.classList.add("no-transition");
-
- let parent = element.parentNode;
-
- console.log(element);
- let elementStyle = window.getComputedStyle(element);
- let parentStyle = window.getComputedStyle(parent);
-
- let fontSize = parseFloat(elementStyle.getPropertyValue("font-size")) / parseFloat(parentStyle.getPropertyValue("font-size"));
-
- let maxHeight = elementStyle.height;
- let maxWidth = elementStyle.width;
-
- let pHeight = parentStyle.height;
- let pWidth = parentStyle.width;
-
- let relativeAttributes = element.style;
- relativeAttributes['max-height'] = Math.floor(maxHeight / pHeight * 100) + "%";
- relativeAttributes['margin-left'] = Math.floor(parseFloat(elementStyle.getPropertyValue('margin-left')) / pWidth * 100) + "%";
- relativeAttributes['margin-right'] = Math.floor(parseFloat(elementStyle.getPropertyValue('margin-right')) / pWidth * 100) + "%";
- relativeAttributes['margin-top'] = Math.floor(parseFloat(elementStyle.getPropertyValue('margin-top')) / pHeight * 100) + "%";
- relativeAttributes['margin-bottom'] = Math.floor(parseFloat(elementStyle.getPropertyValue('margin-bottom')) / pHeight * 100) + "%";
- relativeAttributes['max-width'] = Math.floor(maxWidth / pWidth * 100) + "%";
- relativeAttributes["font-size"] = fontSize + "em";
- // console.log(relativeAttributes);
- // element.css(relativeAttributes);
-
- if (!hasTransitionClass) {
- element.classList.remove("no-transition");
- }
- }
-
- static isChrome() {
- let isChromium = window.chrome,
- winNav = window.navigator,
- vendorName = winNav.vendor,
- isOpera = winNav.userAgent.indexOf("OPR") > -1,
- isIEedge = winNav.userAgent.indexOf("Edge") > -1,
- isIOSChrome = winNav.userAgent.match("CriOS");
-
- if (isIOSChrome) {
- return true;
- } else {
- return isChromium !== null &&
- typeof isChromium !== "undefined" &&
- vendorName === "Google Inc." &&
- isOpera === false &&
- isIEedge === false;
- }
- }
-
- static getIndexedObject(array, keyValue) {
- let obj = {};
- for (let i = 0, n = array.length; i < n; i++) {
- obj[array[i][keyValue]] = array[i];
- }
- return obj;
- }
-
- static invertKeyValues(obj) {
- let new_obj = {};
-
- for (let prop in obj) {
- if (obj.hasOwnProperty(prop)) {
- new_obj[obj[prop]] = prop;
- }
- }
-
- return new_obj;
- }
-
- static toArray(object) {
- let res = [];
- for (let k in object) {
- res.push(object[k]);
- }
- return res;
- }
-}
-Helper.init();
-
-class SystemSettings {
- static setBasePath(basePath) {
- SystemSettings._basePath = basePath;
- }
-
- static getBasePath() {
- return SystemSettings._basePath;
- }
-
- static set(key, value) {
- SystemSettings._settings[key] = value;
- }
-
- static get(key, defaultValue) {
- return Helper.nonNull(SystemSettings._settings[key], defaultValue);
- }
-
- static has(key){
- return Helper.nonNull(SystemSettings._settings[key]);
- }
-}
-
-SystemSettings.setBasePath("/");
-SystemSettings._settings = {};
-
-class ThemeManager {
- static init() {
- ThemeManager.loadCurrentTheme();
- }
-
- static changeCurrentTheme(newTheme) {
- let theme = null;
- if (typeof newTheme === 'string') {
- let themes = ThemeManager.themes.filter(function (theme) {
- return theme._name === newTheme;
- });
- if (themes.length > 0) {
- theme = themes[0];
- }
- }
- else if (ThemeManager.themes.indexOf(newTheme) !== -1) {
- theme = newTheme;
- }
- if (Helper.isNotNull(theme)) {
- localStorage.setItem("currentTheme", theme._name);
- let themePromise = new Promise(function (resolve) {
- document.querySelector("nav.top-bar").addEventListener("transitionend", function(){
- resolve();
- });
- });
- document.body.className = theme._className;
- ThemeManager.currentTheme = theme;
- for (let i = 0, n = ThemeManager.changeListeners.length; i < n; i++) {
- ThemeManager.changeListeners[i](ThemeManager.currentTheme, themePromise);
- }
- }
- }
-
- static addTheme(theme) {
- ThemeManager.themes.push(theme);
- }
-
- static loadCurrentTheme() {
- ThemeManager.changeCurrentTheme(localStorage.getItem("currentTheme"));
- if (Helper.isNull(ThemeManager.currentTheme)) {
- let className = document.body.className;
- let themes = ThemeManager.themes.filter(function (theme) {
- return theme._className === className;
- });
- if (themes.length > 0) {
- ThemeManager.changeCurrentTheme(themes[0]);
- }
- else if (ThemeManager.themes.length > 0) {
- ThemeManager.changeCurrentTheme(ThemeManager.themes[0]);
- }
- }
- }
-
- static generateChangeThemeMenuAction() {
- return new MenuAction(ThemeManager.currentTheme._name, function (action) {
- let currentThemeIndex = ThemeManager.themes.indexOf(ThemeManager.currentTheme);
- let nextIndex = (currentThemeIndex + 1) % ThemeManager.themes.length;
- ThemeManager.changeCurrentTheme(ThemeManager.themes[nextIndex]);
- action.title = ThemeManager.currentTheme._name;
- action._menu.redraw();
- }, Menu.SHOW_ALWAYS)
- }
-
- static addChangeListener(listener) {
- ThemeManager.changeListeners.push(listener);
- }
-
- static getCurrentTheme(){
- return ThemeManager.currentTheme;
- }
-}
-
-ThemeManager.currentTheme = null;
-ThemeManager.themes = [];
-ThemeManager.changeListeners = [];
-
-AndroidBridge.addDefinition("ThemeManager", {
- "addChangeListener": ThemeManager.addChangeListener,
- "getCurrentTheme": ThemeManager.getCurrentTheme,
-});
-
-class CookieCompliance {
-
- static async showIfNeeded(cookieContainer) {
- let cookieCompliance = new CookieCompliance(cookieContainer);
- return cookieCompliance.showIfNeeded();
- }
-
- constructor(cookieContainerId) {
- this.cookieContainerId = cookieContainerId;
- this.dropCookie = true;
- this.cookieDuration = 365 * 10;
- this.cookieName = 'complianceCookie';
- this.cookieValue = 'true';
- }
-
- async showIfNeeded() {
- if (CookieCompliance.checkCookie(this.cookieName) !== this.cookieValue) {
- return this.show();
- }
- return Promise.resolve();
- }
-
- removeMe() {
- this.createCookie(this.cookieName, this.cookieValue, this.cookieDuration);
- }
-
- createCookie(name, value, days) {
- let expires;
- if (Helper.isNotNull(days)) {
- const date = new Date();
- date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
- expires = "; expires=" + date.toGMTString();
- }
- else {
- expires = "";
- }
- if (this.dropCookie) {
- document.cookie = name + "=" + value + expires + "; path=/";
- }
- }
-
- eraseCookie(name) {
- this.createCookie(name, "", -1);
- }
-
- static checkCookie(name) {
- const nameEQ = name + "=";
- const cookies = document.cookie.split(';');
- for (let i = 0; i < cookies.length; i++) {
- let c = cookies[i];
- while (c.charAt(0) === ' ') {
- c = c.substring(1, c.length);
- }
- if (c.indexOf(nameEQ) === 0) {
- return c.substring(nameEQ.length, c.length);
- }
- }
- return null;
- }
-
- show() {
- let cookieCompliance = this;
- const cookieMessage = document.getElementById(this.cookieContainerId);
- cookieMessage.style.display = 'block';
- return new Promise(r => {
- cookieMessage.querySelector("#close-cookie-msg").onclick = function () {
- cookieCompliance.removeMe();
- cookieMessage.remove();
- r();
- };
- });
- }
-}
-
-class ActionBarMenu extends Menu {
- static init() {
- function parseStyleToObject(str) {
- let styleObject = {};
-
- if (typeof str !== 'string') {
- return styleObject;
- }
-
- str = str.trim().slice(1, -1); // browsers re-quote string style values
-
- if (!str) {
- return styleObject;
- }
-
- styleObject = str.split('&').reduce(function (ret, param) {
- const parts = param.replace(/\+/g, ' ').split('=');
- let key = parts[0];
- let val = parts[1];
- key = decodeURIComponent(key);
-
- // missing `=` should be `null`:
- // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
- val = val === undefined ? null : decodeURIComponent(val);
-
- if (!ret.hasOwnProperty(key)) {
- ret[key] = val;
- } else if (Array.isArray(ret[key])) {
- ret[key].push(val);
- } else {
- ret[key] = [ret[key], val];
- }
- return ret;
- }, {});
-
- return styleObject;
- }
-
- let cssStyle = document.getElementsByClassName('foundation-mq');
- if (cssStyle.length === 0) {
- return;
- }
- let queries = [];
- cssStyle = parseStyleToObject(window.getComputedStyle(cssStyle[0]).getPropertyValue('font-family'));
- for (let key in cssStyle) {
- if (cssStyle.hasOwnProperty(key)) {
- queries.push({
- _name: key,
- value: 'only screen and (min-width: ' + cssStyle[key] + ')'
- });
- }
- }
-
- window.addEventListener('resize', function () {
- if (Helper.isNotNull(ActionBarMenu.currentMenu)) {
- ActionBarMenu.currentMenu.updateToggleButton();
- }
- });
- let responsiveMenu = document.getElementById("responsive-menu");
- document.getElementById("responsive-menu-toggle").onclick = function () {
- if (window.getComputedStyle(responsiveMenu).getPropertyValue('display') === 'none') {
- responsiveMenu.style.display = 'block';
- }
- else if (Helper.isNotNull(ActionBarMenu.currentMenu)) {
- ActionBarMenu.currentMenu.close();
-
- }
- };
- responsiveMenu.firstElementChild.addEventListener("click", function (e) {
- if (e.target === responsiveMenu.firstElementChild && Helper.isNotNull(ActionBarMenu.currentMenu)) {
- ActionBarMenu.currentMenu.close();
- }
- }
- );
- ActionBarMenu.queries = queries;
- }
-
- static _getCurrentSize() {
- let matched;
-
- for (let i = 0; i < ActionBarMenu.queries.length; i++) {
- let query = ActionBarMenu.queries[i];
-
- if (matchMedia(query.value).matches) {
- matched = query;
- }
- }
-
- if (typeof matched === 'object') {
- return matched._name;
- } else {
- return matched;
- }
- }
-
- static filterVisibleElements(elements) {
- let visibleElements = [];
- for (let i = 0, n = elements.length; i < n; i++) {
- if (!elements[i].classList.contains("hidden")) {
- visibleElements.push(elements[i]);
- }
- }
- return visibleElements;
- }
-
- renderLiElement(aElement, action) {
- let liElement = super.renderLiElement(aElement, action);
- liElement.classList.add(action.getShowFor());
- return liElement;
- }
-
- updateToggleButton() {
- let size = ActionBarMenu._getCurrentSize();
- let firstParentElement = this.parentElements[0];
- if ((size === "medium" || size === "smedium" || size === "small") && ActionBarMenu.filterVisibleElements(firstParentElement.getElementsByClassName(Menu.SHOW_FOR_LARGE)).length > 0 ||
- (size === "smedium" || size === "small") && ActionBarMenu.filterVisibleElements(firstParentElement.getElementsByClassName(Menu.SHOW_FOR_MEDIUM)).length > 0 ||
- (size === "small") && ActionBarMenu.filterVisibleElements(firstParentElement.getElementsByClassName(Menu.SHOW_FOR_SMEDIUM)).length > 0 ||
- ActionBarMenu.filterVisibleElements(firstParentElement.getElementsByClassName(Menu.SHOW_NEVER)).length > 0) {
- document.getElementById("responsive-menu-toggle").style.display = 'block';
- } else {
- document.getElementById("responsive-menu-toggle").style.display = 'none';
- if (Helper.isNotNull(ActionBarMenu.currentMenu)) {
- ActionBarMenu.currentMenu.close();
- }
- }
- }
-
- _getOnClickListener() {
- let superListener = super._getOnClickListener();
- return function (event) {
- let action = superListener(event);
- if (!(action instanceof OpenSubmenuAction) && Helper.isNotNull(ActionBarMenu.currentMenu)) {
- ActionBarMenu.currentMenu.close();
- }
- }
- }
-
- draw(parentElement) {
- let returnValue = super.draw(parentElement);
- this.updateToggleButton();
-
- ActionBarMenu.currentMenu = this;
- return returnValue;
- }
-
- close() {
- document.getElementById("responsive-menu").style.display = 'none';
- for (let i = 0, n = this.submenus.length; i < n; i++) {
- this.submenus[i].close();
- }
- }
-
- removeAction(action) {
- let res = super.removeAction(action);
- this.updateToggleButton();
- return res;
- }
-}
-
-ActionBarMenu.queries = [];
-ActionBarMenu.currentMenu = null;
-ActionBarMenu.init();
-
-class ViewInflater {
- static inflate(viewUrl, parentUrls) {
- parentUrls = Helper.nonNull(parentUrls, []).slice(0);
-
- let resultPromise = Promise.resolve();
- if (viewUrl instanceof Element) {
- resultPromise = Promise.resolve(viewUrl);
- }
- else {
- if (parentUrls.indexOf(viewUrl) !== -1) {
- return Promise.reject("views are in a circuit! cannot resolve view for url " + parentUrls[0] + "! url " + viewUrl + " is in stack before!");
- }
- parentUrls.push(viewUrl);
- resultPromise = fetch(Helper.basePath(viewUrl), {credentials: "same-origin"}).then(function (result) {
- return result.text();
- }).then(function (htmlText) {
- let doc = (new DOMParser()).parseFromString(htmlText, "text/html");
- if (Helper.isNull(doc)) {
- doc = document.implementation.createHTMLDocument('');
- doc.body.innerHTML = htmlText;
- }
- return doc.body.firstChild
- });
- }
-
- return resultPromise.then(function (parentElement) {
- let promises = [];
- let childViews = parentElement.querySelectorAll("[data-view]");
-
- for (let i = 0, n = childViews.length; i < n; i++) {
- promises.push(ViewInflater.inflate(childViews[i].dataset["view"], parentUrls).then(function (element) {
- childViews[i].replaceWith(element);
- }));
- }
- return Promise.all(promises).then(function () {
- return parentElement;
- });
- });
- }
-}
-
-class Context {
- constructor(view) {
- let self = this;
- this._siteContent = null;
- this.firstStart = true;
- this.inflatePromise = new Promise(function (resolver) {
- self.inflatePromiseResolver = resolver;
- });
- this.fragments = {};
-
- if (Helper.isNotNull(view)) {
- this.inflateView(view);
- }
- }
-
- onConstruct() {
- let results = [];
- for (let k in this.fragments) {
- results.push(this.fragments[k].onConstruct.apply(this.fragments[k], arguments));
- results.push(this.fragments[k].inflatePromise);
- }
- return Promise.all(results);
- }
-
- onStart() {
- if (this.firstStart) {
- this.onFirstStart();
- this.firstStart = false;
- }
-
- for (let k in this.fragments) {
- let fragment = this.fragments[k];
- fragment.onStart.apply(this.fragments[k], arguments);
- this.fragments[k].inflatePromise.then(function (fragmentView) {
- if (fragment.isActive()) {
- fragmentView.classList.remove("hidden");
- }
- else {
- fragmentView.classList.add("hidden");
- }
- });
- }
- }
-
- onFirstStart() {
- // for (let k in this.fragments) {
- // this.fragments[k].onFirstStart.apply(this.fragments[k], arguments);
- // }
- }
-
- onPause() {
- for (let k in this.fragments) {
- this.fragments[k].onPause.apply(this.fragments[k], arguments);
- }
- }
-
- onDestroy() {
- for (let k in this.fragments) {
- this.fragments[k].onDestroy.apply(this.fragments[k], arguments);
- }
- }
-
- addFragment(viewQuery, fragment) {
- this.fragments[viewQuery] = fragment;
- this.inflatePromise = this.inflatePromise.then(function (siteContent) {
- return fragment.inflatePromise.then(function (fragmentView) {
- siteContent.querySelector(viewQuery).appendChild(fragmentView);
- return siteContent;
- });
- });
- }
-
- /** @protected */
- inflateView(link) {
- let self = this;
- this.inflatePromiseResolver(ViewInflater.inflate(link).then(function (siteContent) {
- self._siteContent = siteContent;
- return siteContent;
- }));
-
- return this.inflatePromise;
- }
-
- findBy(query, all, asPromise) {
- all = Helper.nonNull(all, false);
- asPromise = Helper.nonNull(asPromise, false);
-
- let getVal = function (root) {
- let res = null;
- if (all) {
- res = root.querySelectorAll(query);
- if (root.matches(query)) {
- res.push(root);
- }
- }
- else {
- if (root.matches(query)) {
- res = root;
- }
- else {
- res = root.querySelector(query);
- }
- }
- return res;
- };
-
- if (asPromise) {
- return this.inflatePromise.then(function (rootView) {
- return getVal(rootView);
- });
- }
- return getVal(this._siteContent);
- }
-}
-
-class AbstractSite extends Context {
- constructor(siteManager, view, deepLink) {
- super(view);
-
- this.isVisible = false;
- this.siteManager = siteManager;
- this.isFinishing = false;
- this.actionMenu = null;
- this.url = "";
- this.deepLink = deepLink;
- this.startArgs = {};
- this.title = siteManager.getDefaultTitle();
- }
-
- setTitle(titleElement, title) {
- if (typeof titleElement === "string") {
- title = titleElement;
- titleElement = document.createTextNode(titleElement);
- }
- this.title = {
- element: titleElement
- };
- this.title["title"] = Helper.nonNull(title, this.title["title"]);
-
- if (this.isVisible) {
- this.siteManager.updateTitle();
- }
- }
-
- startStartsite() {
- return this.startSite(this.siteManager.getStartSiteName());
- }
-
- inflateView(link) {
- let self = this;
- return super.inflateView(link).then(function (res) {
- let promises = [];
- for (let i = 0, n = self.fragments.length; i < n; i++) {
- promises.push(self.fragments[i].inflatePromise);
- }
- return Promise.all(promises).then(function () {
- return res;
- });
- });
- }
-
- onConstruct(args) {
- this.startArgs = args;
- if (Helper.isNotNull(this.deepLink)) {
- this.setUrlFromParams(args);
- }
- return super.onConstruct(args);
- }
-
- onStart(args) {
- this.isVisible = true;
- let res = super.onStart(args);
- this.actionMenu.redraw();
- return res;
- }
-
- onPause(args) {
- super.onPause(args);
- this.isVisible = false;
- }
-
- finish(result) {
- if (!this.isFinishing) {
- this.isFinishing = true;
- this.siteManager.endSite(this, result);
- }
- }
-
- startSite(siteName, args) {
- return this.siteManager.startSite(siteName, args);
- }
-
- toForeground() {
- this.siteManager.toForeground(this);
- }
-
- finishAndStartNext(siteName, startParams, finishResult) {
- this.startSite(siteName, startParams);
- this.finish(finishResult);
- }
-
- createActionBarMenu(menu) {
- let defaultActions = this.siteManager.getDefaultActions();
- for (let i = 0, n = defaultActions.length; i < n; i++) {
- menu.addAction(defaultActions[i].copy());
- }
- return menu;
- }
-
- setUrl(url) {
- this.url = url;
- this.siteManager.updateUrl(this);
- }
-
- setUrlFromParams(params) {
- this.setUrl(this.deepLink + Helper.buildQuery(params));
- }
-
- updateUrlParams(params) {
- this.startArgs = Object.assign(this.startArgs, params);
- this.setUrlFromParams(this.startArgs);
- }
-
- getUrl() {
- return this.url;
- }
-
- getFullUrl() {
- return Helper.basePath(this.url);
- }
-
- onBackPressed() {
- }
-
- addListener(event, selector, listenerFunction) {
- this.siteManager.addListener(this, event, selector, listenerFunction);
- }
-
- addKeyListener(keycode, listenerFunction)
- {
- this.siteManager.addKeyListener(this, keycode, listenerFunction);
- }
-
- addKeyAndEventListener(keycode, event, selector, listenerFunction) {
- this.siteManager.addKeyAndEventListener(this, keycode, event, selector, listenerFunction);
- }
-}
-
-class SiteContainer {
- constructor(site, finishResolver) {
- this._site = site;
- this._siteContent = null;
- this._pauseParameters = {};
- this._startParameters = {};
- this._finishResolver = finishResolver;
- }
- getSite() {
- return this._site;
- }
-
- setSite(site) {
- if (site instanceof AbstractSite) {
- this._site = site;
- }
- }
-
- getSiteContent() {
- return this._siteContent;
- }
-
- setSiteContent(value) {
- this._siteContent = value;
- }
-
- getPauseParameters() {
- return this._pauseParameters;
- }
-
- setPauseParameters(value) {
- this._pauseParameters = value;
- }
-
- getStartParameters() {
- return this._startParameters;
- }
-
- setStartParameters(value) {
- this._startParameters = value;
- }
-
- getFinishResolver() {
- return this._finishResolver;
- }
-
- setFinishResolver(value) {
- this._finishResolver = value;
- }
-}
-
-class SiteManager {
- constructor(siteDivId, actionBarMenuSelector, app) {
- this.siteDiv = document.getElementById(siteDivId);
- this.siteContainerStack = [];
- this.currentSiteContainerToShow = null;
- this.actionBarMenuSelector = Helper.nonNull(actionBarMenuSelector, '.action-bar');
-
- this.siteStartingPromise = Promise.resolve();
- this.defaultActions = [];
- this.startSiteName = null;
- this.app = app;
-
- this.titleElement = document.querySelector(".top-bar-title");
-
- const defaultTitleElem = document.createElement("span");
- while (this.titleElement.childNodes.length > 0) {
- const child = this.titleElement.firstChild;
- child.remove();
- defaultTitleElem.appendChild(child);
- }
-
- this.defaultTitle = {
- element: defaultTitleElem,
- title: document.title
- };
-
- let siteManager = this;
- window.onpopstate = function (e) {
- if (siteManager.siteContainerStack.length >= 1) {
- let site = siteManager.siteContainerStack[siteManager.siteContainerStack.length - 1].getSite();
- if (site.onBackPressed() !== false) {
- siteManager.endSite(site);
- }
- }
- };
- }
-
- getDefaultTitle() {
- return this.defaultTitle;
- }
-
- setStartSiteName(startSiteName) {
- this.startSiteName = startSiteName;
- }
-
- getStartSiteName() {
- return this.startSiteName;
- }
-
- addDefaultAction(action) {
- this.defaultActions.push(action);
- }
-
- getDefaultActions() {
- return this.defaultActions;
- }
-
- getCurrentSite(){
- if (Helper.isNotNull(this.currentSiteContainerToShow)){
- return this.currentSiteContainerToShow.getSite();
- }
- return null;
- }
-
- async findSite(filter){
- for (let i = this.siteContainerStack.length-1; i >= 0; i--) {
- if (await filter(this.siteContainerStack[i].getSite())){
- return this.siteContainerStack[i].getSite();
- }
- }
- return null;
- }
-
- async startSite(siteConstructor, paramsPromise) {
- if (!(siteConstructor.prototype instanceof AbstractSite)) {
- throw {
- "error": "wrong class given! Expected AbstractSite, given " + siteConstructor.name
- };
- }
-
- let site = new siteConstructor(this);
- let resolver = {};
- let finishPromise = new Promise(function (resolve, reject) {
- resolver.resolve = resolve;
- resolver.reject = reject;
- });
- let siteContainer = new SiteContainer(site, resolver);
- this.siteDiv.removeAllChildren().appendChild(Helper.createLoadingSymbol());
-
- this.siteStartingPromise = Promise.resolve(paramsPromise).then(async (params) => {
- siteContainer.setStartParameters(params);
- await Promise.all([site.onConstruct(params), site.inflatePromise]);
-
- site.actionMenu = site.createActionBarMenu(this.buildActionBarMenu());
- return this.show(siteContainer);
- }).catch((e) => {
- console.error("site start error for site ", siteConstructor.name, e);
- });
-
- return finishPromise;
- }
-
- endSite(site, result) {
- let manager = this;
- this.siteStartingPromise.then(function () {
- let index = manager.findContainerIndexBySite(site);
- let container = manager.siteContainerStack.splice(index, 1);
- container = container[0];
-
- let showSiteContainer = null;
- if (container === manager.currentSiteContainerToShow) {
- manager.currentSiteContainerToShow.getSite().onPause();
- manager.currentSiteContainerToShow = null;
- let newSiteContainerIndex = manager.siteContainerStack.length - 1;
- if (newSiteContainerIndex < 0) {
-
- manager.showAppEndedMessage();
- app.endApp();
- // manager.startSite(manager.startSiteName);
- return;
- }
- manager.siteDiv.removeAllChildren().appendChild(Helper.createLoadingSymbol());
- showSiteContainer = manager.siteContainerStack[newSiteContainerIndex];
- }
- container.getSite().onDestroy();
-
- Promise.resolve(result).then(function (resValue) {
- container.getFinishResolver().resolve(resValue);
- if (Helper.isNotNull(showSiteContainer)) {
- manager.show(showSiteContainer);
- }
- });
- });
- }
-
- addListener(site, event, _selector, listener) {
- this.siteDiv.addEventListener(event, function (_event) {
- let _element = _event.target;
- if (site.isVisible && _element.matches(_selector)) {
- listener(_element, _event);
- }
- });
- }
-
- addKeyAndEventListener(site, keycode, event, selector, listener) {
- this.addListener(site, event, selector, listener);
- this.addKeyListener(site, keycode, listener);
- }
-
- addKeyListener(site, keycode, listener) {
- window.addEventListener("keydown", function (e) {
- if (site.isVisible && e.which === keycode) {
- listener(this, e);
- }
- });
- }
-
- toForeground(site) {
- let index = this.findContainerIndexBySite(site);
- let container = this.siteContainerStack.splice(index, 1);
- container = container[0];
-
- this.show(container);
- }
-
- refreshCurrentSite() {
- return this.show(this.currentSiteContainerToShow);
- }
-
- /** @private */
- show(siteContainer) {
- if (Helper.isNotNull(this.currentSiteContainerToShow)) {
- this.currentSiteContainerToShow.setPauseParameters(this.currentSiteContainerToShow.getSite().onPause());
- this.currentSiteContainerToShow.setSiteContent(this.siteDiv.innerHTML);
- }
- this.siteDiv.removeAllChildren().appendChild(Helper.createLoadingSymbol());
-
- let siteManager = this;
- this.currentSiteContainerToShow = siteContainer;
- if (-1 === this.siteContainerStack.indexOf(siteContainer)) {
- this.siteContainerStack.push(siteContainer);
- }
-
- return siteContainer.getSite().inflatePromise.then(function (data) {
- siteContainer.getSite().actionMenu.redraw();
- siteManager.siteDiv.removeAllChildren().appendChild(data);
- siteManager.updateTitle();
- Translator.getInstance().updateTranslations();
- return data;
- }).then(function (data) {
- siteContainer.getSite().onStart(siteContainer.getPauseParameters());
- history.pushState({
- 'siteName': siteContainer.getSite().constructor.name,
- 'siteData': data.outerHTML,
- 'stackPosition': siteManager.siteContainerStack.length - 1
- }, siteContainer.getSite().constructor.name, siteContainer.getSite().getFullUrl());
- });
- }
-
- updateUrl(site) {
- if (Helper.isNotNull(this.currentSiteContainerToShow) && this.currentSiteContainerToShow.getSite() === site) {
- let self = this;
- history.replaceState({
- 'siteName': site.constructor.name,
- 'siteData': site._siteContent.outerHTML,
- 'stackPosition': self.siteContainerStack.length - 1
- }, site.constructor.name, site.getFullUrl());
- }
- }
-
- getCurrentSite() {
- if (this.currentSiteContainerToShow != null)
- return this.currentSiteContainerToShow.getSite();
- }
-
- redrawCurrentActionBar() {
- if (this.currentSiteContainerToShow != null)
- this.currentSiteContainerToShow.getSite().actionMenu.redraw();
- }
-
- updateTitle() {
- let title = this.getCurrentSite().title;
- this.titleElement.removeAllChildren().appendChild(title.element);
- document.title = Helper.nonNull(title.title, this.defaultTitle.title);
- }
-
- /** @private */
- findContainerIndexBySite(site) {
- for (let i = 0, n = this.siteContainerStack.length; i < n; i++) {
- if (this.siteContainerStack[i].getSite() === site) {
- return i;
- }
- }
- return -1;
- }
-
- /** @private */
- findContainerBySite(site) {
- let index = this.findContainerIndexBySite(site);
- if (index === -1) {
- return null;
- }
- return this.siteContainerStack[index];
- }
-
- /** @private */
- showAppEndedMessage() {
- this.siteDiv.removeAllChildren().appendChild(Translator.makePersistentTranslation("The app has ended! Please close the window."));
- }
-
- /** @private */
- buildActionBarMenu() {
- return new ActionBarMenu(this.actionBarMenuSelector);
- }
-}
-
-class PauseSite extends AbstractSite {
- onConstruct(args) {
- let pausedElement = null;
-
- if (Helper.isSet(args, "url")) {
- pausedElement = args["url"];
- }
- else {
- pausedElement = document.createElement("div");
- pausedElement.innerHTML = "Paused...";
- }
-
- this.inflateView(pausedElement);
- }
-
- onPause() {
- for (let i = 0; i < PauseSite.onStartListeners.length; i++) {
- if (typeof PauseSite.onStartListeners[i] === "function") {
- PauseSite.onStartListeners[i]();
- }
- }
- return super.onPause();
- }
-
- onStart() {
- for (let i = 0; i < PauseSite.onPauseListeners.length; i++) {
- if (typeof PauseSite.onPauseListeners[i] === "function") {
- PauseSite.onPauseListeners[i]();
- }
- }
- return super.onPause();
- }
-}
-
-PauseSite.onPauseListeners = [];
-PauseSite.onStartListeners = [];
-
-class App {
- constructor() {
- this._siteManager = null;
- this._actionBarMenuSelector = '.action-bar';
- this._basePath = SystemSettings.getBasePath();
- this._siteContentId = 'site-content';
- this._deepLinks = new Map();
- this._defaultActions = [];
- this._addThemeAction = false;
- this._showCookieCompliance = true;
- this._startSite = null;
- this._appEndListener = () => {
- return this.startSite(this._startSite);
- };
- }
-
- getSiteManager()
- {
- return this._siteManager;
- }
-
- addDefaultAction(action) {
- this._defaultActions.push(action);
- }
-
- setAddThemeAction(addThemeAction) {
- this._addThemeAction = addThemeAction;
- }
-
- getSiteContentId() {
- return this._siteContentId;
- }
-
- setSiteContentId(value) {
- this._siteContentId = value;
- }
-
- getActionBarMenuSelector() {
- return this._actionBarMenuSelector;
- }
-
- setActionBarMenuSelector(value) {
- this._actionBarMenuSelector = value;
- }
-
- getBasePath() {
- return this._basePath;
- }
-
- setBasePath(value) {
- this._basePath = value;
- }
-
- addDeepLink(alias, site) {
- this._deepLinks.set(alias.toLowerCase(), site);
- }
-
- setShowCookieCompliance(cookieCompliance)
- {
- this._showCookieCompliance = cookieCompliance;
- }
-
- refreshCurrentSite()
- {
- this._siteManager.refreshCurrentSite();
- }
-
- pause(elementToShow){
- this.startSite(PauseSite, {"url": elementToShow});
- }
-
- resume(){
- const currentSite = this._siteManager.getCurrentSite();
- if (currentSite instanceof PauseSite)
- {
- currentSite.finish();
- }
- }
-
- _resolveDeepLink(deepLink) {
- deepLink = deepLink.toLowerCase();
- if (this._deepLinks.has(deepLink)) {
- return this._deepLinks.get(deepLink);
- }
- return null;
- }
-
- _getDeepLink() {
- let deepLink = "";
- if (window.location.pathname.search(this._basePath) === 0) {
- deepLink = window.location.pathname.substr(this._basePath.length).trim();
- }
- if (deepLink.charAt(0) === '/') {
- deepLink = deepLink.substr(1).trim();
- }
- if (deepLink.charAt(deepLink.length - 1) === '/') {
- deepLink = deepLink.substr(0, deepLink.length - 2).trim();
- }
- if (deepLink.length === 0 && window.location.hash) {
- deepLink = window.location.hash.substr(1).trim();
- }
-
- return this._resolveDeepLink(deepLink);
- }
-
- _addDeepLinksListener() {
- let app = this;
- let elements = document.getElementsByClassName("deep-link");
- for (let i = 0, n = elements.length; i < n; i++) {
- elements[i].addEventListener("click", function (e) {
- e.preventDefault();
- app._siteManager.startSite(Helper.nonNull(app._resolveDeepLink(this.dataset["siteName"]), app._startSite), App._extractParams(this.dataset["siteArgs"]));
- return true;
- });
- }
- }
-
- removeDefaultAction(action)
- {
- let index = this._defaultActions.indexOf(action);
- if (index >= 0)
- {
- this._defaultActions[index].remove(true);
- this._defaultActions.splice(index, 1);
- }
- }
-
- startSite(site, parameter)
- {
- return this._siteManager.startSite(site, parameter);
- }
-
- start(fallbackStartSite) {
- SystemSettings.setBasePath(this._basePath);
- let startSite = Helper.nonNull(this._getDeepLink(), fallbackStartSite);
- let startParams = App._getStartParams();
- this._startSite = fallbackStartSite;
-
- Translator.init();
- ThemeManager.init();
- if (this._addThemeAction) {
- this.addDefaultAction(ThemeManager.generateChangeThemeMenuAction());
- }
- this._siteManager = new SiteManager(this._siteContentId, this._actionBarMenuSelector);
- this._siteManager.defaultActions = this._defaultActions;
- this._siteManager.setStartSiteName(fallbackStartSite);
- this._siteManager.startSite(startSite, startParams);
- this._addDeepLinksListener();
-
- if (this._showCookieCompliance)
- {
- this._cookieClosePromise = CookieCompliance.showIfNeeded('cookie-compliance');
- }
- }
-
- getCurrentSite(){
- return this._siteManager.getCurrentSite();
- }
-
- async endApp(){
- if (typeof this._appEndListener === "function"){
- this._appEndListener();
- }
- }
-
- setAppEndListener(appEndListener){
- this._appEndListener = appEndListener;
- }
-
- async findSite(filter){
- return this._siteManager.findSite(filter);
- }
-
- static _extractParams(paramString) {
- if (Helper.isNull(paramString)) {
- return null;
- }
- let result = {}, tmp = [];
- let items = paramString.split("&");
- for (let index = 0; index < items.length; index++) {
- tmp = items[index].split("=");
- if (tmp[0].trim().length > 0) {
- result[tmp[0]] = decodeURIComponent(tmp[1]);
- }
- }
- return result;
- }
-
- static _getStartParams() {
- return App._extractParams(window.location.search.substr(1));
- }
-}
-
-class ChainAble{
- constructor()
- {
- this.promise = Promise.resolve();
- }
-
- _chain(func){
- if (typeof func !== "function")
- {
- return this._chain(function(){
- return Promise.resolve(func);
- });
- }
- else
- {
- this.promise = this.promise.then(func);
- }
- return this;
- }
-}
-
-class Dialog {
- constructor(content, title) {
- this.resolver = null;
- this.content = null;
- this.backgroundElement = null;
- this.cancelable = true;
- this.title = Helper.nonNull(title, "");
- this.translatable = true;
- this.additionalClasses = "";
- this.buttons = [];
- this.result = null;
-
- if (Helper.isNotNull(content)) {
- this.setContent(content);
- }
- }
-
- setTitle(title) {
- this.title = title;
- return this;
- }
-
- setTranslatable(translatable) {
- this.translatable = translatable;
- }
-
- setAdditionalClasses(classes) {
- this.additionalClasses = classes;
- }
-
- getTitle() {
- return this.title;
- }
-
- setCancelable(cancelable) {
- this.cancelable = (cancelable === true);
- return this;
- }
-
- async setContent(content) {
- this.contentPromise = Promise.resolve(content);
- this.content = await this.contentPromise;
- return this;
- }
-
- addButton(elementOrText, listenerOrResult, shouldClose) {
- shouldClose = Helper.nonNull(shouldClose, true);
-
- let button = null;
- if (typeof elementOrText === "string") {
- button = document.createElement("button");
- button.classList.add("button");
- button.classList.add("right");
- button.appendChild(Translator.makePersistentTranslation(elementOrText));
- }
- else {
- button = elementOrText;
- }
-
- let self = this;
- if (typeof listenerOrResult !== "function") {
- let result = listenerOrResult;
- listenerOrResult = function () {
- self.result = result;
- };
- }
-
- let callback = null;
- if (shouldClose) {
- callback = function (e) {
- if (Helper.isNotNull(listenerOrResult)) {
- listenerOrResult(e);
- }
- self.close();
- };
- }
- else {
- callback = listenerOrResult;
- }
-
- if (Helper.isNotNull(callback)) {
- button.addEventListener("click", callback);
- }
- this.buttons.push(button);
- }
-
- async show() {
-
- let titleElement = document.createElement("span");
- titleElement.classList.add("title");
- if (this.translatable && this.title !== "") {
- titleElement.appendChild(Translator.makePersistentTranslation(this.title));
- }
- else {
- titleElement.innerHTML = this.title;
- }
-
- let titleBar = document.createElement("div");
- titleBar.appendChild(titleElement);
-
- let contentContainer = document.createElement("div");
- contentContainer.classList.add("content-container");
-
- let modalDialog = document.createElement("div");
- modalDialog.className = this.additionalClasses;
- modalDialog.classList.add("modal");
- modalDialog.appendChild(titleBar);
- modalDialog.appendChild(contentContainer);
-
- let buttonBar = document.createElement("div");
- buttonBar.classList.add("modal-button-container");
-
- for (let i = 0, n = this.buttons.length; i < n; i++) {
- buttonBar.appendChild(this.buttons[i]);
- }
-
- await this.contentPromise;
- if (!(this.content instanceof Node)) {
- this.content = (this.translatable) ? Translator.makePersistentTranslation(this.content) : document.createTextNode(this.content);
- }
- contentContainer.appendChild(this.content);
-
- this.backgroundElement = document.createElement("div");
- this.backgroundElement.classList.add("background");
- this.backgroundElement.appendChild(modalDialog);
-
- this.backgroundElement.querySelector(".modal").appendChild(buttonBar);
- this.backgroundElement.style.display = "block";
-
- let self = this;
- if (this.cancelable) {
- let closeButton = document.createElement("span");
- closeButton.classList.add("close");
- closeButton.innerHTML = "×";
-
- titleBar.appendChild(closeButton);
- closeButton.addEventListener("click", function () {
- self.close();
- });
- window.addEventListener("click", function (e) {
- if (e.target === self.backgroundElement) {
- self.close();
- }
- });
- }
-
- document.body.appendChild(this.backgroundElement);
- Translator.getInstance().updateTranslations();
-
- return new Promise(function (resolve) {
- self.resolver = resolve;
- });
- }
-
- close() {
- if (Helper.isNotNull(this.backgroundElement)) {
- this.backgroundElement.style.display = "none";
- this.backgroundElement.remove();
- this.backgroundElement = null;
- }
- if (Helper.isNotNull(this.resolver)) {
- this.resolver(this.result);
- }
- }
-
- addDefaultButton(){
- this.addButton("confirm-button");
- }
-}
-
-class ConfirmDialog extends Dialog {
- constructor(content, title) {
- super(content, title);
- }
-
- async show() {
- this.addButton("confirm-button", true);
- this.addButton("cancel-button", false);
-
- return super.show();
- }
-
-
- close() {
- if (Helper.isNull(this.result))
- {
- this.result = false;
- }
- return super.close();
- }
-}
-
-class FlashMessenger {
- static deleteMessage(_idNumber, _delayInMilliSeconds) {
- _delayInMilliSeconds = Helper.nonNull(_delayInMilliSeconds, 0);
- setTimeout(function () {
- let elem = document.getElementById("flashMessage" + _idNumber);
- elem.fadeOut(.2).then(function () {
- elem.remove();
- });
- }, _delayInMilliSeconds);
- }
-
- static addMessage(messageType, messageText, timeToShow, translate){
-
- let translationArgs = null;
- if (Helper.isNull(messageText) || typeof messageText === "object")
- {
- translationArgs = messageText;
- messageText = messageType;
- messageType = FlashMessenger.MESSAGE_TYPE_SUCCESS;
- translate = true;
- }
- translate = Helper.nonNull(translate, false);
-
- let id = FlashMessenger.messageCount;
-
- let wrapper = document.createElement("div");
-
- let _flashMessage = document.createElement("div");
- _flashMessage.className = "flashMessage " + messageType;
- _flashMessage.id = "flashMessage" + id;
- _flashMessage.style.opacity = '0';
- _flashMessage.addEventListener("click", function () {
- FlashMessenger.deleteMessage(id);
- });
- _flashMessage.appendChild((translate) ? Translator.makePersistentTranslation(messageText, translationArgs, "span") : document.createTextNode(messageText));
-
- wrapper.appendChild(_flashMessage);
- document.getElementById("flashMessageContainer").appendChild(wrapper);
- _flashMessage.fadeIn();
- timeToShow = Helper.nonNull(timeToShow, FlashMessenger.defaultTimeToShow);
- if (timeToShow > 0) {
- FlashMessenger.deleteMessage(FlashMessenger.messageCount, timeToShow);
- }
- FlashMessenger.messageCount++;
- }
-}
-
-FlashMessenger.messageCount = 0;
-FlashMessenger.defaultTimeToShow = 3500;
-FlashMessenger.LENGTH_SHORT= 1000;
-
-FlashMessenger.MESSAGE_TYPE_SUCCESS = 'success';
-FlashMessenger.MESSAGE_TYPE_ERROR = 'error';
-FlashMessenger.MESSAGE_TYPE_DEFAULT = 'default';
-FlashMessenger.MESSAGE_TYPE_INFO = 'info';
-FlashMessenger.MESSAGE_TYPE_WARNING = 'warning';
-
-class AbstractService{
- constructor(gapiHandler)
- {
- this.gapiHandler = gapiHandler;
- }
-}
-
-class AbstractGapiResponse extends ChainAble{
- constructor(gameService, params)
- {
- super();
- this.gameService = gameService;
- if (Helper.isNotNull(params))
- {
- this.setValues(params);
- }
- }
- setValues(params){}
- load(){}
-}
-
-class Achievement extends AbstractGapiResponse {
- setHiddenIconUrl(hiddenIconUrl)
- {
- this.hiddenIconUrl = hiddenIconUrl;
- }
-
- setValues(params) {
- let self = this;
- this._chain(params)._chain(function (res) {
- self.achievementType = res["achievementType"];
- self.description = res["description"];
- self.experiencePoints = res["experiencePoints"];
- self.id = res["id"];
- self.initialState = res["initialState"];
- self.isRevealedIconUrlDefault = res["isRevealedIconUrlDefault"];
- self.isUnlockedIconUrlDefault = res["isUnlockedIconUrlDefault"];
- self.name = res["name"];
- self.revealedIconUrl = res["revealedIconUrl"];
- self.unlockedIconUrl = res["unlockedIconUrl"];
-
- self.achievementState = res["achievementState"];
- // self.experiencePoints = res["experiencePoints"]; //oben bereits gesetzt
- // self.id = res["id"]; //oben bereits gesetzt
- self.lastUpdatedTimestamp = res["lastUpdatedTimestamp"];
- });
- return this.promise;
- }
-
- show(elem) {
- let self = this;
- this._chain(function () {
- let achievementImg = elem.querySelector(".achievement-img");
- let achievementTitle = elem.querySelector(".achievement-title");
- let achievementDescription = elem.querySelector(".achievement-description");
- let achievementLastTimestamp = elem.querySelector(".achievement-lastTimestamp");
- let achievementXp = elem.querySelector(".achievement-xp");
-
- if (self.achievementState === "UNLOCKED") {
- achievementImg.src = self.unlockedIconUrl;
- achievementLastTimestamp.innerText = Helper.strftime("%d %a %Y", parseInt(self.lastUpdatedTimestamp));
- }
- else if (self.achievementState === "REVEALED") {
- achievementImg.src = self.revealedIconUrl;
- }
- else {
- achievementImg.src = self.hiddenIconUrl;
- achievementTitle.appendChild(Translator.makePersistentTranslation("achievement-hidden-title"));
- achievementDescription.appendChild(Translator.makePersistentTranslation("achievement-hidden-description"));
- return;
- }
-
- achievementTitle.innerText = self.name;
- achievementDescription.innerText = self.description;
- achievementXp.innerText = self.experiencePoints+" XP";
- });
- return this.promise;
- }
-}
-
-class AchievementList extends AbstractGapiResponse {
- constructor(gameService, params) {
- super(gameService, params);
- this.removedAchievementIds = [];
- }
-
- setHiddenImgLink(hiddenImgLink) {
- this.hiddenIconUrl = hiddenImgLink;
- }
-
- setRemovedAchievementIds(removedAchievementIds) {
- this.removedAchievementIds = removedAchievementIds;
- }
-
- load(maxResults, pageToken, language) {
- return this.setValues(Promise.all([this.gameService.getAchievements(maxResults, pageToken, null, language), this.gameService.getPlayerAchievements(null, maxResults, pageToken, null, language)]).then(function (res) {
- if (Helper.isNotNull(res[0]["items"]) && Helper.isNotNull(res[1]["items"])) {
- for (let i = 0, n = Math.min(res[0]["items"].length, res[1]["items"].length); i < n; i++) {
- for (let key in res[1]["items"][i]) {
- res[0]["items"][i][key] = res[1]["items"][i][key];
- }
- }
- }
- return res[0];
- })
- );
- }
-
- setValues(params) {
- let self = this;
- this._chain(params)._chain(function (res) {
- let promises = [];
-
- self.nextPageToken = res["nextPageToken"];
-
- self.items = [];
- if (Helper.isNotNull(res["items"])) {
- for (let i = 0, n = res["items"].length; i < n; i++) {
- if (self.removedAchievementIds.indexOf(res["items"][i]["id"]) === -1) {
-
- let achievement = new Achievement(self.gameService, res["items"][i]);
- achievement.setHiddenIconUrl(self.hiddenIconUrl);
- self.items.push(achievement);
- promises.push(achievement.promise);
- }
- }
- }
- return Promise.all(promises);
- });
- return this.promise;
- }
-
- show(elem) {
- let self = this;
- this._chain(function () {
- let nextButton = elem.querySelector("#achievement-list-next-button");
- let achievementTemplate = elem.querySelector("#achievement-list-achievement-template");
- let parentAchievementTemplate = achievementTemplate.parentElement;
- parentAchievementTemplate.removeAllChildren();
- achievementTemplate.id = "";
-
- let promises = [];
- for (let i = 0, n = self.items.length; i < n; i++) {
- let achievementElem = Helper.cloneNode(achievementTemplate);
- promises.push(self.items[i].show(achievementElem));
- parentAchievementTemplate.appendChild(achievementElem);
- }
- return Promise.all(promises);
- });
- return this.promise;
- }
-}
-
-class GameService extends AbstractService {
- getLeaderboards(maxResults, pageToken, language, consistencyToken) {
- language = Helper.nonNull(language, Translator.currentLanguage);
- return this.gapiHandler.promise.then(function () {
- return new Promise(function (resolve) {
- gapi["client"]["games"]["leaderboards"]["list"]({
- "maxResults": maxResults,
- "consistencyToken": consistencyToken,
- "pageToken": pageToken,
- "language": language
- })["execute"](function (response) {
- resolve(response);
- });
- });
- });
- }
-
- getScoresAroundPlayer(leaderboardId, collection, timeSpan, maxResults, pageToken, resultsAbove, returnTopIfAbsent, consistencyToken, language) {
- language = Helper.nonNull(language, Translator.currentLanguage);
- return this.gapiHandler.promise.then(function () {
- return new Promise(function (resolve) {
- gapi["client"]["games"]["scores"]["listWindow"]({
- "collection": collection,
- "leaderboardId": leaderboardId,
- "timeSpan": timeSpan,
- "consistencyToken": consistencyToken,
- "language": language,
- "maxResults": maxResults,
- "pageToken": pageToken,
- "resultsAbove": resultsAbove,
- "returnTopIfAbsent": returnTopIfAbsent
- })["execute"](function (response) {
- resolve(response);
- });
- });
- });
- }
-
- getAchievements(maxResults, pageToken, consistencyToken, language) {
- language = Helper.nonNull(language, Translator.currentLanguage);
- return this.gapiHandler.promise.then(function () {
- return new Promise(function (resolve) {
- gapi["client"]["games"]["achievementDefinitions"]["list"]({
- "consistencyToken": consistencyToken,
- "language": language,
- "maxResults": maxResults,
- "pageToken": pageToken,
- })["execute"](function (response) {
- resolve(response);
- });
- });
- });
- }
-
- getPlayerAchievements(playerId, maxResults, pageToken, consistencyToken, language) {
- playerId = Helper.nonNull(playerId, "me");
- language = Helper.nonNull(language, Translator.currentLanguage);
- return this.gapiHandler.promise.then(function () {
- return new Promise(function (resolve) {
- gapi["client"]["games"]["achievements"]["list"]({
- "playerId": playerId,
- "consistencyToken": consistencyToken,
- "language": language,
- "maxResults": maxResults,
- "pageToken": pageToken,
- })["execute"](function (response) {
- resolve(response);
- });
- });
- });
- }
-
- submitScore(leaderboardId, score) {
- return this.gapiHandler.promise.then(function () {
- return new Promise(function (resolve) {
- gapi["client"]["games"]["scores"]["submit"]({
- "leaderboardId": leaderboardId,
- "score": score
- })["execute"](function (response) {
- resolve(response);
- });
- });
- });
- }
-
- revealAchievement(achievementId) {
- return this.gapiHandler.promise.then(function () {
- return new Promise(function (resolve) {
- gapi["client"]["games"]["achievements"]["reveal"]({
- "achievementId": achievementId
- })["execute"](function (response) {
- resolve(response);
- });
- });
- });
- }
-
- unlockAchievement(achievementId, showIsNewAchievement) {
- return this.gapiHandler.promise.then(function () {
- return new Promise(function (resolve) {
- gapi["client"]["games"]["achievements"]["unlock"]({
- "achievementId": achievementId
- })["execute"](function (response) {
- resolve(response);
- });
- });
- }).then(function(response){
- if (showIsNewAchievement && response["newlyUnlocked"])
- {
- FlashMessenger.addMessage(FlashMessenger.MESSAGE_TYPE_SUCCESS, Translator.translate("new-unlocked-achievement"));
- }
- });
- }
-}
-
-GameService.COLLECTION_PUBLIC = "PUBLIC";
-GameService.COLLECTION_SOCIAL = "SOCIAL";
-GameService.COLLECTION_SOCIAL_1P = "SOCIAL_1P";
-
-GameService.TIME_SPAN_ALL_TIME = "ALL_TIME";
-GameService.TIME_SPAN_DAILY = "DAILY";
-GameService.TIME_SPAN_WEEKLY = "WEEKLY";
-
-class GapiPlayer extends AbstractGapiResponse{
- setValues(params)
- {
- let self = this;
- this._chain(params)._chain(function(res){
- self.playerId = res["playerId"];
- self.displayName = res["displayName"];
- self.avatarImageUrl = res["avatarImageUrl"];
- self.experienceInfo = res["experienceInfo"];
- // self.bannerUrlPortrait = res["scoreValue"];
- // self.formattedScore = res["formattedScore"];
- // self.timeSpan = res["timeSpan"];
- // self.writeTimestampMillis = res["writeTimestampMillis"];
- // self.scoreTag = res["scoreTag"];
- });
- return this.promise;
- }
-}
-
-class Score extends AbstractGapiResponse
-{
- setValues(params)
- {
- let self = this;
- this._chain(params)._chain(function(res){
- self.player = new GapiPlayer(self.gameService, res["player"]);
- self.scoreRank = res["scoreRank"];
- self.formattedScoreRank = res["formattedScoreRank"];
- self.scoreValue = res["scoreValue"];
- self.formattedScore = res["formattedScore"];
- self.timeSpan = res["timeSpan"];
- self.writeTimestampMillis = res["writeTimestampMillis"];
- self.scoreTag = res["scoreTag"];
-
- return self.player.promise;
- });
- return this.promise;
- }
-}
-
-class Leaderboard extends AbstractGapiResponse {
- setValues(params) {
- let self = this;
- this.promise = this.promise.then(function () {
- return Promise.resolve(params);
- }).then(function (res) {
- let promises = [];
-
- self.nextPageToken = res["nextPageToken"];
- self.previousPageToken = res["prevPageToken"];
- self.numScores = res["numScores"];
- self.playerScore = new Score(self.gameService, res["playerScore"]);
-
- promises.push(self.playerScore.promise);
-
- self.items = [];
- if (Helper.isNotNull(res["items"])) {
- for (let i = 0, n = res["items"].length; i < n; i++) {
- self.items.push(new Score(self.gameService, res["items"][i]));
- promises.push(self.items[i].promise);
- }
- }
-
- return Promise.all(promises);
- });
- return this.promise;
- }
-
- setLeaderboardId(leaderboardId) {
- this.leaderboardId = leaderboardId;
- }
-
- load(maxResults, pageToken, resultsAbove) {
- return this.setValues(this.gameService.getScoresAroundPlayer(this.leaderboardId, this.collection, this.timeSpan, maxResults, pageToken, resultsAbove));
- }
-
- setCollection(collection) {
- this.collection = collection;
- }
-
- setTimeSpan(timeSpan) {
- this.timeSpan = timeSpan;
- }
-
- setDisplayName(name)
- {
- this.displayName = name;
- }
-
- show(elem, buildTimeSelect, buildCollectionSelect, isTime) {
- buildCollectionSelect = Helper.nonNull(buildCollectionSelect, true);
- buildTimeSelect = Helper.nonNull(buildTimeSelect, true);
- isTime = Helper.nonNull(isTime, false);
- let args = arguments;
-
- let self = this;
- this._chain(function () {
- let prevButton = elem.querySelector("#leaderboard-previous-button");
- let nextButton = elem.querySelector("#leaderboard-next-button");
- let scoreTemplate = elem.querySelector("#leaderboard-score-template");
- let parentScoreElem = scoreTemplate.parentElement;
- parentScoreElem.removeAllChildren();
-
- let timeElem = self._buildTime(buildTimeSelect);
- elem.querySelector("#leaderboard-time-span").removeAllChildren().appendChild(timeElem);
-
- let collectionElem = self._buildCollection(buildCollectionSelect);
- elem.querySelector("#leaderboard-collection").removeAllChildren().appendChild(collectionElem);
-
- timeElem.onchange = function () {
- self._updateWithDataFromElem(elem, parentScoreElem, scoreTemplate, args);
- };
-
- collectionElem.onchange = function () {
- self._updateWithDataFromElem(elem, parentScoreElem, scoreTemplate, args);
- };
-
- for (let i = 0, n = self.items.length; i < n; i++) {
- let score = self.items[i];
- let scoreElem = Helper.cloneNode(scoreTemplate);
- scoreElem.querySelector(".leaderboard-rank").innerText = score.scoreRank;
- scoreElem.querySelector(".leaderboard-player-img").src = score.player.avatarImageUrl;
- scoreElem.querySelector(".leaderboard-player-name").innerText = score.player.displayName;
- scoreElem.querySelector(".leaderboard-points").innerText = (isTime)?Helper.strftime("%H:%M:%S", new Date(parseInt(score.scoreValue)), true):score.formattedScore;
- scoreElem.id = "";
-
- if (Helper.isNotNull(self.playerScore) && Helper.isNotNull(self.playerScore.player) && score.player.playerId === self.playerScore.player.playerId) {
- scoreElem.classList.add("leaderboard-current-player");
- }
- parentScoreElem.appendChild(scoreElem);
- }
- if (self.items.length === 0)
- {
- parentScoreElem.appendChild(Translator.makePersistentTranslation("no-scores-available"));
- }
-
- });
- return this.promise;
- }
-
- _buildCollection(buildCollectionSelect) {
- if (buildCollectionSelect) {
- let select = document.createElement("select");
- let publicOption = document.createElement("option");
- publicOption.value = GameService.COLLECTION_PUBLIC;
- publicOption.innerHTML = Translator.translate(GameService.COLLECTION_PUBLIC);
- publicOption.dataset["translate"] = GameService.COLLECTION_PUBLIC;
-
- if (GameService.COLLECTION_PUBLIC === this.collection) {
- publicOption.selected = true;
- }
-
- let socialOption = document.createElement("option");
- socialOption.value = GameService.COLLECTION_SOCIAL;
- socialOption.innerHTML = Translator.translate(GameService.COLLECTION_SOCIAL);
- socialOption.dataset["translate"] = GameService.COLLECTION_SOCIAL;
-
- if (GameService.COLLECTION_SOCIAL === this.collection) {
- socialOption.selected = true;
- }
-
- select.appendChild(socialOption);
- select.appendChild(publicOption);
- return select;
- }
- else {
- return Translator.makePersistentTranslation(this.collection);
- }
- }
-
- _updateWithDataFromElem(rootElem, scoreTable, scoreTemplate, args) {
- let loadingSymbol = Helper.createLoadingSymbol();
- rootElem.replaceWith(loadingSymbol);
- scoreTable.removeAllChildren().appendChild(scoreTemplate);
-
- let collectionElem = rootElem.querySelector("#leaderboard-collection select");
- if (Helper.isNotNull(collectionElem)) {
- this.collection = collectionElem.options[collectionElem.selectedIndex].value;
- }
-
- let timeSpanElem = rootElem.querySelector("#leaderboard-time-span select");
- if (Helper.isNotNull(timeSpanElem)) {
- this.timeSpan = timeSpanElem.options[timeSpanElem.selectedIndex].value;
- }
-
- this.load();
- this.show.apply(this, args).then(function () {
- loadingSymbol.replaceWith(rootElem);
- });
- }
-
- _buildTime(buildTimeSelect) {
- if (buildTimeSelect) {
- let select = document.createElement("select");
- let allTime = document.createElement("option");
- allTime.value = GameService.TIME_SPAN_ALL_TIME;
- allTime.innerHTML = Translator.translate(GameService.TIME_SPAN_ALL_TIME);
- allTime.dataset["translate"] = GameService.TIME_SPAN_ALL_TIME;
-
- if (GameService.TIME_SPAN_ALL_TIME === this.timeSpan) {
- allTime.selected = true;
- }
-
- let weeklyOption = document.createElement("option");
- weeklyOption.value = GameService.TIME_SPAN_WEEKLY;
- weeklyOption.innerHTML = Translator.translate(GameService.TIME_SPAN_WEEKLY);
- weeklyOption.dataset["translate"] = GameService.TIME_SPAN_WEEKLY;
-
- if (GameService.TIME_SPAN_WEEKLY === this.timeSpan) {
- weeklyOption.selected = true;
- }
-
- let dailyOption = document.createElement("option");
- dailyOption.value = GameService.TIME_SPAN_DAILY;
- dailyOption.innerHTML = Translator.translate(GameService.TIME_SPAN_DAILY);
- dailyOption.dataset["translate"] = GameService.TIME_SPAN_DAILY;
-
- if (GameService.TIME_SPAN_DAILY === this.timeSpan) {
- dailyOption.selected = true;
- }
-
- select.appendChild(dailyOption);
- select.appendChild(weeklyOption);
- select.appendChild(allTime);
- return select;
- }
- else {
- return Translator.makePersistentTranslation(this.timeSpan);
- }
- }
-}
-
-class GapiHandler {
- constructor() {
- this.loginCallbacks = [];
- this.games = new GameService(this);
- }
-
- init() {
- this.promise = new Promise(function (resolver) {
- let scriptElem = document.createElement("script");
- scriptElem.src = "https://apis.google.com/js/api.js";
- scriptElem.async = true;
- scriptElem.defer = true;
- scriptElem.onload = resolver;
- scriptElem.onreadystatechange = function () {
- if (this.readyState === "complete") {
- resolver();
- }
- };
- document.body.appendChild(scriptElem);
- }).then(function () {
- window["gapi"] = gapi;
- });
- return this.promise;
- }
-
- load(libs) {
- this.promise = this.promise.then(function () {
- return new Promise(function (resolver) {
- gapi["load"](libs, resolver);
- });
- });
- return this.promise;
- }
-
- initClient(apiKey, clientId, scope, discoveryDocs, fetchBasicProfile, uxMode) {
- scope = Helper.nonNull(scope, "profile");
- fetchBasicProfile = Helper.nonNull(fetchBasicProfile, false);
- discoveryDocs = Helper.nonNull(discoveryDocs, []);
- uxMode = Helper.nonNull(uxMode,"popup");
- let self = this;
- this.promise = this.promise.then(function () {
- return gapi["client"]["init"]({
- "apiKey": apiKey,
- "discoveryDocs": discoveryDocs,
- "clientId": clientId,
- "scope": scope,
- "fetch_basic_profile":fetchBasicProfile,
- "ux_mode":uxMode
- });
- }).then(function () {
- let authInstance = gapi["auth2"]["getAuthInstance"]();
- authInstance["isSignedIn"]["listen"](function (isLoggedIn) {
- for (let i = 0, n = self.loginCallbacks.length; i < n; i++) {
- self.loginCallbacks[i](isLoggedIn);
- }
- });
- });
- return this.promise;
- }
-
- loadClient(lib, version)
- {
- this.promise = this.promise.then(function () {
- return new Promise(function (resolver) {
- gapi["client"]["load"](lib, version, resolver);
- });
- });
- return this.promise;
- }
-
- addLoginCallback(callback) {
- this.loginCallbacks.push(callback);
- let authInstance = gapi["auth2"]["getAuthInstance"]();
- callback(authInstance["isSignedIn"]["get"]());
- }
-
- addLoginAction(app, callback) {
- let self = this;
- callback = Helper.nonNull(callback, function(){
- self.login();
- });
- this.loginAction = new MenuAction("login", callback, MenuAction.SHOW_NEVER, 10001);
- app.addDefaultAction(this.loginAction);
- ActionBarMenu.currentMenu.addAction(this.loginAction.copy());
- }
-
- removeLoginAction(app) {
- app.removeDefaultAction(this.loginAction);
- }
-
- login() {
- this.promise = this.promise.then(function () {
- let authInstance = gapi["auth2"]["getAuthInstance"]();
- return authInstance["signIn"]();
- });
- return this.promise;
- }
-
- logout() {
- this.promise = this.promise.then(function () {
- let authInstance = gapi["auth2"]["getAuthInstance"]();
- return authInstance["signOut"]();
- });
- return this.promise;
- }
-
- isLoggedIn() {
- return this.promise.then(function () {
- let authInstance = gapi["auth2"]["getAuthInstance"]();
- return authInstance["isSignedIn"]["get"]();
- })
- }
-}
-
-class MyDb {
- constructor(dbName, version) {
- this.queryPromise = new Promise(async (resolve, reject) => {
- let indexedDB = null;
- if (window["sqlite"]){
- indexedDB = new Promise(sqliteResolve => {
- function testSqlLiteResolve(){
- if (window["sqliteIndexedDB"]){
- sqliteResolve(window["sqliteIndexedDB"]);
- }
- else {
- setTimeout(testSqlLiteResolve, 200);
- }
- }
- testSqlLiteResolve();
- });
- }
- else {
- indexedDB = Promise.resolve(window["myIndexedDB"] || window["indexedDB"] || window["mozIndexedDB"]|| window["webkitIndexedDB"]|| window["msIndexedDB"] || window["shimIndexedDB"]);
- }
- this.indexeddb = (await indexedDB);
- this._conn = this.indexeddb.open(dbName, version);
-
- let myDB = this;
- this._conn.onupgradeneeded = function (upgradeEvent) {
- try {
- myDB.upgrade(myDB._conn.result, upgradeEvent.oldVersion, upgradeEvent.newVersion, upgradeEvent);
- }
- catch(e){
- reject(e);
- throw e;
- }
- };
- myDB._conn.onsuccess = function (e) {
- myDB._db = myDB._conn.result;
- resolve(e);
- };
- });
- }
-
- openTransaction(name, transactionMode, callback) {
- let myDb = this;
- if (typeof transactionMode === 'function' && Helper.isNull(callback)) {
- callback = transactionMode;
- transactionMode = "read";
- }
-
- return this.queryPromise.then(function () {
- let res = null;
- try {
- res = myDb._conn.result.transaction(name, transactionMode);
- }
- catch (e) {
- console.warn(e);
- res = myDb._conn.result.transaction(name);
- }
- callback(res);
- });
- }
-
- openStore(name, transactionMode, callback) {
- if (typeof transactionMode === 'function' && Helper.isNull(callback)) {
- callback = transactionMode;
- transactionMode = "readonly";
- }
- return this.openTransaction(name, transactionMode, function (t) {
- callback(t.objectStore(name));
- });
- }
-
- saveObj(obj, objectStore) {
- let self = this;
- return new Promise(function (resolve) {
- self.openStore(objectStore, "readwrite", function (store) {
- let request = store.put(obj);
- request.onsuccess = resolve;
- request.onerror = function (e) {
- throw {
- "type": "indexed-db-error",
- "event": e
- }
- };
- });
- });
- }
-
- saveMany(manyObj, objectStore) {
- let self = this;
- return new Promise(function (resolve) {
- self.openStore(objectStore, "readwrite", function (store) {
- let promises = [];
- for (let i = 0, n = manyObj.length; i < n; i++) {
- promises.push(new Promise(function (resolveInner) {
- let request = store.put(manyObj[i]);
- request.onsuccess = resolveInner;
- request.onerror = function (e) {
- throw {
- "type": "indexed-db-error",
- "event": e
- }
- };
- }));
- }
- resolve(Promise.all(promises));
- });
- });
- }
-
- load(key, objectStore) {
- let self = this;
- return new Promise((resolve, reject) => {
- self.openStore(objectStore, function (store) {
- let request = store.get(key);
- request.onsuccess = function (e) {
- resolve(e.currentTarget.result);
- };
- request.onerror = function (e) {
- console.warn(e);
- throw {
- "type": "indexed-db-load-error",
- "event": e
- }
- };
- }).catch(e => {
- console.warn(e);
- reject(e);
- });
- });
- }
-
- loadAll(objectStore, query, count) {
- let self = this;
- return new Promise((resolve, reject) => {
- self.openStore(objectStore, function (store) {
- let request = store.getAll(query, count);
- request.onsuccess = function (e) {
- resolve(e.currentTarget.result);
- };
- request.onerror = function (e) {
- console.warn(e);
- throw {
- "type": "indexed-db-load-error",
- "event": e
- }
- };
- }).catch(e => {
- console.warn(e);
- reject(e);
- });
- });
- }
-
- loadMany(index, value, objectStore, limit, direction) {
- let self = this;
- return new Promise(function (resolve) {
- self.openStore(objectStore, function (store) {
- let indexRequest = store.index(index);
- indexRequest.onerror = function (e) {
- throw {
- "type": "indexed-db-index-error",
- "event": e
- }
- };
- let request = indexRequest.openCursor(value, direction);
- request.onerror = function (e) {
- throw {
- "type": "indexed-db-index-error",
- "event": e
- }
- };
- let objects = [];
- let numberResults = 0;
- request.onsuccess = function (e) {
- let cursor = e.target.result;
- if (cursor) {
- objects.push(cursor.value);
- numberResults++;
- if (Helper.isNull(limit) || numberResults < limit) {
- cursor.continue();
- return;
- }
- }
- resolve(objects);
- };
- });
- });
- }
-
- remove(id, objectStore) {
- let self = this;
- return new Promise(function (resolve) {
- self.openStore(objectStore, "readwrite", function (store) {
- let deleteRequest = store.delete(id);
- deleteRequest.onerror = function (e) {
- throw {
- "type": "indexed-db-delete-error",
- "event": e
- }
- };
- deleteRequest.onsuccess = function (e) {
- resolve();
- };
- });
- });
- }
-
- removeMany(ids, objectStore) {
- let self = this;
- return new Promise(function (resolve) {
- self.openStore(objectStore, "readwrite", function (store) {
- let promises = [];
- for (let i = 0, n = ids.length; i < n; i++) {
- let deleteRequest = store.delete(ids[i]);
- deleteRequest.onerror = function (e) {
- throw {
- "type": "indexed-db-delete-error",
- "event": e
- }
- };
- promises.push(new Promise(function (resolve) {
- deleteRequest.onsuccess = function () {
- resolve();
- };
- }));
- }
- resolve(Promise.all(promises));
- });
- });
- }
-
- removeWithIndex(index, value, objectStore) {
- let self = this;
- return new Promise(function (resolve) {
- self.openStore(objectStore, "readwrite", function (store) {
- let indexRequest = store.index(index);
- indexRequest.onerror = function (e) {
- throw {
- "type": "indexed-db-index-error",
- "event": e
- }
- };
- let request = indexRequest.openCursor(value);
- request.onerror = function (e) {
- throw {
- "type": "indexed-db-index-error",
- "event": e
- }
- };
- request.onsuccess = function (e) {
- let cursor = e.target.result;
- if (cursor) {
- cursor.delete();
- cursor.continue();
- }
- else {
- resolve();
- }
- };
- });
- });
- }
-
- removeAll(objectStore) {
- return new Promise((resolve) => {
- this.openStore(objectStore, "readwrite", (store) => {
- let req = store.clear();
- req.onerror = (e) => {
- throw {
- "type": "indexed-db-index-error",
- "event": e
- }
- };
- req.onsuccess = resolve;
- });
- })
- }
-
- upgrade(db) {
- };
-}
-
-class Prioritised {
- constructor(resultPromises, callback) {
- this.result = null;
- this.prioResult = -1;
- this.callback = null;
- this.hasResult = false;
- this.highestPrio = -1;
-
- let self = this;
- this.callbackCalledPromise = new Promise(function (resolver) {
- self.callbackCalledPromiseResolver = resolver;
- });
-
- this.endPromise = new Promise(function (resolver) {
- self.endPromiseResolver = resolver;
- });
-
- this.setCallback(callback);
-
- for (let k in resultPromises) {
- this.registerResultPromise(k, resultPromises[k]);
- }
- }
-
- async registerResultPromise(prio, promise) {
- this.highestPrio = Math.max(prio, this.highestPrio);
- let res = await Promise.resolve(promise);
- this._setResult(prio, res);
- }
-
- _setResult(prio, result) {
- if (this.prioResult <= prio || !this.hasResult) {
- this.hasResult = true;
-
- this.prioResult = prio;
- this.result = result;
- if (Helper.isNotNull(this.callback)) {
- this.callback(result, prio, this);
- this.callbackCalledPromiseResolver();
- }
-
- if (prio == this.highestPrio) {
- this.endPromiseResolver();
- }
- }
- }
-
- setCallback(callback) {
- this.callback = callback;
- if (this.hasResult && Helper.isNotNull(callback)) {
- callback(this.result, this.prioResult, this);
- this.callbackCalledPromiseResolver();
- }
- }
-
- getCallbackCalledPromise() {
- return this.callbackCalledPromise;
- }
-
- getEndPromise() {
- return this.endPromise;
- }
-}
-
-class ScriptLoader {
- static loadScript(scriptSrc) {
- if (Helper.isNotNull(ScriptLoader.scriptPromises[scriptSrc])) {
- return ScriptLoader.scriptPromises[scriptSrc];
- }
- else {
- let scriptPromise = new Promise(function (resolve) {
- let script = document.createElement("script");
- script.src = Helper.basePath(scriptSrc);
- script.onload = resolve;
-
- document.body.appendChild(script);
- });
- ScriptLoader.scriptPromises[scriptSrc] = scriptPromise;
- return scriptPromise;
- }
- }
- static loadCss(cssFile, media){
- if (Helper.isNotNull(ScriptLoader.cssPromises[cssFile])) {
- return ScriptLoader.cssPromises[cssFile];
- }
- else {
- media = Helper.nonNull(media, "all");
- let cssPromise = new Promise(function (resolve) {
- let link = document.createElement("link");
- link.rel='stylesheet';
- link.type="text/css";
- link.href = Helper.basePath(cssFile);
- link.media = media;
- link.onload = resolve;
-
- document.head.appendChild(link);
- });
- ScriptLoader.cssPromises[cssFile] = cssPromise;
- return cssPromise;
- }
- }
-}
-
-ScriptLoader.scriptPromises = {};
-ScriptLoader.cssPromises = {};
-
-class ShareButton {
- constructor(deviceType, icon, callback, shouldLoadImg)
- {
- this._deviceType = deviceType;
- this._icon = icon;
- this._callback = callback;
-
- if (Helper.nonNull(shouldLoadImg, false)){
- this._icon = ViewInflater.inflate(this._icon);
- }
- }
-
- shouldShowFor(deviceType)
- {
- return (deviceType === (deviceType & this._deviceType))
- }
-
- getIcon()
- {
- return this._icon;
- }
-
- getCallback()
- {
- return this._callback;
- }
-}
-ShareButton.TYPE_DESKTOP = 1;
-ShareButton.TYPE_MOBILE_APPLE = 2;
-ShareButton.TYPE_MOBILE_LEFTOVER = 4;
-ShareButton.TYPE_MOBILE = ShareButton.TYPE_MOBILE_APPLE+ShareButton.TYPE_MOBILE_LEFTOVER;
-ShareButton.TYPE_ALL = ShareButton.TYPE_DESKTOP+ShareButton.TYPE_MOBILE;
-
-AndroidBridge.addDefinition(() => {
- window["ShareButton"] = ShareButton;
- window["ShareButton"]["TYPE_ALL"] = ShareButton.TYPE_ALL;
-
-});
-
-class CopyShareButton extends ShareButton
-{
- constructor(icon, shouldLoadImg) {
- super(ShareButton.TYPE_ALL, icon, function (link) {
- try{
- let elementToCopy = document.createElement("div");
- elementToCopy.style.position = "fixed";
- elementToCopy.style.top = 0;
- elementToCopy.style.left = 0;
- elementToCopy.style.width = "0em";
- elementToCopy.style.height = "0em";
- elementToCopy.style.padding = 0;
- elementToCopy.style.border = "none";
- elementToCopy.style.outline = "none";
- elementToCopy.style.boxShadow = "none";
- elementToCopy.style.backgroundElement = "transparent";
- elementToCopy.style.color = "transparent";
- elementToCopy.innerText = link;
- document.body.appendChild(elementToCopy);
- Helper.select(elementToCopy);
- if (document.execCommand("copy")) {
- FlashMessenger.addMessage(FlashMessenger.MESSAGE_TYPE_SUCCESS, Translator.translate("copied"), 1800);
- }
- elementToCopy.remove();
- } catch(e) {
- console.error(e);
- }
- }, shouldLoadImg);
- }
-}
-
-class MultipleShareButton extends ShareButton{
- constructor(deviceType, icon, callbacks, shouldLoadImg)
- {
- if (Array.isArray(deviceType) && deviceType[0] instanceof ShareButton){
- let btn = deviceType[0];
- callbacks = deviceType;
- deviceType = btn._deviceType;
- icon = btn._icon;
- shouldLoadImg = Helper.nonNull(shouldLoadImg, icon);
- }
-
- super(deviceType, icon, function (link, element, event) {
- if (!Array.isArray(callbacks)){
- callbacks = [callbacks];
- }
- for (let i = 0; i < callbacks.length; i++) {
- if (callbacks[i] instanceof ShareButton){
- callbacks[i].getCallback()(link, element, event);
- }
- else {
- console.log(callbacks, i);
- callbacks[i](link, element, event);
- }
- }
- }, shouldLoadImg);
- }
-}
-
-class ShareManager {
- static init() {
- ShareManager.shareButtons = [];
- }
-
- static addShareButton(shareButton) {
- ShareManager.shareButtons.push(shareButton);
- }
-
- static generateDefaultShareElement(shareUrl) {
- return ShareManager.generateShareElement(shareUrl, ShareManager.getDefaultGenerateCallback());
- }
-
- static generateDefaultShareElementForButtons(shareUrl, buttons) {
- return ShareManager.generateShareElementForButtons(shareUrl, buttons, ShareManager.getDefaultGenerateCallback());
- }
-
- static generateShareElement(shareUrl, generateCallback) {
- return ShareManager.generateShareElementForButtons(shareUrl, ShareManager.shareButtons, generateCallback);
- }
-
- static generateShareElementForButtons(shareUrl, buttons, generateCallback) {
- let shareButtonElement = document.createElement("div");
- let currentDeviceType = ShareManager.getCurrentDeviceType();
- for (let i = 0, n = buttons.length; i < n; i++) {
- if (buttons[i].shouldShowFor(currentDeviceType)) {
- let elem = generateCallback(buttons[i], shareUrl);
- elem.onclick = function (event) {
- buttons[i].getCallback()(shareUrl, this, event);
- };
- shareButtonElement.appendChild(elem);
- }
- }
- return shareButtonElement;
- }
-
- static getCurrentDeviceType() {
- if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
- return ShareButton.TYPE_MOBILE_APPLE;
- }
- else if ((navigator.userAgent.match(/Android|BlackBerry|Opera Mini|IEMobile/i) !== null || (typeof window.orientation !== "undefined"))) {
- return ShareButton.TYPE_MOBILE_LEFTOVER;
- }
- else {
- return ShareButton.TYPE_DESKTOP;
- }
- }
-
- static getDefaultGenerateCallback() {
- return function (button) {
- let linkElement = document.createElement("a");
- linkElement.classList.add("share-icon");
- let iconUrl = button.getIcon();
- if (typeof iconUrl === "string") {
- let iconElement = document.createElement("img");
- iconElement.src = Helper.basePath(button.getIcon());
- iconElement.classList.add("share-icon");
- linkElement.appendChild(iconElement);
- }
- else {
- Promise.resolve(iconUrl).then(elem => {
- linkElement.appendChild(elem);
- });
- }
-
- return linkElement;
- }
- }
-}
-
-ShareManager.init();
-
-AndroidBridge.addDefinition("ShareManager.addShareButton", ShareManager.addShareButton);
-
-class SmsShareButton extends ShareButton
-{
- constructor(icon, shouldLoadImg) {
- super(ShareButton.TYPE_MOBILE, icon, function (link) {
- let linkToOpen = "";
- if (ShareManager.getCurrentDeviceType() === ShareButton.TYPE_MOBILE_APPLE) {
- linkToOpen = "sms:&body="+encodeURIComponent(link);
- }
- else {
- linkToOpen = "sms:?&body=" + encodeURIComponent(link);
- }
- window.open(linkToOpen, '_blank', "noopener");
- }, shouldLoadImg);
- }
-}
-
-class TelegramShareButton extends ShareButton {
- constructor(icon, shouldLoadImg) {
- super(ShareButton.TYPE_ALL, icon, function (link) {
- let linkToOpen = "https://t.me/share/url?url="+encodeURIComponent(link);
- window.open(linkToOpen, '_blank', "noopener");
- }, shouldLoadImg);
- }
-}
-
-class WhatsappShareButton extends ShareButton {
- constructor(icon, shouldLoadImg) {
- super(ShareButton.TYPE_ALL, icon, function (link) {
- let linkToOpen = "";
- if (ShareManager.getCurrentDeviceType() === ShareButton.TYPE_DESKTOP) {
- linkToOpen = "https://web.whatsapp.com/send?text="+encodeURIComponent(link);
- }
- else {
- linkToOpen = "whatsapp://send?text=" + encodeURIComponent(link);
- }
- window.open(linkToOpen, '_blank', "noopener");
- }, shouldLoadImg);
- }
-}
-
-class SimpleWS{
- static _initMe(ws, url, protocols) {
- ws._connectionPromise = new Promise(function (resolve) {
- ws._ws = new WebSocket(url, protocols);
- ws._ws.onopen = function () {
- resolve();
- for (let i = 0, n = ws._openListeners.length; i < n; i++) {
- if (Helper.isNotNull(ws._openListeners[i])) {
- ws._openListeners[i]();
- }
- }
- };
-
- ws._ws.onerror = function (err) {
- resolve(Promise.reject("WS-Error"));
- console.error(err);
- for (let i = 0, n = ws._errorListeners.length; i < n; i++) {
- if (Helper.isNotNull(ws._errorListeners[i])) {
- ws._errorListeners[i](err);
- }
- }
- };
-
- ws._ws.onclose = function (e) {
- console.log("ws-close");
- for (let i = 0, n = ws._closeListeners.length; i < n; i++) {
- if (Helper.isNotNull(ws._closeListeners[i])) {
- ws._closeListeners[i](e, ws._shouldReconnectAfterClose);
- }
- }
- if (ws._shouldReconnectAfterClose) {
- setTimeout(function () {
- SimpleWS._initMe(ws, url, protocols);
- }, 200);
- }
- };
-
- ws._ws.onmessage = function (message) {
- if (message.data === "pong") {
- ws.ping();
- return;
- }
-
- let jsonMessage = JSON.parse(message.data);
- for (let i = 0, n = ws._messageListeners.length; i < n; i++) {
- if (ws._messageListeners[i]) {
- ws._messageListeners[i](jsonMessage, message);
- }
- }
- };
- });
- }
-
- constructor(url, protocols, shouldReconnectAfterClose) {
- this._shouldReconnectAfterClose = Helper.nonNull(shouldReconnectAfterClose, true);
- this._ws = null;
-
- this._openListeners = [];
- this._errorListeners = [];
- this._messageListeners = [];
- this._closeListeners = [];
-
- this._connectionPromise = Promise.resolve();
- this._pong = null;
- this._ping = null;
-
- SimpleWS._initMe(this, url, protocols);
- this.activatePingPong();
- }
-
- ping(interval, answerTime) {
- interval = Helper.nonNull(interval, 5000);
- answerTime = Helper.nonNull(answerTime, 5000);
- if (this._pong !== null) {
- clearTimeout(this._pong);
- }
- if (this._ping !== null) {
- clearTimeout(this._ping);
- }
-
- let self = this;
- this._ping = setTimeout(function () {
- self.send({'action':"ping"});
- self._pong = setTimeout(function () {
- self._ws.close();
- }, answerTime);
- }, interval);
- }
-
- activatePingPong() {
- this.ping();
- }
-
- send(jsonMessage) {
- let ws = this;
- return this._connectionPromise.then(function () {
- ws._ws.send(JSON.stringify(jsonMessage));
- });
- }
-
- connectedPromise()
- {
- let self = this;
- return new Promise(function(resolve){
- self.addOpenListener(function(){
- resolve();
- }, true);
- })
- }
-
- promiseSend(jsonMessage)
- {
- let self = this;
- return this.connectedPromise().then(function(){
- return self.send(jsonMessage);
- });
- }
-
- close() {
- this._shouldReconnectAfterClose = false;
- this._ws.close();
- }
-
- addErrorListener(listener) {
- if (typeof listener === 'function') {
- return this._errorListeners.push(listener) - 1;
- }
- return -1;
- }
-
- removeErrorListener(listenerId) {
- if (listenerId < this._errorListeners.length && listenerId >= 0) {
- this._errorListeners[listenerId] = null;
- }
- }
-
- addCloseListener(listener, callNowIfClosed) {
- callNowIfClosed = Helper.nonNull(callNowIfClosed, false);
- if (typeof listener === 'function') {
- if (callNowIfClosed && this.status() !== WebSocket.OPEN) {
- listener();
- }
- return this._closeListeners.push(listener) - 1;
- }
- return -1;
- }
-
- removeCloseListener(listenerId) {
- if (listenerId < this._closeListeners.length && listenerId >= 0) {
- this._closeListeners[listenerId] = null;
- }
- }
-
- addOpenListener(listener, callNowIfOpen) {
- callNowIfOpen = Helper.nonNull(callNowIfOpen, false);
- if (typeof listener === 'function') {
- if (callNowIfOpen && this.status() === WebSocket.OPEN) {
- listener();
- }
- return this._openListeners.push(listener) - 1;
- }
- return -1;
- }
-
- removeOpenListener(listenerId) {
- if (listenerId < this._openListeners.length && listenerId >= 0) {
- this._openListeners[listenerId] = null;
- }
- }
-
- addMessageListener(listener) {
- if (typeof listener === 'function') {
- return this._messageListeners.push(listener) - 1;
- }
- return -1;
- }
-
- removeMessageListener(listenerId) {
- if (listenerId < this._messageListeners.length && listenerId >= 0) {
- this._messageListeners[listenerId] = null;
- }
- }
-
- status() {
- return this._ws.readyState;
- }
-}
-
-class Fragment extends Context
-{
- constructor(site, view)
- {
- super(view);
- this.site = site;
- this.active = true;
- }
-
- getSite()
- {
- return this.site;
- }
-
- isActive()
- {
- return this.active;
- }
-}
-
-class Theme
-{
- constructor(name, className, icon)
- {
- this._name = name;
- this._className = className;
- this._icon = icon;
- }
-}
-
-class DBTranslator extends Translator {
- _loadLanguage(language) {
- let self = this;
- return this._db.loadTranslationsForLang(language).then(function (res) {
- self._translations[language] = Object.assign(res, self._translations[language]);
- }).catch(function (err) {
- console.error("could not load lang " + language + " because of error: ", err);
- });
- }
-
- loadUserLanguage() {
- this._currentLanguage = null;
- let self = this;
- return this._db.getLanguage().then(function (userLanguage) {
- if (Helper.isNull(userLanguage) || self._supportedLanguages.indexOf(userLanguage) === -1) {
- let userLanguages = [];
- if (Helper.isNotNull(navigator.languages)) {
- userLanguages = navigator.languages.slice(0); //.slice(0) klont das Array. Behebt einen Bug in Firefox
- }
-
- if (navigator.language !== undefined) {
- userLanguages.push(navigator.language);
- }
- //sicherstellen, dass überhaupt eine Sprache gefunden wird
- userLanguages.push(self._baseLanguage);
-
- if (userLanguages !== undefined) {
- for (let i = 0, numLanguages = userLanguages.length; i < numLanguages; i++) {
- if (self._supportedLanguages.indexOf(userLanguages[i]) !== -1) {
- userLanguage = userLanguages[i];
- break;
- }
- }
- }
- }
- return self.setLanguage(userLanguage.toLowerCase())
- });
- }
-}
-
-function applyPolyfills() {
- if (!String.prototype.format) {
- String.prototype["format"] = function (args) {
- return this.replace(/{(\d+)}/g, function (match, number) {
- return args[number] !== undefined
- ? args[number]
- : match
- ;
- });
- };
- }
- Object["assign"] = Helper.nonNull(Object["assign"], function (base, obj) {
- base = Helper.nonNull(base, {});
- if (obj === null || typeof(obj) !== 'object' || 'isActiveClone' in obj)
- return base;
-
- // if (obj instanceof Date) {
- // temp = new obj.constructor(); //or new Date(obj);
- // }
- // else {
- // temp = obj.constructor();
- // }
-
- for (let key in obj) {
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
- obj['isActiveClone'] = null;
- base[key] = obj[key];
- delete obj['isActiveClone'];
- }
- }
-
- return base;
- });
-
- if (typeof window !== 'undefined') {
- if (Helper.isNotNull(window["Node"]) && !window["Node"]["prototype"]["removeAllChildren"]) {
- Node.prototype["removeAllChildren"] = function () {
- while (this.firstChild) {
- this.removeChild(this.firstChild);
- }
- return this;
- };
- }
-
- if (HTMLElement) {
- HTMLElement.prototype["fadeOut"] = Helper.nonNull(HTMLElement.prototype["fadeOut"],
- function (time, effect, delay) {
- time = Helper.nonNull(time, 0.5);
- effect = Helper.nonNull(effect, "ease-in-out");
- delay = Helper.nonNull(delay, 0);
- this.style.transition = "opacity " + time + "s " + effect + " " + delay + "s";
- let elem = this;
- let animPromise = new Promise(function (resolve) {
- let transEndLis = function (e) {
- elem.removeEventListener("transitionend", transEndLis);
- elem.removeEventListener("transitioncancel", transCancelledLis);
- elem.style.opacity = null;
- elem.style.transition = null;
- resolve(true, e);
- };
-
- let transCancelledLis = function (e) {
- elem.removeEventListener("transitionend", transEndLis);
- elem.removeEventListener("transitioncancel", transCancelledLis);
- elem.style.opacity = null;
- elem.style.transition = null;
- resolve(false, e);
- };
- elem.addEventListener("transitionend", transEndLis);
- elem.addEventListener("transitioncancel", transCancelledLis);
- //Fallback
- setTimeout(() => {
- resolve(false);
- }, (time + delay) * 1000);
- });
-
- //Nach Seitenneuzeichnen, damit chrome das immer macht (und FF auch)
- requestAnimationFrame(function () {
- requestAnimationFrame(function () {
- elem.style.opacity = 0;
- });
- });
- return animPromise
- });
-
- HTMLElement.prototype["fadeIn"] = Helper.nonNull(HTMLElement.prototype["fadeIn"], function (time, effect, delay) {
- time = Helper.nonNull(time, 0.5);
- effect = Helper.nonNull(effect, "ease-in-out");
- delay = Helper.nonNull(delay, 0);
- this.style.transition = "opacity " + time + "s " + effect + " " + delay + "s";
-
- let elem = this;
- let animPromise = new Promise(function (resolve) {
- let transEndLis = function (e) {
- elem.removeEventListener("transitionend", transEndLis);
- elem.removeEventListener("transitioncancel", transCancelledLis);
- elem.style.opacity = null;
- elem.style.transition = null;
- resolve(true, e);
- };
-
- let transCancelledLis = function (e) {
- elem.removeEventListener("transitionend", transEndLis);
- elem.removeEventListener("transitioncancel", transCancelledLis);
- elem.style.opacity = null;
- elem.style.transition = null;
- resolve(false, e);
- };
- elem.addEventListener("transitionend", transEndLis);
- elem.addEventListener("transitioncancel", transCancelledLis);
-
- if (getComputedStyle(elem).getPropertyValue("opacity") === "1") {
- resolve(false);
- }
- //Fallback
- setTimeout(() => {
- resolve(false);
- }, (time + delay) * 1000);
-
- //Nach Seitenneuzeichnen, damit chrome das immer macht (und FF auch)
- requestAnimationFrame(function () {
- requestAnimationFrame(function () {
- elem.style.opacity = 1;
- });
- });
- });
- return animPromise;
- });
- }
-
- if (Node) {
- Node.prototype["replaceWith"] = Helper.nonNull(Node.prototype["replaceWith"], function (elem) {
- this.parentElement.replaceChild(elem, this);
- });
- Node.prototype["remove"] = Helper.nonNull(Node.prototype["remove"], function () {
- this.parentElement.removeChild(this);
- });
- }
-
- if (Element) {
- Element.prototype.matches = Helper.nonNull(Element.prototype.matches, Helper.nonNull(Element.prototype["matchesSelector"], Element.prototype["webkitMatchesSelector"]));
-
- window["Element"]["prototype"]["closest"] = Helper.nonNull(window["Element"]["prototype"]["getAll"], function (s) {
- // if (!Element.prototype.matches)
- // Element.prototype.matches = Element.prototype.msMatchesSelector ||
- // Element.prototype.webkitMatchesSelector;
- //
- // if (!Element.prototype.closest)
- // Element.prototype.closest = function(s) {
- let el = this;
- if (!document.documentElement.contains(el)) return null;
- do {
- if (el.matches(s)) return el;
- el = el.parentElement;
- } while (el !== null);
- return null;
- // };
- });
- }
-
- window["IDBObjectStore"]["prototype"]["getAll"] = Helper.nonNull(window["IDBObjectStore"]["prototype"]["getAll"], function () {
- let res = {};
- let items = [];
- this.openCursor().onsuccess = function (e) {
- let cursor = e.target.result;
- if (Helper.isNotNull(cursor)) {
- items.push(cursor.value);
- cursor.continue();
- }
- else if (Helper.isNotNull(res.onsuccess)) {
- res.onsuccess({currentTarget: {result: items}});
- }
- };
- return res;
- });
- }
-
- String.prototype.startsWith = Helper.nonNull(String.prototype.startsWith, function (searchString, position) {
- position = position || 0;
- return this.indexOf(searchString, position) === position;
- });
-
- String.prototype.includes = Helper.nonNull(String.prototype.includes, function (searchString) {
- return this.indexOf(searchString) >= 0;
- });
-
- String.prototype.endsWith = Helper.nonNull(String.prototype.endsWith, function (searchString, position) {
- var subjectString = this.toString();
- if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
- position = subjectString.length;
- }
- position -= searchString.length;
- var lastIndex = subjectString.indexOf(searchString, position);
- return lastIndex !== -1 && lastIndex === position;
- });
-
-
- window["fetch"] = Helper.nonNull(window["fetch"], function (url, params) {
- console.log("customFetch", url);
- let request = null;
- if (window.XMLHttpRequest) { // Mozilla, Safari, ...
- request = new XMLHttpRequest();
- } else if (window.ActiveXObject) { // IE
- try {
- request = new ActiveXObject('Msxml2.XMLHTTP');
- }
- catch (e) {
- try {
- request = new ActiveXObject('Microsoft.XMLHTTP');
- }
- catch (e) {
- }
- }
- }
-
- let onloadPromise = new Promise((r) => {
- // this.result
- request.onload = r;
- request.onerror = function (err) {
- r(Promise.reject(err));
- };
- });
-
- let resultPromise = new Promise(function (resolve) {
-
- let response = {
- "json": function () {
- request.send();
-
- return onloadPromise.then(() => {
- return JSON.parse(request.responseText)
- });
- },
- "text": function () {
- request.send();
- return onloadPromise.then(() => request.responseText);
- },
- "arrayBuffer": () => {
- request.responseType = "arraybuffer";
- request.send();
- return onloadPromise.then(() => request.response);
- }
- };
- resolve(response);
- });
-
-
- request.open('get', url, true);
- // request.send();
- return resultPromise;
- });
-}
-
-export { AndroidBridge, App, ChainAble, CookieCompliance, ConfirmDialog, Dialog, FlashMessenger, AbstractService, AbstractGapiResponse, Achievement, AchievementList, GameService, GapiPlayer, Leaderboard, Score, GapiHandler, Helper, InitPromise, ActionBarMenu, Menu, MenuAction, OpenSubmenuAction, Submenu, MyDb, Prioritised, ScriptLoader, CopyShareButton, MultipleShareButton, ShareButton, ShareManager, SmsShareButton, TelegramShareButton, WhatsappShareButton, SimpleWS, AbstractSite, Context, Fragment, PauseSite, SiteContainer, SiteManager, SystemSettings, Theme, ThemeManager, DBTranslator, Translator, TranslatorDB, ViewInflater, applyPolyfills };
diff --git a/src/js/lib/pwa-user-management.js b/src/js/lib/pwa-user-management.js
deleted file mode 100755
index 5485355..0000000
--- a/src/js/lib/pwa-user-management.js
+++ /dev/null
@@ -1,551 +0,0 @@
-import { FlashMessenger, Helper, InitPromise, Translator, MenuAction, AbstractSite, Fragment, ScriptLoader, Menu } from './pwa-lib.js';
-import { DataManager, SettingsManager, Form, SettingsSite, LocalStorageSettingsFragment, Constants, DataSmartColumn, ImgConstSmartColumn, ListHelper, SmartColumn } from './pwa-core.js';
-
-class UserManager {
- static init(app) {
- UserManager.getMeUrl = null;
- UserManager.userData = {
- online: false,
- id: null,
- accesses: ["default"]
- };
- UserManager.app = app;
-
- UserManager.fetchMePromise = new Promise(function (resolve) {
- UserManager.fetchMePromiseResolver = resolve;
- });
- }
-
- static setData(data) {
- UserManager.userData = Object.assign(UserManager.userData, data);
- let siteManager = UserManager.app.getSiteManager();
-
- if (siteManager)
- siteManager.redrawCurrentActionBar();
- }
-
- static fetchMe(url) {
- UserManager.getMeUrl = Helper.nonNull(url, UserManager.getMeUrl);
- return DataManager.load(UserManager.getMeUrl).then(function (result) {
- if (result["success"]) {
- UserManager.setData(result["result"]);
- }
- UserManager.fetchMePromiseResolver();
- });
- }
-
- static logOut() {
- return DataManager.load("u/logout").then(function (data) {
- if (data["success"]) {
- UserManager.setData(data["result"]);
- let siteManager = UserManager.app.getSiteManager();
-
- if (siteManager)
- siteManager.refreshCurrentSite();
- FlashMessenger.addMessage(FlashMessenger.MESSAGE_TYPE_SUCCESS, Translator.translate("logged-out-successfully"));
- }
- });
- }
-
- static hasAccess(access) {
- // console.log("Has access", access, UserManager.userData["accesses"].indexOf(access), UserManager.userData);
- return (UserManager.userData["accesses"].indexOf(access) >= 0)
- }
-
- static addCurrentUserListener(userId, listener) {
- UserManager.addIsLoggedInListener(function (isLoggedIn) {
- listener(isLoggedIn && UserManager.isCurrentUser(userId));
- });
- }
-
- static addIsLoggedInListener(listener) {
- this.fetchMePromise.then(function () {
- listener(UserManager.isLoggedIn());
- });
- }
-
- static isCurrentUser(userId) {
- return UserManager.userData.id === userId;
- }
-
- static isLoggedIn() {
- return Helper.isNotNull(UserManager.userData) && Helper.isNotNull(UserManager.userData.id);
- }
-}
-UserManager.waitForData = true;
-
-
-InitPromise.addPromise(function(app){
- UserManager.init(app);
- let userManagerPromise = UserManager.fetchMe("u/me").then(function(){
- UserManager.addIsLoggedInListener(function (isLoggedIn) {
- if (isLoggedIn) {
- const settingsManager = SettingsManager.getInstance();
- const settings = Helper.cloneJson(settingsManager.getSettings());
- for (let k in settings) {
- settings[k]["value"] = JSON.stringify(settings[k]["value"]);
- }
- DataManager.send("u/syncSettings", settings).then(function(res){
- if (res["success"])
- {
- for (let k in res["result"])
- {
- res["result"][k]["value"] = JSON.parse(res["result"][k]["value"]);
- }
- settingsManager.setSettings(res["result"]);
- }
- });
- }
- });
- });
-
- if (UserManager.waitForData){
- return userManagerPromise;
- }
-});
-
-class UserAction extends MenuAction {
- constructor(title, callback, icon, order, access) {
- super(title, callback, icon, order);
- this._access = Helper.nonNull(access, "default");
- }
-
- getVisible() {
- // console.log("Action-access: ", this._access);
- return (super.getVisible() && UserManager.hasAccess(this._access));
- }
-
- getAccess() {
- return this._access;
- }
-
- copy(instance){
- let copy = super.copy(Helper.nonNull(instance, new UserAction()));
- copy._access = this._access;
- return copy;
- }
-}
-
-class NotAllowedSite extends AbstractSite{
- constructor(siteManager) {
- super(siteManager, 'userManagement/html/403.html');
- }
-}
-
-class UserSite extends AbstractSite {
-
- constructor(siteManager, view, deepLink, access) {
- super(siteManager, view, deepLink);
- this._access = access;
- }
-
- onConstruct(args) {
- if (!UserManager.hasAccess(this._access))
- {
- this.startSite(NotAllowedSite);
- this.finish({
- "error":403
- });
- return;
- }
- return super.onConstruct(args);
- }
-
- onStart(args) {
- if (!UserManager.hasAccess(this._access))
- {
- this.startSite(NotAllowedSite);
- this.finish({
- "error":403
- });
- return;
- }
- return super.onStart(args);
- }
-}
-
-class LoginForm extends Form {
-
- constructor(formElem, url, method, isCachable) {
- super(formElem, url, method, isCachable);
-
- let emailElem = formElem.querySelector("#email");
- let passwordElem = formElem.querySelector("#password");
-
- let listener = function(){
- emailElem.setCustomValidity("");
- passwordElem.setCustomValidity("");
- };
-
- emailElem.addEventListener("keydown", listener);
- passwordElem.addEventListener("keydown", listener);
- }
-}
-
-class RegistrationForm extends Form {
- constructor(formElem, url, method, isCachable) {
- super(formElem, url, method, isCachable);
-
- // this.pw1 = formElem.querySelector("#password1");
- // this.pw2 = formElem.querySelector("#password2");
-
- // let self=this;
- // this.pw1.addEventListener("change", function(){
- // self.checkPw();
- // });
- // this.pw2.addEventListener("change", function(){
- // self.checkPw();
- // });
- }
-
- checkPw(){
- // if (this.pw1.value !== this.pw2.value || this.pw1.value.length < 8)
- // {
- //
- // }
- }
-}
-
-class UserFragment extends Fragment{
-
- constructor(site, view, access) {
- super(site, view);
- this._access = access;
- }
-
- isActive() {
- return super.isActive() && UserManager.hasAccess(this._access);
- }
-}
-
-class PasswordSettingsFragment extends UserFragment{
- constructor(site)
- {
- super(site, "userManagement/html/fragments/passwordSettings.html", "online");
- }
- onFirstStart() {
- let res = super.onFirstStart();
- let form = new Form(document.getElementById("change-password-form"), "u/passwordSettings/set", "post");
- form.onSubmit(function(res){
- for (let i = 0, n = res.length; i < n; i++)
- {
- FlashMessenger.addMessage(res[i]);
- }
- form.setValues({
- "oldPassword":"",
- "newPassword1":"",
- "newPassword2":""
- });
- });
- return res;
- }
-}
-InitPromise.addPromise(function(){
- SettingsSite.addSettingsFragment("password-settings", PasswordSettingsFragment);
-});
-
-class SynchronizedSettingsFragment extends LocalStorageSettingsFragment {
- onFirstStart() {
- let res = super.onFirstStart();
- let settings = this.findBy(".setting", true);
- for (let i = 0, n = settings.length; i < n; i++) {
- settings[i].addEventListener("change", function () {
- let isCheckable = (this instanceof HTMLInputElement && (this.type === 'checkbox' || this.type === 'radio'));
- let value = this.value;
- let isChecked = isCheckable && this.checked;
- let name = this.name;
-
- UserManager.addIsLoggedInListener(function (isLoggedIn) {
- if (isLoggedIn) {
- let val = {
- "value": JSON.stringify(null),
- "lastUpdated": new Date().getTime()
- };
- if (isCheckable && isChecked || !isCheckable) {
- val["value"] = JSON.stringify(value);
- }
- let res = {};
- res[name] = val;
-
- DataManager.send("u/syncSettings", {
- "settings": JSON.stringify(res)
- });
- }
- });
- });
- }
- return res;
- }
-}
-
-class UserSettingsFragment extends UserFragment{
- constructor(site)
- {
- super(site, "userManagement/html/fragments/userSettings.html", "online");
- }
-
- onFirstStart() {
- let res = super.onFirstStart();
- (new Form(document.getElementById("user-settings-form"), "u/userSettings/set", "post")).load('u/userSettings').onSubmit(function(res){
- for (let i = 0, n = res.length; i < n; i++)
- {
- FlashMessenger.addMessage(res[i]);
- }
- });
- return res;
- }
-}
-InitPromise.addPromise(function(){
- SettingsSite.addSettingsFragment("user-settings", UserSettingsFragment);
-});
-
-class EditUserRolesSite extends UserSite {
- constructor(siteManager) {
- super(siteManager, 'userManagement/html/editUserRoles.html', "userRoles", "admin");
- }
-
- onConstruct(args) {
- let res = super.onConstruct(args);
- this.userId = args["id"];
-
- let self = this;
- return Promise.all([
- ScriptLoader.loadScript(Constants.SCRIPTS.LIST_JS),
- DataManager.load("u/userRoles" + DataManager.buildQuery({"id": self.userId})).then(function (res) {
- if (!res["success"]) {
- FlashMessenger.addMessage(res["errors"][0]);
- self.finish();
- }
- else {
- self.setUserRoles(res["result"]["userRoles"]);
- self.setAvailableRoles(res["result"]["availableRoles"]);
- self.setUsername(res["result"]["username"]);
- }
- })
- ]).then(function () {
- return res;
- });
- }
-
- onFirstStart() {
- this.findBy("#username").innerHTML = this.username;
-
- const userRolesElement = this.findBy("#userRoles");
- const availableRolesElement = this.findBy("#availableRoles");
-
- const imgColumnUserRoles = new ImgConstSmartColumn("img/minus.png", "", false);
- const imgColumnAvailableRoles = new ImgConstSmartColumn("img/plus.png", "", false);
-
- const userRolesColumns = [
- new DataSmartColumn("id"),
- new SmartColumn("name", "name"),
- new SmartColumn("description", "description"),
- imgColumnUserRoles,
- ];
-
- const availableRolesColumns = [
- new DataSmartColumn("id"),
- new SmartColumn("name", "name"),
- new SmartColumn("description", "description"),
- imgColumnAvailableRoles,
- ];
-
- const userRolesListHelper = new ListHelper(userRolesElement, userRolesColumns, this.userRoles);
- const availableRolesListHelper = new ListHelper(availableRolesElement, availableRolesColumns, this.availableRoles);
-
- const userRolesTable = userRolesListHelper.createTable();
- const availableRolesTable = availableRolesListHelper.createTable();
-
- let self = this;
- const changeRoleFunction = function (roleId, addRole) {
- userRolesListHelper.setBusy(true);
- availableRolesListHelper.setBusy(true);
-
- return DataManager.send("u/changeUserRole", {
- "id": roleId,
- "userId": self.userId,
- "add": addRole
- }).then(function (res) {
- userRolesListHelper.setBusy(false);
- availableRolesListHelper.setBusy(false);
-
- if (!res["success"]) {
- FlashMessenger.addMessage(res["errors"][0]);
- return res;
- }
-
- let removingTable = null;
- let addingTable = null;
- if (res["result"]["hasRole"]) {
- removingTable = availableRolesTable;
- addingTable = userRolesTable;
- }
- else {
- addingTable = availableRolesTable;
- removingTable = userRolesTable;
- }
-
- const rowData = removingTable.get("id", roleId);
- if (rowData.length === 1) {
- addingTable.add(rowData[0].values());
- removingTable.remove("id", roleId);
- }
-
- return res;
- });
- };
-
- imgColumnUserRoles.setClickListener(function (cell) {
- let userRoleId = cell.closest("tr")["dataset"]["id"];
- changeRoleFunction(userRoleId, false);
- });
-
- imgColumnAvailableRoles.setClickListener(function (cell) {
- let availableRoleId = cell.closest("tr")["dataset"]["id"];
- changeRoleFunction(availableRoleId, true);
- });
-
- }
-
- setUserRoles(userRoles) {
- this.userRoles = userRoles;
- }
-
- setAvailableRoles(availableRoles) {
- this.availableRoles = availableRoles;
- }
-
- setUsername(username) {
- this.username = username;
- }
-}
-
-InitPromise.addPromise(function (app) {
- app.addDeepLink("userRoles", EditUserRolesSite);
- app.addDefaultAction(new UserAction('userRoles', function(){
- app.startSite(EditUserRolesSite);
- }, null, 1100, "admin"));
-});
-
-class ForgotPasswordSite extends UserSite{
-
- constructor(siteManager) {
- super(siteManager, 'userManagement/html/forgotPassword.html', "forgotPassword", "offline");
- }
-
- onFirstStart() {
- let self = this;
- (new Form(document.getElementById("forgot-password-form"), "u/newPassword", "post")).onSubmit(function(res){
- // UserManager.setData(res);
- // self.startStartsite();
- FlashMessenger.addMessage(FlashMessenger.MESSAGE_TYPE_SUCCESS, Translator.translate("new-password-code-send"));
- self.finish();
- });
- }
-}
-InitPromise.addPromise(function(app){
- app.addDeepLink("forgotPassword", ForgotPasswordSite);
-});
-
-class LoginSite extends UserSite {
- constructor(siteManager) {
- super(siteManager, 'userManagement/html/login.html', "login", "offline");
- }
-
- onFirstStart() {
- let self = this;
- (new LoginForm(document.getElementById("login-form"), "u/login", "post")).onSubmit(function (res) {
- UserManager.setData(res);
- self.startStartsite();
- FlashMessenger.addMessage(FlashMessenger.MESSAGE_TYPE_SUCCESS, Translator.translate("login-success"));
- self.finish();
- });
-
- this.findBy("#forgot-password-link").addEventListener("click", function () {
- self.startSite(ForgotPasswordSite);
- self.finish();
- });
- }
-}
-
-LoginSite.loginAction = null;
-LoginSite.logoutAction = null;
-LoginSite.addLoginAction = true;
-LoginSite.addLogoutAction = true;
-
-InitPromise.addPromise(function (app) {
- app.addDeepLink("login", LoginSite);
-
- if (Helper.isNull(LoginSite.loginAction)) {
- LoginSite.loginAction = new UserAction('login', function () {
- app.startSite(LoginSite);
- }, Menu.SHOW_NEVER, 1100, "offline");
- }
- if (Helper.isNull(LoginSite.logoutAction)) {
- LoginSite.logoutAction = new UserAction('logout', function () {
- UserManager.logOut();
- }, Menu.SHOW_NEVER, 1100, "online");
- }
- if (LoginSite.addLoginAction){
- app.addDefaultAction(LoginSite.loginAction);
- }
- if (LoginSite.addLogoutAction){
- app.addDefaultAction(LoginSite.logoutAction);
- }
-});
-
-class RegistrationSite extends UserSite {
- constructor(siteManager) {
- super(siteManager, 'userManagement/html/registration.html', "registration", "offline");
- }
-
- onFirstStart() {
- (new RegistrationForm(document.getElementById("registration-form"), "u/registration", "post")).onSubmit(function (res) {
- FlashMessenger.addMessage(FlashMessenger.MESSAGE_TYPE_SUCCESS, Translator.translate("registration-success"));
- });
- }
-}
-
-RegistrationSite.action = null;
-RegistrationSite.addAction = true;
-
-InitPromise.addPromise(function (app) {
- app.addDeepLink("registration", RegistrationSite);
-
- if (Helper.isNull(RegistrationSite.action)) {
- RegistrationSite.action = new UserAction('registration', function () {
- app.startSite(RegistrationSite);
- }, null, 1100, "offline");
- }
- if (RegistrationSite.addAction) {
- app.addDefaultAction(RegistrationSite.action);
- }
-});
-
-class SetNewPasswordSite extends UserSite {
- constructor(siteManager) {
- super(siteManager, 'userManagement/html/setNewPassword.html', "newPassword", "offline");
- }
-
- onConstruct(args) {
- this.code = args["code"];
- return super.onConstruct(args);
- }
-
- onFirstStart() {
- let formElem = document.getElementById("new-password-form");
- document.getElementById("code").value = this.code;
-
- let self = this;
- (new Form(formElem, "c/code", "post")).onSubmit(function(res){
- FlashMessenger.addMessage(FlashMessenger.MESSAGE_TYPE_SUCCESS, Translator.translate("password-updated"));
- self.startSite(LoginSite);
- self.finish();
- });
- }
-}
-InitPromise.addPromise(function(app){
- app.addDeepLink("newPassword", SetNewPasswordSite);
-});
-
-export { UserAction, UserManager, UserSite, LoginForm, RegistrationForm, PasswordSettingsFragment, SynchronizedSettingsFragment, UserFragment, UserSettingsFragment, EditUserRolesSite, ForgotPasswordSite, LoginSite, NotAllowedSite, RegistrationSite, SetNewPasswordSite };
diff --git a/src/js/settings.js b/src/js/settings.js
deleted file mode 100755
index 2f81148..0000000
--- a/src/js/settings.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import {SystemSettings, Translator} from "./lib/pwa-lib";
-import {Matomo} from "./lib/pwa-assets";
-
-let basePath = "/pwa/wordRotator/public/";
-if (window.location.pathname.indexOf("publicTest/") >= 0)
-{
- basePath = "/pwa/wordRotator/publicTest/";
-}
-
-SystemSettings.setBasePath(basePath);
-Translator.supportedLanguages = ["de"];
-Translator.markTranslations = false;
-window["version"] = "1-local";
-
-
-Matomo.SIDE_ID = "2";
diff --git a/src/module/Application/config/controller.config.php b/src/module/Application/config/controller.config.php
deleted file mode 100755
index 084a05e..0000000
--- a/src/module/Application/config/controller.config.php
+++ /dev/null
@@ -1,16 +0,0 @@
- [
- 'factories' => [
- IndexController::class => ServiceActionControllerFactory::class,
- SyncController::class => ServiceActionControllerFactory::class
- ],
- ],
-);
\ No newline at end of file
diff --git a/src/module/Application/config/doctrine.config.php b/src/module/Application/config/doctrine.config.php
deleted file mode 100755
index 12f96a1..0000000
--- a/src/module/Application/config/doctrine.config.php
+++ /dev/null
@@ -1,31 +0,0 @@
- array(
- 'driver' => array(
- 'orm_default' => array(
- 'drivers' => array(
- __NAMESPACE__ . '\Model' => 'entities_default',
- ),
- ),
- 'entities_default' => array(
- 'paths' => array(
- __DIR__ . '/../src/Model',
- )
- )
- ),
- 'configuration' => [
- 'orm_default' => [
- 'numeric_functions' => [
- 'CHAR_LENGTH' => CharLength::class,
- ],
- ],
- ],
- ),
-);
diff --git a/src/module/Application/config/factories.config.php b/src/module/Application/config/factories.config.php
deleted file mode 100755
index e469460..0000000
--- a/src/module/Application/config/factories.config.php
+++ /dev/null
@@ -1,25 +0,0 @@
- array(
- 'abstract_factories' => array(
- ),
- 'aliases' => array(
- 'translator' => 'MvcTranslator',
- ),
- 'factories' => array(
- AuthTokenManager::class => DefaultManagerFactory::class,
- LevelManager::class => LevelManagerFactory::class,
- RatingManager::class => DefaultManagerFactory::class,
- WordManager::class => DefaultManagerFactory::class,
- ),
- ),
-);
\ No newline at end of file
diff --git a/src/module/Application/config/manager.config.php b/src/module/Application/config/manager.config.php
deleted file mode 100755
index a8cd93c..0000000
--- a/src/module/Application/config/manager.config.php
+++ /dev/null
@@ -1,25 +0,0 @@
- array(
- 'factories' => array(
- ),
- 'aliases' => [
- ],
- 'invokables' => [
- ]
- ),
- 'translator' => array(
- 'locale' => 'en_US',
- 'translation_file_patterns' => array(
- array(
- 'type' => 'gettext',
- 'base_dir' => __DIR__ . '/../language',
- 'pattern' => '%s.mo',
- ),
- ),
- ),
-);
\ No newline at end of file
diff --git a/src/module/Application/config/navigation.config.php b/src/module/Application/config/navigation.config.php
deleted file mode 100755
index 054b3f3..0000000
--- a/src/module/Application/config/navigation.config.php
+++ /dev/null
@@ -1,7 +0,0 @@
- [
- 'left' => [
- ],
- ],
-];
\ No newline at end of file
diff --git a/src/module/Application/config/routes.config.php b/src/module/Application/config/routes.config.php
deleted file mode 100755
index 0e7c618..0000000
--- a/src/module/Application/config/routes.config.php
+++ /dev/null
@@ -1,7 +0,0 @@
- [
- 'routes' => [
- 'data' => [
- 'child_routes' => [
- 'words' => [
- 'type' => Segment::class,
- 'options' => [
- 'route' => '/words',
- 'defaults' => [
- 'controller' => IndexController::class,
- 'action' => 'selectWords',
- 'resource' => 'select-words',
- ],
- ],
- ],
- 'checkWord' => [
- 'type' => Segment::class,
- 'options' => [
- 'route' => '/checkWord',
- 'defaults' => [
- 'controller' => IndexController::class,
- 'action' => 'changeChecked',
- 'resource' => 'select-words',
- ],
- ],
- ],
- 'getDoubleWords' => [
- 'type' => Segment::class,
- 'options' => [
- 'route' => '/getDoubleUsedWordsAction',
- 'defaults' => [
- 'controller' => IndexController::class,
- 'action' => 'getDoubleUsedWords',
- 'resource' => 'admin',
- ],
- ],
- ],
- 'deleteLevel' => [
- 'type' => Segment::class,
- 'options' => [
- 'route' => '/deleteLevel',
- 'defaults' => [
- 'controller' => IndexController::class,
- 'action' => 'deleteLevel',
- 'resource' => 'admin',
- ],
- ],
- ],
- 'generateLevels' => [
- 'type' => Segment::class,
- 'options' => [
- 'route' => '/generateLevels',
- 'defaults' => [
- 'controller' => IndexController::class,
- 'action' => 'generateLevels',
- 'resource' => 'admin',
- ],
- ],
- ],
- ],
- ],
- ],
- ],
-);
\ No newline at end of file
diff --git a/src/module/Application/config/routes/routes.sync.php b/src/module/Application/config/routes/routes.sync.php
deleted file mode 100755
index 2526cc6..0000000
--- a/src/module/Application/config/routes/routes.sync.php
+++ /dev/null
@@ -1,69 +0,0 @@
- [
- 'routes' => [
- 'data' => [
- 'child_routes' => [
- 'wordRotator' => [
- 'type' => Segment::class,
- 'options' => [
- 'route' => '/wordRotator',
- ],
- 'child_routes' => [
- 'words' => [
- 'type' => Segment::class,
- 'options' => [
- 'route' => '/words',
- 'defaults' => [
- 'controller' => SyncController::class,
- 'action' => 'getWords',
- 'resource' => 'default',
- ]
- ],
- ],
- 'levels' => [
- 'type' => Segment::class,
- 'options' => [
- 'route' => '/levels',
- 'defaults' => [
- 'controller' => SyncController::class,
- 'action' => 'getLevels',
- 'resource' => 'default',
- ]
- ],
- ],
- 'getAuthToken' => [
- 'type' => Segment::class,
- 'options' => [
- 'route' => '/token',
- 'defaults' => [
- 'controller' => SyncController::class,
- 'action' => 'getAuthToken',
- 'resource' => 'default',
- ]
- ],
- ],
- 'rate' => [
- 'type' => Segment::class,
- 'options' => [
- 'route' => '/rate',
- 'defaults' => [
- 'controller' => SyncController::class,
- 'action' => 'rate',
- 'resource' => 'default',
- ]
- ],
- ],
- ],
- ],
- ],
- ],
- ],
- ],
-);
diff --git a/src/module/Application/pwa/js/Fragment/WordRotatorSettingFragment.js b/src/module/Application/pwa/js/Fragment/WordRotatorSettingFragment.js
deleted file mode 100644
index 4f8a523..0000000
--- a/src/module/Application/pwa/js/Fragment/WordRotatorSettingFragment.js
+++ /dev/null
@@ -1,153 +0,0 @@
-import {LocalStorageSettingsFragment, SettingsManager, SettingsSite} from "../../../../../js/lib/pwa-core";
-import {Dialog, FlashMessenger, Helper, InitPromise, ThemeManager, Translator} from "../../../../../js/lib/pwa-lib";
-import {WordRotatorDb} from "../WordRotatorDb";
-import {InstallManager, Matomo, MyStorageManager, SoundManager} from "../../../../../js/lib/pwa-assets";
-import {CreditsSite} from "../site/CreditsSite";
-import {PrivacyPolicySite} from "../site/PrivacyPolicySite";
-import {ChooseThemeDialog} from "../dialog/ChooseThemeDialog";
-import {ContactSite} from "../../../../../js/lib/pwa-contact";
-import {ImpressumSite} from "../site/ImpressumSite";
-import {PersistDialog} from "../dialog/PersistDialog";
-
-export class WordRotatorSettingFragment extends LocalStorageSettingsFragment {
- constructor(site) {
- super(site, "html/application/fragment/settings.html");
- }
-
- onFirstStart() {
- let currentThemeName = ThemeManager.currentTheme._name;
- SettingsManager.getInstance().setSetting("theme", currentThemeName);
-
- let themeNameElem = this.findBy("#theme-name");
- themeNameElem.removeAllChildren().appendChild(Translator.makePersistentTranslation(currentThemeName));
- this.findBy("#theme-chooser").addEventListener("click", async () => {
- let newTheme = await (new ChooseThemeDialog()).show();
- if (Helper.isNotNull(newTheme)) {
- SettingsManager.getInstance().setSetting("theme", newTheme);
- ThemeManager.changeCurrentTheme(newTheme);
- themeNameElem.removeAllChildren().appendChild(Translator.makePersistentTranslation(newTheme));
- }
- });
-
- this.findBy("#reset-levels").addEventListener("click", async () => {
- localStorage.removeItem("currentLevel");
- localStorage.removeItem("date-last-sync");
- localStorage.removeItem("levelCounter");
- localStorage.removeItem("tutorial-step");
- (await WordRotatorDb.getInstance()).removeAll(WordRotatorDb.OBJECT_STORE.LEVEL);
- (await WordRotatorDb.getInstance()).removeAll(WordRotatorDb.OBJECT_STORE.SYSTEM_VARS);
- });
-
- if (location.hostname.includes("beta") || location.hostname.includes("127.0.0.1")) {
- this.findBy("#reset-levels").classList.remove("hidden");
- }
-
- let playMusicButton = this.findBy("#play-music");
- playMusicButton.addEventListener("change", () => {
- let soundManager = SoundManager.getInstance();
- soundManager.set({muted: !playMusicButton.checked}, SoundManager.CHANNELS.MUSIC);
- if (playMusicButton.checked) {
- soundManager.play(SoundManager.CHANNELS.MUSIC);
- }
- });
-
- this.findBy("#track-switch").addEventListener("change", function (e) {
- Matomo.setTrack(this.checked === true);
- e.stopPropagation();
- e.preventDefault();
- });
-
- this.findBy("#credits-button").addEventListener("click", () => {
- this.getSite().startSite(CreditsSite);
- });
- this.findBy("#privacy-policy-button").addEventListener("click", () => {
- this.getSite().startSite(PrivacyPolicySite);
- });
- this.findBy("#contact-button").addEventListener("click", () => {
- this.getSite().startSite(ContactSite);
- });
- this.findBy("#impressum-button").addEventListener("click", () => {
- this.getSite().startSite(ImpressumSite);
- });
- this.findBy("#version-info").innerText = window["version"];
-
- InstallManager.setCanInstallListener(() => {
- let installButton = this.findBy("#install-button");
- installButton.addEventListener("click", () => {
- installButton.classList.add("hidden");
- InstallManager.prompt().then((e) => {
- console.log("clicked", e);
- if (e["outcome"] === "accepted") {
- Matomo.trackEvent("installed", "installed")
- }
- });
- });
- installButton.classList.remove("hidden");
- });
-
- let storageManager = MyStorageManager.getInstance();
- if (storageManager.canPersist()) {
- Promise.all([storageManager.isPersistent(), navigator.serviceWorker["ready"]]).then(res => {
- let isPersisted = res[0];
- let storageObject = this.findBy("#storage-info");
- storageObject.appendChild(Translator.makePersistentTranslation("storage-info", [
- ((isPersisted) ? "" : "nicht")]));
- storageObject.parentElement.classList.remove("hidden");
- storageObject.parentElement.addEventListener("click", async () => {
- if (!isPersisted) {
- let shouldAskForNotifications = false;
- try {
- // Helper.isChrome()
- shouldAskForNotifications = await (new PersistDialog().show());
- if (shouldAskForNotifications) {
- if (Helper.isChrome()) {
- let sub = await res[1]["pushManager"]["subscribe"]({
- "userVisibleOnly": true,
- "applicationServerKey": new Uint8Array([4, 148, 221, 15, 14, 122, 35, 21, 93, 74, 222, 174, 235, 216, 129, 40, 51, 187, 105, 151, 5, 96, 178, 155, 61, 201, 78, 209, 176, 187, 145, 94, 98, 96, 95, 27, 59, 90, 162, 0, 12, 225, 59, 105, 99, 135, 208, 210, 69, 29, 148, 141, 4, 178, 66, 114, 80, 207, 22, 90, 0, 115, 60, 150, 217])
- });
- }
- }
- } catch (e) {
- if ('Notification' in window && Notification.permission === 'denied') {
- FlashMessenger.addMessage('notification-permission-denied');
- }
- }
- if (Helper.isChrome() || shouldAskForNotifications) {
- isPersisted = await storageManager.persist();
- storageObject.removeAllChildren().appendChild(Translator.makePersistentTranslation("storage-info", [
- ((isPersisted) ? "" : "nicht")]));
- }
- }
- else {
- new Dialog("already-persisted-dialog-message", "already-persisted-dialog-title").show();
- }
- // storageManager.persist().then(isPersisted => {
- // storageObject.removeAllChildren().appendChild(Translator.makePersistentTranslation("storage-info", [
- // Math.round(storage.usage / (1024 * 1024) * 100) / 100,
- // Math.round(storage.quota / (1024 * 1024) * 100) / 100,
- // Math.round(storage.usage / storage.quota * 10000) / 100,
- // ((isPersisted) ? "" : "nicht")]));
- //
- // console.log("p", isPersisted);
- // if (!isPersisted){
- // FlashMessenger.addMessage("storage-permission-not-get");
- // }
- // else {
- // FlashMessenger.addMessage("storage-permission-get");
- // }
- // });
- })
- });
- }
- return super.onFirstStart();
- }
-
- onStart() {
- Matomo.update("Settings Site");
- super.onStart();
- }
-}
-
-InitPromise.addPromise(function () {
- SettingsSite.addSettingsFragment("settings", WordRotatorSettingFragment);
-});
\ No newline at end of file
diff --git a/src/module/Application/pwa/js/WordRotatorDb.js b/src/module/Application/pwa/js/WordRotatorDb.js
deleted file mode 100755
index cba3d58..0000000
--- a/src/module/Application/pwa/js/WordRotatorDb.js
+++ /dev/null
@@ -1,101 +0,0 @@
-import {Helper, MyDb} from "../../../../js/lib/pwa-lib";
-
-export class WordRotatorDb extends MyDb {
-
- static async getInstance() {
- if (Helper.isNull(WordRotatorDb.instance)) {
- WordRotatorDb.instance = new WordRotatorDb();
- }
- await WordRotatorDb.instance.queryPromise;
- return WordRotatorDb.instance;
- }
-
- constructor() {
- super("wordRotator", 6);
- }
-
- upgrade(db, oldVersion, newVersion, e) {
- console.log("upgrading!");
-
- if (Helper.isNull(oldVersion) || oldVersion < 1 && newVersion >= 1) {
- let levelObjectStore = db.createObjectStore(WordRotatorDb.OBJECT_STORE.LEVEL, {"keyPath": "id"});
- }
- if (Helper.isNull(oldVersion) || oldVersion < 2 && newVersion >= 2) {
- let levelObjectStore = e.target.transaction.objectStore(WordRotatorDb.OBJECT_STORE.LEVEL);
- levelObjectStore.createIndex("played", ["deleted", "played", "difficulty", "id"], {"unique": false});
- }
- if (Helper.isNull(oldVersion) || oldVersion < 3 && newVersion >= 3) {
- let levelObjectStore = e.target.transaction.objectStore(WordRotatorDb.OBJECT_STORE.LEVEL);
- levelObjectStore.createIndex("difficulty", "difficulty", {"unique": false});
- }
-
- console.log("update", oldVersion, newVersion);
- if (Helper.isNull(oldVersion) || oldVersion < 6 && newVersion >= 6) {
- try {
- db.deleteObjectStore(WordRotatorDb.OBJECT_STORE.SYSTEM_VARS);
- } catch (e) {}
- let levelObjectStore = db.createObjectStore(WordRotatorDb.OBJECT_STORE.SYSTEM_VARS, {"keyPath": "name"});
- }
- };
-
- async saveManyLevels(levels) {
- return this.saveMany(levels, WordRotatorDb.OBJECT_STORE.LEVEL).catch(e => {
- console.error("insert error!", e);
- });
- }
-
- async loadLevel(levelId) {
- // console.log("load Level", levelId);
- return this.load(levelId, WordRotatorDb.OBJECT_STORE.LEVEL);
- }
-
- async loadNextLevel(rendererTypes) {
- let levels = await this.loadAll(WordRotatorDb.OBJECT_STORE.LEVEL);
- levels = levels.sort((a, b) => {
- return (a["difficulty"] - b["difficulty"]);
- });
-
- let wrongLevels = [];
- let newLevels = [];
- let difficulty = -1;
- for (let i = 0, n = levels.length; i < n; i++) {
- if ((difficulty < 0 || difficulty === levels[i]["difficulty"]) && !levels[i]["deleted"] && !levels[i]["played"] && rendererTypes.indexOf(levels[i]["rendererType"]) !== -1) {
- newLevels.push(levels[i]);
- difficulty = levels[i]["difficulty"];
- }
- else if (levels[i]["difficulty"] !== 0 && !levels[i]["deleted"] && !levels[i]["played"]) {
- wrongLevels.push(levels[i]);
- }
- }
-
- if (newLevels.length === 0) {
- return null;
- }
-
- return newLevels[Math.round(Math.random() * newLevels.length) % newLevels.length];
- }
-
- async saveLevelPlayed(levelId) {
- const level = await this.loadLevel(levelId);
- level.played = true;
- return await this.saveObj(level, WordRotatorDb.OBJECT_STORE.LEVEL);
- }
-
- async loadDateLastSync() {
- let dateLastSync = await this.load("date-last-sync", WordRotatorDb.OBJECT_STORE.SYSTEM_VARS);
- if (dateLastSync) {
- return dateLastSync["value"];
- }
- return null;
- }
-
- async saveDateLastSync(value) {
- return await this.saveObj({"name": "date-last-sync", "value": value}, WordRotatorDb.OBJECT_STORE.SYSTEM_VARS)
- }
-}
-
-WordRotatorDb.OBJECT_STORE = {
- LEVEL: "level",
- SYSTEM_VARS: "vars"
-};
-WordRotatorDb.instance = null;
diff --git a/src/module/Application/pwa/js/dialog/ChooseThemeDialog.js b/src/module/Application/pwa/js/dialog/ChooseThemeDialog.js
deleted file mode 100644
index 2ff3250..0000000
--- a/src/module/Application/pwa/js/dialog/ChooseThemeDialog.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import {Dialog, Helper, ThemeManager, Translator, ViewInflater} from "../../../../../js/lib/pwa-lib";
-
-export class ChooseThemeDialog extends Dialog {
-
- constructor() {
- let viewPromise = ViewInflater.inflate("html/application/dialog/chooseTheme.html").then(view => {
-
- let template = view.querySelector("#choose-theme-template");
- template.remove();
- template.id = null;
-
- let themeTemplateContainer = view.querySelector("#theme-choose-container");
-
- for (let i = 0; i < ThemeManager.themes.length; i++) {
- let themeElem = Helper.cloneNode(template);
- let theme = ThemeManager.themes[i];
- themeElem.querySelector(".name").appendChild(Translator.makePersistentTranslation(theme._name));
- themeElem["dataset"]["theme"] = theme._name;
-
- themeElem.addEventListener("click", () => {
- this.result = themeElem["dataset"]["theme"];
- this.close()
- });
- themeTemplateContainer.appendChild(themeElem);
- }
-
- return view;
- });
-
- super(viewPromise, "choose-theme-dialog-title");
- }
-}
\ No newline at end of file
diff --git a/src/module/Application/pwa/js/dialog/PersistDialog.js b/src/module/Application/pwa/js/dialog/PersistDialog.js
deleted file mode 100644
index ce90614..0000000
--- a/src/module/Application/pwa/js/dialog/PersistDialog.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import {ConfirmDialog, Dialog, Helper, ThemeManager, Translator, ViewInflater} from "../../../../../js/lib/pwa-lib";
-
-export class PersistDialog extends ConfirmDialog{
- constructor() {
- super(Helper.isChrome()?"persist-storage-dialog-message":"persist-storage-dialog-message-firefox", "persist-storage-dialog-title");
- }
-}
\ No newline at end of file
diff --git a/src/module/Application/pwa/js/site/CreditsSite.js b/src/module/Application/pwa/js/site/CreditsSite.js
deleted file mode 100644
index 4649665..0000000
--- a/src/module/Application/pwa/js/site/CreditsSite.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import {WordRotatorBaseSite} from "./WordRotatorBaseSite";
-import {InitPromise} from "../../../../../js/lib/pwa-lib";
-import {PrivacyPolicySite} from "./PrivacyPolicySite";
-import {Matomo} from "../../../../../js/lib/pwa-assets";
-
-export class CreditsSite extends WordRotatorBaseSite{
- constructor(siteManager) {
- super(siteManager, "html/application/credits.html", "credits");
- }
-
- onStart(args) {
- Matomo.update("Credits Site");
- return super.onStart(args);
- }
-}
-
-InitPromise.addPromise(app => {
- app.addDeepLink("credits", CreditsSite);
-});
\ No newline at end of file
diff --git a/src/module/Application/pwa/js/site/WordRotatorBaseSite.js b/src/module/Application/pwa/js/site/WordRotatorBaseSite.js
deleted file mode 100644
index 55caa5a..0000000
--- a/src/module/Application/pwa/js/site/WordRotatorBaseSite.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import {AbstractSite, Menu, MenuAction} from "../../../../../js/lib/pwa-lib";
-import {SettingsSite} from "../../../../../js/lib/pwa-core";
-
-export class WordRotatorBaseSite extends AbstractSite {
- // createActionBarMenu(menu) {
- // menu = super.createActionBarMenu(menu);
- // // menu.addAction(SettingsSite.settingsAction.copy());
- // // let actions = menu.actions;
- // // for (let i = 0; i < actions.length; i++) {
- // // if (actions[i].title === "login" || actions[i].title === "registration"){
- // // actions[i].setVisible(false);
- // // }
- // // }
- // return menu;
- // }
-}
\ No newline at end of file
diff --git a/src/module/Application/pwa/js/wordrotator/Level/Level.js b/src/module/Application/pwa/js/wordrotator/Level/Level.js
deleted file mode 100755
index ec83c86..0000000
--- a/src/module/Application/pwa/js/wordrotator/Level/Level.js
+++ /dev/null
@@ -1,161 +0,0 @@
-import {LeafSegment} from "../Segment/LeafSegment";
-import {Helper} from "../../../../../../js/lib/pwa-lib";
-import {ParentSegment} from "../Segment/ParentSegment";
-
-export class Level {
- constructor(templateContainer) {
- this.rootSegment = null;
- this.words = [];
- this.startRotations = [];
- this.templateContainer = templateContainer;
-
- this.hasWon = false;
- this.id = null;
-
- this.wonResolver = null;
- this.giveUpResolver = null;
-
- const self = this;
- this.wonPromise = new Promise((resolve, reject) => {
- self.wonResolver = resolve;
- self.giveUpResolver = reject;
- });
-
- this.segmentClickedListener = () => {};
- }
-
- saveAsCurrentLevel(){
- let rotations = this.getCurrentRotations();
- let locked = this.getCurrentLocked();
- localStorage.setItem("currentLevel", JSON.stringify({"id": this.id, "rotations": rotations, "locks":locked}));
- }
-
- getCurrentLocked(){
- if (this.rootSegment !== null)
- {
- return this.rootSegment.getCurrentLocked([]);
- }
- return [];
- }
-
- getCurrentRotations(){
- if (this.rootSegment !== null)
- {
- return this.rootSegment.getCurrentRotations([]);
- }
- return [];
- }
-
- setLocks(locks)
- {
- if (this.rootSegment !== null){
- this.rootSegment.applyLocks(locks);
- }
- }
-
- setId(id)
- {
- this.id = id;
- }
-
- getId()
- {
- return this.id;
- }
-
- getLevel()
- {
- return this;
- }
-
- setRootSegment(rootSegment)
- {
- this.rootSegment = rootSegment;
- this.rootSegment.setParent(this);
- if (this.startRotations)
- {
- this.applyRotations();
- }
- }
-
- setWords(words)
- {
- this.words = [];
- for (let i = 0, n = words.length; i < n; i++) {
- this.words.push(words[i].replace(/ß/g, "ẞ").toUpperCase());
- }
- }
-
- setStartRotations(rotations)
- {
- this.startRotations = rotations;
- }
-
- applyRotations(rotations)
- {
- if (this.rootSegment)
- {
- rotations = Helper.nonNull(rotations, this.startRotations);
- this.rootSegment.applyRotations(rotations);
- }
- }
-
- getHasWon()
- {
- return this.hasWon;
- }
-
- checkHasWon(delayPromise) {
- if (this.rootSegment.isSolved()){
- this.hasWon = true;
- const self = this;
- Promise.resolve(delayPromise).then(()=>{
- self.wonResolver(true);
- });
- return true;
- }
- this.saveAsCurrentLevel();
- return false;
- }
-
- getWonPromise(){
- return this.wonPromise;
- }
-
- getRootSegment(){
- return this.rootSegment;
- }
-
- createSegments() {};
-
- getRotatableSegments(){
- return Level._getRotatableSegmentsFrom(this.rootSegment);
- }
-
- setSegmentClickedListener(listener){
- this.segmentClickedListener = listener;
- }
-
- static _getRotatableSegmentsFrom(segment){
- let rotatable = [];
- if (segment.canRotate())
- {
- rotatable.push(segment);
- }
- if (segment instanceof ParentSegment){
- for (let i = 0; i < segment.children.length; i++) {
- rotatable.push.apply(rotatable, Level._getRotatableSegmentsFrom(segment.children[i]));
- }
- }
- return rotatable;
- }
-
- static _createLeafsForWord(word, leafSegmentTemplate)
- {
- let leafSegments = [];
- for (let i = 0, n = word.length; i < n; i++) {
- leafSegments.push(new LeafSegment(Helper.cloneNode(leafSegmentTemplate), word.charAt(i)));
- }
- return leafSegments;
- }
-}
\ No newline at end of file
diff --git a/src/module/Application/pwa/public/html/application/credits.html b/src/module/Application/pwa/public/html/application/credits.html
deleted file mode 100644
index 1806416..0000000
--- a/src/module/Application/pwa/public/html/application/credits.html
+++ /dev/null
@@ -1,5 +0,0 @@
-
\ No newline at end of file
diff --git a/src/module/Application/pwa/public/html/application/end.html b/src/module/Application/pwa/public/html/application/end.html
deleted file mode 100755
index 50859fe..0000000
--- a/src/module/Application/pwa/public/html/application/end.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/src/module/Application/pwa/public/html/application/fragment/settings.html b/src/module/Application/pwa/public/html/application/fragment/settings.html
deleted file mode 100644
index 22498e6..0000000
--- a/src/module/Application/pwa/public/html/application/fragment/settings.html
+++ /dev/null
@@ -1,149 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/module/Application/pwa/public/html/application/setting-template.html b/src/module/Application/pwa/public/html/application/setting-template.html
deleted file mode 100644
index 0391640..0000000
--- a/src/module/Application/pwa/public/html/application/setting-template.html
+++ /dev/null
@@ -1,9 +0,0 @@
-
\ No newline at end of file
diff --git a/src/module/Application/pwa/public/html/application/sync.html b/src/module/Application/pwa/public/html/application/sync.html
deleted file mode 100755
index d42b490..0000000
--- a/src/module/Application/pwa/public/html/application/sync.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
- Sync
-
\ No newline at end of file
diff --git a/src/module/Application/pwa/translations/en.json b/src/module/Application/pwa/translations/en.json
deleted file mode 100755
index 83a1c17..0000000
--- a/src/module/Application/pwa/translations/en.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "won":"Won!",
- "continue":"Continue",
-
- "help": "?",
- "not-enugh-coins":"You have to few coins!"
-}
\ No newline at end of file
diff --git a/src/module/Application/src/Controller/IndexController.php b/src/module/Application/src/Controller/IndexController.php
deleted file mode 100755
index 17ff321..0000000
--- a/src/module/Application/src/Controller/IndexController.php
+++ /dev/null
@@ -1,130 +0,0 @@
-get(SelectWordsBot::class);
-// $bot->setWebhook("");
-// $bot->handleUpdates($bot->getUpdates());
-// $bot->sendWordToCheck();
- return new ViewModel();
- }
-
- public function selectWordsAction()
- {
- /** @var WordManager $wordManager */
- $wordManager = $this->get(WordManager::class);
- $wordsNotChecked = $wordManager->countNotChecked(self::LENGTH_WORDS_MIN, self::LENGTH_WORDS_MAX);
- $wordsDeleted = $wordManager->countDeleted(self::LENGTH_WORDS_MIN, self::LENGTH_WORDS_MAX);
- $wordsChecked = $wordManager->countChecked(self::LENGTH_WORDS_MIN, self::LENGTH_WORDS_MAX);
- $wordsUnsure = $wordManager->countUnsure(self::LENGTH_WORDS_MIN, self::LENGTH_WORDS_MAX);
- $wordsNotUsed = $wordManager->countNotUsed(self::LENGTH_WORDS_MIN, self::LENGTH_WORDS_MAX);
-
- $wordsToCheck = [];
- for ($i = 0; $i < self::NUMBER_WORDS_TO_CHECK_SIMULTANEOUSLY; $i++) {
- $word = $wordManager->getRandomWordNotChecked(self::LENGTH_WORDS_MIN, self::LENGTH_WORDS_MAX);
- if ($word != null) {
- $wordsToCheck[] = WordManager::wordToArray($word);
- }
- }
-
- return [
- "wordsNotChecked" => $wordsNotChecked,
- "wordsDeleted" => $wordsDeleted,
- "wordsChecked" => $wordsChecked,
- "wordsUnsure" => $wordsUnsure,
- "wordsToCheck" => $wordsToCheck,
- "wordsNotUsed" => $wordsNotUsed,
- ];
- }
-
- public function changeCheckedAction()
- {
- $request = $this->getRequest();
-
- if (!$request->isPost()) {
- return $this->triggerDispatchError(403);
- }
-
- $wordId = $request->getPost("wordId", "");
- $action = $request->getPost("action", "");
-
- /** @var WordManager $wordManager */
- $wordManager = $this->get(WordManager::class);
- $word = $wordManager->getEntityById($wordId);
-
- if ($word == null) {
- return $this->triggerDispatchError(404);
- }
-
- $word = WordManager::doAction($word, $action);
- $wordManager->save($word);
-
- $randomWordNotChecked = $wordManager->getRandomWordNotChecked(self::LENGTH_WORDS_MIN, self::LENGTH_WORDS_MAX);
-
- if ($randomWordNotChecked != null) {
- return [
- WordManager::wordToArray($randomWordNotChecked),
- ];
- }
- return [
- "id" => -1,
- "word" => "Kein Wort mehr! ",
-// "created" => $word->getCreated()->format(SyncController::DATETIME_SYNC_FORMAT),
-// "lastUpdated" => $word->getLastUpdated()->format(SyncController::DATETIME_SYNC_FORMAT),
-// "language" => $word->getLang(),
-// "deleted" => $word->isDeleted(),
- ];
- }
-
- public function getDoubleUsedWordsAction()
- {
- /** @var LevelManager $levelManager */
- $levelManager = $this->get(LevelManager::class);
- return $levelManager->getDoubleUsedWords();
- }
-
- public function deleteLevelAction()
- {
- $request = $this->getRequest();
-
- if (!$request->isPost()) {
- return $this->triggerDispatchError(403);
- }
-
- $levelId = $request->getPost("levelId", "");
-
- /** @var LevelManager $levelManager */
- $levelManager = $this->get(LevelManager::class);
- $level = $levelManager->getEntityById($levelId);
- $level->setDeleted(true);
- $level->setLastUpdated(new \DateTime());
-
- $levelManager->save($level);
-
- return [];
- }
-
- public function generateLevelsAction()
- {
- /** @var LevelManager $levelManager */
- $levelManager = $this->get(LevelManager::class);
- return ["levelsGenerated" => $levelManager->generateLevels()];
-
- }
-}
diff --git a/src/module/Application/src/Controller/SyncController.php b/src/module/Application/src/Controller/SyncController.php
deleted file mode 100755
index 7bd4fc7..0000000
--- a/src/module/Application/src/Controller/SyncController.php
+++ /dev/null
@@ -1,219 +0,0 @@
-getRequest()->isPost()) {
- return $this->triggerDispatchError(404);
- }
-
- /** @var AuthTokenManager $authTokenManager */
- $authTokenManager = $this->get(AuthTokenManager::class);
-
- $token = new AuthToken();
- $name = $this->getRequest()->getPost("name");
- if (trim($name) == "") {
- return $this->triggerDispatchError(400);
- }
- $token->setName($name);
- $token->setToken($authTokenManager->generateNewAuthToken());
- $authTokenManager->save($token);
-
- $this->layout("layout/ajaxData");
- $viewModel = new ViewModel();
- $viewModel->setTemplate("ajax/json");
- $viewModel->setVariable("json", [
- "result" => true,
- "data" => [
- "authToken" => $token->getToken(),
- ],
- ]);
- return $viewModel;
- }
-
- public function getWordsAction()
- {
- $request = $this->getRequest();
- if (!$request->isPost()) {
- return $this->triggerDispatchError();
- }
-
- $this->getEventManager()->trigger(Module::EVENT_LOG, null, array(
- "message" => "Synchronized Words: " . $request->toString(),
- "level" => Logger::INFO
- ));
-
- $currentRun = (int)$request->getPost("currentRun", null);
- $dateLastSync = $request->getPost("dateLastSync", null);
- if ($dateLastSync != null) {
- try {
- $dateLastSync = \DateTime::createFromFormat(self::DATETIME_SYNC_FORMAT, $dateLastSync);
- } catch (\Throwable $t) {
- $dateLastSync = null;
- }
- }
-
- /** @var WordManager $wordManager */
- $wordManager = $this->get(WordManager::class);
- $newDate = new \DateTime();
- $words = $wordManager->wordsToArray($wordManager->findNewerThan($dateLastSync, $currentRun));
- $numberWordsToSync = $wordManager->countNewerThan($dateLastSync);
-
- $this->layout("layout/ajaxData");
- $viewModel = new ViewModel();
- $viewModel->setTemplate("ajax/json");
- $viewModel->setVariable("json", [
- "result" => true,
- "data" => [
- "countWords" => $numberWordsToSync,
- "currentSyncDate" => $newDate->format(self::DATETIME_SYNC_FORMAT),
- "currentRun" => $currentRun,
- "maxRuns" => ceil($numberWordsToSync / SyncController::SYNC_MAX_WORDS),
- "words" => $words,
- ],
- ]);
- return $viewModel;
- }
-
- public function getLevelsAction()
- {
- $request = $this->getRequest();
-
- $currentRun = (int)$request->getQuery("currentRun", null);
- $dateLastSync = $request->getQuery("dateLastSync", null);
- try {
- $dateLastSync = new \DateTime("@" . $dateLastSync, new \DateTimeZone("UTC"));
- } catch (\Throwable $e) {
- $dateLastSync = new \DateTime();
- }
-
- /** @var LevelManager $levelManager */
- $levelManager = $this->get(LevelManager::class);
- $newDate = new \DateTime("now", new \DateTimeZone("UTC"));
- $levels = $levelManager->levelsToArray($levelManager->findNewerThan($dateLastSync, $currentRun));
- $numberLevelsToSync = $levelManager->countNewerThan($dateLastSync);
-
- return [
- "countLevels" => $numberLevelsToSync,
- "currentSyncDate" => $newDate->getTimestamp(),
- "currentRun" => $currentRun,
- "maxRuns" => ceil($numberLevelsToSync / SyncController::SYNC_MAX_LEVELS),
- "levels" => $levels,
- ];
- }
-
- public function rateAction()
- {
- $request = $this->getRequest();
- if (!$request->isPost()) {
- return $this->triggerDispatchError(404);
- }
-
- $this->getEventManager()->trigger(Module::EVENT_LOG, null, array(
- "message" => "Synchronized Level: " . $request->toString(),
- "level" => Logger::INFO
- ));
-
- /** @var AuthTokenManager $authTokenManager */
- $authTokenManager = $this->get(AuthTokenManager::class);
- $authToken = $authTokenManager->findOneByToken($request->getPost("authToken"));
-
- if ($authToken == null) {
- return $this->triggerDispatchError(403);
- }
-
- /** @var RatingManager $ratingManager */
- $ratingManager = $this->get(RatingManager::class);
-
- /** @var LevelManager $levelManager */
- $levelManager = $this->get(LevelManager::class);
- $levelsArray = json_decode($request->getPost("levels"), true);
-
- $levels = [];
- foreach ($levelsArray as $levelArray) {
- $levelManager->beginTransaction();
-
- $words = json_encode($levelArray["words"]);
- $rotations = json_encode($levelArray["rotations"]);
- $level = $levelManager->findOneBy([
- "words" => $words,
- "positions" => $rotations,
- "renderer" => $levelArray["rendererType"],
- "lang" => $levelArray["language"],
- ]);
- if ($level == null) {
- $level = new Level();
- $level->setDeleted(false);
- $level->setWords($words);
- $level->setPositions($rotations);
- $level->setRenderer($levelArray["rendererType"]);
- $level->setLang($levelArray["language"]);
- $level->setLastUpdated(new \DateTime());
- $level->setDeleted(false);
- $level->setDifficulty($levelArray["difficulty"]);
- $levelManager->save($level);
- }
- $rating = $ratingManager->findOneBy([
- "level" => $level,
- "authToken" => $authToken,
- ]);
-
- if ($rating == null) {
- $rating = new Rating();
- $rating->setAuthToken($authToken);
- $rating->setLevel($level);
- $level->getRatings()->add($rating);
- }
-
- $ratingScore = $levelArray["rating"];
- $rating->setRating($ratingScore);
-
- if ($level->getRatings()->count() >= self::MAX_RATINGS_PER_LEVEL || $ratingScore < 0) {
- $level->setDeleted(true);
- $level->setLastUpdated(new \DateTime());
-// $levelManager->save($level);
- }
-
- $ratingManager->save($rating);
- $levelManager->endTransaction();
- $levels[] = $level;
- }
- $this->layout("layout/ajaxData");
- $viewModel = new ViewModel();
- $viewModel->setTemplate("ajax/json");
- $viewModel->setVariable("json", [
- "result" => true,
- "data" => [
- "levels" => $levelManager->levelsToArray($levels),
- ],
- ]);
- return $viewModel;
- }
-}
\ No newline at end of file
diff --git a/src/module/Application/src/DoctrineExtensions/CharLength.php b/src/module/Application/src/DoctrineExtensions/CharLength.php
deleted file mode 100644
index ad1ec0a..0000000
--- a/src/module/Application/src/DoctrineExtensions/CharLength.php
+++ /dev/null
@@ -1,30 +0,0 @@
-walkArithmeticPrimary($this->expr1).')';
- }
- public function parse(\Doctrine\ORM\Query\Parser $parser)
- {
- $parser->match(Lexer::T_IDENTIFIER);
- $parser->match(Lexer::T_OPEN_PARENTHESIS);
- $this->expr1 = $parser->ArithmeticExpression();
- $parser->match(Lexer::T_CLOSE_PARENTHESIS);
- }
-}
\ No newline at end of file
diff --git a/src/module/Application/src/Factory/Model/Manager/LevelManagerFactory.php b/src/module/Application/src/Factory/Model/Manager/LevelManagerFactory.php
deleted file mode 100644
index 9ddb6d8..0000000
--- a/src/module/Application/src/Factory/Model/Manager/LevelManagerFactory.php
+++ /dev/null
@@ -1,31 +0,0 @@
-createService($container, $requestedName);
- }
-
- public function createService(ContainerInterface $serviceLocator, $managerName)
- {
- $em = $serviceLocator->get('doctrine.entitymanager.orm_default');
- /** @var WordManager $wordManager */
- $wordManager = $serviceLocator->get(WordManager::class);
- return new LevelManager($em->getRepository(Level::class), $wordManager);
- }
-}
\ No newline at end of file
diff --git a/src/module/Application/src/Model/AuthToken.php b/src/module/Application/src/Model/AuthToken.php
deleted file mode 100755
index 44fbb0f..0000000
--- a/src/module/Application/src/Model/AuthToken.php
+++ /dev/null
@@ -1,134 +0,0 @@
-id = null;
- $this->token = null;
- $this->ratings = new ArrayCollection();
- $this->creationDate = new \DateTime();
- }
-
- /**
- * @return mixed
- */
- public function getId()
- {
- return $this->id;
- }
-
- /**
- * @param mixed $id
- */
- public function setId($id)
- {
- $this->id = $id;
- }
-
- /**
- * @return string
- */
- public function getToken()
- {
- return $this->token;
- }
-
- /**
- * @param string $token
- */
- public function setToken($token)
- {
- $this->token = $token;
- }
-
- /**
- * @return string
- */
- public function getName()
- {
- return $this->name;
- }
-
- /**
- * @param string $name
- */
- public function setName($name)
- {
- $this->name = $name;
- }
-
- /**
- * @return Rating[]
- */
- public function getRatings()
- {
- return $this->ratings;
- }
-
- /**
- * @param Rating[] $ratings
- */
- public function setRatings($ratings)
- {
- $this->ratings = $ratings;
- }
-
- /**
- * @return \DateTime
- */
- public function getCreationDate()
- {
- return $this->creationDate;
- }
-
- /**
- * @param \DateTime $creationDate
- */
- public function setCreationDate($creationDate)
- {
- $this->creationDate = $creationDate;
- }
-}
diff --git a/src/module/Application/src/Model/Level.php b/src/module/Application/src/Model/Level.php
deleted file mode 100755
index d20f5b4..0000000
--- a/src/module/Application/src/Model/Level.php
+++ /dev/null
@@ -1,222 +0,0 @@
-id = null;
- $this->ratings = new ArrayCollection();
- }
-
- /**
- * @return mixed
- */
- public function getId()
- {
- return $this->id;
- }
-
- /**
- * @param mixed $id
- */
- public function setId($id)
- {
- $this->id = $id;
- }
-
- /**
- * @return string
- */
- public function getWords()
- {
- return $this->words;
- }
-
- /**
- * @param string $words
- */
- public function setWords($words)
- {
- $this->words = $words;
- }
-
- /**
- * @return string
- */
- public function getPositions()
- {
- return $this->positions;
- }
-
- /**
- * @param string $positions
- */
- public function setPositions($positions)
- {
- $this->positions = $positions;
- }
-
- /**
- * @return Rating[]|ArrayCollection
- */
- public function getRatings()
- {
- return $this->ratings;
- }
-
- /**
- * @param Rating[] $ratings
- */
- public function setRatings($ratings)
- {
- $this->ratings = $ratings;
- }
-
- /**
- * @return int
- */
- public function getRenderer()
- {
- return $this->renderer;
- }
-
- /**
- * @param int $renderer
- */
- public function setRenderer($renderer)
- {
- $this->renderer = $renderer;
- }
-
- /**
- * @return \DateTime
- */
- public function getLastUpdated()
- {
- return $this->lastUpdated;
- }
-
- /**
- * @param \DateTime $lastUpdated
- */
- public function setLastUpdated($lastUpdated)
- {
- $this->lastUpdated = $lastUpdated;
- }
-
- /**
- * @return int
- */
- public function getLang()
- {
- return $this->lang;
- }
-
- /**
- * @param int $lang
- */
- public function setLang($lang)
- {
- $this->lang = $lang;
- }
-
- /**
- * @return boolean
- */
- public function isDeleted()
- {
- return $this->deleted;
- }
-
- /**
- * @param boolean $deleted
- */
- public function setDeleted($deleted)
- {
- $this->deleted = $deleted;
- }
-
- /**
- * @return int
- */
- public function getDifficulty()
- {
- return $this->difficulty;
- }
-
- /**
- * @param int $difficulty
- */
- public function setDifficulty($difficulty)
- {
- $this->difficulty = $difficulty;
- }
-}
diff --git a/src/module/Application/src/Model/Manager/AuthTokenManager.php b/src/module/Application/src/Model/Manager/AuthTokenManager.php
deleted file mode 100755
index df9a32e..0000000
--- a/src/module/Application/src/Model/Manager/AuthTokenManager.php
+++ /dev/null
@@ -1,57 +0,0 @@
-repository = $repository;
- parent::__construct($repository, $entity);
- }
-
- /**
- * @param int $id
- * @return AuthToken
- */
- public function getEntityById($id)
- {
- return parent::getEntityById($id);
- }
-
- public function generateNewAuthToken()
- {
- do {
- $token = "";
- for ($i = 0; $i < 256; $i++) {
- $rand = rand(0, 61);
- if ($rand > 9) {
- if ($rand > 35) {
- $rand += ord('a') - 36;
- } else {
- $rand += ord('A') - 10;
- }
- $rand = chr($rand);
- }
- $token .= $rand;
- }
- } while($this->findOneByToken($token) != null);
- return $token;
- }
-
- /**
- * @param $token
- * @return null|AuthToken
- */
- public function findOneByToken($token)
- {
- return $this->findOneBy(["token" => $token]);
- }
-}
\ No newline at end of file
diff --git a/src/module/Application/src/Model/Manager/LevelManager.php b/src/module/Application/src/Model/Manager/LevelManager.php
deleted file mode 100755
index 777cc3f..0000000
--- a/src/module/Application/src/Model/Manager/LevelManager.php
+++ /dev/null
@@ -1,328 +0,0 @@
-repository = $repository;
- $this->wordManager = $wordManager;
- parent::__construct($repository, $entity);
- }
-
- /**
- * @param int $id
- * @return Level
- */
- public function getEntityById($id)
- {
- return parent::getEntityById($id);
- }
-
- public function beginTransaction()
- {
- $this->repository->beginTransaction();
- }
-
- public function endTransaction()
- {
- $this->repository->endTransaction();
- }
-
- /**
- * @param \DateTime $dateTime
- * @param int $offset
- * @return array
- */
- public function findNewerThan($dateTime, $offset = 0)
- {
- return $this->repository->findNewerThanDate($dateTime, $offset);
- }
-
- public function countNewerThan($dateTime)
- {
- return $this->repository->countNewerThanDate($dateTime);
- }
-
- static function levelToArray(Level $level)
- {
- return [
- "id" => $level->getId(),
- "words" => json_decode($level->getWords()),
- "rotations" => json_decode($level->getPositions()),
- "lastUpdated" => $level->getLastUpdated()->format("Y-m-d H:i:s"),
- "language" => $level->getLang(),
- "rendererType" => $level->getRenderer(),
- "difficulty" => $level->getDifficulty(),
- "deleted" => $level->isDeleted(),
- ];
- }
-
- static function levelsToArray($levels)
- {
- $returnArray = [];
- /** @var Level $level */
- foreach ($levels as $level) {
- $returnArray[] = LevelManager::levelToArray($level);
- }
- return $returnArray;
- }
-
- public function countWhere($whereArray)
- {
- return $this->repository->countWhere($whereArray);
- }
-
- public function getDoubleUsedWords()
- {
- $words = [];
- $sameWords = [];
-
- /** @var Level[] $level */
- $level = $this->findBy(["deleted" => 0]);
-
- $levelNumber = count($level);
- for ($i = 0; $i < $levelNumber; $i++) {
- $words[$i] = $words[$i] ?? json_decode($level[$i]->getWords());
- $wordLength = count($words[$i]);
- for ($j = $i + 1; $j < $levelNumber; $j++) {
- $words[$j] = $words[$j] ?? json_decode($level[$j]->getWords());
- for ($k = 0; $k < $wordLength; $k++) {
- if (in_array($words[$i][$k], $words[$j])) {
-
- $sameWords[$words[$i][$k]] = ($sameWords[$words[$i][$k]] ?? []);
- $sameWords[$words[$i][$k]][] = $level[$i];
- $sameWords[$words[$i][$k]][] = $level[$j];
- }
- }
- }
- }
- foreach ($sameWords as $key => &$levels) {
- $sameWords[$key] = array_unique(LevelManager::levelsToArray($levels), SORT_REGULAR);
- }
-
- return $sameWords;
- }
-
- public function generateLevels()
- {
- $levelsToGenerate = [
- 80 => //(0) 80
- [
- "wordLength" => 10,
- "numWords" => 4,
- "numPositions" => 11,
- "renderer" => 80,
- "difficulty" => function () {
- return 1000;
- },
- "creationRatio" => 1,
- ],
- 81 => //(1) 81
- [
- "wordLength" => 10,
- "numWords" => 4,
- "numPositions" => 11,
- "renderer" => 81,
- "difficulty" => function () {
- return 1000;
- },
- "creationRatio" => 1,
- ],
- 82 => //(2) 82
- [
- "wordLength" => 10,
- "numWords" => 4,
- "numPositions" => 11,
- "renderer" => 82,
- "difficulty" => function () {
- return 1000;
- },
- "creationRatio" => 1,
- ],
- 83 => //(3) 83
- [
- "wordLength" => 10,
- "numWords" => 4,
- "numPositions" => 11,
- "renderer" => 83,
- "difficulty" => function () {
- return 1000;
- },
- "creationRatio" => 1,
- ],
- 100 => //(4) 100
- [
- "wordLength" => 8,
- "numWords" => 6,
- "numPositions" => 14,
- "renderer" => 100,
- "difficulty" => function () {
- return 1000;
- },
- "creationRatio" => 8,
- ],
- 110 => //(5) 110
- [
- "wordLength" => 10,
- "numWords" => 4,
- "numPositions" => 12,
- "renderer" => 110,
- "difficulty" => function () {
- return 1000;
- },
- "creationRatio" => 5.333333,
- ],
- 111 => //(6) 111
- [
- "wordLength" => 10,
- "numWords" => 4,
- "numPositions" => 12,
- "renderer" => 111,
- "difficulty" => function () {
- return 1000;
- },
- "creationRatio" => 5.333333,
- ],
- 112 => //(7) 112
- [
- "wordLength" => 10,
- "numWords" => 4,
- "numPositions" => 12,
- "renderer" => 112,
- "difficulty" => function () {
- return 1000;
- },
- "creationRatio" => 5.333333,
- ],
- 120 => //(8) 120
- [
- "wordLength" => 8,
- "numWords" => 4,
- "numPositions" => 10,
- "renderer" => 120,
- "difficulty" => function () {
- return 1000;
- },
- "creationRatio" => 32,
- ],
- 140 => //(9) 140
- [
- "wordLength" => 12,
- "numWords" => 6,
- "numPositions" => 21,
- "renderer" => 140,
- "difficulty" => function () {
- return 1000;
- },
- "creationRatio" => 64,
- ],
- 160 => //(10) 160
- [
- "wordLength" => 12,
- "numWords" => 4,
- "numPositions" => 15,
- "renderer" => 160,
- "difficulty" => function () {
- return 1000;
- },
- "creationRatio" => 128,
- ],
- ];
-
- $currentNumbers = [];
- foreach ($levelsToGenerate as $renderer => $levelInfo) {
- $currentNumbers[$renderer] = $this->countWhere(["renderer" => $levelInfo["renderer"], "difficulty" => 1000]);
- }
-
- $renderers = array_keys($levelsToGenerate);
-
- $levelGenerated = 0;
-
- $currentIndex = 0;
- $words = [];
- do {
-// var_dump($levelsToGenerate);
- while ($currentIndex === 0 || $currentNumbers[$renderers[$currentIndex]] >= $currentNumbers[$renderers[0]] * $levelsToGenerate[$renderers[$currentIndex]]["creationRatio"]) {
- $currentIndex = ($currentIndex + 1) % count($renderers);
- if ($currentIndex === 0){
- break;
- }
- }
-
- $words[$levelsToGenerate[$renderers[$currentIndex]]["wordLength"]] = $words[$levelsToGenerate[$renderers[$currentIndex]]["wordLength"]] ?? $this->wordManager->findWordsForLength($levelsToGenerate[$renderers[$currentIndex]]["wordLength"]);
-
- $currentWords = $words[$levelsToGenerate[$renderers[$currentIndex]]["wordLength"]];
-
- $level = $this->generateLevelWithData($levelsToGenerate[$renderers[$currentIndex]], $currentWords);
- if ($level) {
- $words[$levelsToGenerate[$renderers[$currentIndex]]["wordLength"]] = $currentWords;
- $this->save($level, false);
- $levelGenerated++;
- $currentNumbers[$renderers[$currentIndex]]++;
- } else {
- var_dump($renderers[$currentIndex]);
- break;
- }
-
- } while (count($levelsToGenerate) > 0 && $levelGenerated < 180);
-
- $this->emFlush();
- $this->wordManager->emFlush();
- return $levelGenerated;
- }
-
- private function generateLevelWithData($levelData, &$words)
- {
- if (count($words) >= $levelData["numWords"]) {
- $selectedWords = [];
- for ($i = 0; $i < $levelData["numWords"]; $i++) {
- $wordCount = count($words);
- $currentWordIndex = rand(0, $wordCount - 1);
- $selectedWords[] = strtoupper($words[$currentWordIndex]->getWord());
- $words[$currentWordIndex]->setUsed(true);
- $this->wordManager->save($words[$currentWordIndex], false);
- array_splice($words, $currentWordIndex, 1);
- }
-
- $positions = [];
- do {
- for ($i = 0; $i < $levelData["numPositions"]; $i++) {
- $positions[] = rand(0, 3);
- }
- } while (count(array_filter($positions, function ($position) {
- return $position == 0;
- })) / $levelData["numPositions"] >= 0.67);
-
- $level = new Level();
- $level->setWords(json_encode($selectedWords));
- $level->setPositions(json_encode($positions));
- $level->setDifficulty($levelData["difficulty"]());
- $level->setLastUpdated(new \DateTime());
- $level->setLang(1); //German
- $level->setDeleted(false);
-
- if (is_int($levelData["renderer"])) {
- $level->setRenderer($levelData["renderer"]);
- } else {
- $level->setRenderer($levelData["renderer"]());
- }
-
- return $level;
- } else {
- return null;
- }
-
- }
-}
\ No newline at end of file
diff --git a/src/module/Application/src/Model/Manager/RatingManager.php b/src/module/Application/src/Model/Manager/RatingManager.php
deleted file mode 100755
index 84165ff..0000000
--- a/src/module/Application/src/Model/Manager/RatingManager.php
+++ /dev/null
@@ -1,28 +0,0 @@
-repository = $repository;
- parent::__construct($repository, $entity);
- }
-
- /**
- * @param int $id
- * @return Rating
- */
- public function getEntityById($id)
- {
- return parent::getEntityById($id);
- }
-}
\ No newline at end of file
diff --git a/src/module/Application/src/Model/Manager/WordManager.php b/src/module/Application/src/Model/Manager/WordManager.php
deleted file mode 100755
index 3a564dc..0000000
--- a/src/module/Application/src/Model/Manager/WordManager.php
+++ /dev/null
@@ -1,142 +0,0 @@
-repository = $repository;
- parent::__construct($repository, $entity);
- }
-
- /**
- * @param Word $word
- * @param $action
- * @return mixed
- */
- public static function doAction($word, $action)
- {
- switch($action)
- {
- case self::ACTION_UNSURE:
- {
- $word->setChecked(-1);
- break;
- }
- case self::ACTION_CHECKED:
- {
- $word->setChecked(1);
- $word->setDeleted(false);
- break;
- }
- case self::ACTION_DELETED:
- {
- $word->setChecked(1);
- $word->setDeleted(true);
- break;
- }
- }
- $word->setLastUpdated(new \DateTime());
-
- return $word;
- }
-
- /**
- * @param int $id
- * @return Word
- */
- public function getEntityById($id)
- {
- return parent::getEntityById($id);
- }
-
- /**
- * @param \DateTime $dateTime
- * @param int $offset
- * @return array
- */
- public function findNewerThan($dateTime, $offset = 0)
- {
- return $this->repository->findNewerThanDate($dateTime, $offset);
- }
-
- public function countNewerThan($dateTime)
- {
- return $this->repository->countNewerThanDate($dateTime);
- }
-
- static function wordToArray(Word $word)
- {
- return [
- "id" => $word->getId(),
- "word" => $word->getWord(),
-// "created" => $word->getCreated()->format(SyncController::DATETIME_SYNC_FORMAT),
-// "lastUpdated" => $word->getLastUpdated()->format(SyncController::DATETIME_SYNC_FORMAT),
- "language" => $word->getLang(),
- "deleted" => $word->isDeleted(),
- ];
- }
-
- public function wordsToArray($words)
- {
- $returnArray = [];
- /** @var Word $word */
- foreach ($words as $word)
- {
- $returnArray[] = $this->wordToArray($word);
- }
- return $returnArray;
- }
-
- public function getRandomWordNotChecked($minLength = 0, $maxLength = 100)
- {
- return $this->repository->getRandomWordNotChecked($minLength, $maxLength);
- }
-
- public function countNotChecked($minLength = 0, $maxLength = 100)
- {
- return $this->repository->countNotChecked($minLength, $maxLength);
- }
-
- public function countDeleted($minLength = 0, $maxLength = 100)
- {
- return $this->repository->countDeleted($minLength, $maxLength);
- }
-
- public function countChecked($minLength = 0, $maxLength = 100)
- {
- return $this->repository->countChecked($minLength, $maxLength);
- }
-
- public function countUnsure($minLength = 0, $maxLength = 100)
- {
- return $this->repository->countUnsure($minLength, $maxLength);
- }
-
- /**
- * @param $length
- * @return Word[]
- */
- public function findWordsForLength($length)
- {
- return $this->repository->findWordsForLength($length);
- }
-
- public function countNotUsed($minLength = 0, $maxLength = 100)
- {
- return $this->repository->countNotUsed($minLength, $maxLength);
- }
-}
\ No newline at end of file
diff --git a/src/module/Application/src/Model/Rating.php b/src/module/Application/src/Model/Rating.php
deleted file mode 100755
index e88597d..0000000
--- a/src/module/Application/src/Model/Rating.php
+++ /dev/null
@@ -1,112 +0,0 @@
-id = null;
- $this->authToken = null;
- $this->level = null;
- }
-
- /**
- * @return mixed
- */
- public function getId()
- {
- return $this->id;
- }
-
- /**
- * @param mixed $id
- */
- public function setId($id)
- {
- $this->id = $id;
- }
-
- /**
- * @return Level
- */
- public function getLevel()
- {
- return $this->level;
- }
-
- /**
- * @param Level $level
- */
- public function setLevel($level)
- {
- $this->level = $level;
- }
-
- /**
- * @return AuthToken
- */
- public function getAuthToken()
- {
- return $this->authToken;
- }
-
- /**
- * @param AuthToken $authToken
- */
- public function setAuthToken($authToken)
- {
- $this->authToken = $authToken;
- }
-
- /**
- * @return int
- */
- public function getRating()
- {
- return $this->rating;
- }
-
- /**
- * @param int $rating
- */
- public function setRating($rating)
- {
- $this->rating = $rating;
- }
-}
diff --git a/src/module/Application/src/Model/Repository/AuthTokenRepository.php b/src/module/Application/src/Model/Repository/AuthTokenRepository.php
deleted file mode 100755
index 9bb19d4..0000000
--- a/src/module/Application/src/Model/Repository/AuthTokenRepository.php
+++ /dev/null
@@ -1,10 +0,0 @@
-_em->createQueryBuilder();
- $queryBuilder->select("l")->from(Level::class, "l");
-
- if ($date != null) {
- $queryBuilder->andWhere($queryBuilder->expr()->gte("l.lastUpdated", ":fromDate"));
- $queryBuilder->setParameter("fromDate", $date->format("Y-m-d H:i:00"));
- }
- $queryBuilder->setMaxResults(SyncController::SYNC_MAX_LEVELS);
- $queryBuilder->setFirstResult($offset * SyncController::SYNC_MAX_LEVELS);
-
- return $queryBuilder->getQuery()->getResult();
- }
-
- public function countNewerThanDate($date)
- {
- $queryBuilder = $this->_em->createQueryBuilder();
- $queryBuilder->select("COUNT(l.id) as number")->from(Level::class, "l");
-
- if ($date != null) {
- $queryBuilder->andWhere($queryBuilder->expr()->gte("l.lastUpdated", ":fromDate"));
- $queryBuilder->setParameter("fromDate", $date->format("Y-m-d H:i:00"));
- }
-
- return $queryBuilder->getQuery()->getSingleScalarResult();
- }
-
- public function beginTransaction()
- {
- $this->_em->getConnection()->beginTransaction();
- }
-
- public function endTransaction()
- {
- try {
- $this->_em->getConnection()->commit();
- } catch (\Exception $e) {
- $this->_em->getConnection()->rollBack();
- throw $e;
- }
- }
-
- public function countWhere($whereArray)
- {
- $queryBuilder = $this->_em->createQueryBuilder();
- $queryBuilder->select("COUNT(l.id) as number")->from(Level::class, "l");
-
- foreach ($whereArray as $field => $arg) {
- $queryBuilder->andWhere($queryBuilder->expr()->eq("l.".$field, ":".$field));
- $queryBuilder->setParameter("".$field, $arg);
- }
-
- return $queryBuilder->getQuery()->getSingleScalarResult();
- }
-}
\ No newline at end of file
diff --git a/src/module/Application/src/Model/Repository/RatingRepository.php b/src/module/Application/src/Model/Repository/RatingRepository.php
deleted file mode 100755
index 08baf68..0000000
--- a/src/module/Application/src/Model/Repository/RatingRepository.php
+++ /dev/null
@@ -1,10 +0,0 @@
-_em->createQueryBuilder();
- $queryBuilder->select("w")->from(Word::class, "w");
-
- $queryBuilder->andWhere($queryBuilder->expr()->eq("w.checked", "1"));
- if ($date != null)
- {
- $queryBuilder->andWhere($queryBuilder->expr()->gte("w.lastUpdated", ":fromDate"));
- $queryBuilder->setParameter("fromDate", $date->format("Y-m-d"));
- }
- $queryBuilder->setMaxResults(SyncController::SYNC_MAX_WORDS);
- $queryBuilder->setFirstResult($offset * SyncController::SYNC_MAX_WORDS);
-
- return $queryBuilder->getQuery()->getResult();
- }
-
- public function countNewerThanDate($date)
- {
- $queryBuilder = $this->_em->createQueryBuilder();
- $queryBuilder->select("COUNT(w.id) as number")->from(Word::class, "w");
-
- $queryBuilder->andWhere($queryBuilder->expr()->eq("w.checked", "1"));
- if ($date != null)
- {
- $queryBuilder->andWhere($queryBuilder->expr()->gte("w.lastUpdated", ":fromDate"));
- $queryBuilder->setParameter("fromDate", $date->format("Y-m-d"));
- }
- return $queryBuilder->getQuery()->getSingleScalarResult();
- }
-
- public function getRandomWordNotChecked($minLength = 0, $maxLength = 100)
- {
- $numberWords = $this->countNotChecked($minLength, $maxLength);
-
- $queryBuilder = $this->_em->createQueryBuilder();
- $queryBuilder->select("w")->from(Word::class, "w");
-
- $offset = rand(0,$numberWords-1);
-
- $queryBuilder->andWhere($queryBuilder->expr()->eq("w.checked", "0"));
- $queryBuilder->andWhere($queryBuilder->expr()->gte("CHAR_LENGTH(w.word)", ":minLength"));
- $queryBuilder->andWhere($queryBuilder->expr()->lte("CHAR_LENGTH(w.word)", ":maxLength"));
- $queryBuilder->setParameter("minLength", $minLength);
- $queryBuilder->setParameter("maxLength", $maxLength);
- $queryBuilder->setMaxResults(1);
- $queryBuilder->setFirstResult($offset);
-
- $res = $queryBuilder->getQuery()->getResult();
- if (is_array($res))
- {
- return $res[0];
- }
- return $res;
- }
-
- public function countNotChecked($minLength = 0, $maxLength = 100)
- {
- $queryBuilder = $this->_em->createQueryBuilder();
- $queryBuilder->select("COUNT(w.id)")->from(Word::class, "w");
-
-// $queryBuilder->andWhere($queryBuilder->expr()->eq("w.word", "Sechsfüßer"));
-
- $queryBuilder->andWhere($queryBuilder->expr()->eq("w.checked", "0"));
- $queryBuilder->andWhere($queryBuilder->expr()->gte("CHAR_LENGTH(w.word)", ":minLength"));
- $queryBuilder->andWhere($queryBuilder->expr()->lte("CHAR_LENGTH(w.word)", ":maxLength"));
- $queryBuilder->setParameter("minLength", $minLength);
- $queryBuilder->setParameter("maxLength", $maxLength);
- $queryBuilder->setMaxResults(1);
- return $queryBuilder->getQuery()->getSingleScalarResult();
- }
-
- public function countDeleted($minLength, $maxLength)
- {
- $queryBuilder = $this->_em->createQueryBuilder();
- $queryBuilder->select("COUNT(w.id)")->from(Word::class, "w");
-
- $queryBuilder->andWhere($queryBuilder->expr()->eq("w.checked", "1"));
- $queryBuilder->andWhere($queryBuilder->expr()->eq("w.deleted", "1"));
- $queryBuilder->andWhere($queryBuilder->expr()->gte("CHAR_LENGTH(w.word)", ":minLength"));
- $queryBuilder->andWhere($queryBuilder->expr()->lte("CHAR_LENGTH(w.word)", ":maxLength"));
- $queryBuilder->setParameter("minLength", $minLength);
- $queryBuilder->setParameter("maxLength", $maxLength);
- $queryBuilder->setMaxResults(1);
- return $queryBuilder->getQuery()->getSingleScalarResult();
- }
-
- public function countChecked($minLength, $maxLength)
- {
- $queryBuilder = $this->_em->createQueryBuilder();
- $queryBuilder->select("COUNT(w.id)")->from(Word::class, "w");
-
- $queryBuilder->andWhere($queryBuilder->expr()->eq("w.checked", "1"));
- $queryBuilder->andWhere($queryBuilder->expr()->eq("w.deleted", "0"));
- $queryBuilder->andWhere($queryBuilder->expr()->gte("CHAR_LENGTH(w.word)", ":minLength"));
- $queryBuilder->andWhere($queryBuilder->expr()->lte("CHAR_LENGTH(w.word)", ":maxLength"));
- $queryBuilder->setParameter("minLength", $minLength);
- $queryBuilder->setParameter("maxLength", $maxLength);
- $queryBuilder->setMaxResults(1);
- return $queryBuilder->getQuery()->getSingleScalarResult();
- }
-
- public function countUnsure($minLength, $maxLength)
- {
- $queryBuilder = $this->_em->createQueryBuilder();
- $queryBuilder->select("COUNT(w.id)")->from(Word::class, "w");
-
- $queryBuilder->andWhere($queryBuilder->expr()->eq("w.checked", "-1"));
- $queryBuilder->andWhere($queryBuilder->expr()->gte("CHAR_LENGTH(w.word)", ":minLength"));
- $queryBuilder->andWhere($queryBuilder->expr()->lte("CHAR_LENGTH(w.word)", ":maxLength"));
- $queryBuilder->setParameter("minLength", $minLength);
- $queryBuilder->setParameter("maxLength", $maxLength);
- $queryBuilder->setMaxResults(1);
- return $queryBuilder->getQuery()->getSingleScalarResult();
- }
-
- public function findWordsForLength($length)
- {
- $queryBuilder = $this->_em->createQueryBuilder();
- $queryBuilder->select("w")->from(Word::class, "w");
-
- $queryBuilder->andWhere($queryBuilder->expr()->eq("w.checked", "1"));
- $queryBuilder->andWhere($queryBuilder->expr()->eq("w.deleted", "0"));
- $queryBuilder->andWhere($queryBuilder->expr()->eq("w.used", "0"));
- $queryBuilder->andWhere($queryBuilder->expr()->eq("CHAR_LENGTH(w.word)", ":length"));
- $queryBuilder->setParameter("length", $length);
- return $queryBuilder->getQuery()->getResult();
- }
-
- public function countNotUsed(int $minLength, int $maxLength)
- {
- $queryBuilder = $this->_em->createQueryBuilder();
- $queryBuilder->select("COUNT(w.id)")->from(Word::class, "w");
-
- $queryBuilder->andWhere($queryBuilder->expr()->eq("w.checked", "1"));
- $queryBuilder->andWhere($queryBuilder->expr()->eq("w.deleted", "0"));
- $queryBuilder->andWhere($queryBuilder->expr()->eq("w.used", "0"));
- $queryBuilder->andWhere($queryBuilder->expr()->gte("CHAR_LENGTH(w.word)", ":minLength"));
- $queryBuilder->andWhere($queryBuilder->expr()->lte("CHAR_LENGTH(w.word)", ":maxLength"));
- $queryBuilder->setParameter("minLength", $minLength);
- $queryBuilder->setParameter("maxLength", $maxLength);
- $queryBuilder->setMaxResults(1);
- return $queryBuilder->getQuery()->getSingleScalarResult();
- }
-}
\ No newline at end of file
diff --git a/src/module/Application/src/Model/Word.php b/src/module/Application/src/Model/Word.php
deleted file mode 100755
index cc0ea9f..0000000
--- a/src/module/Application/src/Model/Word.php
+++ /dev/null
@@ -1,211 +0,0 @@
-id = null;
- $this->created = new \DateTime();
- $this->lastUpdated = new \DateTime();
- $this->deleted = false;
- $this->lang = self::LANGUAGE_DE;
- $this->word = "";
- $this->checked = -1;
- $this->used = false;
- }
-
- /**
- * @return mixed
- */
- public function getId()
- {
- return $this->id;
- }
-
- /**
- * @param mixed $id
- */
- public function setId($id)
- {
- $this->id = $id;
- }
-
- /**
- * @return string
- */
- public function getWord()
- {
- return $this->word;
- }
-
- /**
- * @param string $word
- */
- public function setWord($word)
- {
- $this->word = $word;
- }
-
- /**
- * @return \DateTime
- */
- public function getCreated()
- {
- return $this->created;
- }
-
- /**
- * @param \DateTime $created
- */
- public function setCreated($created)
- {
- $this->created = $created;
- }
-
- /**
- * @return \DateTime
- */
- public function getLastUpdated()
- {
- return $this->lastUpdated;
- }
-
- /**
- * @param \DateTime $lastUpdated
- */
- public function setLastUpdated($lastUpdated)
- {
- $this->lastUpdated = $lastUpdated;
- }
-
- /**
- * @return boolean
- */
- public function isDeleted()
- {
- return $this->deleted;
- }
-
- /**
- * @param boolean $deleted
- */
- public function setDeleted($deleted)
- {
- $this->deleted = $deleted;
- }
-
- /**
- * @return int
- */
- public function getLang()
- {
- return $this->lang;
- }
-
- /**
- * @param int $lang
- */
- public function setLang($lang)
- {
- $this->lang = $lang;
- }
-
- /**
- * @return int
- */
- public function getChecked()
- {
- return $this->checked;
- }
-
- /**
- * @param int $checked
- */
- public function setChecked($checked)
- {
- $this->checked = $checked;
- }
-
- /**
- * @return bool
- */
- public function isUsed()
- {
- return $this->used;
- }
-
- /**
- * @param bool $used
- */
- public function setUsed($used)
- {
- $this->used = $used;
- }
-}
diff --git a/src/module/Application/src/Module.php b/src/module/Application/src/Module.php
deleted file mode 100755
index f6d1b73..0000000
--- a/src/module/Application/src/Module.php
+++ /dev/null
@@ -1,143 +0,0 @@
-getApplication()->getEventManager();
- $moduleRouteListener = new ModuleRouteListener();
- $moduleRouteListener->attach($eventManager);
- $request = $e->getRequest();
-
- $logPath = realpath(self::LOG_DIR);
- $logger = new Logger();
- $catchAllWriter = new Stream($logPath . "/log.log");
- $logger->addWriter($catchAllWriter);
- $errorWriter = new Stream($logPath . "/error.log");
- $errorWriter->addFilter(new Priority(Logger::ERR));
- $logger->addWriter($errorWriter);
- $errorLogger = new Logger();
- $phpErrorWriter = new Stream($logPath . "/php_error.log");
- $errorLogger->addWriter($catchAllWriter);
- $errorLogger->addWriter($phpErrorWriter);
- Logger::registerErrorHandler($errorLogger);
- Logger::registerFatalErrorShutdownFunction($errorLogger);
-
- $exceptionLogger = new Logger();
- $exceptionWriter = new Stream($logPath . "/php_exceptions.log");
- $exceptionLogger->addWriter($catchAllWriter);
- $exceptionLogger->addWriter($exceptionWriter);
- Logger::registerExceptionHandler($exceptionLogger);
-
- if (($request instanceof Request)) {
- $chromePhp = new ChromePhp();
- $errorLogger->addWriter($chromePhp);
- $exceptionLogger->addWriter($chromePhp);
- }
-
- $eventManager->getSharedManager()->attach('*', self::EVENT_LOG, function (Event $e) use ($logger) {
- $params = $e->getParams();
-
- if (isset($params["message"])) {
- if (isset($params["level"]) && ($params["level"] == Logger::ALERT || $params["level"] == Logger::CRIT || $params["level"] == Logger::DEBUG || $params["level"] == Logger::EMERG || $params["level"] == Logger::ERR || $params["level"] == Logger::INFO || $params["level"] == Logger::NOTICE)) {
- $logLevel = $params["level"];
- } else {
- $logLevel = Logger::INFO;
- }
- $logger->log($logLevel, $params["message"]);
- }
- });
- }
-
- public function getConfig()
- {
- $config = array();
- foreach (glob(__DIR__ . '/../config/*.config.php') as $filename) {
- $config = array_merge_recursive($config, include($filename));
- }
- return $config;
- }
-
-// public function getServiceConfig()
-// {
-// return [
-// 'factories' => [
-// SessionManager::class => function ($container) {
-// $config = $container->get('config');
-// if (!isset($config['session'])) {
-// $sessionManager = new SessionManager();
-// Container::setDefaultManager($sessionManager);
-// return $sessionManager;
-// }
-//
-// $session = $config['session'];
-//
-// $sessionConfig = null;
-// if (isset($session['config'])) {
-// $class = isset($session['config']['class'])
-// ? $session['config']['class']
-// : SessionConfig::class;
-//
-// $options = isset($session['config']['options'])
-// ? $session['config']['options']
-// : [];
-//
-// $sessionConfig = new $class();
-// $sessionConfig->setOptions($options);
-// }
-//
-// $sessionStorage = null;
-// if (isset($session['storage'])) {
-// $class = $session['storage'];
-// $sessionStorage = new $class();
-// }
-//
-// $sessionSaveHandler = null;
-// if (isset($session['save_handler'])) {
-// // class should be fetched from service manager
-// // since it will require constructor arguments
-// $sessionSaveHandler = $container->get($session['save_handler']);
-// }
-//
-// $sessionManager = new SessionManager(
-// $sessionConfig,
-// $sessionStorage,
-// $sessionSaveHandler
-// );
-//
-// Container::setDefaultManager($sessionManager);
-// return $sessionManager;
-// },
-// ],
-// ];
-// }
-}
diff --git a/src/scss/_settings.scss b/src/scss/_settings.scss
deleted file mode 100755
index 04b72a4..0000000
--- a/src/scss/_settings.scss
+++ /dev/null
@@ -1,40 +0,0 @@
-@import "defaultSettings";
-
-$themes: map-merge($themes, (dark: (
- class: dark,
- themeColor: #373737,
- lightThemeColor: #4b4b4b,
- linkColor: #fff,
- spinnerColor: #ffffff,
- navBarTextColor: #fff,
- textColor: #ffffff,
- textColor2: #9b9b9b,
- lightLinkColor: #ffffff,
- linkBorderBottom: 1px solid #ffffff,
- linkHoverColor: #ffffff,
- lightLinkHoverColor: #ffffff,
- background: #000000
-)));
-
-$rotationDegrees: (90 180 270 360);
-$animationDuration: .25s;
-
-//$degreeMatrix: (
-// //0:matrix(1, 0, 0, 1, 0, 0),
-// 0:rotate(0deg),
-// 90:matrix(0, 1, -1, 0, 0, 0),
-// 180:matrix(-1, 0, 0, -1, 0, 0),
-// 270:matrix(0, -1, 1, 0, 0, 0),
-// //360:matrix(0.99999, 0, 0, 0.99999, 0, 0),
-// //450:matrix(0, 1, -1, 0, 0, 0),
-// 360:rotate(360deg),
-// 450:rotate(450deg),
-//);
-$degreeMatrix: (
- 0:rotate(0deg),
- 90:rotate(90deg),
- 180:rotate(180deg),
- 270:rotate(270deg),
- 360:rotate(360deg),
- 450:rotate(450deg),
-);
\ No newline at end of file
diff --git a/src/server/index.ts b/src/server/index.ts
new file mode 100644
index 0000000..7f9f509
--- /dev/null
+++ b/src/server/index.ts
@@ -0,0 +1,106 @@
+import "dotenv/config";
+import {EasySyncServerDb} from "cordova-sites-easy-sync/dist/server";
+
+import * as path from "path";
+
+import * as express from 'express';
+import {routes} from './routes';
+import {UserManager} from "cordova-sites-user-management/dist/server";
+
+//Import Models
+import "../shared/model/LevelData"
+
+import {ServerTranslator} from "cordova-sites/dist/server";
+import {Translator} from "cordova-sites/dist/shared";
+import {Setup1000000002000} from "../shared/model/migration/shared/Setup";
+import {SetupUserManagement1000000001000} from "cordova-sites-user-management/dist/shared/migrations/SetupUserManagement"
+import {ConvertData1000000005000} from "../shared/model/migration/server/ConvertData";
+
+const translationGerman = require("../client/translations/de");
+const translationEnglish = require ("../client/translations/en");
+
+const port = process.env.PORT || 3000;
+process.env.JWT_SECRET = process.env.JWT_SECRET || "bkl2d90did98sehjdnovfe4g795bgrgh93fbnnlosh90u";
+
+// BaseModel._databaseClass = EasySyncServerDb;
+EasySyncServerDb.CONNECTION_PARAMETERS = {
+ "type": "mysql",
+ "host": process.env.MYSQL_HOST || "localhost",
+ "username": process.env.MYSQL_USER || "root",
+ "password": process.env.MYSQL_PASSWORD || "",
+ "database": process.env.MYSQL_DATABASE || "wordRotator",
+ "synchronize": false,
+ "migrationsRun": true,
+ "migrations": [
+ SetupUserManagement1000000001000,
+ Setup1000000002000,
+ ConvertData1000000005000,
+ ],
+
+ "logging": ["error", "warn"]
+ // "logging": true
+};
+
+UserManager.PEPPER = process.env.PEPPER || "gfjioüwdfnmklf";
+
+UserManager.REGISTRATION_IS_ACTIVATED = false;
+UserManager.LOGIN_NEED_TO_BE_ACTIVATED = false;
+
+UserManager.REGISTRATION_DEFAULT_ROLE_IDS = [4];
+
+const app = express();
+
+//Todo guten wert finden?
+app.use(express.json({limit: "50mb"}));
+
+//Allow Origin setzen bevor rest passiert
+app.use(function (req, res, next) {
+
+ // Website you wish to allow to connect
+ res.setHeader('Access-Control-Allow-Origin', '*');
+
+ // Request methods you wish to allow
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
+
+ // Request headers you wish to allow
+ res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type,Authorization');
+
+ // Set to true if you need the website to include cookies in the requests sent
+ // to the API (e.g. in case you use sessions)
+ res.setHeader('Access-Control-Allow-Credentials', 'true');
+
+ // Pass to next layer of middleware
+ next();
+});
+app.use(ServerTranslator.setUserLanguage);
+app.use('/api', routes);
+
+app.use(express.static(path.resolve(path.dirname(process.argv[1]), "public")));
+
+//Handle errors
+app.use(function (err, req, res, next) {
+ console.error(err);
+ res.status(err.status || 500);
+ if (err instanceof Error) {
+ res.json({error: err.message});
+ } else {
+ res.json({error: err});
+ }
+});
+
+EasySyncServerDb.getInstance()._connectionPromise.then(async () => {
+ // await setupDB();
+ Translator.init({
+ translations: {
+ "de": translationGerman,
+ "en": translationEnglish
+ },
+ fallbackLanguage: "de",
+ // markTranslations: true,
+ markUntranslatedTranslations: true,
+ });
+
+ app.listen(port, () => {
+ console.log('Server started on Port: ' + port);
+ });
+});
diff --git a/src/server/logic/v1/controller/ContactController.ts b/src/server/logic/v1/controller/ContactController.ts
new file mode 100644
index 0000000..6580ee5
--- /dev/null
+++ b/src/server/logic/v1/controller/ContactController.ts
@@ -0,0 +1,60 @@
+
+import * as nodemailer from "nodemailer";
+import {Helper} from "js-helper/dist/shared/Helper";
+
+export class ContactController {
+ static async sendContactMail(req, res){
+
+ let emailadress = req.body.email;
+ let message = req.body.message;
+ let hasAcceptedPolicy = req.body.policy;
+
+ if (hasAcceptedPolicy !== "1"){
+ return res.json({success: false, message: "policy must be accepted!"});
+ }
+ if (Helper.isNull(message) || message.trim() === ""){
+ return res.json({success: false, message: "message must be submitted!"});
+ }
+ if (Helper.isNull(emailadress)){
+ return res.json({success: false, message: "email must be submitted!"});
+ }
+
+ let atIndex = emailadress.indexOf("@");
+ if (atIndex === -1 || atIndex === emailadress.length-1){
+ return res.json({success: false, message: "email is not valid"});
+ }
+
+ let transporter = nodemailer.createTransport({
+ host: process.env.EMAIL_HOST,
+ port: process.env.EMAIL_PORT,
+ secure: Helper.nonNull(process.env.EMAIL_SECURE, "1") !== "0",
+ auth: {
+ user: process.env.EMAIL_USER,
+ pass: process.env.EMAIL_PASSWORD,
+ },
+ tls: {
+ ciphers:'SSLv3'
+ }
+ });
+
+ let mailOptions = {
+ from: process.env.EMAIL_FROM,
+ to: process.env.CONTACT_EMAIL,
+ replyTo: emailadress,
+ subject: "[wordRotator][contact] Nachricht über das Kontaktformular",
+ text:"Von: "+emailadress+"\n\n"+ message+"\n\n\n-------------\n\n Diese Nachricht wurde über ein Kontaktformular automatisiert gesendet. Zum Antworten an "+emailadress+" druücke auf Antworten.",
+ };
+
+ await new Promise((resolve, reject) => {
+ transporter.sendMail(mailOptions, (err, info) => {
+ if (err) {
+ reject(err)
+ } else {
+ resolve(info);
+ }
+ })
+ });
+
+ res.json({success: true});
+ }
+}
\ No newline at end of file
diff --git a/src/server/logic/v1/routes.ts b/src/server/logic/v1/routes.ts
new file mode 100644
index 0000000..effcb5d
--- /dev/null
+++ b/src/server/logic/v1/routes.ts
@@ -0,0 +1,20 @@
+import * as express from 'express';
+import {userRoutes, syncRoutes} from "cordova-sites-user-management/dist/server";
+import {ContactController} from "./controller/ContactController";
+
+const routerV1 = express.Router();
+
+const errorHandler = (fn, context) => {
+ return (req, res, next) => {
+ const resPromise = fn.call(context, req,res,next);
+ if (resPromise && resPromise.catch){
+ resPromise.catch(err => next(err));
+ }
+ }
+};
+
+routerV1.use("/sync", syncRoutes);
+routerV1.use("/user", userRoutes);
+routerV1.post("/contact", errorHandler(ContactController.sendContactMail, ContactController));
+
+export {routerV1};
\ No newline at end of file
diff --git a/src/server/public/.gitkeep b/src/server/public/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/src/server/public/bundle.js b/src/server/public/bundle.js
new file mode 100644
index 0000000..5a0dada
--- /dev/null
+++ b/src/server/public/bundle.js
@@ -0,0 +1,3 @@
+/*! For license information please see bundle.js.LICENSE.txt */
+!function(){var e={11983:function(e,t,n){"use strict";n(16266),n(10990),n(70911),n(14160),n(6197),n(96728),n(54039),n(93568),n(78051),n(38250),n(15434),n(54952),n(96337),n(35666)},24631:function(e,t,n){"use strict";function r(e,t){for(var n=0;n0&&(n=r[r.length-1])}this.storagePath=n}var t,n,u;return t=e,(n=[{key:"download",value:function(){return i(this,void 0,void 0,regeneratorRuntime.mark((function e(){var t,n,r;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return t=s.DataManager.fetchBlob(this.downloadUrl),e.next=4,a.FilePromise.open(this.storagePath);case 4:return n=e.sent,e.next=7,n.createWriter();case 7:return r=e.sent,e.t0=r,e.next=11,t;case 11:return e.t1=e.sent,e.next=14,e.t0.write.call(e.t0,e.t1);case 14:case"end":return e.stop()}}),e,this)})))}}])&&r(t.prototype,n),u&&r(t,u),e}();t.FileTransferPromise=u},70482:function(e,t){"use strict";function n(e,t){for(var n=0;n=r)){t.next=9;break}return i="INSERT OR REPLACE INTO "+a+" ("+c.join(",")+") VALUES "+f.join(","),t.next=7,this._queryRunner.query(i,l);case 7:f=[],l=[];case 9:case"end":return t.stop()}}),t,this)})))}));case 12:if(!(f.length>0)){n.next=16;break}return p="INSERT OR REPLACE INTO "+a+" ("+c.join(",")+") VALUES "+f.join(","),n.next=16,this._queryRunner.query(p,l);case 16:case"end":return n.stop()}}),n,this)})))}},{key:"_deleteModels",value:function(e,t){return i(this,void 0,void 0,regeneratorRuntime.mark((function n(){var r,o,a,u,c,l=this;return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:if(r=300,0!==t.length){n.next=3;break}return n.abrupt("return");case 3:return o=e.getSchemaName(),o=s.Helper.toSnakeCase(o),a=[],u=[],n.next=9,s.Helper.asyncForEach(t,(function(e){return i(l,void 0,void 0,regeneratorRuntime.mark((function t(){var n;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(a.push(e),u.push("?"),!(u.length>=r)){t.next=8;break}return n="DELETE FROM "+o+" WHERE id IN ("+a.join(",")+")",t.next=6,this._queryRunner.query(n);case 6:u=[],a=[];case 8:case"end":return t.stop()}}),t,this)})))}));case 9:if(!(u.length>0)){n.next=13;break}return c="DELETE FROM "+o+" WHERE id IN ("+a.join(",")+")",n.next=13,this._queryRunner.query(c);case 13:case"end":return n.stop()}}),n,this)})))}},{key:"_handleManyToManyRelations",value:function(){return i(this,void 0,void 0,regeneratorRuntime.mark((function e(){var t,n=this;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this._savePromise;case 2:return t=[],Object.keys(this._manyToManyRelations).forEach((function(e){var r="DELETE FROM "+e+" WHERE ",i=[];Object.keys(n._manyToManyRelations[e]).forEach((function(t){t.startsWith("delete_")&&i.push(t.substr(7)+" IN ("+n._manyToManyRelations[e][t].join(",")+")")})),r+=i.join(" OR ")+";",t.push(n._queryRunner.query(r).then((function(){if(n._manyToManyRelations[e].values.length>0){var t=Object.keys(n._manyToManyRelations[e].values[0]),r=[];n._manyToManyRelations[e].values.forEach((function(e){var n=[];t.forEach((function(t){n.push(e[t])})),r.push("("+n.join(",")+")")}));var i="INSERT OR REPLACE INTO "+e+"("+t.join(",")+") VALUES "+r.join(",")+";";return n._queryRunner.query(i)}})))})),e.next=6,Promise.all(t);case 6:case"end":return e.stop()}}),e,this)})))}}])&&r(t.prototype,n),d&&r(t,d),e}();t.SyncJob=d,d.SYNC_PATH_PREFIX="sync"},26590:function(e,t,n){"use strict";function r(e,t){for(var n=0;nr)){a.next=5;break}s=t[r],a.next=9;break;case 5:if(!p.Helper.isNotNull(e.id)){a.next=9;break}return a.next=8,this.findById(e.id,this.getRelations());case 8:s=a.sent;case 9:null===s&&(s=new this),e.version||0===e.version||(e.version=1),t[r]=Object.assign(s,e),this._handleColumns(t[r]),this._handleRelations(t[r],n,o),i();case 15:case"end":return a.stop()}}),a,this)})))})))})),r.next=9,Promise.all(a);case 9:return r.next=11,Promise.all(o);case 11:return i||(t=t.length>0?t[0]:null),r.abrupt("return",t);case 13:case"end":return r.stop()}}),r)})))}},{key:"_handleRelations",value:function(e,t,n){var r=this.getRelationDefinitions();Object.keys(r).forEach((function(i){var o=e[i];if("number"==typeof o||Array.isArray(o)&&o.length>=1&&"number"==typeof o[0])if(!0===t){var a=null;a=Array.isArray(o)?f.BaseDatabase.getModel(r[i].target).findByIds(o):f.BaseDatabase.getModel(r[i].target).findById(o),n.push(a.then((function(t){e[i]=t})))}else!1===t&&("many-to-many"===r[i].type||"one-to-many"===r[i].type?e[i]=[]:e[i]=null)}))}},{key:"_handleColumns",value:function(e){var t=this.getSchemaDefinition().columns;Object.keys(t).forEach((function(n){t[n].escapeHTML&&(e[n]=p.XSSHelper.escapeHTML(e[n])),t[n].escapeJS&&(e[n]=p.XSSHelper.escapeJS(e[n]))}))}},{key:"prepareSync",value:function(e){return e}}],(n=[{key:"toJSON",value:function(e){var t=this,n=this.constructor.getRelationDefinitions(),r=this.constructor.getColumnDefinitions(),i={};return Object.keys(r).forEach((function(e){i[e]=t[e]})),Object.keys(n).forEach((function(n){if(!0===e)i[n]=t[n];else if(Array.isArray(t[n])){var r=[];t[n].forEach((function(e){return e&&r.push(e.id)})),i[n]=r}else t[n]instanceof f.BaseModel?i[n]=t[n].id:i[n]=null})),i}}])&&i(t.prototype,n),r&&i(t,r),EasySyncBaseModel}(f.BaseModel);t.EasySyncBaseModel=EasySyncBaseModel,EasySyncBaseModel.delegateClass=null,EasySyncBaseModel.CAN_BE_SYNCED=!0},38335:function(e,t,n){"use strict";function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){for(var n=0;nr)){a.next=5;break}s=t[r],a.next=9;break;case 5:if(!d.Helper.isNotNull(e.id)){a.next=9;break}return a.next=8,this.findById(e.id,this.getRelations());case 8:s=a.sent;case 9:null===s&&(s=new this),e.version||(e.version=1),t[r]=Object.assign(s,e),this._handleColumns_(t[r]),this._handleRelations_(t[r],n,o),i();case 15:case"end":return a.stop()}}),a,this)})))})))})),r.next=9,Promise.all(a);case 9:return r.next=11,Promise.all(o);case 11:return i||(t=t.length>0?t[0]:null),r.abrupt("return",t);case 13:case"end":return r.stop()}}),r)})))}},{key:"_handleRelations_",value:function(e,t,n){var r=this.getRelationDefinitions();Object.keys(r).forEach((function(i){var o=e[i];if("number"==typeof o||Array.isArray(o)&&o.length>=1&&"number"==typeof o[0])if(!0===t){var a=null;a=Array.isArray(o)?m.BaseDatabase.getModel(r[i].target).findByIds(o):m.BaseDatabase.getModel(r[i].target).findById(o),n.push(a.then((function(t){e[i]=t})))}else!1===t&&("many-to-many"===r[i].type||"one-to-many"===r[i].type?e[i]=[]:e[i]=null)}))}},{key:"_handleColumns_",value:function(e){var t=this.getSchemaDefinition().columns;Object.keys(t).forEach((function(n){t[n].escapeHTML&&(e[n]=y.XSSHelper.escapeHTML(e[n])),t[n].escapeJS&&(e[n]=y.XSSHelper.escapeJS(e[n]))}))}}],(n=[{key:"toJSON",value:function(e){var t=this,n=this.constructor.getRelationDefinitions(),r=this.constructor.getColumnDefinitions(),i={};return Object.keys(r).forEach((function(e){"clientId"!==e&&(i[e]=t[e])})),Object.keys(n).forEach((function(n){if(!0===e)i[n]=t[n];else if(Array.isArray(t[n])){var r=[];t[n].forEach((function(e){return e&&r.push(e.id)})),i[n]=r}else t[n]instanceof m.BaseModel?i[n]=t[n].id:i[n]=null})),i}}])&&o(t.prototype,n),r&&o(t,r),p}(p.EasySyncBaseModel);t.EasySyncPartialModel=g,g.CAN_BE_SYNCED=!0},95592:function(e,t,n){"use strict";function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){for(var n=0;n=2?c.StartSiteMenuAction._app.startSite(i[0],i[1]):c.StartSiteMenuAction._app.startSite(i))}),o,a,s)}return n}(u.UserMenuAction);t.StartUserSiteMenuAction=l},4705:function(e,t,n){"use strict";function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n0)){r.next=8;break}return r.abrupt("return",i);case 8:return a=new m.User,r.next=11,c._getNewId();case 11:return a.id=r.sent,a.email=e,a.password=this._hashPassword(n),a.username=t,a.roles=c.DEFAULT_ROLES,a.activated=!0,r.next=19,a.save();case 19:return r.next=21,this.login(e,n);case 21:return r.abrupt("return",a);case 22:case"end":return r.stop()}}),r,this)})))}},{key:"_hashPassword",value:function(e){return e}}])&&a(t.prototype,n),r&&a(t,r),c}(d.UserManager);t.OfflineUserManager=g,g.LOGGED_OUT_ACCESSES=d.UserManager.OFFLINE_ACCESSES,g.DEFAULT_ROLES=[],g._lastId=null},37730:function(e,t,n){"use strict";function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,t){for(var n=0;n0&&(t[n[0]]=decodeURIComponent(n[1]));return t}},{key:"setStartParam",value:function(e,t){this._startParams[e]=t}}],(n=[{key:"addDeepLink",value:function(e,t){this._deepLinks[e]=t}},{key:"startSite",value:function(e,t){return i(this,void 0,void 0,regeneratorRuntime.mark((function n(){return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:if(!this._siteManager){n.next=2;break}return n.abrupt("return",this._siteManager.startSite(e,t));case 2:case"end":return n.stop()}}),n,this)})))}},{key:"start",value:function(t){return i(this,void 0,void 0,regeneratorRuntime.mark((function n(){var r,i,a;return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return n.next=2,this.ready();case 2:r=t,i=e._getStartParams(),o.Helper.isNotNull(i.s)&&(t=o.Helper.nonNull(this._deepLinks[i.s],t),delete i.s),(a=this._siteManager).init("site",this._deepLinks),o.Helper.removeAllChildren(document.getElementById("site")),a.startSite(t,i),a.setAppEndedListener((function(e){e.startSite(r)}));case 10:case"end":return n.stop()}}),n,this)})))}},{key:"ready",value:function(t){return i(this,void 0,void 0,regeneratorRuntime.mark((function n(){var r,i=this;return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:if(r=this._readyPromise.then((function(){return e._resolver.resolve(i),Promise.all(e._promises)})),!t){n.next=5;break}return n.abrupt("return",r.then(t));case 5:return n.abrupt("return",r);case 6:case"end":return n.stop()}}),n,this)})))}}])&&r(t.prototype,n),s&&r(t,s),e}();t.App=s,s._promises=[],s._resolver={resolve:null,reject:null},s._mainPromise=new Promise((function(e,t){s._resolver={resolve:e,reject:t}})),s._startParams={}},97698:function(e,t,n){"use strict";function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){for(var n=0;n186?{r:0,g:0,b:0}:{r:255,g:255,b:255}:{r:e=255-e,g:t=255-t,b:n=255-n}}},{key:"toHEX",value:function(e,t,n){return"object"===r(e)&&(t=e.g,n=e.b,e=e.r),e=e.toString(16),t=t.toString(16),n=n.toString(16),"#"+f.Helper.padZero(e)+f.Helper.padZero(t)+f.Helper.padZero(n)}}])&&o(t.prototype,n),u&&o(t,u),l}(l.Singleton);t.ColorIndicator=p},8408:function(e,t,n){"use strict";function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,t){for(var n=0;n "),f.Translator.translate("error"));e.setTranslatable(!1),e.show()}),c.MenuAction.SHOW_ALWAYS,-1e3,u.ERROR_ICON))._visible=u._errors.length>0,e._shouldTranslate=!1,console.log("icon: ",u.ERROR_ICON),e}return t=u,r=[{key:"addError",value:function(e){-1===this._errors.indexOf(e)&&(this._errors.push(e),this.getInstance().setVisibility(this._errors.length>0))}},{key:"removeError",value:function(e){var t=this._errors.indexOf(e);t>=0&&(this._errors.splice(t,1),this.getInstance().setVisibility(this._errors.length>0))}},{key:"getInstance",value:function(){return null===this._instance&&(this._instance=new u),this._instance}}],(n=null)&&i(t.prototype,n),r&&i(t,r),u}(c.MenuAction);t.ErrorAction=h,h.ERROR_ICON=p,h._instance=null,h._errors=[]},68515:function(e,t,n){"use strict";function r(e,t){for(var n=0;n=2?n._app.startSite(r[0],r[1]):n._app.startSite(r))}),i,o,a)}return n}(u.MenuAction);t.StartSiteMenuAction=l,l._app=null,c.App.addInitialization((function(e){l._app=e}))},75139:function(e,t,n){"use strict";function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,t){for(var n=0;n span"),r=this.findBy(".background-img"),i=function(){var e=t.findBy("nav.top-bar");n.getBoundingClientRect().bottom>=r.getBoundingClientRect().bottom?e.classList.add("solid"):e.classList.remove("solid")};r.addEventListener("load",i),e.addEventListener("scroll",i),requestAnimationFrame(i)}}},{key:"setBackgroundImage",value:function(e){var t=this;if(this._backgroundImage=e,this._view){var n=this.findBy("nav.top-bar");if(d.Helper.isNotNull(this._backgroundImage)){var r=this.findBy(".background-img"),i=w.ColorIndicator.getInstance();r.addEventListener("load",(function(){if(""!==t._backgroundImage){var e=i.getAverageImgColor(r,void 0,150),o=i.invertColorBW(e);0===o.r&&0===o.g&&0===o.b?(n.classList.remove("color-white"),n.classList.add("color-black")):(n.classList.remove("color-black"),n.classList.add("color-white"))}else n.classList.remove("color-black"),n.classList.remove("color-white")})),requestAnimationFrame((function(){var e=n.querySelector(".grid-container");n.style="min-height:"+e.getBoundingClientRect().height+"px",e.addEventListener("resize",(function(){n.style="min-height:"+e.getBoundingClientRect().height+"px"}))})),r.src=this._backgroundImage,n.classList.add("with-image")}else n.classList.remove("with-image")}}},{key:"onViewLoaded",value:function(){var e=this,t=Object.create(null,{onViewLoaded:{get:function(){return o(c(_.prototype),"onViewLoaded",e)}}});return l(this,void 0,void 0,regeneratorRuntime.mark((function e(){var n,r,i,o,a=this;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n=t.onViewLoaded.call(this),this.setTitleElement(document.createTextNode(_.title)),(r=[]).push(new g.DropdownRenderer(this.findBy("#navbar-menu-visible"))),r.push(new b.AccordionRenderer(this.findBy("#navbar-menu-hidden"))),this._menu=new m.Menu(r,this._menuActions),this._closeListenerContainer=this.findBy("#navbar-close-listener-container"),this._menu.setOpenSubmenuListener((function(){a._showCloseListener()})),i=this._menu.getOnClickListener(),this._menu.setOnClickListener((function(e){i(e)instanceof v.OpenSubmenuAction||a.closeMenu()})),this._responsiveMenu=this.findBy("#responsive-menu"),this.findBy("#responsive-menu-toggle").onclick=function(){a._responsiveMenu.classList.contains("visible")?a.closeMenu():a.openMenu()},o=this,this.findBy("#navbar-close-listener").addEventListener("click",(function(e){e.target===this&&o.closeMenu()})),window.addEventListener("resize",(function(){a._state===y.Context.STATE_RUNNING&&a.updateToggleButton()})),this.drawMenu(),this.findBy(".back-button").addEventListener("click",(function(){a.goBack()})),this.setCanGoBack(this._canGoBack),this.setBackgroundImage(this._backgroundImage),this.setScrollWidget(this._scrollWidget),this.setLogo(this._logo),e.abrupt("return",n);case 22:case"end":return e.stop()}}),e,this)})))}},{key:"goBack",value:function(){this._canGoBack&&this.getSite().goBack()}},{key:"onStart",value:function(e){var t=this,n=Object.create(null,{onStart:{get:function(){return o(c(_.prototype),"onStart",t)}}});return l(this,void 0,void 0,regeneratorRuntime.mark((function t(){return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:n.onStart.call(this,e),this.updateToggleButton();case 2:case"end":return t.stop()}}),t,this)})))}},{key:"_showCloseListener",value:function(){this._closeListenerContainer&&(this._closeListenerContainer.style.display="block")}},{key:"closeMenu",value:function(){d.Helper.isNotNull(this._responsiveMenu)&&this._responsiveMenu.classList.remove("visible"),this._closeListenerContainer&&(this._closeListenerContainer.style.display="none"),this._menu&&this._menu.close()}},{key:"openMenu",value:function(){d.Helper.isNotNull(this._responsiveMenu)&&this._responsiveMenu.classList.add("visible"),this._showCloseListener()}},{key:"drawMenu",value:function(){d.Helper.isNotNull(this._menu)&&this._menu.draw()}},{key:"updateToggleButton",value:function(){var e=_._getCurrentSize(),t=this.findBy("#navbar-menu-visible");("medium"===e||"smedium"===e||"small"===e)&&t.querySelectorAll("."+h.MenuAction.SHOW_FOR_LARGE+":not(.hidden)").length>0||("smedium"===e||"small"===e)&&t.querySelectorAll("."+h.MenuAction.SHOW_FOR_MEDIUM+":not(.hidden)").length>0||"small"===e&&t.querySelectorAll("."+h.MenuAction.SHOW_FOR_SMEDIUM+":not(.hidden)").length>0||t.querySelectorAll("."+h.MenuAction.SHOW_NEVER+":not(.hidden)").length>0?document.getElementById("responsive-menu-toggle").style.display="block":(document.getElementById("responsive-menu-toggle").style.display="none",this.closeMenu())}},{key:"addAction",value:function(e){this._menuActions.push(e),d.Helper.isNotNull(this._menu)&&this._menu.addAction(e)}},{key:"removeAllActions",value:function(e){this._menuActions=[],d.Helper.isNotNull(this._menu)&&this._menu.removeAllActions(e)}},{key:"setTitleElement",value:function(e){d.Helper.removeAllChildren(this.findBy("#title-element-container")).appendChild(e)}}])&&i(t.prototype,n),u&&i(t,u),_}(f.AbstractFragment);t.NavbarFragment=_,_.queries=[],_.title="MeinBerufBau",_.defaultActions=[]},55181:function(e,t,n){"use strict";function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e){return function(e){if(Array.isArray(e))return o(e)}(e)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return o(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return o(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function o(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=1){var e=this.getCurrentSite();e&&!1!==e.onBackPressed()&&this.endSite(e)}}},{key:"getCurrentSite",value:function(){return this._siteStack.length>=1?this._siteStack[this._siteStack.length-1]:null}},{key:"startSite",value:function(e,t){return i(this,void 0,void 0,regeneratorRuntime.mark((function n(){var r,c,l=this;return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:if(e.prototype instanceof a.AbstractSite){n.next=2;break}throw{error:"wrong class given! Expected AbstractSite, given "+e.name};case 2:return p.EventManager.trigger("site-manager-start-site",{site:e,paramPromise:t}),r=s.ViewInflater.createLoadingSymbol("overlay"),this._siteDiv.appendChild(r),c=new e(this),this._siteStack.unshift(c),Promise.resolve(t).then((function(e){return i(l,void 0,void 0,regeneratorRuntime.mark((function t(){return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return c._onConstructPromise=c.onConstruct(o.Helper.nonNull(e,{})),t.next=3,Promise.all([c._onConstructPromise,c.getViewPromise()]);case 3:if(c._state===u.Context.STATE_DESTROYED||c._state===u.Context.STATE_DESTROYING){t.next=8;break}return t.next=6,c.onViewLoaded();case 6:return c._viewLoadedPromise.resolve(),t.abrupt("return",this._show(c));case 8:r.remove();case 9:case"end":return t.stop()}}),t,this)})))})).catch((function(t){console.error("site start error for site ",e.name,t),c.getFinishResolver().reject(t),r.remove();for(var n=l._siteStack.length-1;n>=0;n--)if(l._siteStack[n]!==c)return l._show(l._siteStack[n]);c._viewLoadedPromise.reject()})),n.abrupt("return",c.getFinishPromise());case 9:case"end":return n.stop()}}),n,this)})))}},{key:"updateUrl",value:function(e,t){var n=this._generateUrl(e,t);f.HistoryManager.getInstance().replaceState({site:e,parameters:t},e.constructor.name,n)}},{key:"_generateUrl",value:function(e,t){var n=this.getDeepLinkFor(e),r=[location.protocol,"//",location.host,location.pathname].join("");return o.Helper.isNotNull(n)&&(t.s=n,r=[r,l.DataManager.buildQuery(t)].join("")),r}},{key:"getDeepLinkFor",value:function(e){return this._inversedDeepLinks[e.constructor]}},{key:"_pauseSite",value:function(e){e=o.Helper.nonNull(e,this.getCurrentSite()),o.Helper.isNotNull(e)&&e._state===u.Context.STATE_RUNNING&&(e._pauseParameters=e.onPause(),o.Helper.removeAllChildren(this._siteDiv).appendChild(s.ViewInflater.createLoadingSymbol()))}},{key:"_resumeSite",value:function(e){return i(this,void 0,void 0,regeneratorRuntime.mark((function t(){return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(e=o.Helper.nonNull(e,this.getCurrentSite()),!o.Helper.isNotNull(e)||e._state!==u.Context.STATE_PAUSED&&e._state!==u.Context.STATE_CONSTRUCTED){t.next=10;break}return t.next=4,e.getViewPromise();case 4:return o.Helper.removeAllChildren(this._siteDiv).appendChild(e._view),t.next=7,c.Translator.getInstance().updateTranslations();case 7:return o.Helper.isNull(e._historyId)?e._historyId=f.HistoryManager.getInstance().pushState({site:e,parameters:e.getParameters()},e.constructor.name,this._generateUrl(e,e.getParameters())):f.HistoryManager.getInstance().stateToCurrentPosition(e._historyId),t.next=10,e.onStart(e._pauseParameters);case 10:case"end":return t.stop()}}),t,this)})))}},{key:"_show",value:function(e){return i(this,void 0,void 0,regeneratorRuntime.mark((function t(){var n,r=this;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(e._state!==u.Context.STATE_DESTROYING&&e._state!==u.Context.STATE_DESTROYED){t.next=2;break}return t.abrupt("return");case 2:if(e._state!==u.Context.STATE_RUNNING||this.getCurrentSite()!==e){t.next=4;break}return t.abrupt("return");case 4:return this._pauseSite(),o.Helper.removeAllChildren(this._siteDiv).appendChild(s.ViewInflater.createLoadingSymbol()),-1!==(n=this._siteStack.indexOf(e))&&this._siteStack.splice(n,1),this._siteStack.push(e),t.abrupt("return",e.getViewPromise().then((function(){return i(r,void 0,void 0,regeneratorRuntime.mark((function t(){return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(this.getCurrentSite()!==e){t.next=3;break}return t.next=3,this._resumeSite(e);case 3:case"end":return t.stop()}}),t,this)})))})));case 10:case"end":return t.stop()}}),t,this)})))}},{key:"endSite",value:function(e){return i(this,void 0,void 0,regeneratorRuntime.mark((function t(){var n,r=this;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return n=this._siteStack.indexOf(e),this._siteStack.splice(n,1),n===this._siteStack.length&&(this._pauseSite(e),this._siteDiv.appendChild(s.ViewInflater.createLoadingSymbol("overlay")),e.getFinishPromise().then((function(){var e=r.getCurrentSite();o.Helper.isNotNull(e)&&r.toForeground(e)}))),this._siteStack.length<=0&&(console.log("stack is empty, starting normal site!"),f.HistoryManager.getInstance().cutStack(0),f.HistoryManager.getInstance().go(-1*history.length,!0),o.Helper.removeAllChildren(this._siteDiv).appendChild(document.createTextNode("App ist beendet")),"function"==typeof this._appEndedListener&&this._appEndedListener(this)),e._context=u.Context.STATE_DESTROYING,t.next=7,e.onDestroy();case 7:e._context=u.Context.STATE_DESTROYED,e.getFinishResolver().resolve(e._result);case 9:case"end":return t.stop()}}),t,this)})))}},{key:"toForeground",value:function(e){return this._show(e)}},{key:"updateTitle",value:function(e,t,n){n=o.Helper.nonNull(n,o.Helper.isNull(e)?"document-title-empty":"document-title"),o.Helper.isNotNull(this._titleTranslationCallbackId)&&c.Translator.removeTranslationCallback(this._titleTranslationCallbackId),this._titleTranslationCallbackId=c.Translator.addTranslationCallback((function(){!1!==t&&(e=c.Translator.translate(e,t)),document.title=c.Translator.translate(n,[e])}))}}])&&r(t.prototype,n),h&&r(t,h),e}();t.SiteManager=h,h._instance=null},97533:function(e,t,n){"use strict";function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,t){for(var n=0;n=f.MIN_X)){n.next=13;break}if(!(i>0)){n.next=11;break}return n.next=9,this._fragments[this._activeIndex].onSwipeLeft();case 9:n.next=13;break;case 11:return n.next=13,this._fragments[this._activeIndex].onSwipeRight();case 13:case"end":return n.stop()}}),n,this)})))}},{key:"onStart",value:function(e){var t=this,n=Object.create(null,{onStart:{get:function(){return o(c(f.prototype),"onStart",t)}}});return l(this,void 0,void 0,regeneratorRuntime.mark((function t(){return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return this._activeIndex>=0&&this._activeIndex=0&&ee.length)&&(t=e.length);for(var n=0,r=new Array(t);nt._currentStackIndex&&t._currentStackIndex>=0&&(r=t._states[t._stack[t._currentStackIndex]]),t._onPopStateListener(r,n,e)}}},this._updateNativeHistoryStack()}var t,n,o;return t=e,o=[{key:"getInstance",value:function(){return i.Helper.isNull(e._instance)&&(e._instance=new e),e._instance}}],(n=[{key:"_updateNativeHistoryStack",value:function(t){t=i.Helper.nonNull(t,window.location.href),this._currentStackIndex>=0&&history.pushState({type:e.BACK},"back",t),history.pushState({type:e.CURRENT},"current",t),this._currentStackIndexthis._currentStackIndex&&this._currentStackIndex>=0&&(this._states[r]={state:e,title:t,url:n},this._updateNativeHistoryStack(n))}},{key:"stateToCurrentPosition",value:function(e){if(i.Helper.isNotNull(this._states[e])){var t=this._stack.indexOf(e);-1!==t&&(this._stack.splice(t,1),this._stack.splice(this._currentStackIndex+(t<=this._currentStackIndex?-1:0),0,e))}}},{key:"go",value:function(e,t){this._ignoreOnPopState=!0===i.Helper.nonNull(t,!1),history.go(e)}},{key:"cutStack",value:function(e){e=i.Helper.nonNull(e,this._currentStackIndex+1),this._stack.splice(e),this._currentStackIndex=Math.min(this._currentStackIndex,this._stack.length-1),this._updateNativeHistoryStack()}},{key:"back",value:function(){this.go(-1)}},{key:"forward",value:function(){this.go(1)}},{key:"setOnPopStateListener",value:function(e){this._onPopStateListener=e}}])&&r(t.prototype,n),o&&r(t,o),e}();t.HistoryManager=o,o.BACK=-1,o.FORWARD=1,o.CURRENT=0},48981:function(e,t,n){"use strict";function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){return(o=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function a(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,r=u(e);if(t){var i=u(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return s(this,n)}}function s(e,t){return!t||"object"!==r(t)&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function u(e){return(u=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.EventManager=void 0;var c=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&o(e,t)}(n,e);var t=a(n);function n(){return i(this,n),t.apply(this,arguments)}return n}(n(12030).EventManager);t.EventManager=c},34177:function(e,t,n){"use strict";function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,t){for(var n=0;n2?r-2:0),o=2;o1?n-1:0),i=1;i1&&0==(3&c)&&(c%100!=0||c%400==0)?1:0),3),"%k":""+l,"%l":(l+11)%12+1,"%m":m(u+1,2),"%M":m(n.getMinutes(),2),"%p":l<12?"AM":"PM","%P":l<12?"am":"pm","%s":Math.round(n.getTime()/1e3),"%S":m(n.getSeconds(),2),"%u":o||7,"%w":""+o,"%x":n.toLocaleDateString(),"%X":n.toLocaleTimeString(),"%y":(""+c).slice(2),"%Y":c,"%z":n.toTimeString().replace(/.+GMT([+-]\d+).+/,"$1"),"%Z":n.toTimeString().replace(/.+\((.+?)\)$/,"$1")}[e]||e}))}},{key:"arrayToObject",value:function(e,t){var n={};return e.forEach((function(e){n[t(e)]=e})),n}},{key:"cloneJson",value:function(t){var n;if(e.isNull(t)||"object"!==r(t))return t;if(t instanceof Array){var i=[];for(n=0;n=n?t:new Array(n-t.length+1).join(r)+t}},{key:"deepEqual",value:function(t,n){if(t===n)return!0;if("object"===r(t)&&"object"===r(n)){var i=Object.keys(n);return Object.keys(t).every((function(r){var o=i.indexOf(r);return!(o<0)&&(i.splice(o,1),e.deepEqual(t[r],n[r]))}))&&0===i.length}return!1}},{key:"htmlspecialcharsDecode",value:function(t){var n={"&":"&","&":"&","<":"<",">":">",""":'"',"'":"'","’":"’","‘":"‘","–":"–","—":"—","…":"…","”":"”"};return e.isNotNull(t)&&"function"==typeof t.replace?t.replace(/\&[\w\d\#]{2,5}\;/g,(function(e){return n[e]})):t}},{key:"invertKeyValues",value:function(e){var t={};for(var n in e)e.hasOwnProperty(n)&&(t[e[n]]=n);return t}},{key:"asyncForEach",value:function(t,n,r){return o(this,void 0,void 0,regeneratorRuntime.mark((function i(){var o,a,s,u;return regeneratorRuntime.wrap((function(i){for(;;)switch(i.prev=i.next){case 0:r=e.nonNull(r,!1),t instanceof Map&&(t=Array.from(t.values())),o=[],a=0;case 4:if(!(a0)){i.next=8;break}return i.next=8,new Promise((function(e){setTimeout(e,c),t.style.fontSize=f+"px"}));case 8:return p=this,h=function(){return new Promise((function(i){setTimeout((function(){i(p.scaleTo(e,t,n,r,a,s,u,c,!1))}),"number"==typeof l?l:255)}))},!1!==l&&window.addEventListener("resize",h),i.abrupt("return",h);case 12:case"end":return i.stop()}}),i,this)})))}},{key:"scaleToFull",value:function(e,t,n,r,o,a,s,u){return i(this,void 0,void 0,regeneratorRuntime.mark((function i(){return regeneratorRuntime.wrap((function(i){for(;;)switch(i.prev=i.next){case 0:return i.abrupt("return",this.scaleTo(1,e,t,n,r,o,a,s,u));case 1:case"end":return i.stop()}}),i,this)})))}},{key:"_getNewFontSize",value:function(e,t,n,r,a,s,u,c){return i(this,void 0,void 0,regeneratorRuntime.mark((function i(){var l,f,p,h,d,y,m,v,g,b,w,E,_;return regeneratorRuntime.wrap((function(i){for(;;)switch(i.prev=i.next){case 0:for(s=o.Helper.nonNull(s,10),r=o.Helper.nonNull(r,!1),a=o.Helper.nonNull(a,!1),u=o.Helper.nonNull(u,t.innerHTML.length),c=o.Helper.nonNull(c,!0),(l=n.classList.contains("no-transition"))||n.classList.add("no-transition"),f=5,p=0,h=[],d=0;d(1-e)*b||a)&&(g>(1-e)*w||r)){i.next=17;break}case 30:if(m-=s,t.style.fontSize=c?m+"px":y,l){i.next=36;break}return i.next=35,new Promise((function(e){setTimeout(e,50)}));case 35:n.classList.remove("no-transition");case 36:return i.abrupt("return",m);case 37:case"end":return i.stop()}}),i)})))}}])&&r(t.prototype,n),a&&r(t,a),e}();t.ScaleHelper=a},2234:function(e,t,n){"use strict";function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,t){for(var n=0;n=0}},{key:"setItem",value:function(e,t){return o(this,void 0,void 0,regeneratorRuntime.mark((function n(){var r=this;return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:if(!this.persistent){n.next=8;break}if(!this._isElectron()){n.next=5;break}return n.abrupt("return",new Promise((function(n,i){return r.electronStorage.set(r.prefix+e,t,(function(e){e?i(e):n()}))})));case 5:return n.abrupt("return",new Promise((function(n,i){return NativeStorage.setItem(r.prefix+e,t,n,i)})));case 6:n.next=9;break;case 8:this._cache[this.prefix+e]=t;case 9:case"end":return n.stop()}}),n,this)})))}},{key:"getItem",value:function(e,t){return o(this,void 0,void 0,regeneratorRuntime.mark((function n(){var r=this;return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return n.abrupt("return",new Promise((function(n,i){r._isElectron()?r.electronStorage.get(r.prefix+e,(function(i,o){n(i?a.Helper.nonNull(r._cache[r.prefix+e],t):s.JsonHelper.deepEqual(o,{})?t:o)})):NativeStorage.getItem(r.prefix+e,(function(e){return n(a.Helper.nonNull(e,t))}),(function(i){n(a.Helper.nonNull(r._cache[r.prefix+e],t))}))})));case 1:case"end":return n.stop()}}),n)})))}},{key:"keys",value:function(){return o(this,void 0,void 0,regeneratorRuntime.mark((function e(){var t,n=this;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(t=[],!this.persistent){e.next=13;break}if(!this._isElectron()){e.next=8;break}return e.next=5,new Promise((function(e,t){return n.electronStorage.keys((function(n,r){n?t(n):e(r)}))}));case 5:t=e.sent,e.next=11;break;case 8:return e.next=10,new Promise((function(e,t){return NativeStorage.keys(e,t)}));case 10:t=e.sent;case 11:e.next=14;break;case 13:t=Object.keys(this._cache);case 14:return e.abrupt("return",t.filter((function(e){return e.startsWith(n.prefix)})));case 15:case"end":return e.stop()}}),e,this)})))}},{key:"remove",value:function(e){return o(this,void 0,void 0,regeneratorRuntime.mark((function t(){var n=this;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(delete this._cache[this.prefix+e],!this._isElectron()){t.next=5;break}return t.abrupt("return",new Promise((function(t,r){return n.electronStorage.remove(n.prefix+e,(function(e){e?r(e):t()}))})));case 5:return t.abrupt("return",new Promise((function(t,r){return NativeStorage.remove(n.prefix+e,t,r)})));case 6:case"end":return t.stop()}}),t,this)})))}},{key:"clear",value:function(){return o(this,void 0,void 0,regeneratorRuntime.mark((function e(){var t,n=this;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.keys();case 2:return t=e.sent,e.next=5,a.Helper.asyncForEach(t,(function(e){return o(n,void 0,void 0,regeneratorRuntime.mark((function t(){return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,this.remove(e);case 2:case"end":return t.stop()}}),t,this)})))}),!0);case 5:case"end":return e.stop()}}),e,this)})))}},{key:"makePersistent",value:function(){return o(this,void 0,void 0,regeneratorRuntime.mark((function e(){var t=this;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(this.persistent){e.next=4;break}return this.persistent=!0,e.next=4,a.Helper.asyncForEach(Object.keys(this._cache),(function(e){return o(t,void 0,void 0,regeneratorRuntime.mark((function t(){return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,this.setItem(e,this._cache[e]);case 2:case"end":return t.stop()}}),t,this)})))}),!0);case 4:case"end":return e.stop()}}),e,this)})))}},{key:"makeUnpersistent",value:function(){return o(this,void 0,void 0,regeneratorRuntime.mark((function e(){var t,n,r=this;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(!this.persistent){e.next=10;break}return e.next=3,this.keys();case 3:return t=e.sent,n={},e.next=7,a.Helper.asyncForEach(t,(function(e){return o(r,void 0,void 0,regeneratorRuntime.mark((function t(){return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,this.getItem(e);case 2:n[e]=t.sent;case 3:case"end":return t.stop()}}),t,this)})))}));case 7:this.clear(),this.persistent=!1,this._cache=n;case 10:case"end":return e.stop()}}),e,this)})))}}],(n=null)&&i(t.prototype,n),u&&i(t,u),e}();t.NativeStoragePromise=u,u._cache={},u.prefix="",u.persistent=!0,u.electronStorage=null},97961:function(e,t,n){"use strict";function r(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{translations:{},fallbackLanguage:"en",markUntranslatedTranslations:!0,markTranslations:!1,logMissingTranslations:!0};r(this,e),this._translations={},this.addDynamicTranslations(e._translations),this.addDynamicTranslations(n.translations),this._fallbackLanguage=n.fallbackLanguage,this._markUntranslatedTranslations=n.markUntranslatedTranslations,this._markTranslations=n.markTranslations,!0===n.logMissingTranslations?this._logMissingTranslationsFunction=function(e,n){n===t._fallbackLanguage?console.error("missing base translation for key "+e):console.warn("missing translation for language "+n+" and key "+e)}:"function"==typeof n.logMissingTranslations?this._logMissingTranslationsFunction=n.logMissingTranslations:this._logMissingTranslationsFunction=null,this._translationCallbacks=new Map,this._lastTranslationCallbackId=0}var t,n,a;return t=e,a=[{key:"translate",value:function(t,n,r){var i=e.getInstance();return i?i.translate(t,n,r):""}},{key:"addDynamicTranslations",value:function(t){var n=e.getInstance();if(n)return n.addDynamicTranslations(t);Object.keys(t).forEach((function(n){o.Helper.isNull(e._translations[n])&&(e._translations[n]={}),Object.assign(e._translations[n],t[n])}))}},{key:"init",value:function(t){e.instance=new e(t)}},{key:"getInstance",value:function(){return e.instance}},{key:"_isValid",value:function(e){return"string"==typeof e}},{key:"_format",value:function(e,t){return e.replace(/{(\d+)}/g,(function(e,n){return void 0!==t[n]?t[n]:e}))}}],(n=[{key:"translate",value:function(t,n,r){if(o.Helper.isNull(t))return"";r=o.Helper.nonNull(r,n,this._fallbackLanguage);var i=null;return t=t.toLowerCase(),o.Helper.isNotNull(this._translations[r])&&o.Helper.isNotNull(this._translations[r][t])&&(i=this._translations[r][t]),e._isValid(i)||(null!==this._logMissingTranslationsFunction&&this._logMissingTranslationsFunction(t,r),this._translations[this._fallbackLanguage]&&(i=this._translations[this._fallbackLanguage][t]),e._isValid(i)||(null!==this._logMissingTranslationsFunction&&this._logMissingTranslationsFunction(t,r),i=t),this._markUntranslatedTranslations&&(i=">>"+i+"<<")),this._markTranslations&&(i="$"+i+"$"),void 0!==n&&(i=e._format(i,n)),i}},{key:"addDynamicTranslations",value:function(e){for(var t in e)for(var n in this._translations[t]||(this._translations[t]={}),e[t])this._translations[t][n.toLowerCase()]=e[t][n]}},{key:"getLanguages",value:function(){return Object.keys(this._translations)}},{key:"getFallbackLanguage",value:function(){return this._fallbackLanguage}}])&&i(t.prototype,n),a&&i(t,a),e}();t.Translator=a,a._translations={},a.instance=null},79742:function(e,t){"use strict";t.byteLength=function(e){var t=u(e),n=t[0],r=t[1];return 3*(n+r)/4-r},t.toByteArray=function(e){var t,n,o=u(e),a=o[0],s=o[1],c=new i(function(e,t,n){return 3*(t+n)/4-n}(0,a,s)),l=0,f=s>0?a-4:a;for(n=0;n>16&255,c[l++]=t>>8&255,c[l++]=255&t;2===s&&(t=r[e.charCodeAt(n)]<<2|r[e.charCodeAt(n+1)]>>4,c[l++]=255&t);1===s&&(t=r[e.charCodeAt(n)]<<10|r[e.charCodeAt(n+1)]<<4|r[e.charCodeAt(n+2)]>>2,c[l++]=t>>8&255,c[l++]=255&t);return c},t.fromByteArray=function(e){for(var t,r=e.length,i=r%3,o=[],a=16383,s=0,u=r-i;su?u:s+a));1===i?(t=e[r-1],o.push(n[t>>2]+n[t<<4&63]+"==")):2===i&&(t=(e[r-2]<<8)+e[r-1],o.push(n[t>>10]+n[t>>4&63]+n[t<<2&63]+"="));return o.join("")};for(var n=[],r=[],i="undefined"!=typeof Uint8Array?Uint8Array:Array,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",a=0,s=o.length;a0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");return-1===n&&(n=t),[n,n===t?0:4-n%4]}function c(e,t,r){for(var i,o,a=[],s=t;s>18&63]+n[o>>12&63]+n[o>>6&63]+n[63&o]);return a.join("")}r["-".charCodeAt(0)]=62,r["_".charCodeAt(0)]=63},48764:function(e,t,n){"use strict";var r=n(79742),i=n(80645),o="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):null;t.Buffer=u,t.SlowBuffer=function(e){+e!=e&&(e=0);return u.alloc(+e)},t.INSPECT_MAX_BYTES=50;var a=2147483647;function s(e){if(e>a)throw new RangeError('The value "'+e+'" is invalid for option "size"');var t=new Uint8Array(e);return Object.setPrototypeOf(t,u.prototype),t}function u(e,t,n){if("number"==typeof e){if("string"==typeof t)throw new TypeError('The "string" argument must be of type string. Received type number');return f(e)}return c(e,t,n)}function c(e,t,n){if("string"==typeof e)return function(e,t){"string"==typeof t&&""!==t||(t="utf8");if(!u.isEncoding(t))throw new TypeError("Unknown encoding: "+t);var n=0|y(e,t),r=s(n),i=r.write(e,t);i!==n&&(r=r.slice(0,i));return r}(e,t);if(ArrayBuffer.isView(e))return p(e);if(null==e)throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e);if(J(e,ArrayBuffer)||e&&J(e.buffer,ArrayBuffer))return h(e,t,n);if("undefined"!=typeof SharedArrayBuffer&&(J(e,SharedArrayBuffer)||e&&J(e.buffer,SharedArrayBuffer)))return h(e,t,n);if("number"==typeof e)throw new TypeError('The "value" argument must not be of type number. Received type number');var r=e.valueOf&&e.valueOf();if(null!=r&&r!==e)return u.from(r,t,n);var i=function(e){if(u.isBuffer(e)){var t=0|d(e.length),n=s(t);return 0===n.length||e.copy(n,0,0,t),n}if(void 0!==e.length)return"number"!=typeof e.length||H(e.length)?s(0):p(e);if("Buffer"===e.type&&Array.isArray(e.data))return p(e.data)}(e);if(i)return i;if("undefined"!=typeof Symbol&&null!=Symbol.toPrimitive&&"function"==typeof e[Symbol.toPrimitive])return u.from(e[Symbol.toPrimitive]("string"),t,n);throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e)}function l(e){if("number"!=typeof e)throw new TypeError('"size" argument must be of type number');if(e<0)throw new RangeError('The value "'+e+'" is invalid for option "size"')}function f(e){return l(e),s(e<0?0:0|d(e))}function p(e){for(var t=e.length<0?0:0|d(e.length),n=s(t),r=0;r=a)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+a.toString(16)+" bytes");return 0|e}function y(e,t){if(u.isBuffer(e))return e.length;if(ArrayBuffer.isView(e)||J(e,ArrayBuffer))return e.byteLength;if("string"!=typeof e)throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof e);var n=e.length,r=arguments.length>2&&!0===arguments[2];if(!r&&0===n)return 0;for(var i=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":return B(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return F(e).length;default:if(i)return r?-1:B(e).length;t=(""+t).toLowerCase(),i=!0}}function m(e,t,n){var r=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return M(this,t,n);case"utf8":case"utf-8":return x(this,t,n);case"ascii":return P(this,t,n);case"latin1":case"binary":return N(this,t,n);case"base64":return O(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return A(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function v(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function g(e,t,n,r,i){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),H(n=+n)&&(n=i?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(i)return-1;n=e.length-1}else if(n<0){if(!i)return-1;n=0}if("string"==typeof t&&(t=u.from(t,r)),u.isBuffer(t))return 0===t.length?-1:b(e,t,n,r,i);if("number"==typeof t)return t&=255,"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):b(e,[t],n,r,i);throw new TypeError("val must be string, number or Buffer")}function b(e,t,n,r,i){var o,a=1,s=e.length,u=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;a=2,s/=2,u/=2,n/=2}function c(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(i){var l=-1;for(o=n;os&&(n=s-u),o=n;o>=0;o--){for(var f=!0,p=0;pi&&(r=i):r=i;var o=t.length;r>o/2&&(r=o/2);for(var a=0;a>8,i=n%256,o.push(i),o.push(r);return o}(t,e.length-n),e,n,r)}function O(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function x(e,t,n){n=Math.min(e.length,n);for(var r=[],i=t;i239?4:c>223?3:c>191?2:1;if(i+f<=n)switch(f){case 1:c<128&&(l=c);break;case 2:128==(192&(o=e[i+1]))&&(u=(31&c)<<6|63&o)>127&&(l=u);break;case 3:o=e[i+1],a=e[i+2],128==(192&o)&&128==(192&a)&&(u=(15&c)<<12|(63&o)<<6|63&a)>2047&&(u<55296||u>57343)&&(l=u);break;case 4:o=e[i+1],a=e[i+2],s=e[i+3],128==(192&o)&&128==(192&a)&&128==(192&s)&&(u=(15&c)<<18|(63&o)<<12|(63&a)<<6|63&s)>65535&&u<1114112&&(l=u)}null===l?(l=65533,f=1):l>65535&&(l-=65536,r.push(l>>>10&1023|55296),l=56320|1023&l),r.push(l),i+=f}return function(e){var t=e.length;if(t<=C)return String.fromCharCode.apply(String,e);var n="",r=0;for(;rn&&(e+=" ... "),""},o&&(u.prototype[o]=u.prototype.inspect),u.prototype.compare=function(e,t,n,r,i){if(J(e,Uint8Array)&&(e=u.from(e,e.offset,e.byteLength)),!u.isBuffer(e))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof e);if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===i&&(i=this.length),t<0||n>e.length||r<0||i>this.length)throw new RangeError("out of range index");if(r>=i&&t>=n)return 0;if(r>=i)return-1;if(t>=n)return 1;if(this===e)return 0;for(var o=(i>>>=0)-(r>>>=0),a=(n>>>=0)-(t>>>=0),s=Math.min(o,a),c=this.slice(r,i),l=e.slice(t,n),f=0;f>>=0,isFinite(n)?(n>>>=0,void 0===r&&(r="utf8")):(r=n,n=void 0)}var i=this.length-t;if((void 0===n||n>i)&&(n=i),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var o=!1;;)switch(r){case"hex":return w(this,e,t,n);case"utf8":case"utf-8":return E(this,e,t,n);case"ascii":return _(this,e,t,n);case"latin1":case"binary":return S(this,e,t,n);case"base64":return R(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return T(this,e,t,n);default:if(o)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),o=!0}},u.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var C=4096;function P(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;ir)&&(n=r);for(var i="",o=t;on)throw new RangeError("Trying to access beyond buffer length")}function j(e,t,n,r,i,o){if(!u.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>i||te.length)throw new RangeError("Index out of range")}function D(e,t,n,r,i,o){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function I(e,t,n,r,o){return t=+t,n>>>=0,o||D(e,0,n,4),i.write(e,t,n,r,23,4),n+4}function L(e,t,n,r,o){return t=+t,n>>>=0,o||D(e,0,n,8),i.write(e,t,n,r,52,8),n+8}u.prototype.slice=function(e,t){var n=this.length;(e=~~e)<0?(e+=n)<0&&(e=0):e>n&&(e=n),(t=void 0===t?n:~~t)<0?(t+=n)<0&&(t=0):t>n&&(t=n),t>>=0,t>>>=0,n||k(e,t,this.length);for(var r=this[e],i=1,o=0;++o>>=0,t>>>=0,n||k(e,t,this.length);for(var r=this[e+--t],i=1;t>0&&(i*=256);)r+=this[e+--t]*i;return r},u.prototype.readUInt8=function(e,t){return e>>>=0,t||k(e,1,this.length),this[e]},u.prototype.readUInt16LE=function(e,t){return e>>>=0,t||k(e,2,this.length),this[e]|this[e+1]<<8},u.prototype.readUInt16BE=function(e,t){return e>>>=0,t||k(e,2,this.length),this[e]<<8|this[e+1]},u.prototype.readUInt32LE=function(e,t){return e>>>=0,t||k(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},u.prototype.readUInt32BE=function(e,t){return e>>>=0,t||k(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},u.prototype.readIntLE=function(e,t,n){e>>>=0,t>>>=0,n||k(e,t,this.length);for(var r=this[e],i=1,o=0;++o=(i*=128)&&(r-=Math.pow(2,8*t)),r},u.prototype.readIntBE=function(e,t,n){e>>>=0,t>>>=0,n||k(e,t,this.length);for(var r=t,i=1,o=this[e+--r];r>0&&(i*=256);)o+=this[e+--r]*i;return o>=(i*=128)&&(o-=Math.pow(2,8*t)),o},u.prototype.readInt8=function(e,t){return e>>>=0,t||k(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},u.prototype.readInt16LE=function(e,t){e>>>=0,t||k(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt16BE=function(e,t){e>>>=0,t||k(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt32LE=function(e,t){return e>>>=0,t||k(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},u.prototype.readInt32BE=function(e,t){return e>>>=0,t||k(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},u.prototype.readFloatLE=function(e,t){return e>>>=0,t||k(e,4,this.length),i.read(this,e,!0,23,4)},u.prototype.readFloatBE=function(e,t){return e>>>=0,t||k(e,4,this.length),i.read(this,e,!1,23,4)},u.prototype.readDoubleLE=function(e,t){return e>>>=0,t||k(e,8,this.length),i.read(this,e,!0,52,8)},u.prototype.readDoubleBE=function(e,t){return e>>>=0,t||k(e,8,this.length),i.read(this,e,!1,52,8)},u.prototype.writeUIntLE=function(e,t,n,r){(e=+e,t>>>=0,n>>>=0,r)||j(this,e,t,n,Math.pow(2,8*n)-1,0);var i=1,o=0;for(this[t]=255&e;++o>>=0,n>>>=0,r)||j(this,e,t,n,Math.pow(2,8*n)-1,0);var i=n-1,o=1;for(this[t+i]=255&e;--i>=0&&(o*=256);)this[t+i]=e/o&255;return t+n},u.prototype.writeUInt8=function(e,t,n){return e=+e,t>>>=0,n||j(this,e,t,1,255,0),this[t]=255&e,t+1},u.prototype.writeUInt16LE=function(e,t,n){return e=+e,t>>>=0,n||j(this,e,t,2,65535,0),this[t]=255&e,this[t+1]=e>>>8,t+2},u.prototype.writeUInt16BE=function(e,t,n){return e=+e,t>>>=0,n||j(this,e,t,2,65535,0),this[t]=e>>>8,this[t+1]=255&e,t+2},u.prototype.writeUInt32LE=function(e,t,n){return e=+e,t>>>=0,n||j(this,e,t,4,4294967295,0),this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e,t+4},u.prototype.writeUInt32BE=function(e,t,n){return e=+e,t>>>=0,n||j(this,e,t,4,4294967295,0),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},u.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t>>>=0,!r){var i=Math.pow(2,8*n-1);j(this,e,t,n,i-1,-i)}var o=0,a=1,s=0;for(this[t]=255&e;++o>0)-s&255;return t+n},u.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t>>>=0,!r){var i=Math.pow(2,8*n-1);j(this,e,t,n,i-1,-i)}var o=n-1,a=1,s=0;for(this[t+o]=255&e;--o>=0&&(a*=256);)e<0&&0===s&&0!==this[t+o+1]&&(s=1),this[t+o]=(e/a>>0)-s&255;return t+n},u.prototype.writeInt8=function(e,t,n){return e=+e,t>>>=0,n||j(this,e,t,1,127,-128),e<0&&(e=255+e+1),this[t]=255&e,t+1},u.prototype.writeInt16LE=function(e,t,n){return e=+e,t>>>=0,n||j(this,e,t,2,32767,-32768),this[t]=255&e,this[t+1]=e>>>8,t+2},u.prototype.writeInt16BE=function(e,t,n){return e=+e,t>>>=0,n||j(this,e,t,2,32767,-32768),this[t]=e>>>8,this[t+1]=255&e,t+2},u.prototype.writeInt32LE=function(e,t,n){return e=+e,t>>>=0,n||j(this,e,t,4,2147483647,-2147483648),this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24,t+4},u.prototype.writeInt32BE=function(e,t,n){return e=+e,t>>>=0,n||j(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},u.prototype.writeFloatLE=function(e,t,n){return I(this,e,t,!0,n)},u.prototype.writeFloatBE=function(e,t,n){return I(this,e,t,!1,n)},u.prototype.writeDoubleLE=function(e,t,n){return L(this,e,t,!0,n)},u.prototype.writeDoubleBE=function(e,t,n){return L(this,e,t,!1,n)},u.prototype.copy=function(e,t,n,r){if(!u.isBuffer(e))throw new TypeError("argument should be a Buffer");if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r=this.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t=0;--o)e[o+t]=this[o+n];else Uint8Array.prototype.set.call(e,this.subarray(n,r),t);return i},u.prototype.fill=function(e,t,n,r){if("string"==typeof e){if("string"==typeof t?(r=t,t=0,n=this.length):"string"==typeof n&&(r=n,n=this.length),void 0!==r&&"string"!=typeof r)throw new TypeError("encoding must be a string");if("string"==typeof r&&!u.isEncoding(r))throw new TypeError("Unknown encoding: "+r);if(1===e.length){var i=e.charCodeAt(0);("utf8"===r&&i<128||"latin1"===r)&&(e=i)}}else"number"==typeof e?e&=255:"boolean"==typeof e&&(e=Number(e));if(t<0||this.length>>=0,n=void 0===n?this.length:n>>>0,e||(e=0),"number"==typeof e)for(o=t;o55295&&n<57344){if(!i){if(n>56319){(t-=3)>-1&&o.push(239,191,189);continue}if(a+1===r){(t-=3)>-1&&o.push(239,191,189);continue}i=n;continue}if(n<56320){(t-=3)>-1&&o.push(239,191,189),i=n;continue}n=65536+(i-55296<<10|n-56320)}else i&&(t-=3)>-1&&o.push(239,191,189);if(i=null,n<128){if((t-=1)<0)break;o.push(n)}else if(n<2048){if((t-=2)<0)break;o.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;o.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;o.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return o}function F(e){return r.toByteArray(function(e){if((e=(e=e.split("=")[0]).trim().replace(q,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function U(e,t,n,r){for(var i=0;i=t.length||i>=e.length);++i)t[i+n]=e[i];return i}function J(e,t){return e instanceof t||null!=e&&null!=e.constructor&&null!=e.constructor.name&&e.constructor.name===t.name}function H(e){return e!=e}var V=function(){for(var e="0123456789abcdef",t=new Array(256),n=0;n<16;++n)for(var r=16*n,i=0;i<16;++i)t[r+i]=e[n]+e[i];return t}()},73754:function(e){"use strict";e.exports=JSON.parse('{"login":"Login","logout":"Logout","email":"E-Mail","password":"Passwort","email or password is wrong":"Die E-Mail oder das Passwort stimmt nicht!","stay logged in":"Angemeldet bleiben","goodbye":"Auf Wiedersehen","welcome back":"Willkommen zurück","registration successful":"Registrierung erfolgreich","registration":"Anmelden","I have read and accepted the terms and conditions.":"Ich habe die AGB gelesen und akzeptiert.","retype password":"Passwort wiederholen","the passwords do not match.":"Die Passwörter stimmen nicht überein.","username":"Username","email is already in use.":"Die E-Mail wird bereits verwendet.","username is already in use.":"Der Username ist bereits vergeben.","wrong email or password":"Falsche E-Mail oder falsches Passwort","wrong rights":"Keine Berechtigung!","passwort vergessen?":"Passwort vergessen?","password forgotten":"Passwort vergessen","request new password":"Neues Passwort setzen","email is not in our database":"Die E-Mail ist nicht registriert!","forgot-password-mail sent":"Es wurde eine E-Mail an die angegebene Adresse gesendet.","password resetted":"Das Passwort wurde erfolgreich zurückgesetzt.","token is not valid":"Der Link ist nicht mehr gültig.","reset password":"Passwort zurücksetzen","repeat password":"Passwort wiederholen","token not valid":"Der Link ist nicht mehr gültig","Not allowed":"Nicht erlaubt","You don\'t have the rights to do this!":"Du hast nicht die Berechtigung, um das zu tun!","If you are not logged in, please log in and try again.":"Wenn du noch nicht eingeloggt bist, logge dich ein und versuche es erneut."}')},10562:function(e){"use strict";e.exports=JSON.parse('{"login":"Login","logout":"Logout","email":"E-Mail","password":"Password","email or password is wrong":"The e-mail or password is incorrect!","stay logged in":"Stay logged in","goodbye":"Goodbye","welcome back":"Welcome back","registration successful":"Registration successful","registration":"Registration","I have read and accepted the terms and conditions.":"I have read and accepted the terms and conditions.","retype password":"Retype Password","the passwords do not match.":"The passwords do not match.","username":"Username","email is already in use.":"This e-mail is already in use.","username is already in use.":"This Username is already taken.","wrong email or password":"Wrong E-Mail or Password!","wrong rights":"Wrong Rights!","passwort vergessen?":"password forgotten?","password forgotten":"Password Forgotten","request new password":"Request New Password","email is not in our database":"The given E-Mailaddress is not registered!","forgot-password-mail sent":"We sent you an E-Mail with instructions","password resetted":"The password was successfully changed.","token is not valid":"The given link is no longer valid.","reset password":"Reset Password","repeat password":"Repeat Password","token not valid":"The link is not valid any more","Not allowed":"Not allowed","You don\'t have the rights to do this!":"You don\'t have the rights to do this!","If you are not logged in, please log in and try again.":"If you are not logged in, please log in and try again."}')},77809:function(e){"use strict";e.exports=JSON.parse('{"Sunday":"Sonntag","Monday":"Montag","Tuesday":"Dienstag","Wednesday":"Mittwoch","Thursday":"Donnerstag","Friday":"Freitag","Saturday":"Samstag","January":"Januar","February":"Februar","March":"März","April":"April","May":"Mai","June":"Juni","July":"Juli","August":"August","September":"September","October":"Oktober","November":"November","December":"Dezember","Sun":"So","Mon":"Mo","Tue":"Di","Wed":"Mi","Thu":"Do","Fri":"Fr","Sat":"Sa","Jan":"Jan","Feb":"Feb","Mar":"Mär","Apr":"Apr","Jun":"Jun","Jul":"Jul","Aug":"Aug","Sep":"Sep","Oct":"Okt","Nov":"Nov","Dec":"Dez"}')},85015:function(e){"use strict";e.exports=JSON.parse('{"Sunday":"Sunday","Monday":"Monday","Tuesday":"Tuesday","Wednesday":"Wednesday","Thursday":"Thursday","Friday":"Friday","Saturday":"Saturday","January":"January","February":"February","March":"March","April":"April","May":"May","June":"June","July":"July","August":"August","September":"September","October":"October","November":"November","December":"December","Sun":"Sun","Mon":"Mon","Tue":"Tue","Wed":"Wed","Thu":"Thu","Fri":"Fri","Sat":"Sat","Jan":"Jan","Feb":"Feb","Mar":"Mar","Apr":"Apr","Jun":"Jun","Jul":"Jul","Aug":"Aug","Sep":"Sep","Oct":"Oct","Nov":"Nov","Dec":"Dec"}')},16266:function(e,t,n){n(95767),n(68132),n(48388),n(37470),n(94882),n(41520),n(27476),n(79622),n(89375),n(43533),n(84672),n(64157),n(35095),n(49892),n(75115),n(99176),n(68838),n(96253),n(39730),n(6059),n(48377),n(71084),n(64299),n(11246),n(30726),n(1901),n(75972),n(53403),n(92516),n(49371),n(86479),n(91736),n(51889),n(65177),n(81246),n(76503),n(66786),n(50932),n(57526),n(21591),n(9073),n(80347),n(30579),n(4669),n(67710),n(45789),n(33514),n(99978),n(58472),n(86946),n(35068),n(413),n(50191),n(98306),n(64564),n(39115),n(29539),n(96620),n(62850),n(10823),n(17732),n(40856),n(80703),n(91539),n(5292),n(45177),n(73694),n(37648),n(27795),n(4531),n(23605),n(6780),n(69937),n(10511),n(81822),n(19977),n(91031),n(46331),n(41560),n(20774),n(30522),n(58295),n(87842),n(50110),n(20075),n(24336),n(19371),n(98837),n(26773),n(15745),n(33057),n(3750),n(23369),n(99564),n(32e3),n(48977),n(52310),n(94899),n(31842),n(56997),n(83946),n(18269),n(66108),n(76774),n(21466),n(59357),n(76142),n(51876),n(40851),n(88416),n(98184),n(30147),n(59192),n(30142),n(1786),n(75368),n(46964),n(62152),n(74821),n(79103),n(81303),n(83318),n(70162),n(33834),n(21572),n(82139),n(10685),n(85535),n(17347),n(83049),n(96633),n(68989),n(78270),n(64510),n(73984),n(75769),n(50055),n(96014),e.exports=n(25645)},70911:function(e,t,n){n(1268),e.exports=n(25645).Array.flatMap},10990:function(e,t,n){n(62773),e.exports=n(25645).Array.includes},15434:function(e,t,n){n(83276),e.exports=n(25645).Object.entries},78051:function(e,t,n){n(98351),e.exports=n(25645).Object.getOwnPropertyDescriptors},38250:function(e,t,n){n(96409),e.exports=n(25645).Object.values},54952:function(e,t,n){"use strict";n(40851),n(9865),e.exports=n(25645).Promise.finally},6197:function(e,t,n){n(92770),e.exports=n(25645).String.padEnd},14160:function(e,t,n){n(41784),e.exports=n(25645).String.padStart},54039:function(e,t,n){n(94325),e.exports=n(25645).String.trimRight},96728:function(e,t,n){n(65869),e.exports=n(25645).String.trimLeft},93568:function(e,t,n){n(79665),e.exports=n(28787).f("asyncIterator")},40115:function(e,t,n){n(34579),e.exports=n(11327).global},85663:function(e){e.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},12159:function(e,t,n){var r=n(36727);e.exports=function(e){if(!r(e))throw TypeError(e+" is not an object!");return e}},11327:function(e){var t=e.exports={version:"2.6.11"};"number"==typeof __e&&(__e=t)},19216:function(e,t,n){var r=n(85663);e.exports=function(e,t,n){if(r(e),void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 2:return function(n,r){return e.call(t,n,r)};case 3:return function(n,r,i){return e.call(t,n,r,i)}}return function(){return e.apply(t,arguments)}}},89666:function(e,t,n){e.exports=!n(7929)((function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}))},97467:function(e,t,n){var r=n(36727),i=n(33938).document,o=r(i)&&r(i.createElement);e.exports=function(e){return o?i.createElement(e):{}}},83856:function(e,t,n){var r=n(33938),i=n(11327),o=n(19216),a=n(41818),s=n(27069),u=function(e,t,n){var c,l,f,p=e&u.F,h=e&u.G,d=e&u.S,y=e&u.P,m=e&u.B,v=e&u.W,g=h?i:i[t]||(i[t]={}),b=g.prototype,w=h?r:d?r[t]:(r[t]||{}).prototype;for(c in h&&(n=t),n)(l=!p&&w&&void 0!==w[c])&&s(g,c)||(f=l?w[c]:n[c],g[c]=h&&"function"!=typeof w[c]?n[c]:m&&l?o(f,r):v&&w[c]==f?function(e){var t=function(t,n,r){if(this instanceof e){switch(arguments.length){case 0:return new e;case 1:return new e(t);case 2:return new e(t,n)}return new e(t,n,r)}return e.apply(this,arguments)};return t.prototype=e.prototype,t}(f):y&&"function"==typeof f?o(Function.call,f):f,y&&((g.virtual||(g.virtual={}))[c]=f,e&u.R&&b&&!b[c]&&a(b,c,f)))};u.F=1,u.G=2,u.S=4,u.P=8,u.B=16,u.W=32,u.U=64,u.R=128,e.exports=u},7929:function(e){e.exports=function(e){try{return!!e()}catch(e){return!0}}},33938:function(e){var t=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=t)},27069:function(e){var t={}.hasOwnProperty;e.exports=function(e,n){return t.call(e,n)}},41818:function(e,t,n){var r=n(4743),i=n(83101);e.exports=n(89666)?function(e,t,n){return r.f(e,t,i(1,n))}:function(e,t,n){return e[t]=n,e}},33758:function(e,t,n){e.exports=!n(89666)&&!n(7929)((function(){return 7!=Object.defineProperty(n(97467)("div"),"a",{get:function(){return 7}}).a}))},36727:function(e){e.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},4743:function(e,t,n){var r=n(12159),i=n(33758),o=n(33206),a=Object.defineProperty;t.f=n(89666)?Object.defineProperty:function(e,t,n){if(r(e),t=o(t,!0),r(n),i)try{return a(e,t,n)}catch(e){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(e[t]=n.value),e}},83101:function(e){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},33206:function(e,t,n){var r=n(36727);e.exports=function(e,t){if(!r(e))return e;var n,i;if(t&&"function"==typeof(n=e.toString)&&!r(i=n.call(e)))return i;if("function"==typeof(n=e.valueOf)&&!r(i=n.call(e)))return i;if(!t&&"function"==typeof(n=e.toString)&&!r(i=n.call(e)))return i;throw TypeError("Can't convert object to primitive value")}},34579:function(e,t,n){var r=n(83856);r(r.G,{global:n(33938)})},24963:function(e){e.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},83365:function(e,t,n){var r=n(92032);e.exports=function(e,t){if("number"!=typeof e&&"Number"!=r(e))throw TypeError(t);return+e}},17722:function(e,t,n){var r=n(86314)("unscopables"),i=Array.prototype;null==i[r]&&n(87728)(i,r,{}),e.exports=function(e){i[r][e]=!0}},76793:function(e,t,n){"use strict";var r=n(24496)(!0);e.exports=function(e,t,n){return t+(n?r(e,t).length:1)}},83328:function(e){e.exports=function(e,t,n,r){if(!(e instanceof t)||void 0!==r&&r in e)throw TypeError(n+": incorrect invocation!");return e}},27007:function(e,t,n){var r=n(55286);e.exports=function(e){if(!r(e))throw TypeError(e+" is not an object!");return e}},5216:function(e,t,n){"use strict";var r=n(20508),i=n(92337),o=n(10875);e.exports=[].copyWithin||function(e,t){var n=r(this),a=o(n.length),s=i(e,a),u=i(t,a),c=arguments.length>2?arguments[2]:void 0,l=Math.min((void 0===c?a:i(c,a))-u,a-s),f=1;for(u0;)u in n?n[s]=n[u]:delete n[s],s+=f,u+=f;return n}},46852:function(e,t,n){"use strict";var r=n(20508),i=n(92337),o=n(10875);e.exports=function(e){for(var t=r(this),n=o(t.length),a=arguments.length,s=i(a>1?arguments[1]:void 0,n),u=a>2?arguments[2]:void 0,c=void 0===u?n:i(u,n);c>s;)t[s++]=e;return t}},79315:function(e,t,n){var r=n(22110),i=n(10875),o=n(92337);e.exports=function(e){return function(t,n,a){var s,u=r(t),c=i(u.length),l=o(a,c);if(e&&n!=n){for(;c>l;)if((s=u[l++])!=s)return!0}else for(;c>l;l++)if((e||l in u)&&u[l]===n)return e||l||0;return!e&&-1}}},10050:function(e,t,n){var r=n(741),i=n(49797),o=n(20508),a=n(10875),s=n(16886);e.exports=function(e,t){var n=1==e,u=2==e,c=3==e,l=4==e,f=6==e,p=5==e||f,h=t||s;return function(t,s,d){for(var y,m,v=o(t),g=i(v),b=r(s,d,3),w=a(g.length),E=0,_=n?h(t,w):u?h(t,0):void 0;w>E;E++)if((p||E in g)&&(m=b(y=g[E],E,v),e))if(n)_[E]=m;else if(m)switch(e){case 3:return!0;case 5:return y;case 6:return E;case 2:_.push(y)}else if(l)return!1;return f?-1:c||l?l:_}}},37628:function(e,t,n){var r=n(24963),i=n(20508),o=n(49797),a=n(10875);e.exports=function(e,t,n,s,u){r(t);var c=i(e),l=o(c),f=a(c.length),p=u?f-1:0,h=u?-1:1;if(n<2)for(;;){if(p in l){s=l[p],p+=h;break}if(p+=h,u?p<0:f<=p)throw TypeError("Reduce of empty array with no initial value")}for(;u?p>=0:f>p;p+=h)p in l&&(s=t(s,l[p],p,c));return s}},42736:function(e,t,n){var r=n(55286),i=n(4302),o=n(86314)("species");e.exports=function(e){var t;return i(e)&&("function"!=typeof(t=e.constructor)||t!==Array&&!i(t.prototype)||(t=void 0),r(t)&&null===(t=t[o])&&(t=void 0)),void 0===t?Array:t}},16886:function(e,t,n){var r=n(42736);e.exports=function(e,t){return new(r(e))(t)}},34398:function(e,t,n){"use strict";var r=n(24963),i=n(55286),o=n(97242),a=[].slice,s={},u=function(e,t,n){if(!(t in s)){for(var r=[],i=0;i1?arguments[1]:void 0,3);n=n?n.n:this._f;)for(r(n.v,n.k,this);n&&n.r;)n=n.p},has:function(e){return!!m(d(this,t),e)}}),p&&r(l.prototype,"size",{get:function(){return d(this,t)[y]}}),l},def:function(e,t,n){var r,i,o=m(e,t);return o?o.v=n:(e._l=o={i:i=h(t,!0),k:t,v:n,p:r=e._l,n:void 0,r:!1},e._f||(e._f=o),r&&(r.n=o),e[y]++,"F"!==i&&(e._i[i]=o)),e},getEntry:m,setStrong:function(e,t,n){c(e,t,(function(e,n){this._t=d(e,t),this._k=n,this._l=void 0}),(function(){for(var e=this,t=e._k,n=e._l;n&&n.r;)n=n.p;return e._t&&(e._l=n=n?n.n:e._t._f)?l(0,"keys"==t?n.k:"values"==t?n.v:[n.k,n.v]):(e._t=void 0,l(1))}),n?"entries":"values",!n,!0),f(t)}}},23657:function(e,t,n){"use strict";var r=n(24408),i=n(84728).getWeak,o=n(27007),a=n(55286),s=n(83328),u=n(3531),c=n(10050),l=n(79181),f=n(1616),p=c(5),h=c(6),d=0,y=function(e){return e._l||(e._l=new m)},m=function(){this.a=[]},v=function(e,t){return p(e.a,(function(e){return e[0]===t}))};m.prototype={get:function(e){var t=v(this,e);if(t)return t[1]},has:function(e){return!!v(this,e)},set:function(e,t){var n=v(this,e);n?n[1]=t:this.a.push([e,t])},delete:function(e){var t=h(this.a,(function(t){return t[0]===e}));return~t&&this.a.splice(t,1),!!~t}},e.exports={getConstructor:function(e,t,n,o){var c=e((function(e,r){s(e,c,t,"_i"),e._t=t,e._i=d++,e._l=void 0,null!=r&&u(r,n,e[o],e)}));return r(c.prototype,{delete:function(e){if(!a(e))return!1;var n=i(e);return!0===n?y(f(this,t)).delete(e):n&&l(n,this._i)&&delete n[this._i]},has:function(e){if(!a(e))return!1;var n=i(e);return!0===n?y(f(this,t)).has(e):n&&l(n,this._i)}}),c},def:function(e,t,n){var r=i(o(t),!0);return!0===r?y(e).set(t,n):r[e._i]=n,e},ufstore:y}},45795:function(e,t,n){"use strict";var r=n(3816),i=n(42985),o=n(77234),a=n(24408),s=n(84728),u=n(3531),c=n(83328),l=n(55286),f=n(74253),p=n(7462),h=n(22943),d=n(40266);e.exports=function(e,t,n,y,m,v){var g=r[e],b=g,w=m?"set":"add",E=b&&b.prototype,_={},S=function(e){var t=E[e];o(E,e,"delete"==e||"has"==e?function(e){return!(v&&!l(e))&&t.call(this,0===e?0:e)}:"get"==e?function(e){return v&&!l(e)?void 0:t.call(this,0===e?0:e)}:"add"==e?function(e){return t.call(this,0===e?0:e),this}:function(e,n){return t.call(this,0===e?0:e,n),this})};if("function"==typeof b&&(v||E.forEach&&!f((function(){(new b).entries().next()})))){var R=new b,T=R[w](v?{}:-0,1)!=R,O=f((function(){R.has(1)})),x=p((function(e){new b(e)})),C=!v&&f((function(){for(var e=new b,t=5;t--;)e[w](t,t);return!e.has(-0)}));x||((b=t((function(t,n){c(t,b,e);var r=d(new g,t,b);return null!=n&&u(n,m,r[w],r),r}))).prototype=E,E.constructor=b),(O||C)&&(S("delete"),S("has"),m&&S("get")),(C||T)&&S(w),v&&E.clear&&delete E.clear}else b=y.getConstructor(t,e,m,w),a(b.prototype,n),s.NEED=!0;return h(b,e),_[e]=b,i(i.G+i.W+i.F*(b!=g),_),v||y.setStrong(b,e,m),b}},25645:function(e){var t=e.exports={version:"2.6.11"};"number"==typeof __e&&(__e=t)},92811:function(e,t,n){"use strict";var r=n(99275),i=n(90681);e.exports=function(e,t,n){t in e?r.f(e,t,i(0,n)):e[t]=n}},741:function(e,t,n){var r=n(24963);e.exports=function(e,t,n){if(r(e),void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 2:return function(n,r){return e.call(t,n,r)};case 3:return function(n,r,i){return e.call(t,n,r,i)}}return function(){return e.apply(t,arguments)}}},53537:function(e,t,n){"use strict";var r=n(74253),i=Date.prototype.getTime,o=Date.prototype.toISOString,a=function(e){return e>9?e:"0"+e};e.exports=r((function(){return"0385-07-25T07:06:39.999Z"!=o.call(new Date(-50000000000001))}))||!r((function(){o.call(new Date(NaN))}))?function(){if(!isFinite(i.call(this)))throw RangeError("Invalid time value");var e=this,t=e.getUTCFullYear(),n=e.getUTCMilliseconds(),r=t<0?"-":t>9999?"+":"";return r+("00000"+Math.abs(t)).slice(r?-6:-4)+"-"+a(e.getUTCMonth()+1)+"-"+a(e.getUTCDate())+"T"+a(e.getUTCHours())+":"+a(e.getUTCMinutes())+":"+a(e.getUTCSeconds())+"."+(n>99?n:"0"+a(n))+"Z"}:o},870:function(e,t,n){"use strict";var r=n(27007),i=n(21689),o="number";e.exports=function(e){if("string"!==e&&e!==o&&"default"!==e)throw TypeError("Incorrect hint");return i(r(this),e!=o)}},91355:function(e){e.exports=function(e){if(null==e)throw TypeError("Can't call method on "+e);return e}},67057:function(e,t,n){e.exports=!n(74253)((function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}))},62457:function(e,t,n){var r=n(55286),i=n(3816).document,o=r(i)&&r(i.createElement);e.exports=function(e){return o?i.createElement(e):{}}},74430:function(e){e.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},5541:function(e,t,n){var r=n(47184),i=n(64548),o=n(14682);e.exports=function(e){var t=r(e),n=i.f;if(n)for(var a,s=n(e),u=o.f,c=0;s.length>c;)u.call(e,a=s[c++])&&t.push(a);return t}},42985:function(e,t,n){var r=n(3816),i=n(25645),o=n(87728),a=n(77234),s=n(741),u=function(e,t,n){var c,l,f,p,h=e&u.F,d=e&u.G,y=e&u.S,m=e&u.P,v=e&u.B,g=d?r:y?r[t]||(r[t]={}):(r[t]||{}).prototype,b=d?i:i[t]||(i[t]={}),w=b.prototype||(b.prototype={});for(c in d&&(n=t),n)f=((l=!h&&g&&void 0!==g[c])?g:n)[c],p=v&&l?s(f,r):m&&"function"==typeof f?s(Function.call,f):f,g&&a(g,c,f,e&u.U),b[c]!=f&&o(b,c,p),m&&w[c]!=f&&(w[c]=f)};r.core=i,u.F=1,u.G=2,u.S=4,u.P=8,u.B=16,u.W=32,u.U=64,u.R=128,e.exports=u},8852:function(e,t,n){var r=n(86314)("match");e.exports=function(e){var t=/./;try{"/./"[e](t)}catch(n){try{return t[r]=!1,!"/./"[e](t)}catch(e){}}return!0}},74253:function(e){e.exports=function(e){try{return!!e()}catch(e){return!0}}},28082:function(e,t,n){"use strict";n(18269);var r=n(77234),i=n(87728),o=n(74253),a=n(91355),s=n(86314),u=n(21165),c=s("species"),l=!o((function(){var e=/./;return e.exec=function(){var e=[];return e.groups={a:"7"},e},"7"!=="".replace(e,"$")})),f=function(){var e=/(?:)/,t=e.exec;e.exec=function(){return t.apply(this,arguments)};var n="ab".split(e);return 2===n.length&&"a"===n[0]&&"b"===n[1]}();e.exports=function(e,t,n){var p=s(e),h=!o((function(){var t={};return t[p]=function(){return 7},7!=""[e](t)})),d=h?!o((function(){var t=!1,n=/a/;return n.exec=function(){return t=!0,null},"split"===e&&(n.constructor={},n.constructor[c]=function(){return n}),n[p](""),!t})):void 0;if(!h||!d||"replace"===e&&!l||"split"===e&&!f){var y=/./[p],m=n(a,p,""[e],(function(e,t,n,r,i){return t.exec===u?h&&!i?{done:!0,value:y.call(t,n,r)}:{done:!0,value:e.call(n,t,r)}:{done:!1}})),v=m[0],g=m[1];r(String.prototype,e,v),i(RegExp.prototype,p,2==t?function(e,t){return g.call(e,this,t)}:function(e){return g.call(e,this)})}}},53218:function(e,t,n){"use strict";var r=n(27007);e.exports=function(){var e=r(this),t="";return e.global&&(t+="g"),e.ignoreCase&&(t+="i"),e.multiline&&(t+="m"),e.unicode&&(t+="u"),e.sticky&&(t+="y"),t}},13325:function(e,t,n){"use strict";var r=n(4302),i=n(55286),o=n(10875),a=n(741),s=n(86314)("isConcatSpreadable");e.exports=function e(t,n,u,c,l,f,p,h){for(var d,y,m=l,v=0,g=!!p&&a(p,h,3);v0)m=e(t,n,d,o(d.length),m,f-1)-1;else{if(m>=9007199254740991)throw TypeError();t[m]=d}m++}v++}return m}},3531:function(e,t,n){var r=n(741),i=n(28851),o=n(86555),a=n(27007),s=n(10875),u=n(69002),c={},l={},f=e.exports=function(e,t,n,f,p){var h,d,y,m,v=p?function(){return e}:u(e),g=r(n,f,t?2:1),b=0;if("function"!=typeof v)throw TypeError(e+" is not iterable!");if(o(v)){for(h=s(e.length);h>b;b++)if((m=t?g(a(d=e[b])[0],d[1]):g(e[b]))===c||m===l)return m}else for(y=v.call(e);!(d=y.next()).done;)if((m=i(y,g,d.value,t))===c||m===l)return m};f.BREAK=c,f.RETURN=l},40018:function(e,t,n){e.exports=n(3825)("native-function-to-string",Function.toString)},3816:function(e){var t=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=t)},79181:function(e){var t={}.hasOwnProperty;e.exports=function(e,n){return t.call(e,n)}},87728:function(e,t,n){var r=n(99275),i=n(90681);e.exports=n(67057)?function(e,t,n){return r.f(e,t,i(1,n))}:function(e,t,n){return e[t]=n,e}},40639:function(e,t,n){var r=n(3816).document;e.exports=r&&r.documentElement},1734:function(e,t,n){e.exports=!n(67057)&&!n(74253)((function(){return 7!=Object.defineProperty(n(62457)("div"),"a",{get:function(){return 7}}).a}))},40266:function(e,t,n){var r=n(55286),i=n(27375).set;e.exports=function(e,t,n){var o,a=t.constructor;return a!==n&&"function"==typeof a&&(o=a.prototype)!==n.prototype&&r(o)&&i&&i(e,o),e}},97242:function(e){e.exports=function(e,t,n){var r=void 0===n;switch(t.length){case 0:return r?e():e.call(n);case 1:return r?e(t[0]):e.call(n,t[0]);case 2:return r?e(t[0],t[1]):e.call(n,t[0],t[1]);case 3:return r?e(t[0],t[1],t[2]):e.call(n,t[0],t[1],t[2]);case 4:return r?e(t[0],t[1],t[2],t[3]):e.call(n,t[0],t[1],t[2],t[3])}return e.apply(n,t)}},49797:function(e,t,n){var r=n(92032);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==r(e)?e.split(""):Object(e)}},86555:function(e,t,n){var r=n(87234),i=n(86314)("iterator"),o=Array.prototype;e.exports=function(e){return void 0!==e&&(r.Array===e||o[i]===e)}},4302:function(e,t,n){var r=n(92032);e.exports=Array.isArray||function(e){return"Array"==r(e)}},18367:function(e,t,n){var r=n(55286),i=Math.floor;e.exports=function(e){return!r(e)&&isFinite(e)&&i(e)===e}},55286:function(e){e.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},55364:function(e,t,n){var r=n(55286),i=n(92032),o=n(86314)("match");e.exports=function(e){var t;return r(e)&&(void 0!==(t=e[o])?!!t:"RegExp"==i(e))}},28851:function(e,t,n){var r=n(27007);e.exports=function(e,t,n,i){try{return i?t(r(n)[0],n[1]):t(n)}catch(t){var o=e.return;throw void 0!==o&&r(o.call(e)),t}}},49988:function(e,t,n){"use strict";var r=n(42503),i=n(90681),o=n(22943),a={};n(87728)(a,n(86314)("iterator"),(function(){return this})),e.exports=function(e,t,n){e.prototype=r(a,{next:i(1,n)}),o(e,t+" Iterator")}},42923:function(e,t,n){"use strict";var r=n(4461),i=n(42985),o=n(77234),a=n(87728),s=n(87234),u=n(49988),c=n(22943),l=n(468),f=n(86314)("iterator"),p=!([].keys&&"next"in[].keys()),h="keys",d="values",y=function(){return this};e.exports=function(e,t,n,m,v,g,b){u(n,t,m);var w,E,_,S=function(e){if(!p&&e in x)return x[e];switch(e){case h:case d:return function(){return new n(this,e)}}return function(){return new n(this,e)}},R=t+" Iterator",T=v==d,O=!1,x=e.prototype,C=x[f]||x["@@iterator"]||v&&x[v],P=C||S(v),N=v?T?S("entries"):P:void 0,M="Array"==t&&x.entries||C;if(M&&(_=l(M.call(new e)))!==Object.prototype&&_.next&&(c(_,R,!0),r||"function"==typeof _[f]||a(_,f,y)),T&&C&&C.name!==d&&(O=!0,P=function(){return C.call(this)}),r&&!b||!p&&!O&&x[f]||a(x,f,P),s[t]=P,s[R]=y,v)if(w={values:T?P:S(d),keys:g?P:S(h),entries:N},b)for(E in w)E in x||o(x,E,w[E]);else i(i.P+i.F*(p||O),t,w);return w}},7462:function(e,t,n){var r=n(86314)("iterator"),i=!1;try{var o=[7][r]();o.return=function(){i=!0},Array.from(o,(function(){throw 2}))}catch(e){}e.exports=function(e,t){if(!t&&!i)return!1;var n=!1;try{var o=[7],a=o[r]();a.next=function(){return{done:n=!0}},o[r]=function(){return a},e(o)}catch(e){}return n}},15436:function(e){e.exports=function(e,t){return{value:t,done:!!e}}},87234:function(e){e.exports={}},4461:function(e){e.exports=!1},13086:function(e){var t=Math.expm1;e.exports=!t||t(10)>22025.465794806718||t(10)<22025.465794806718||-2e-17!=t(-2e-17)?function(e){return 0==(e=+e)?e:e>-1e-6&&e<1e-6?e+e*e/2:Math.exp(e)-1}:t},34934:function(e,t,n){var r=n(61801),i=Math.pow,o=i(2,-52),a=i(2,-23),s=i(2,127)*(2-a),u=i(2,-126);e.exports=Math.fround||function(e){var t,n,i=Math.abs(e),c=r(e);return is||n!=n?c*(1/0):c*n}},46206:function(e){e.exports=Math.log1p||function(e){return(e=+e)>-1e-8&&e<1e-8?e-e*e/2:Math.log(1+e)}},61801:function(e){e.exports=Math.sign||function(e){return 0==(e=+e)||e!=e?e:e<0?-1:1}},84728:function(e,t,n){var r=n(93953)("meta"),i=n(55286),o=n(79181),a=n(99275).f,s=0,u=Object.isExtensible||function(){return!0},c=!n(74253)((function(){return u(Object.preventExtensions({}))})),l=function(e){a(e,r,{value:{i:"O"+ ++s,w:{}}})},f=e.exports={KEY:r,NEED:!1,fastKey:function(e,t){if(!i(e))return"symbol"==typeof e?e:("string"==typeof e?"S":"P")+e;if(!o(e,r)){if(!u(e))return"F";if(!t)return"E";l(e)}return e[r].i},getWeak:function(e,t){if(!o(e,r)){if(!u(e))return!0;if(!t)return!1;l(e)}return e[r].w},onFreeze:function(e){return c&&f.NEED&&u(e)&&!o(e,r)&&l(e),e}}},14351:function(e,t,n){var r=n(3816),i=n(74193).set,o=r.MutationObserver||r.WebKitMutationObserver,a=r.process,s=r.Promise,u="process"==n(92032)(a);e.exports=function(){var e,t,n,c=function(){var r,i;for(u&&(r=a.domain)&&r.exit();e;){i=e.fn,e=e.next;try{i()}catch(r){throw e?n():t=void 0,r}}t=void 0,r&&r.enter()};if(u)n=function(){a.nextTick(c)};else if(!o||r.navigator&&r.navigator.standalone)if(s&&s.resolve){var l=s.resolve(void 0);n=function(){l.then(c)}}else n=function(){i.call(r,c)};else{var f=!0,p=document.createTextNode("");new o(c).observe(p,{characterData:!0}),n=function(){p.data=f=!f}}return function(r){var i={fn:r,next:void 0};t&&(t.next=i),e||(e=i,n()),t=i}}},43499:function(e,t,n){"use strict";var r=n(24963);function i(e){var t,n;this.promise=new e((function(e,r){if(void 0!==t||void 0!==n)throw TypeError("Bad Promise constructor");t=e,n=r})),this.resolve=r(t),this.reject=r(n)}e.exports.f=function(e){return new i(e)}},35345:function(e,t,n){"use strict";var r=n(67057),i=n(47184),o=n(64548),a=n(14682),s=n(20508),u=n(49797),c=Object.assign;e.exports=!c||n(74253)((function(){var e={},t={},n=Symbol(),r="abcdefghijklmnopqrst";return e[n]=7,r.split("").forEach((function(e){t[e]=e})),7!=c({},e)[n]||Object.keys(c({},t)).join("")!=r}))?function(e,t){for(var n=s(e),c=arguments.length,l=1,f=o.f,p=a.f;c>l;)for(var h,d=u(arguments[l++]),y=f?i(d).concat(f(d)):i(d),m=y.length,v=0;m>v;)h=y[v++],r&&!p.call(d,h)||(n[h]=d[h]);return n}:c},42503:function(e,t,n){var r=n(27007),i=n(35588),o=n(74430),a=n(69335)("IE_PROTO"),s=function(){},u=function(){var e,t=n(62457)("iframe"),r=o.length;for(t.style.display="none",n(40639).appendChild(t),t.src="javascript:",(e=t.contentWindow.document).open(),e.write("