diff --git a/Changelog.txt b/Changelog.txt index bdda323..494bd77 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,5 +1,10 @@ CHANGE LOG: +31.07.2024 + + - Open Source Models Connection (API and Endpoint adjustable from .env) + - Chatlog is saved on the localstorage + 16.04.2024 Changelog – HAWKI V1. - Multi language package added. diff --git a/README.md b/README.md index 719748c..698b2e6 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,10 @@ Display of mathematical formulas, LaTex and improvement of syntax highlighting. Dark Mode for our night owls. -System prompts can now be viewed transparently. +System prompts can now be viewed and edited. + +In the new version each room's chatlog is saved by default and should be deleted before starting a new chat. + ### Security updates @@ -72,6 +75,7 @@ The new version also supports the Shibboleth for user authentication. Define you To generate answers HAWKI uses the Open AI api. Follow the instructions on https://platform.openai.com/docs/introduction to generate an API key and paste it in the configuration file like instructed in chapter [Configuration](#configuration). + ## Configuration To get started you need to add a configuration file to the project first. Copy the file ".env.example" from the root directory and rename it to ".env". Replace the example values in it with your own configuration. A detailed description of all values is listed below. @@ -85,20 +89,25 @@ To get started you need to add a configuration file to the project first. Copy t | LDAP_SEARCH_DN | string | "ou=...,dc=..." | Distinguished name that is used for authenticating users. | | LDAP_PORT | string | "..." | The LDAP port. | | LDAP_FILTER | string | "..." | LDAP Filter. Choose the filter based on your LDAP configuration. See .env.example for more details.| +| LDAP_DEFAULT_INITIALS | string | "ABC" | User initials to use for every user. If not set, try to compute initials from LDAP displayname.| | SHIBBOLET_LOGIN_PATH | string | "..." | Path to shibboleth login page. | | SHIBBOLET_LOGIN_PAGE | string | "..." | Shibboleth login page. | | OIDC_IDP | string | "https://...." | URL of the Identity provider supporting OpenID Connect. | | OIDC_CLIENT_ID | string | "..." | Client Id for this application in Identity provider. | | OIDC_CLIENT_SECRET | string | "..." | Secret key for OpenID Connect. | OIDC_LOGOUT_URI | string | "https://...." | URL to logout from Identity provider | -| OPENAI_API_URL | string | "https://api.openai.com/v1/chat/completions" | Open AI URL | +| MODEL_SELECTOR_ACTIVATION | string | "true" | Set to true to activate dropdown. Deactivated Dropdown will force Gpt-4-0 as default model. | +| OPENAI_API_URL | string | "https://api.openai.com/v1/chat/completions" | Open AI Endpoint URL | | OPENAI_API_KEY | string | sk-... | Open AI Api key | +| GWDG_API_URL | string | "https://api.openai.com/v1/chat/completions" | GWDG Endpoint URL | +| GWDG_API_KEY | string | | GWDG Api key | | IMPRINT_LOCATION | string | https://your-university/imprint | A link to your imprint. Alternatively you can replace the file index.php under /impressum with your own html/ php of your imprint. | | PRIVACY_LOCATION | string | https://your-university/privacy-policy | A link to your privacy policy. Alternatively you can replace the file index.php under /datenschutz with your own html/ php of your privacy policy. | | TESTUSER | string | "tester" | Set value for testing purposes. Leave TESTUSER and TESTPASSWORD empty or comment them out to disable test user. | | TESTPASSWORD | string | "superlangespasswort123" | Set value for testing purposes. Leave TESTUSER and TESTPASSWORD empty or comment them out to disable test user. | | FAVICON_URI | string | "https://...." | Link to favicon | | DEFAULT_LANGUAGE | string | "de_DE"/ "en_US"/ "es_ES"/ "fr_FR"/ "it_IT" | Default website language. Only applicable if the user has not previously changed the language or their browser language is not one of the supported languages. Current supported languages: 'de_DE', 'en_US', 'es_ES', 'fr_FR', 'it_IT' | +| CHATLOG_ENCRYPTION_SALT | string | ... | Set a strong salt specific to your application. This will be user to encrypt users' chatlogs in localstorage.| ## Web Server Configuration There are a few things to keep in mind when publishing your HAWKI instance on a webserver. diff --git a/index.php b/index.php index 78de8be..9006d62 100644 --- a/index.php +++ b/index.php @@ -57,8 +57,13 @@ include_once( LIBRARY_PATH . "stream-api.php"); } exit; + case('/api/GWDG-api'): + if($_SERVER["REQUEST_METHOD"] == "POST"){ + include_once( LIBRARY_PATH . "GWDG-stream-api.php"); + } + exit; default: - header("Location: /login"); + header("Location: login"); exit(); } \ No newline at end of file diff --git a/private/.env.example b/private/.env.example index 336d441..4201af8 100644 --- a/private/.env.example +++ b/private/.env.example @@ -11,16 +11,24 @@ LDAP_PORT="" ; (|(sAMAccountName=username)(mail=username)) ; (|(uid=username)(mail=username)) LDAP_FILTER="(|(sAMAccountName=username)(mail=username))" +; LDAP_DEFAULT_INITIALS="ABC" #Shibbolet SHIBBOLETH_LOGIN_PATH="Shibboleth.sso/Login?target=" SHIBBOLETH_LOGIN_PAGE="login.php" SHIBBOLETH_LOGOUT_URL="" +# Activates Model Selector Dropdown +MODEL_SELECTOR_ACTIVATION="true" + # Open Ai config OPENAI_API_URL="https://api.openai.com/v1/chat/completions" OPENAI_API_KEY="sk-..." +#GWDG Ai Config +GWDG_API_URL="https://chat-ai.academiccloud.de/v1/chat/completions" +GWDG_API_KEY="" + # Legal config IMPRINT_LOCATION="https://my-univiersity.com/imprint" PRIVACY_LOCATION="https://my-univiersity.com/ai-privacy-policy" @@ -49,3 +57,6 @@ FAVICON_URI="" # Default Language, leave blank to use default language of the user's browser. DEFAULT_LANGUAGE="de_DE" + +# fix salt for encryption users' chatlog in localstorage +CHATLOG_ENCRYPTION_SALT="" diff --git a/private/app/php/GWDG-stream-api.php b/private/app/php/GWDG-stream-api.php new file mode 100644 index 0000000..e4e7b58 --- /dev/null +++ b/private/app/php/GWDG-stream-api.php @@ -0,0 +1,64 @@ + + + diff --git a/private/app/php/submit_vote.php b/private/app/php/submit_vote.php index dd3eb89..0eebc2f 100644 --- a/private/app/php/submit_vote.php +++ b/private/app/php/submit_vote.php @@ -56,9 +56,9 @@ // Find the feedback entry by ID $foundFeedback = null; - foreach ($feedbackData as $feedback) { + foreach ($feedbackData as &$feedback) { if ($feedback['id'] === $data['id']) { - $foundFeedback = $feedback; + $foundFeedback = &$feedback; break; } } diff --git a/private/app/php/user_feedback.php b/private/app/php/user_feedback.php new file mode 100644 index 0000000..075bbf8 --- /dev/null +++ b/private/app/php/user_feedback.php @@ -0,0 +1,104 @@ + diff --git a/private/pages/interface.php b/private/pages/interface.php index f6c96ed..9975f4c 100644 --- a/private/pages/interface.php +++ b/private/pages/interface.php @@ -4,13 +4,14 @@ require_once BOOTSTRAP_PATH; require_once LIBRARY_PATH . 'language_controller.php'; + if(!isset($_SESSION['translation'])){ setLanguage(); } $translation = $_SESSION['translation']; if (!isset($_SESSION['username'])) { - header("Location: login.php"); + header("Location: login"); exit; } @@ -52,27 +53,30 @@ media="screen" /> - - - + + + - - - + + + - - - + + + - - - + + + - + + + + + + + - - - -
- - - - - -
-
- (" . $_SESSION['username']. ")"); ?> -
- - - -
- +
+
+
+ +
+
+
+ +
+ '; + $stream_api_models = explode(';', isset($env) ? $env["STREAM_API_MODELS"] : getenv("STREAM_API_MODELS")); + $gwdg_api_models = explode(';', isset($env) ? $env[""] : getenv("")); + $options = ""; + foreach($stream_api_models as $model) { + $value = explode(',', $model); + $options = $options . ''; + } + foreach($gwdg_api_models as $model) { + if (strlen($model) < 1){ + continue; + } + $value = explode(',', $model); + $options = $options . ''; + } + unset($model); + $options = $options . ''; + echo $model_selector . $options; -
-
-
- -
+ } + else{ + echo '
'; + } + ?> +
+ +
+
+ +
+
- -
-
-
- -
-
- - - - - - -
-
- -
-
-
-
-

System Prompt:

-
- - - -
+ +
+ +
+
+ + + + + +
- -
+
+
+
+

System Prompt:

+
+ + + +
+ +
+
+ + + + +
+
+
+ + + +
+
+ + + +
+
+ +
+ + +
+ + +
-

+

+ + + +

+
+ +
+
+ +
-
-
- -
-
- - -
- - + + + + + diff --git a/private/pages/login.php b/private/pages/login.php index dfbbc46..07cd045 100644 --- a/private/pages/login.php +++ b/private/pages/login.php @@ -2,13 +2,13 @@ // Secure session (optional, depends on the application's specific needs) ini_set('session.cookie_httponly', 1); ini_set('session.use_only_cookies', 1); - if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') { - ini_set('session.cookie_secure', 1); - } - session_set_cookie_params([ - 'secure' => true, // cookies are sent over secure connections only - 'httponly' => true, // cookies are accessible only through the HTTP protocol - ]); + // if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') { + // ini_set('session.cookie_secure', 1); + // } + // session_set_cookie_params([ + // 'secure' => true, // cookies are sent over secure connections only + // 'httponly' => true, // cookies are accessible only through the HTTP protocol + // ]); session_start(); @@ -17,7 +17,6 @@ require_once LIBRARY_PATH . 'auth.php'; require_once LIBRARY_PATH . 'language_controller.php'; - // Generate CSRF Token if(!isset($_SESSION['csrf_token'])){ generate_csrf_token(); @@ -30,7 +29,7 @@ // Check if the user is already logged in if (isset($_SESSION['username'])) { - header("Location: /interface"); + header("Location: interface"); exit; } @@ -52,11 +51,11 @@ media="screen" /> media="screen" /> - - - + + + - + @@ -72,7 +71,16 @@
@@ -145,7 +153,7 @@
- +
diff --git a/private/pages/logout.php b/private/pages/logout.php index 3da4ce4..8c29838 100644 --- a/private/pages/logout.php +++ b/private/pages/logout.php @@ -14,23 +14,23 @@ // Finally, destroy the session. session_destroy(); - if (file_exists(ENV_FILE_PATH)){ $env = parse_ini_file(ENV_FILE_PATH); } - if(isset($env) ? $env['Authentication'] : getenv('Authentication') === 'Shibboleth'){ - $redirect_uri = $env['SHIBBOLETH_LOGOUT_URL']; + + $authentication = isset($env) ? $env["Authentication"] : getenv("Authentication"); + if($authentication === 'Shibboleth'){ + $redirect_uri = isset($env) ? $env["SHIBBOLETH_LOGOUT_URL"] : getenv("SHIBBOLETH_LOGOUT_URL"); } - elseif(isset($env) ? $env['Authentication'] : getenv('Authentication') === 'OIDC'){ - $redirect_uri = getenv('OIDC_LOGOUT_URI'); + elseif($authentication === 'OIDC'){ + $redirect_uri = isset($env) ? $env["OIDC_LOGOUT_URI"] : getenv("OIDC_LOGOUT_URI"); } else{ // Redirect to the login page - $redirect_uri ='/login'; + $redirect_uri ='login'; } header("Location: $redirect_uri"); exit(); - ?> diff --git a/private/pages/oidc_login.php b/private/pages/oidc_login.php index 8274c9d..bf55d8f 100644 --- a/private/pages/oidc_login.php +++ b/private/pages/oidc_login.php @@ -33,7 +33,7 @@ //TODO: check for affiliation if ((isset($env) ? strtolower($env["Authentication"]) : strtolower(getenv("Authentication"))) == "you_shall_not_pass") { - header("Location: /login"); + header("Location: login"); exit(); } @@ -41,7 +41,7 @@ $_SESSION['username'] = $oidc->requestUserInfo('email'); -header("Location: /interface"); +header("Location: interface"); exit(); ?> \ No newline at end of file diff --git a/private/resources/language/de_DE.json b/private/resources/language/de_DE.json index 8d0f2e8..7b1a668 100644 --- a/private/resources/language/de_DE.json +++ b/private/resources/language/de_DE.json @@ -1,7 +1,5 @@ { "AI_Icon": "KI", - "AI_Model_Selection": "KI Modell", - "AI_Model_Selection_Info": " Wähle ein KI Modell.", "AboutHAWKI": "Über HM-KI", "AboutHAWKI_ArianInfo": " | Wissenschaftlicher Mitarbeiter | HAWKI", "AboutHAWKI_Info": "Das Angebot wurde auf Basis der Entwicklung der Kollegen der HAWK vom Interaction Design Lab für die HM angepasst und weiterentwickelt, um allen Hochschulangehörigen die Möglichkeit zu geben, künstliche Intelligenz in die Arbeitsprozesse zu integrieren und einen Begegnungsraum zu haben, damit sich eventuell neue Arbeitsweisen ergeben und eine hochschulinterne Diskussion über den Einsatz von K.I. entstehen kann. Dieses Angebot möchte auch didaktisch unterstützen, ein Verständnis für die Wirkungsweise eines solchen Sprachmodells zu entwickeln und gibt daher in den verschiedenen Bereichen auch Hinweise auf gut funktionierende Prompts (Texteingaben). Wir freuen uns über konstruktives Feedback, um dieses Angebot entsprechend Ihren Bedürfnissen und Erkenntnissen zusammen mit der HAWK weiterzuentwickeln.", @@ -137,8 +135,14 @@ "tokenUsedMessage": "Sie haben alle ihre Token aufgebraucht.", "unableToSaveRegistration": "Ihre Anmeldung konnte nicht gespeichert werden.
Bitte versuchen Sie es erneut.
", "usageNoticeTitle": "Nutzungshinweis", + "usage_guideline_confirm_request": "Die Funktion von HAWKI setzt für die Generierung der Ausgaben zwingend voraus, dass Ihre Eingaben an Dritte (je nach KI-Modell OpenAI Inc. oder GWDG) übermittelt werden. Sind Sie damit einverstanden und werden keine personenbezogenen Daten von Ihnen oder anderen Personen eingeben?", "usage_guideline": "

Willkommen zum Leitfaden für den Umgang mit HM-KI, das auf der OpenAI API basiert. Dieser Leitfaden soll allen Hochschulangehörigen - Studierenden, Lehrenden und Mitarbeitenden - eine klare Richtlinie bieten, wie mit dieser Technologie verantwortungsbewusst umgegangen werden soll. Bitte beachten Sie, dass dieser Leitfaden die Nutzungsbedingungen von OpenAI ergänzt und keinen Anspruch auf Vollständigkeit erhebt. Es liegt in der Verantwortung der Nutzerinnen und Nutzer, die Nutzungsbedingungen einzuhalten.

Allgemeine Bestimmungen

Was verboten ist:

Was zu beachten ist:

Sie sind verantwortlich für den von Ihnen bereitgestellten Input und den daraus resultierenden Output. Sie müssen sicherstellen, dass Ihr Input keine Rechte verletzt und dass Sie über alle notwendigen Rechte, Lizenzen und Genehmigungen für die Bereitstellung des Inputs verfügen.

Genauigkeit:

Die Nutzung der Dienste kann zu ungenauem oder fehlerhaftem Output führen. Es ist wichtig, dass Sie den Output kritisch prüfen und nicht als alleinige Quelle der Wahrheit verwenden.Ihre Eingaben werden nicht von der HM, aber von OpenAI für 30 Tage gespeichert, um einen eventuellen Missbrauch festzustellen. Nach 30 Tagen werden die Daten gelöscht. Ihre Eingaben werden nicht verwendet, um das Produkt sicherer oder besser zu machen.

Spezifische Bestimmungen

Für Studierende:

Für Lehrende:

Für Mitarbeitende:

Dieser Leitfaden dient als Orientierungshilfe für den verantwortungsbewussten Umgang mit HM-KI. Es ist wichtig, dass alle Nutzer*innen die genannten Bestimmungen verstehen und befolgen, um einen sicheren und ethischen Einsatz dieser Technologie zu gewährleisten. Die Hochschule kann diesen Service nur anbieten, wenn Sie keine persönlichen Daten eingeben. Ungeachtet dieses Leitfadens gelten die Nutzungsbedingungen von OpenAI.

", "username": "Benutzername", "welcomeBackTitle": "Willkommen zurück!", - "writingAssistanceRequest": "Ich arbeite an einem wissenschaftlichen Projekt und benötige Hilfe beim Schreibstil und der Formatierung. Ich habe meine Arbeit bereits verfasst, bin mir aber nicht sicher, ob ich alle Formatierungsrichtlinien und Schreibkonventionen korrekt befolgt habe. Könntest du mir bitte helfen, meine Arbeit zu überprüfen und mir Ratschläge zur Verbesserung der Formatierung und des Schreibstils geben?" + "writingAssistanceRequest": "Ich arbeite an einem wissenschaftlichen Projekt und benötige Hilfe beim Schreibstil und der Formatierung. Ich habe meine Arbeit bereits verfasst, bin mir aber nicht sicher, ob ich alle Formatierungsrichtlinien und Schreibkonventionen korrekt befolgt habe. Könntest du mir bitte helfen, meine Arbeit zu überprüfen und mir Ratschläge zur Verbesserung der Formatierung und des Schreibstils geben?", + "deleteChat": "Dieser Chat wird endgültig gelöscht.
Möchten Sie fortfahren?", + "delete": "Löschen", + "cancel": "Abbrechen", + "agree": "Einverstanden", + "disagree": "Nicht einverstanden" } \ No newline at end of file diff --git a/private/resources/language/en_US.json b/private/resources/language/en_US.json index df3d722..83f07f6 100644 --- a/private/resources/language/en_US.json +++ b/private/resources/language/en_US.json @@ -1,7 +1,5 @@ { "AI_Icon": "AI", - "AI_Model_Selection": "AI Model", - "AI_Model_Selection_Info": "Choose an AI model.", "AboutHAWKI": "About HM-KI", "AboutHAWKI_ArianInfo": " | Research Assistant | HAWKI", "AboutHAWKI_Info": "This service was developed in the Interaction Design Lab of HAWK to give all university members the opportunity to integrate artificial intelligence into their work processes and to have a space for encounter so that new working methods might emerge and an internal university discussion on the use of AI can take place. This offer also aims to support didactically, to develop an understanding of how such a language model works and therefore gives hints on well-functioning prompts (text inputs) in various areas. We welcome constructive feedback to further develop this offer according to your needs and findings.", @@ -137,8 +135,14 @@ "tokenUsedMessage": "You have used up all your tokens.", "unableToSaveRegistration": "Your registration could not be saved.
Please try again.
", "usageNoticeTitle": "Usage Notice", + "usage_guideline_confirm_request": "The function of HAWKI requires that your input is transmitted to third parties (OpenAI Inc. or GWDG, depending on the AI model) in order to generate the outputs. Do you agree to this and will you not enter any personal data about yourself or other persons?", "usage_guideline": "

Welcome to the guide for using HM_AI, which is based on the OpenAI API. This guide is intended for all university affiliates - students, teachers, and staff - to provide a clear guideline on how to handle this technology responsibly. Please note that this guide supplements the terms of use of OpenAI and does not claim to be exhaustive. It is the users' responsibility to comply with these terms.

General Provisions

What is prohibited:

What to consider:

You are responsible for the input you provide and the resulting output. You must ensure that your input does not infringe any rights and that you have all necessary rights, licenses, and permissions to provide it.

Accuracy:

Using the services can lead to inaccurate or incorrect output. It is important that you critically examine the output and not use it as the sole source of truth. Your inputs are not stored by HAWK, but by OpenAI for 30 days to detect any misuse. After 30 days, the data is deleted. Your inputs are not used to improve the product's safety or quality.

Specific Provisions

For students:

For teachers:

For staff:

This guide serves as an orientation aid for the responsible handling of HM-AI. It is important that all users understand and follow these provisions to ensure safe and ethical use of this technology. The university can only offer this service if you do not enter personal data. Regardless of this guide, the OpenAI Terms of Use apply.

", "username": "Username", "welcomeBackTitle": "Welcome back!", - "writingAssistanceRequest": "I am working on a scientific project and need help with writing style and formatting. I have already composed my work, but I am not sure if I have followed all formatting guidelines and writing conventions correctly. Could you please help me review my work and give me advice on improving the formatting and writing style?" + "writingAssistanceRequest": "I am working on a scientific project and need help with writing style and formatting. I have already composed my work, but I am not sure if I have followed all formatting guidelines and writing conventions correctly. Could you please help me review my work and give me advice on improving the formatting and writing style?", + "deleteChat": "The chat will be permanently deleted.
Do you want to continue?", + "delete": "Delete", + "cancel": "Cancel", + "agree": "Agree", + "disagree": "Disagree" } \ No newline at end of file diff --git a/private/resources/language/es_ES.json b/private/resources/language/es_ES.json index 72f41e8..9a41a51 100644 --- a/private/resources/language/es_ES.json +++ b/private/resources/language/es_ES.json @@ -135,7 +135,13 @@ "unableToSaveRegistration": "No se pudo guardar su registro.
Por favor, inténtelo de nuevo.
", "usageNoticeTitle": "Aviso de Uso", "usage_guideline": "

Bienvenidos a la guía para el manejo de HAWKI, basada en la API de OpenAI. Esta guía está diseñada para todos los miembros de la universidad - estudiantes, docentes y personal - para proporcionar una línea clara de cómo manejar esta tecnología de forma responsable. Por favor, tenga en cuenta que esta guía complementa las condiciones de uso de OpenAI y no es exhaustiva. Es responsabilidad de los usuarios cumplir con estas condiciones.

Disposiciones generales

Lo que está prohibido:

Lo que debe considerarse:

Usted es responsable de la entrada que proporciona y del resultado que genera. Debe asegurarse de que su entrada no infrinja derechos y de que posee todos los derechos, licencias y permisos necesarios para proporcionarla.

Precisión:

El uso de los servicios puede llevar a resultados inexactos o erróneos. Es importante que revise críticamente el resultado y no lo utilice como la única fuente de verdad. Sus entradas no son almacenadas por HAWK, sino por OpenAI por 30 días para detectar posibles abusos. Después de 30 días, los datos son eliminados. Sus entradas no se utilizan para mejorar la seguridad o calidad del producto.

Disposiciones específicas

Existen una guía provisional y una declaración de independencia para el uso de sistemas de IA generativa.

Para estudiantes:

Para docentes:

Para el personal:

Esta guía sirve como una herramienta de orientación para el manejo responsable de HAWKI. Es crucial que todos los usuarios comprendan y sigan estas disposiciones para asegurar un uso seguro y ético de esta tecnología. La universidad solo puede ofrecer este servicio si no se introducen datos personales. Para cualquier pregunta o incertidumbre, por favor contacte a Prof. Stefan Wölwer, Arian Sadafi, Jonas Trippler o Vincent Timm. Independientemente de esta guía, se aplican las condiciones de uso de OpenAI.

", + "usage_guideline_confirm_request": "La función HAWKI requiere que sus datos sean transmitidos a terceros (OpenAI Inc. o GWDG, dependiendo del modelo de IA) para generar los resultados. Está de acuerdo con ello y no se introducirán datos personales suyos ni de otras personas?", "username": "Nombre de Usuario", "welcomeBackTitle": "¡Bienvenido de nuevo!", - "writingAssistanceRequest": "Estoy trabajando en un proyecto científico y necesito ayuda con el estilo de escritura y la formateación. Ya he redactado mi trabajo, pero no estoy seguro de si he seguido todas las directrices de formateo y convenciones de escritura correctamente. ¿Podrías ayudarme a revisar mi trabajo y ofrecerme consejos para mejorar la formateación y el estilo de escritura?" + "writingAssistanceRequest": "Estoy trabajando en un proyecto científico y necesito ayuda con el estilo de escritura y la formateación. Ya he redactado mi trabajo, pero no estoy seguro de si he seguido todas las directrices de formateo y convenciones de escritura correctamente. ¿Podrías ayudarme a revisar mi trabajo y ofrecerme consejos para mejorar la formateación y el estilo de escritura?", + "deleteChat": "El chat se borrará permanentemente.
¿Quieres continuar?", + "delete": "Borrar", + "cancel": "Cancelar", + "agree": "De acuerdo", + "disagree": "En desacuerdo" } \ No newline at end of file diff --git a/private/resources/language/fr_FR.json b/private/resources/language/fr_FR.json index 91e423a..8ba5595 100644 --- a/private/resources/language/fr_FR.json +++ b/private/resources/language/fr_FR.json @@ -135,7 +135,13 @@ "unableToSaveRegistration": "Votre inscription n'a pas pu être sauvegardée.
Veuillez réessayer.
", "usageNoticeTitle": "Conseil d'Utilisation", "usage_guideline": "

Bienvenue dans le guide d'utilisation de HAWKI, basé sur l'API OpenAI. Ce guide est destiné à tous les membres de l'université - étudiants, enseignants et personnel - afin de fournir une ligne directrice claire sur la manière de gérer cette technologie de manière responsable. Veuillez noter que ce guide complète les conditions d'utilisation d'OpenAI et n'est pas exhaustif. Il est de la responsabilité des utilisateurs de respecter ces conditions.

Dispositions générales

Ce qui est interdit :

À noter :

Vous êtes responsable de l'entrée que vous fournissez et de la sortie résultante. Vous devez vous assurer que votre entrée ne viole aucun droit et que vous disposez de tous les droits, licences et autorisations nécessaires pour fournir l'entrée.

Exactitude :

L'utilisation des services peut entraîner une sortie inexacte ou incorrecte. Il est important de critiquer la sortie et de ne pas l'utiliser comme la seule source de vérité. Vos entrées ne sont pas stockées par HAWK, mais par OpenAI pendant 30 jours pour détecter d'éventuels abus. Après 30 jours, les données sont supprimées. Vos entrées ne sont pas utilisées pour améliorer la sécurité ou la qualité du produit.

Dispositions spécifiques

Il existe une directive provisoire et une déclaration d'indépendance pour l'utilisation des systèmes de IA générative.

Pour les étudiants :

Pour les enseignants :

Pour le personnel :

Ce guide vise à fournir une orientation pour une gestion responsable de HAWKI. Il est crucial que tous les utilisateurs comprennent et suivent ces dispositions pour assurer une utilisation sûre et éthique de cette technologie. L'université ne peut offrir ce service que si aucune donnée personnelle n'est saisie. Pour toute question ou incertitude, veuillez contacter Prof. Stefan Wölwer, Arian Sadafi, Jonas Trippler ou Vincent Timm. Indépendamment de ce guide, les conditions d'utilisation d'OpenAI s'appliquent.

", + "usage_guideline_confirm_request": "Le fonctionnement de HAWKI suppose impérativement, pour la génération des sorties, que vos entrées soient transmises à des tiers (selon le modèle d'IA, OpenAI Inc. ou GWDG). Êtes-vous d'accord avec cela et ne saisirez-vous pas de données personnelles vous concernant ou concernant d'autres personnes?", "username": "Nom d'utilisateur", "welcomeBackTitle": "Bienvenue de nouveau !", - "writingAssistanceRequest": "Je travaille sur un projet scientifique et j'ai besoin d'aide pour le style d'écriture et la mise en forme. J'ai déjà rédigé mon travail, mais je ne suis pas sûr d'avoir suivi toutes les directives de formatage et les conventions d'écriture correctement. Pourriez-vous m'aider à réviser mon travail et me donner des conseils pour améliorer la mise en forme et le style d'écriture ?" + "writingAssistanceRequest": "Je travaille sur un projet scientifique et j'ai besoin d'aide pour le style d'écriture et la mise en forme. J'ai déjà rédigé mon travail, mais je ne suis pas sûr d'avoir suivi toutes les directives de formatage et les conventions d'écriture correctement. Pourriez-vous m'aider à réviser mon travail et me donner des conseils pour améliorer la mise en forme et le style d'écriture ?", + "deleteChat": "La discussion sera définitivement supprimée.
Voulez-vous continuer ?", + "delete": "Supprimer", + "cancel": "Annuler", + "agree": "d'accord", + "disagree": "pas d'accord" } \ No newline at end of file diff --git a/private/resources/language/it_IT.json b/private/resources/language/it_IT.json index 00994a6..c614c8e 100644 --- a/private/resources/language/it_IT.json +++ b/private/resources/language/it_IT.json @@ -135,7 +135,13 @@ "unableToSaveRegistration": "La registrazione non può essere salvata.
Si prega di riprovare.
", "usageNoticeTitle": "Avviso di Utilizzo", "usage_guideline": "

Benvenuti alla guida per l'uso di HAWKI, basata sull'API di OpenAI. Questa guida è destinata a tutti i membri dell'università - studenti, insegnanti e personale - per fornire una linea guida chiara su come gestire questa tecnologia in modo responsabile. Si prega di notare che questa guida integra i termini di utilizzo di OpenAI e non è esaustiva. È responsabilità degli utenti rispettare tali termini.

Disposizioni generali

Cosa è vietato:

Cosa tenere presente:

Siete responsabili dell'input fornito e dell'output risultante. Dovete assicurarvi che il vostro input non violi alcun diritto e che disponiate di tutti i diritti, licenze e autorizzazioni necessari per fornirlo.

Accuratezza:

L'utilizzo dei servizi può portare a output inaccurati o errati. È importante che valutiate criticamente l'output e che non lo utilizziate come unica fonte di verità. I vostri input non sono memorizzati da HAWK, ma da OpenAI per 30 giorni al fine di rilevare eventuali abusi. Dopo 30 giorni, i dati vengono cancellati. I vostri input non sono utilizzati per migliorare la sicurezza o la qualità del prodotto.

Disposizioni specifiche

Ci sono una linea guida provvisoria e una dichiarazione di indipendenza per l'utilizzo dei sistemi di IA generativa.

Per gli studenti:

Per gli insegnanti:

Per il personale:

Questa guida serve come orientamento per un uso responsabile di HAWKI. È importante che tutti gli utenti comprendano e seguano queste disposizioni per garantire un utilizzo sicuro ed etico di questa tecnologia. L'università può offrire questo servizio solo se non vengono inseriti dati personali. Per qualsiasi domanda o incertezza, si prega di contattare il Prof. Stefan Wölwer, Arian Sadafi, Jonas Trippler o Vincent Timm. Indipendentemente da questa guida, si applicano le condizioni d'uso di OpenAI.

", + "usage_guideline_confirm_request": "La funzione HAWKI prevede che i vostri input vengano trasmessi a terzi (OpenAI Inc. o GWDG, a seconda del modello di AI) per generare gli output. Siete d'accordo e non verranno inseriti dati personali da parte vostra o di altre persone?", "username": "Nome Utente", "welcomeBackTitle": "Bentornato!", - "writingAssistanceRequest": "Sto lavorando a un progetto scientifico e ho bisogno di aiuto con lo stile di scrittura e la formattazione. Ho già redatto il mio lavoro, ma non sono sicuro di aver seguito tutte le linee guida di formattazione e le convenzioni di scrittura correttamente. Potresti aiutarmi a rivedere il mio lavoro e fornirmi consigli su come migliorare la formattazione e lo stile di scrittura?" + "writingAssistanceRequest": "Sto lavorando a un progetto scientifico e ho bisogno di aiuto con lo stile di scrittura e la formattazione. Ho già redatto il mio lavoro, ma non sono sicuro di aver seguito tutte le linee guida di formattazione e le convenzioni di scrittura correttamente. Potresti aiutarmi a rivedere il mio lavoro e fornirmi consigli su come migliorare la formattazione e lo stile di scrittura?", + "deleteChat": "La chat sarà cancellata in modo permanente.
Volete continuare?", + "delete": "Cancellare", + "cancel": "Annullamento", + "agree": "Sono d'accordo", + "disagree": "Non sono d'accordo" } \ No newline at end of file diff --git a/private/views/chat.php b/private/views/chat.php index 9e04dc7..3f82a15 100644 --- a/private/views/chat.php +++ b/private/views/chat.php @@ -50,3 +50,17 @@
+ + diff --git a/private/views/guidelines.php b/private/views/guidelines.php index a6a2ddd..1e53932 100644 --- a/private/views/guidelines.php +++ b/private/views/guidelines.php @@ -10,10 +10,13 @@

-
- - -
+

+ +

+


diff --git a/private/views/settings.php b/private/views/settings.php index 9078e98..b35a344 100644 --- a/private/views/settings.php +++ b/private/views/settings.php @@ -43,7 +43,7 @@
- HAWK Logo + HAWK Logo
diff --git a/public/assets/crypto-js.min.js b/public/assets/crypto-js.min.js new file mode 100644 index 0000000..3f3b373 --- /dev/null +++ b/public/assets/crypto-js.min.js @@ -0,0 +1 @@ +!function (t, e) { "object" == typeof exports ? module.exports = exports = e() : "function" == typeof define && define.amd ? define([], e) : t.CryptoJS = e() }(this, function () { var n, o, s, a, h, t, e, l, r, i, c, f, d, u, p, S, x, b, A, H, z, _, v, g, y, B, w, k, m, C, D, E, R, M, F, P, W, O, I, U = U || function (h) { var i; if ("undefined" != typeof window && window.crypto && (i = window.crypto), "undefined" != typeof self && self.crypto && (i = self.crypto), !(i = !(i = !(i = "undefined" != typeof globalThis && globalThis.crypto ? globalThis.crypto : i) && "undefined" != typeof window && window.msCrypto ? window.msCrypto : i) && "undefined" != typeof global && global.crypto ? global.crypto : i) && "function" == typeof require) try { i = require("crypto") } catch (t) { } var r = Object.create || function (t) { return e.prototype = t, t = new e, e.prototype = null, t }; function e() { } var t = {}, n = t.lib = {}, o = n.Base = { extend: function (t) { var e = r(this); return t && e.mixIn(t), e.hasOwnProperty("init") && this.init !== e.init || (e.init = function () { e.$super.init.apply(this, arguments) }), (e.init.prototype = e).$super = this, e }, create: function () { var t = this.extend(); return t.init.apply(t, arguments), t }, init: function () { }, mixIn: function (t) { for (var e in t) t.hasOwnProperty(e) && (this[e] = t[e]); t.hasOwnProperty("toString") && (this.toString = t.toString) }, clone: function () { return this.init.prototype.extend(this) } }, l = n.WordArray = o.extend({ init: function (t, e) { t = this.words = t || [], this.sigBytes = null != e ? e : 4 * t.length }, toString: function (t) { return (t || c).stringify(this) }, concat: function (t) { var e = this.words, r = t.words, i = this.sigBytes, n = t.sigBytes; if (this.clamp(), i % 4) for (var o = 0; o < n; o++) { var s = r[o >>> 2] >>> 24 - o % 4 * 8 & 255; e[i + o >>> 2] |= s << 24 - (i + o) % 4 * 8 } else for (var c = 0; c < n; c += 4)e[i + c >>> 2] = r[c >>> 2]; return this.sigBytes += n, this }, clamp: function () { var t = this.words, e = this.sigBytes; t[e >>> 2] &= 4294967295 << 32 - e % 4 * 8, t.length = h.ceil(e / 4) }, clone: function () { var t = o.clone.call(this); return t.words = this.words.slice(0), t }, random: function (t) { for (var e = [], r = 0; r < t; r += 4)e.push(function () { if (i) { if ("function" == typeof i.getRandomValues) try { return i.getRandomValues(new Uint32Array(1))[0] } catch (t) { } if ("function" == typeof i.randomBytes) try { return i.randomBytes(4).readInt32LE() } catch (t) { } } throw new Error("Native crypto module could not be used to get secure random number.") }()); return new l.init(e, t) } }), s = t.enc = {}, c = s.Hex = { stringify: function (t) { for (var e = t.words, r = t.sigBytes, i = [], n = 0; n < r; n++) { var o = e[n >>> 2] >>> 24 - n % 4 * 8 & 255; i.push((o >>> 4).toString(16)), i.push((15 & o).toString(16)) } return i.join("") }, parse: function (t) { for (var e = t.length, r = [], i = 0; i < e; i += 2)r[i >>> 3] |= parseInt(t.substr(i, 2), 16) << 24 - i % 8 * 4; return new l.init(r, e / 2) } }, a = s.Latin1 = { stringify: function (t) { for (var e = t.words, r = t.sigBytes, i = [], n = 0; n < r; n++) { var o = e[n >>> 2] >>> 24 - n % 4 * 8 & 255; i.push(String.fromCharCode(o)) } return i.join("") }, parse: function (t) { for (var e = t.length, r = [], i = 0; i < e; i++)r[i >>> 2] |= (255 & t.charCodeAt(i)) << 24 - i % 4 * 8; return new l.init(r, e) } }, f = s.Utf8 = { stringify: function (t) { try { return decodeURIComponent(escape(a.stringify(t))) } catch (t) { throw new Error("Malformed UTF-8 data") } }, parse: function (t) { return a.parse(unescape(encodeURIComponent(t))) } }, d = n.BufferedBlockAlgorithm = o.extend({ reset: function () { this._data = new l.init, this._nDataBytes = 0 }, _append: function (t) { "string" == typeof t && (t = f.parse(t)), this._data.concat(t), this._nDataBytes += t.sigBytes }, _process: function (t) { var e, r = this._data, i = r.words, n = r.sigBytes, o = this.blockSize, s = n / (4 * o), c = (s = t ? h.ceil(s) : h.max((0 | s) - this._minBufferSize, 0)) * o, n = h.min(4 * c, n); if (c) { for (var a = 0; a < c; a += o)this._doProcessBlock(i, a); e = i.splice(0, c), r.sigBytes -= n } return new l.init(e, n) }, clone: function () { var t = o.clone.call(this); return t._data = this._data.clone(), t }, _minBufferSize: 0 }), u = (n.Hasher = d.extend({ cfg: o.extend(), init: function (t) { this.cfg = this.cfg.extend(t), this.reset() }, reset: function () { d.reset.call(this), this._doReset() }, update: function (t) { return this._append(t), this._process(), this }, finalize: function (t) { return t && this._append(t), this._doFinalize() }, blockSize: 16, _createHelper: function (r) { return function (t, e) { return new r.init(e).finalize(t) } }, _createHmacHelper: function (r) { return function (t, e) { return new u.HMAC.init(r, e).finalize(t) } } }), t.algo = {}); return t }(Math); function K(t, e, r) { return t & e | ~t & r } function X(t, e, r) { return t & r | e & ~r } function L(t, e) { return t << e | t >>> 32 - e } function j(t, e, r, i) { var n, o = this._iv; o ? (n = o.slice(0), this._iv = void 0) : n = this._prevBlock, i.encryptBlock(n, 0); for (var s = 0; s < r; s++)t[e + s] ^= n[s] } function T(t) { var e, r, i; return 255 == (t >> 24 & 255) ? (r = t >> 8 & 255, i = 255 & t, 255 === (e = t >> 16 & 255) ? (e = 0, 255 === r ? (r = 0, 255 === i ? i = 0 : ++i) : ++r) : ++e, t = 0, t += e << 16, t += r << 8, t += i) : t += 1 << 24, t } function N() { for (var t = this._X, e = this._C, r = 0; r < 8; r++)E[r] = e[r]; e[0] = e[0] + 1295307597 + this._b | 0, e[1] = e[1] + 3545052371 + (e[0] >>> 0 < E[0] >>> 0 ? 1 : 0) | 0, e[2] = e[2] + 886263092 + (e[1] >>> 0 < E[1] >>> 0 ? 1 : 0) | 0, e[3] = e[3] + 1295307597 + (e[2] >>> 0 < E[2] >>> 0 ? 1 : 0) | 0, e[4] = e[4] + 3545052371 + (e[3] >>> 0 < E[3] >>> 0 ? 1 : 0) | 0, e[5] = e[5] + 886263092 + (e[4] >>> 0 < E[4] >>> 0 ? 1 : 0) | 0, e[6] = e[6] + 1295307597 + (e[5] >>> 0 < E[5] >>> 0 ? 1 : 0) | 0, e[7] = e[7] + 3545052371 + (e[6] >>> 0 < E[6] >>> 0 ? 1 : 0) | 0, this._b = e[7] >>> 0 < E[7] >>> 0 ? 1 : 0; for (r = 0; r < 8; r++) { var i = t[r] + e[r], n = 65535 & i, o = i >>> 16; R[r] = ((n * n >>> 17) + n * o >>> 15) + o * o ^ ((4294901760 & i) * i | 0) + ((65535 & i) * i | 0) } t[0] = R[0] + (R[7] << 16 | R[7] >>> 16) + (R[6] << 16 | R[6] >>> 16) | 0, t[1] = R[1] + (R[0] << 8 | R[0] >>> 24) + R[7] | 0, t[2] = R[2] + (R[1] << 16 | R[1] >>> 16) + (R[0] << 16 | R[0] >>> 16) | 0, t[3] = R[3] + (R[2] << 8 | R[2] >>> 24) + R[1] | 0, t[4] = R[4] + (R[3] << 16 | R[3] >>> 16) + (R[2] << 16 | R[2] >>> 16) | 0, t[5] = R[5] + (R[4] << 8 | R[4] >>> 24) + R[3] | 0, t[6] = R[6] + (R[5] << 16 | R[5] >>> 16) + (R[4] << 16 | R[4] >>> 16) | 0, t[7] = R[7] + (R[6] << 8 | R[6] >>> 24) + R[5] | 0 } function q() { for (var t = this._X, e = this._C, r = 0; r < 8; r++)O[r] = e[r]; e[0] = e[0] + 1295307597 + this._b | 0, e[1] = e[1] + 3545052371 + (e[0] >>> 0 < O[0] >>> 0 ? 1 : 0) | 0, e[2] = e[2] + 886263092 + (e[1] >>> 0 < O[1] >>> 0 ? 1 : 0) | 0, e[3] = e[3] + 1295307597 + (e[2] >>> 0 < O[2] >>> 0 ? 1 : 0) | 0, e[4] = e[4] + 3545052371 + (e[3] >>> 0 < O[3] >>> 0 ? 1 : 0) | 0, e[5] = e[5] + 886263092 + (e[4] >>> 0 < O[4] >>> 0 ? 1 : 0) | 0, e[6] = e[6] + 1295307597 + (e[5] >>> 0 < O[5] >>> 0 ? 1 : 0) | 0, e[7] = e[7] + 3545052371 + (e[6] >>> 0 < O[6] >>> 0 ? 1 : 0) | 0, this._b = e[7] >>> 0 < O[7] >>> 0 ? 1 : 0; for (r = 0; r < 8; r++) { var i = t[r] + e[r], n = 65535 & i, o = i >>> 16; I[r] = ((n * n >>> 17) + n * o >>> 15) + o * o ^ ((4294901760 & i) * i | 0) + ((65535 & i) * i | 0) } t[0] = I[0] + (I[7] << 16 | I[7] >>> 16) + (I[6] << 16 | I[6] >>> 16) | 0, t[1] = I[1] + (I[0] << 8 | I[0] >>> 24) + I[7] | 0, t[2] = I[2] + (I[1] << 16 | I[1] >>> 16) + (I[0] << 16 | I[0] >>> 16) | 0, t[3] = I[3] + (I[2] << 8 | I[2] >>> 24) + I[1] | 0, t[4] = I[4] + (I[3] << 16 | I[3] >>> 16) + (I[2] << 16 | I[2] >>> 16) | 0, t[5] = I[5] + (I[4] << 8 | I[4] >>> 24) + I[3] | 0, t[6] = I[6] + (I[5] << 16 | I[5] >>> 16) + (I[4] << 16 | I[4] >>> 16) | 0, t[7] = I[7] + (I[6] << 8 | I[6] >>> 24) + I[5] | 0 } return F = (M = U).lib, n = F.Base, o = F.WordArray, (M = M.x64 = {}).Word = n.extend({ init: function (t, e) { this.high = t, this.low = e } }), M.WordArray = n.extend({ init: function (t, e) { t = this.words = t || [], this.sigBytes = null != e ? e : 8 * t.length }, toX32: function () { for (var t = this.words, e = t.length, r = [], i = 0; i < e; i++) { var n = t[i]; r.push(n.high), r.push(n.low) } return o.create(r, this.sigBytes) }, clone: function () { for (var t = n.clone.call(this), e = t.words = this.words.slice(0), r = e.length, i = 0; i < r; i++)e[i] = e[i].clone(); return t } }), "function" == typeof ArrayBuffer && (P = U.lib.WordArray, s = P.init, (P.init = function (t) { if ((t = (t = t instanceof ArrayBuffer ? new Uint8Array(t) : t) instanceof Int8Array || "undefined" != typeof Uint8ClampedArray && t instanceof Uint8ClampedArray || t instanceof Int16Array || t instanceof Uint16Array || t instanceof Int32Array || t instanceof Uint32Array || t instanceof Float32Array || t instanceof Float64Array ? new Uint8Array(t.buffer, t.byteOffset, t.byteLength) : t) instanceof Uint8Array) { for (var e = t.byteLength, r = [], i = 0; i < e; i++)r[i >>> 2] |= t[i] << 24 - i % 4 * 8; s.call(this, r, e) } else s.apply(this, arguments) }).prototype = P), function () { var t = U, n = t.lib.WordArray, t = t.enc; t.Utf16 = t.Utf16BE = { stringify: function (t) { for (var e = t.words, r = t.sigBytes, i = [], n = 0; n < r; n += 2) { var o = e[n >>> 2] >>> 16 - n % 4 * 8 & 65535; i.push(String.fromCharCode(o)) } return i.join("") }, parse: function (t) { for (var e = t.length, r = [], i = 0; i < e; i++)r[i >>> 1] |= t.charCodeAt(i) << 16 - i % 2 * 16; return n.create(r, 2 * e) } }; function s(t) { return t << 8 & 4278255360 | t >>> 8 & 16711935 } t.Utf16LE = { stringify: function (t) { for (var e = t.words, r = t.sigBytes, i = [], n = 0; n < r; n += 2) { var o = s(e[n >>> 2] >>> 16 - n % 4 * 8 & 65535); i.push(String.fromCharCode(o)) } return i.join("") }, parse: function (t) { for (var e = t.length, r = [], i = 0; i < e; i++)r[i >>> 1] |= s(t.charCodeAt(i) << 16 - i % 2 * 16); return n.create(r, 2 * e) } } }(), a = (w = U).lib.WordArray, w.enc.Base64 = { stringify: function (t) { var e = t.words, r = t.sigBytes, i = this._map; t.clamp(); for (var n = [], o = 0; o < r; o += 3)for (var s = (e[o >>> 2] >>> 24 - o % 4 * 8 & 255) << 16 | (e[o + 1 >>> 2] >>> 24 - (o + 1) % 4 * 8 & 255) << 8 | e[o + 2 >>> 2] >>> 24 - (o + 2) % 4 * 8 & 255, c = 0; c < 4 && o + .75 * c < r; c++)n.push(i.charAt(s >>> 6 * (3 - c) & 63)); var a = i.charAt(64); if (a) for (; n.length % 4;)n.push(a); return n.join("") }, parse: function (t) { var e = t.length, r = this._map; if (!(i = this._reverseMap)) for (var i = this._reverseMap = [], n = 0; n < r.length; n++)i[r.charCodeAt(n)] = n; var o = r.charAt(64); return !o || -1 !== (o = t.indexOf(o)) && (e = o), function (t, e, r) { for (var i = [], n = 0, o = 0; o < e; o++) { var s, c; o % 4 && (s = r[t.charCodeAt(o - 1)] << o % 4 * 2, c = r[t.charCodeAt(o)] >>> 6 - o % 4 * 2, c = s | c, i[n >>> 2] |= c << 24 - n % 4 * 8, n++) } return a.create(i, n) }(t, e, i) }, _map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" }, h = (F = U).lib.WordArray, F.enc.Base64url = { stringify: function (t, e = !0) { var r = t.words, i = t.sigBytes, n = e ? this._safe_map : this._map; t.clamp(); for (var o = [], s = 0; s < i; s += 3)for (var c = (r[s >>> 2] >>> 24 - s % 4 * 8 & 255) << 16 | (r[s + 1 >>> 2] >>> 24 - (s + 1) % 4 * 8 & 255) << 8 | r[s + 2 >>> 2] >>> 24 - (s + 2) % 4 * 8 & 255, a = 0; a < 4 && s + .75 * a < i; a++)o.push(n.charAt(c >>> 6 * (3 - a) & 63)); var h = n.charAt(64); if (h) for (; o.length % 4;)o.push(h); return o.join("") }, parse: function (t, e = !0) { var r = t.length, i = e ? this._safe_map : this._map; if (!(n = this._reverseMap)) for (var n = this._reverseMap = [], o = 0; o < i.length; o++)n[i.charCodeAt(o)] = o; e = i.charAt(64); return !e || -1 !== (e = t.indexOf(e)) && (r = e), function (t, e, r) { for (var i = [], n = 0, o = 0; o < e; o++) { var s, c; o % 4 && (s = r[t.charCodeAt(o - 1)] << o % 4 * 2, c = r[t.charCodeAt(o)] >>> 6 - o % 4 * 2, c = s | c, i[n >>> 2] |= c << 24 - n % 4 * 8, n++) } return h.create(i, n) }(t, r, n) }, _map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", _safe_map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" }, function (a) { var t = U, e = t.lib, r = e.WordArray, i = e.Hasher, e = t.algo, A = []; !function () { for (var t = 0; t < 64; t++)A[t] = 4294967296 * a.abs(a.sin(t + 1)) | 0 }(); e = e.MD5 = i.extend({ _doReset: function () { this._hash = new r.init([1732584193, 4023233417, 2562383102, 271733878]) }, _doProcessBlock: function (t, e) { for (var r = 0; r < 16; r++) { var i = e + r, n = t[i]; t[i] = 16711935 & (n << 8 | n >>> 24) | 4278255360 & (n << 24 | n >>> 8) } var o = this._hash.words, s = t[e + 0], c = t[e + 1], a = t[e + 2], h = t[e + 3], l = t[e + 4], f = t[e + 5], d = t[e + 6], u = t[e + 7], p = t[e + 8], _ = t[e + 9], y = t[e + 10], v = t[e + 11], g = t[e + 12], B = t[e + 13], w = t[e + 14], k = t[e + 15], m = H(m = o[0], b = o[1], x = o[2], S = o[3], s, 7, A[0]), S = H(S, m, b, x, c, 12, A[1]), x = H(x, S, m, b, a, 17, A[2]), b = H(b, x, S, m, h, 22, A[3]); m = H(m, b, x, S, l, 7, A[4]), S = H(S, m, b, x, f, 12, A[5]), x = H(x, S, m, b, d, 17, A[6]), b = H(b, x, S, m, u, 22, A[7]), m = H(m, b, x, S, p, 7, A[8]), S = H(S, m, b, x, _, 12, A[9]), x = H(x, S, m, b, y, 17, A[10]), b = H(b, x, S, m, v, 22, A[11]), m = H(m, b, x, S, g, 7, A[12]), S = H(S, m, b, x, B, 12, A[13]), x = H(x, S, m, b, w, 17, A[14]), m = z(m, b = H(b, x, S, m, k, 22, A[15]), x, S, c, 5, A[16]), S = z(S, m, b, x, d, 9, A[17]), x = z(x, S, m, b, v, 14, A[18]), b = z(b, x, S, m, s, 20, A[19]), m = z(m, b, x, S, f, 5, A[20]), S = z(S, m, b, x, y, 9, A[21]), x = z(x, S, m, b, k, 14, A[22]), b = z(b, x, S, m, l, 20, A[23]), m = z(m, b, x, S, _, 5, A[24]), S = z(S, m, b, x, w, 9, A[25]), x = z(x, S, m, b, h, 14, A[26]), b = z(b, x, S, m, p, 20, A[27]), m = z(m, b, x, S, B, 5, A[28]), S = z(S, m, b, x, a, 9, A[29]), x = z(x, S, m, b, u, 14, A[30]), m = C(m, b = z(b, x, S, m, g, 20, A[31]), x, S, f, 4, A[32]), S = C(S, m, b, x, p, 11, A[33]), x = C(x, S, m, b, v, 16, A[34]), b = C(b, x, S, m, w, 23, A[35]), m = C(m, b, x, S, c, 4, A[36]), S = C(S, m, b, x, l, 11, A[37]), x = C(x, S, m, b, u, 16, A[38]), b = C(b, x, S, m, y, 23, A[39]), m = C(m, b, x, S, B, 4, A[40]), S = C(S, m, b, x, s, 11, A[41]), x = C(x, S, m, b, h, 16, A[42]), b = C(b, x, S, m, d, 23, A[43]), m = C(m, b, x, S, _, 4, A[44]), S = C(S, m, b, x, g, 11, A[45]), x = C(x, S, m, b, k, 16, A[46]), m = D(m, b = C(b, x, S, m, a, 23, A[47]), x, S, s, 6, A[48]), S = D(S, m, b, x, u, 10, A[49]), x = D(x, S, m, b, w, 15, A[50]), b = D(b, x, S, m, f, 21, A[51]), m = D(m, b, x, S, g, 6, A[52]), S = D(S, m, b, x, h, 10, A[53]), x = D(x, S, m, b, y, 15, A[54]), b = D(b, x, S, m, c, 21, A[55]), m = D(m, b, x, S, p, 6, A[56]), S = D(S, m, b, x, k, 10, A[57]), x = D(x, S, m, b, d, 15, A[58]), b = D(b, x, S, m, B, 21, A[59]), m = D(m, b, x, S, l, 6, A[60]), S = D(S, m, b, x, v, 10, A[61]), x = D(x, S, m, b, a, 15, A[62]), b = D(b, x, S, m, _, 21, A[63]), o[0] = o[0] + m | 0, o[1] = o[1] + b | 0, o[2] = o[2] + x | 0, o[3] = o[3] + S | 0 }, _doFinalize: function () { var t = this._data, e = t.words, r = 8 * this._nDataBytes, i = 8 * t.sigBytes; e[i >>> 5] |= 128 << 24 - i % 32; var n = a.floor(r / 4294967296), r = r; e[15 + (64 + i >>> 9 << 4)] = 16711935 & (n << 8 | n >>> 24) | 4278255360 & (n << 24 | n >>> 8), e[14 + (64 + i >>> 9 << 4)] = 16711935 & (r << 8 | r >>> 24) | 4278255360 & (r << 24 | r >>> 8), t.sigBytes = 4 * (e.length + 1), this._process(); for (var e = this._hash, o = e.words, s = 0; s < 4; s++) { var c = o[s]; o[s] = 16711935 & (c << 8 | c >>> 24) | 4278255360 & (c << 24 | c >>> 8) } return e }, clone: function () { var t = i.clone.call(this); return t._hash = this._hash.clone(), t } }); function H(t, e, r, i, n, o, s) { s = t + (e & r | ~e & i) + n + s; return (s << o | s >>> 32 - o) + e } function z(t, e, r, i, n, o, s) { s = t + (e & i | r & ~i) + n + s; return (s << o | s >>> 32 - o) + e } function C(t, e, r, i, n, o, s) { s = t + (e ^ r ^ i) + n + s; return (s << o | s >>> 32 - o) + e } function D(t, e, r, i, n, o, s) { s = t + (r ^ (e | ~i)) + n + s; return (s << o | s >>> 32 - o) + e } t.MD5 = i._createHelper(e), t.HmacMD5 = i._createHmacHelper(e) }(Math), P = (M = U).lib, t = P.WordArray, e = P.Hasher, P = M.algo, l = [], P = P.SHA1 = e.extend({ _doReset: function () { this._hash = new t.init([1732584193, 4023233417, 2562383102, 271733878, 3285377520]) }, _doProcessBlock: function (t, e) { for (var r = this._hash.words, i = r[0], n = r[1], o = r[2], s = r[3], c = r[4], a = 0; a < 80; a++) { a < 16 ? l[a] = 0 | t[e + a] : (h = l[a - 3] ^ l[a - 8] ^ l[a - 14] ^ l[a - 16], l[a] = h << 1 | h >>> 31); var h = (i << 5 | i >>> 27) + c + l[a]; h += a < 20 ? 1518500249 + (n & o | ~n & s) : a < 40 ? 1859775393 + (n ^ o ^ s) : a < 60 ? (n & o | n & s | o & s) - 1894007588 : (n ^ o ^ s) - 899497514, c = s, s = o, o = n << 30 | n >>> 2, n = i, i = h } r[0] = r[0] + i | 0, r[1] = r[1] + n | 0, r[2] = r[2] + o | 0, r[3] = r[3] + s | 0, r[4] = r[4] + c | 0 }, _doFinalize: function () { var t = this._data, e = t.words, r = 8 * this._nDataBytes, i = 8 * t.sigBytes; return e[i >>> 5] |= 128 << 24 - i % 32, e[14 + (64 + i >>> 9 << 4)] = Math.floor(r / 4294967296), e[15 + (64 + i >>> 9 << 4)] = r, t.sigBytes = 4 * e.length, this._process(), this._hash }, clone: function () { var t = e.clone.call(this); return t._hash = this._hash.clone(), t } }), M.SHA1 = e._createHelper(P), M.HmacSHA1 = e._createHmacHelper(P), function (n) { var t = U, e = t.lib, r = e.WordArray, i = e.Hasher, e = t.algo, o = [], p = []; !function () { function t(t) { return 4294967296 * (t - (0 | t)) | 0 } for (var e = 2, r = 0; r < 64;)!function (t) { for (var e = n.sqrt(t), r = 2; r <= e; r++)if (!(t % r)) return; return 1 }(e) || (r < 8 && (o[r] = t(n.pow(e, .5))), p[r] = t(n.pow(e, 1 / 3)), r++), e++ }(); var _ = [], e = e.SHA256 = i.extend({ _doReset: function () { this._hash = new r.init(o.slice(0)) }, _doProcessBlock: function (t, e) { for (var r = this._hash.words, i = r[0], n = r[1], o = r[2], s = r[3], c = r[4], a = r[5], h = r[6], l = r[7], f = 0; f < 64; f++) { f < 16 ? _[f] = 0 | t[e + f] : (d = _[f - 15], u = _[f - 2], _[f] = ((d << 25 | d >>> 7) ^ (d << 14 | d >>> 18) ^ d >>> 3) + _[f - 7] + ((u << 15 | u >>> 17) ^ (u << 13 | u >>> 19) ^ u >>> 10) + _[f - 16]); var d = i & n ^ i & o ^ n & o, u = l + ((c << 26 | c >>> 6) ^ (c << 21 | c >>> 11) ^ (c << 7 | c >>> 25)) + (c & a ^ ~c & h) + p[f] + _[f], l = h, h = a, a = c, c = s + u | 0, s = o, o = n, n = i, i = u + (((i << 30 | i >>> 2) ^ (i << 19 | i >>> 13) ^ (i << 10 | i >>> 22)) + d) | 0 } r[0] = r[0] + i | 0, r[1] = r[1] + n | 0, r[2] = r[2] + o | 0, r[3] = r[3] + s | 0, r[4] = r[4] + c | 0, r[5] = r[5] + a | 0, r[6] = r[6] + h | 0, r[7] = r[7] + l | 0 }, _doFinalize: function () { var t = this._data, e = t.words, r = 8 * this._nDataBytes, i = 8 * t.sigBytes; return e[i >>> 5] |= 128 << 24 - i % 32, e[14 + (64 + i >>> 9 << 4)] = n.floor(r / 4294967296), e[15 + (64 + i >>> 9 << 4)] = r, t.sigBytes = 4 * e.length, this._process(), this._hash }, clone: function () { var t = i.clone.call(this); return t._hash = this._hash.clone(), t } }); t.SHA256 = i._createHelper(e), t.HmacSHA256 = i._createHmacHelper(e) }(Math), r = (w = U).lib.WordArray, F = w.algo, i = F.SHA256, F = F.SHA224 = i.extend({ _doReset: function () { this._hash = new r.init([3238371032, 914150663, 812702999, 4144912697, 4290775857, 1750603025, 1694076839, 3204075428]) }, _doFinalize: function () { var t = i._doFinalize.call(this); return t.sigBytes -= 4, t } }), w.SHA224 = i._createHelper(F), w.HmacSHA224 = i._createHmacHelper(F), function () { var t = U, e = t.lib.Hasher, r = t.x64, i = r.Word, n = r.WordArray, r = t.algo; function o() { return i.create.apply(i, arguments) } var t1 = [o(1116352408, 3609767458), o(1899447441, 602891725), o(3049323471, 3964484399), o(3921009573, 2173295548), o(961987163, 4081628472), o(1508970993, 3053834265), o(2453635748, 2937671579), o(2870763221, 3664609560), o(3624381080, 2734883394), o(310598401, 1164996542), o(607225278, 1323610764), o(1426881987, 3590304994), o(1925078388, 4068182383), o(2162078206, 991336113), o(2614888103, 633803317), o(3248222580, 3479774868), o(3835390401, 2666613458), o(4022224774, 944711139), o(264347078, 2341262773), o(604807628, 2007800933), o(770255983, 1495990901), o(1249150122, 1856431235), o(1555081692, 3175218132), o(1996064986, 2198950837), o(2554220882, 3999719339), o(2821834349, 766784016), o(2952996808, 2566594879), o(3210313671, 3203337956), o(3336571891, 1034457026), o(3584528711, 2466948901), o(113926993, 3758326383), o(338241895, 168717936), o(666307205, 1188179964), o(773529912, 1546045734), o(1294757372, 1522805485), o(1396182291, 2643833823), o(1695183700, 2343527390), o(1986661051, 1014477480), o(2177026350, 1206759142), o(2456956037, 344077627), o(2730485921, 1290863460), o(2820302411, 3158454273), o(3259730800, 3505952657), o(3345764771, 106217008), o(3516065817, 3606008344), o(3600352804, 1432725776), o(4094571909, 1467031594), o(275423344, 851169720), o(430227734, 3100823752), o(506948616, 1363258195), o(659060556, 3750685593), o(883997877, 3785050280), o(958139571, 3318307427), o(1322822218, 3812723403), o(1537002063, 2003034995), o(1747873779, 3602036899), o(1955562222, 1575990012), o(2024104815, 1125592928), o(2227730452, 2716904306), o(2361852424, 442776044), o(2428436474, 593698344), o(2756734187, 3733110249), o(3204031479, 2999351573), o(3329325298, 3815920427), o(3391569614, 3928383900), o(3515267271, 566280711), o(3940187606, 3454069534), o(4118630271, 4000239992), o(116418474, 1914138554), o(174292421, 2731055270), o(289380356, 3203993006), o(460393269, 320620315), o(685471733, 587496836), o(852142971, 1086792851), o(1017036298, 365543100), o(1126000580, 2618297676), o(1288033470, 3409855158), o(1501505948, 4234509866), o(1607167915, 987167468), o(1816402316, 1246189591)], e1 = []; !function () { for (var t = 0; t < 80; t++)e1[t] = o() }(); r = r.SHA512 = e.extend({ _doReset: function () { this._hash = new n.init([new i.init(1779033703, 4089235720), new i.init(3144134277, 2227873595), new i.init(1013904242, 4271175723), new i.init(2773480762, 1595750129), new i.init(1359893119, 2917565137), new i.init(2600822924, 725511199), new i.init(528734635, 4215389547), new i.init(1541459225, 327033209)]) }, _doProcessBlock: function (t, e) { for (var r = this._hash.words, i = r[0], n = r[1], o = r[2], s = r[3], c = r[4], a = r[5], h = r[6], l = r[7], f = i.high, d = i.low, u = n.high, p = n.low, _ = o.high, y = o.low, v = s.high, g = s.low, B = c.high, w = c.low, k = a.high, m = a.low, S = h.high, x = h.low, b = l.high, r = l.low, A = f, H = d, z = u, C = p, D = _, E = y, R = v, M = g, F = B, P = w, W = k, O = m, I = S, U = x, K = b, X = r, L = 0; L < 80; L++) { var j, T, N = e1[L]; L < 16 ? (T = N.high = 0 | t[e + 2 * L], j = N.low = 0 | t[e + 2 * L + 1]) : ($ = (q = e1[L - 15]).high, J = q.low, G = (Q = e1[L - 2]).high, V = Q.low, Z = (Y = e1[L - 7]).high, q = Y.low, Y = (Q = e1[L - 16]).high, T = (T = (($ >>> 1 | J << 31) ^ ($ >>> 8 | J << 24) ^ $ >>> 7) + Z + ((j = (Z = (J >>> 1 | $ << 31) ^ (J >>> 8 | $ << 24) ^ (J >>> 7 | $ << 25)) + q) >>> 0 < Z >>> 0 ? 1 : 0)) + ((G >>> 19 | V << 13) ^ (G << 3 | V >>> 29) ^ G >>> 6) + ((j += J = (V >>> 19 | G << 13) ^ (V << 3 | G >>> 29) ^ (V >>> 6 | G << 26)) >>> 0 < J >>> 0 ? 1 : 0), j += $ = Q.low, N.high = T = T + Y + (j >>> 0 < $ >>> 0 ? 1 : 0), N.low = j); var q = F & W ^ ~F & I, Z = P & O ^ ~P & U, V = A & z ^ A & D ^ z & D, G = (H >>> 28 | A << 4) ^ (H << 30 | A >>> 2) ^ (H << 25 | A >>> 7), J = t1[L], Q = J.high, Y = J.low, $ = X + ((P >>> 14 | F << 18) ^ (P >>> 18 | F << 14) ^ (P << 23 | F >>> 9)), N = K + ((F >>> 14 | P << 18) ^ (F >>> 18 | P << 14) ^ (F << 23 | P >>> 9)) + ($ >>> 0 < X >>> 0 ? 1 : 0), J = G + (H & C ^ H & E ^ C & E), K = I, X = U, I = W, U = O, W = F, O = P, F = R + (N = (N = (N = N + q + (($ = $ + Z) >>> 0 < Z >>> 0 ? 1 : 0)) + Q + (($ = $ + Y) >>> 0 < Y >>> 0 ? 1 : 0)) + T + (($ = $ + j) >>> 0 < j >>> 0 ? 1 : 0)) + ((P = M + $ | 0) >>> 0 < M >>> 0 ? 1 : 0) | 0, R = D, M = E, D = z, E = C, z = A, C = H, A = N + (((A >>> 28 | H << 4) ^ (A << 30 | H >>> 2) ^ (A << 25 | H >>> 7)) + V + (J >>> 0 < G >>> 0 ? 1 : 0)) + ((H = $ + J | 0) >>> 0 < $ >>> 0 ? 1 : 0) | 0 } d = i.low = d + H, i.high = f + A + (d >>> 0 < H >>> 0 ? 1 : 0), p = n.low = p + C, n.high = u + z + (p >>> 0 < C >>> 0 ? 1 : 0), y = o.low = y + E, o.high = _ + D + (y >>> 0 < E >>> 0 ? 1 : 0), g = s.low = g + M, s.high = v + R + (g >>> 0 < M >>> 0 ? 1 : 0), w = c.low = w + P, c.high = B + F + (w >>> 0 < P >>> 0 ? 1 : 0), m = a.low = m + O, a.high = k + W + (m >>> 0 < O >>> 0 ? 1 : 0), x = h.low = x + U, h.high = S + I + (x >>> 0 < U >>> 0 ? 1 : 0), r = l.low = r + X, l.high = b + K + (r >>> 0 < X >>> 0 ? 1 : 0) }, _doFinalize: function () { var t = this._data, e = t.words, r = 8 * this._nDataBytes, i = 8 * t.sigBytes; return e[i >>> 5] |= 128 << 24 - i % 32, e[30 + (128 + i >>> 10 << 5)] = Math.floor(r / 4294967296), e[31 + (128 + i >>> 10 << 5)] = r, t.sigBytes = 4 * e.length, this._process(), this._hash.toX32() }, clone: function () { var t = e.clone.call(this); return t._hash = this._hash.clone(), t }, blockSize: 32 }); t.SHA512 = e._createHelper(r), t.HmacSHA512 = e._createHmacHelper(r) }(), P = (M = U).x64, c = P.Word, f = P.WordArray, P = M.algo, d = P.SHA512, P = P.SHA384 = d.extend({ _doReset: function () { this._hash = new f.init([new c.init(3418070365, 3238371032), new c.init(1654270250, 914150663), new c.init(2438529370, 812702999), new c.init(355462360, 4144912697), new c.init(1731405415, 4290775857), new c.init(2394180231, 1750603025), new c.init(3675008525, 1694076839), new c.init(1203062813, 3204075428)]) }, _doFinalize: function () { var t = d._doFinalize.call(this); return t.sigBytes -= 16, t } }), M.SHA384 = d._createHelper(P), M.HmacSHA384 = d._createHmacHelper(P), function (l) { var t = U, e = t.lib, f = e.WordArray, i = e.Hasher, d = t.x64.Word, e = t.algo, A = [], H = [], z = []; !function () { for (var t = 1, e = 0, r = 0; r < 24; r++) { A[t + 5 * e] = (r + 1) * (r + 2) / 2 % 64; var i = (2 * t + 3 * e) % 5; t = e % 5, e = i } for (t = 0; t < 5; t++)for (e = 0; e < 5; e++)H[t + 5 * e] = e + (2 * t + 3 * e) % 5 * 5; for (var n = 1, o = 0; o < 24; o++) { for (var s, c = 0, a = 0, h = 0; h < 7; h++)1 & n && ((s = (1 << h) - 1) < 32 ? a ^= 1 << s : c ^= 1 << s - 32), 128 & n ? n = n << 1 ^ 113 : n <<= 1; z[o] = d.create(c, a) } }(); var C = []; !function () { for (var t = 0; t < 25; t++)C[t] = d.create() }(); e = e.SHA3 = i.extend({ cfg: i.cfg.extend({ outputLength: 512 }), _doReset: function () { for (var t = this._state = [], e = 0; e < 25; e++)t[e] = new d.init; this.blockSize = (1600 - 2 * this.cfg.outputLength) / 32 }, _doProcessBlock: function (t, e) { for (var r = this._state, i = this.blockSize / 2, n = 0; n < i; n++) { var o = t[e + 2 * n], s = t[e + 2 * n + 1], o = 16711935 & (o << 8 | o >>> 24) | 4278255360 & (o << 24 | o >>> 8); (m = r[n]).high ^= s = 16711935 & (s << 8 | s >>> 24) | 4278255360 & (s << 24 | s >>> 8), m.low ^= o } for (var c = 0; c < 24; c++) { for (var a = 0; a < 5; a++) { for (var h = 0, l = 0, f = 0; f < 5; f++)h ^= (m = r[a + 5 * f]).high, l ^= m.low; var d = C[a]; d.high = h, d.low = l } for (a = 0; a < 5; a++)for (var u = C[(a + 4) % 5], p = C[(a + 1) % 5], _ = p.high, p = p.low, h = u.high ^ (_ << 1 | p >>> 31), l = u.low ^ (p << 1 | _ >>> 31), f = 0; f < 5; f++)(m = r[a + 5 * f]).high ^= h, m.low ^= l; for (var y = 1; y < 25; y++) { var v = (m = r[y]).high, g = m.low, B = A[y]; l = B < 32 ? (h = v << B | g >>> 32 - B, g << B | v >>> 32 - B) : (h = g << B - 32 | v >>> 64 - B, v << B - 32 | g >>> 64 - B); B = C[H[y]]; B.high = h, B.low = l } var w = C[0], k = r[0]; w.high = k.high, w.low = k.low; for (a = 0; a < 5; a++)for (f = 0; f < 5; f++) { var m = r[y = a + 5 * f], S = C[y], x = C[(a + 1) % 5 + 5 * f], b = C[(a + 2) % 5 + 5 * f]; m.high = S.high ^ ~x.high & b.high, m.low = S.low ^ ~x.low & b.low } m = r[0], k = z[c]; m.high ^= k.high, m.low ^= k.low } }, _doFinalize: function () { var t = this._data, e = t.words, r = (this._nDataBytes, 8 * t.sigBytes), i = 32 * this.blockSize; e[r >>> 5] |= 1 << 24 - r % 32, e[(l.ceil((1 + r) / i) * i >>> 5) - 1] |= 128, t.sigBytes = 4 * e.length, this._process(); for (var n = this._state, e = this.cfg.outputLength / 8, o = e / 8, s = [], c = 0; c < o; c++) { var a = n[c], h = a.high, a = a.low, h = 16711935 & (h << 8 | h >>> 24) | 4278255360 & (h << 24 | h >>> 8); s.push(a = 16711935 & (a << 8 | a >>> 24) | 4278255360 & (a << 24 | a >>> 8)), s.push(h) } return new f.init(s, e) }, clone: function () { for (var t = i.clone.call(this), e = t._state = this._state.slice(0), r = 0; r < 25; r++)e[r] = e[r].clone(); return t } }); t.SHA3 = i._createHelper(e), t.HmacSHA3 = i._createHmacHelper(e) }(Math), Math, F = (w = U).lib, u = F.WordArray, p = F.Hasher, F = w.algo, S = u.create([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13]), x = u.create([5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11]), b = u.create([11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6]), A = u.create([8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11]), H = u.create([0, 1518500249, 1859775393, 2400959708, 2840853838]), z = u.create([1352829926, 1548603684, 1836072691, 2053994217, 0]), F = F.RIPEMD160 = p.extend({ _doReset: function () { this._hash = u.create([1732584193, 4023233417, 2562383102, 271733878, 3285377520]) }, _doProcessBlock: function (t, e) { for (var r = 0; r < 16; r++) { var i = e + r, n = t[i]; t[i] = 16711935 & (n << 8 | n >>> 24) | 4278255360 & (n << 24 | n >>> 8) } for (var o, s, c, a, h, l, f = this._hash.words, d = H.words, u = z.words, p = S.words, _ = x.words, y = b.words, v = A.words, g = o = f[0], B = s = f[1], w = c = f[2], k = a = f[3], m = h = f[4], r = 0; r < 80; r += 1)l = o + t[e + p[r]] | 0, l += r < 16 ? (s ^ c ^ a) + d[0] : r < 32 ? K(s, c, a) + d[1] : r < 48 ? ((s | ~c) ^ a) + d[2] : r < 64 ? X(s, c, a) + d[3] : (s ^ (c | ~a)) + d[4], l = (l = L(l |= 0, y[r])) + h | 0, o = h, h = a, a = L(c, 10), c = s, s = l, l = g + t[e + _[r]] | 0, l += r < 16 ? (B ^ (w | ~k)) + u[0] : r < 32 ? X(B, w, k) + u[1] : r < 48 ? ((B | ~w) ^ k) + u[2] : r < 64 ? K(B, w, k) + u[3] : (B ^ w ^ k) + u[4], l = (l = L(l |= 0, v[r])) + m | 0, g = m, m = k, k = L(w, 10), w = B, B = l; l = f[1] + c + k | 0, f[1] = f[2] + a + m | 0, f[2] = f[3] + h + g | 0, f[3] = f[4] + o + B | 0, f[4] = f[0] + s + w | 0, f[0] = l }, _doFinalize: function () { var t = this._data, e = t.words, r = 8 * this._nDataBytes, i = 8 * t.sigBytes; e[i >>> 5] |= 128 << 24 - i % 32, e[14 + (64 + i >>> 9 << 4)] = 16711935 & (r << 8 | r >>> 24) | 4278255360 & (r << 24 | r >>> 8), t.sigBytes = 4 * (e.length + 1), this._process(); for (var e = this._hash, n = e.words, o = 0; o < 5; o++) { var s = n[o]; n[o] = 16711935 & (s << 8 | s >>> 24) | 4278255360 & (s << 24 | s >>> 8) } return e }, clone: function () { var t = p.clone.call(this); return t._hash = this._hash.clone(), t } }), w.RIPEMD160 = p._createHelper(F), w.HmacRIPEMD160 = p._createHmacHelper(F), P = (M = U).lib.Base, _ = M.enc.Utf8, M.algo.HMAC = P.extend({ init: function (t, e) { t = this._hasher = new t.init, "string" == typeof e && (e = _.parse(e)); var r = t.blockSize, i = 4 * r; (e = e.sigBytes > i ? t.finalize(e) : e).clamp(); for (var t = this._oKey = e.clone(), e = this._iKey = e.clone(), n = t.words, o = e.words, s = 0; s < r; s++)n[s] ^= 1549556828, o[s] ^= 909522486; t.sigBytes = e.sigBytes = i, this.reset() }, reset: function () { var t = this._hasher; t.reset(), t.update(this._iKey) }, update: function (t) { return this._hasher.update(t), this }, finalize: function (t) { var e = this._hasher, t = e.finalize(t); return e.reset(), e.finalize(this._oKey.clone().concat(t)) } }), F = (w = U).lib, M = F.Base, v = F.WordArray, P = w.algo, F = P.SHA1, g = P.HMAC, y = P.PBKDF2 = M.extend({ cfg: M.extend({ keySize: 4, hasher: F, iterations: 1 }), init: function (t) { this.cfg = this.cfg.extend(t) }, compute: function (t, e) { for (var r = this.cfg, i = g.create(r.hasher, t), n = v.create(), o = v.create([1]), s = n.words, c = o.words, a = r.keySize, h = r.iterations; s.length < a;) { var l = i.update(e).finalize(o); i.reset(); for (var f = l.words, d = f.length, u = l, p = 1; p < h; p++) { u = i.finalize(u), i.reset(); for (var _ = u.words, y = 0; y < d; y++)f[y] ^= _[y] } n.concat(l), c[0]++ } return n.sigBytes = 4 * a, n } }), w.PBKDF2 = function (t, e, r) { return y.create(r).compute(t, e) }, M = (P = U).lib, F = M.Base, B = M.WordArray, w = P.algo, M = w.MD5, k = w.EvpKDF = F.extend({ cfg: F.extend({ keySize: 4, hasher: M, iterations: 1 }), init: function (t) { this.cfg = this.cfg.extend(t) }, compute: function (t, e) { for (var r, i = this.cfg, n = i.hasher.create(), o = B.create(), s = o.words, c = i.keySize, a = i.iterations; s.length < c;) { r && n.update(r), r = n.update(t).finalize(e), n.reset(); for (var h = 1; h < a; h++)r = n.finalize(r), n.reset(); o.concat(r) } return o.sigBytes = 4 * c, o } }), P.EvpKDF = function (t, e, r) { return k.create(r).compute(t, e) }, U.lib.Cipher || function () { var t = U, e = t.lib, r = e.Base, s = e.WordArray, i = e.BufferedBlockAlgorithm, n = t.enc, o = (n.Utf8, n.Base64), c = t.algo.EvpKDF, a = e.Cipher = i.extend({ cfg: r.extend(), createEncryptor: function (t, e) { return this.create(this._ENC_XFORM_MODE, t, e) }, createDecryptor: function (t, e) { return this.create(this._DEC_XFORM_MODE, t, e) }, init: function (t, e, r) { this.cfg = this.cfg.extend(r), this._xformMode = t, this._key = e, this.reset() }, reset: function () { i.reset.call(this), this._doReset() }, process: function (t) { return this._append(t), this._process() }, finalize: function (t) { return t && this._append(t), this._doFinalize() }, keySize: 4, ivSize: 4, _ENC_XFORM_MODE: 1, _DEC_XFORM_MODE: 2, _createHelper: function (i) { return { encrypt: function (t, e, r) { return h(e).encrypt(i, t, e, r) }, decrypt: function (t, e, r) { return h(e).decrypt(i, t, e, r) } } } }); function h(t) { return "string" == typeof t ? p : u } e.StreamCipher = a.extend({ _doFinalize: function () { return this._process(!0) }, blockSize: 1 }); var l = t.mode = {}, n = e.BlockCipherMode = r.extend({ createEncryptor: function (t, e) { return this.Encryptor.create(t, e) }, createDecryptor: function (t, e) { return this.Decryptor.create(t, e) }, init: function (t, e) { this._cipher = t, this._iv = e } }), n = l.CBC = ((l = n.extend()).Encryptor = l.extend({ processBlock: function (t, e) { var r = this._cipher, i = r.blockSize; f.call(this, t, e, i), r.encryptBlock(t, e), this._prevBlock = t.slice(e, e + i) } }), l.Decryptor = l.extend({ processBlock: function (t, e) { var r = this._cipher, i = r.blockSize, n = t.slice(e, e + i); r.decryptBlock(t, e), f.call(this, t, e, i), this._prevBlock = n } }), l); function f(t, e, r) { var i, n = this._iv; n ? (i = n, this._iv = void 0) : i = this._prevBlock; for (var o = 0; o < r; o++)t[e + o] ^= i[o] } var l = (t.pad = {}).Pkcs7 = { pad: function (t, e) { for (var e = 4 * e, r = e - t.sigBytes % e, i = r << 24 | r << 16 | r << 8 | r, n = [], o = 0; o < r; o += 4)n.push(i); e = s.create(n, r); t.concat(e) }, unpad: function (t) { var e = 255 & t.words[t.sigBytes - 1 >>> 2]; t.sigBytes -= e } }, d = (e.BlockCipher = a.extend({ cfg: a.cfg.extend({ mode: n, padding: l }), reset: function () { var t; a.reset.call(this); var e = this.cfg, r = e.iv, e = e.mode; this._xformMode == this._ENC_XFORM_MODE ? t = e.createEncryptor : (t = e.createDecryptor, this._minBufferSize = 1), this._mode && this._mode.__creator == t ? this._mode.init(this, r && r.words) : (this._mode = t.call(e, this, r && r.words), this._mode.__creator = t) }, _doProcessBlock: function (t, e) { this._mode.processBlock(t, e) }, _doFinalize: function () { var t, e = this.cfg.padding; return this._xformMode == this._ENC_XFORM_MODE ? (e.pad(this._data, this.blockSize), t = this._process(!0)) : (t = this._process(!0), e.unpad(t)), t }, blockSize: 4 }), e.CipherParams = r.extend({ init: function (t) { this.mixIn(t) }, toString: function (t) { return (t || this.formatter).stringify(this) } })), l = (t.format = {}).OpenSSL = { stringify: function (t) { var e = t.ciphertext, t = t.salt, e = t ? s.create([1398893684, 1701076831]).concat(t).concat(e) : e; return e.toString(o) }, parse: function (t) { var e, r = o.parse(t), t = r.words; return 1398893684 == t[0] && 1701076831 == t[1] && (e = s.create(t.slice(2, 4)), t.splice(0, 4), r.sigBytes -= 16), d.create({ ciphertext: r, salt: e }) } }, u = e.SerializableCipher = r.extend({ cfg: r.extend({ format: l }), encrypt: function (t, e, r, i) { i = this.cfg.extend(i); var n = t.createEncryptor(r, i), e = n.finalize(e), n = n.cfg; return d.create({ ciphertext: e, key: r, iv: n.iv, algorithm: t, mode: n.mode, padding: n.padding, blockSize: t.blockSize, formatter: i.format }) }, decrypt: function (t, e, r, i) { return i = this.cfg.extend(i), e = this._parse(e, i.format), t.createDecryptor(r, i).finalize(e.ciphertext) }, _parse: function (t, e) { return "string" == typeof t ? e.parse(t, this) : t } }), t = (t.kdf = {}).OpenSSL = { execute: function (t, e, r, i) { i = i || s.random(8); t = c.create({ keySize: e + r }).compute(t, i), r = s.create(t.words.slice(e), 4 * r); return t.sigBytes = 4 * e, d.create({ key: t, iv: r, salt: i }) } }, p = e.PasswordBasedCipher = u.extend({ cfg: u.cfg.extend({ kdf: t }), encrypt: function (t, e, r, i) { r = (i = this.cfg.extend(i)).kdf.execute(r, t.keySize, t.ivSize); i.iv = r.iv; i = u.encrypt.call(this, t, e, r.key, i); return i.mixIn(r), i }, decrypt: function (t, e, r, i) { i = this.cfg.extend(i), e = this._parse(e, i.format); r = i.kdf.execute(r, t.keySize, t.ivSize, e.salt); return i.iv = r.iv, u.decrypt.call(this, t, e, r.key, i) } }) }(), U.mode.CFB = ((F = U.lib.BlockCipherMode.extend()).Encryptor = F.extend({ processBlock: function (t, e) { var r = this._cipher, i = r.blockSize; j.call(this, t, e, i, r), this._prevBlock = t.slice(e, e + i) } }), F.Decryptor = F.extend({ processBlock: function (t, e) { var r = this._cipher, i = r.blockSize, n = t.slice(e, e + i); j.call(this, t, e, i, r), this._prevBlock = n } }), F), U.mode.CTR = (M = U.lib.BlockCipherMode.extend(), P = M.Encryptor = M.extend({ processBlock: function (t, e) { var r = this._cipher, i = r.blockSize, n = this._iv, o = this._counter; n && (o = this._counter = n.slice(0), this._iv = void 0); var s = o.slice(0); r.encryptBlock(s, 0), o[i - 1] = o[i - 1] + 1 | 0; for (var c = 0; c < i; c++)t[e + c] ^= s[c] } }), M.Decryptor = P, M), U.mode.CTRGladman = (F = U.lib.BlockCipherMode.extend(), P = F.Encryptor = F.extend({ processBlock: function (t, e) { var r = this._cipher, i = r.blockSize, n = this._iv, o = this._counter; n && (o = this._counter = n.slice(0), this._iv = void 0), 0 === ((n = o)[0] = T(n[0])) && (n[1] = T(n[1])); var s = o.slice(0); r.encryptBlock(s, 0); for (var c = 0; c < i; c++)t[e + c] ^= s[c] } }), F.Decryptor = P, F), U.mode.OFB = (M = U.lib.BlockCipherMode.extend(), P = M.Encryptor = M.extend({ processBlock: function (t, e) { var r = this._cipher, i = r.blockSize, n = this._iv, o = this._keystream; n && (o = this._keystream = n.slice(0), this._iv = void 0), r.encryptBlock(o, 0); for (var s = 0; s < i; s++)t[e + s] ^= o[s] } }), M.Decryptor = P, M), U.mode.ECB = ((F = U.lib.BlockCipherMode.extend()).Encryptor = F.extend({ processBlock: function (t, e) { this._cipher.encryptBlock(t, e) } }), F.Decryptor = F.extend({ processBlock: function (t, e) { this._cipher.decryptBlock(t, e) } }), F), U.pad.AnsiX923 = { pad: function (t, e) { var r = t.sigBytes, e = 4 * e, e = e - r % e, r = r + e - 1; t.clamp(), t.words[r >>> 2] |= e << 24 - r % 4 * 8, t.sigBytes += e }, unpad: function (t) { var e = 255 & t.words[t.sigBytes - 1 >>> 2]; t.sigBytes -= e } }, U.pad.Iso10126 = { pad: function (t, e) { e *= 4, e -= t.sigBytes % e; t.concat(U.lib.WordArray.random(e - 1)).concat(U.lib.WordArray.create([e << 24], 1)) }, unpad: function (t) { var e = 255 & t.words[t.sigBytes - 1 >>> 2]; t.sigBytes -= e } }, U.pad.Iso97971 = { pad: function (t, e) { t.concat(U.lib.WordArray.create([2147483648], 1)), U.pad.ZeroPadding.pad(t, e) }, unpad: function (t) { U.pad.ZeroPadding.unpad(t), t.sigBytes-- } }, U.pad.ZeroPadding = { pad: function (t, e) { e *= 4; t.clamp(), t.sigBytes += e - (t.sigBytes % e || e) }, unpad: function (t) { for (var e = t.words, r = t.sigBytes - 1, r = t.sigBytes - 1; 0 <= r; r--)if (e[r >>> 2] >>> 24 - r % 4 * 8 & 255) { t.sigBytes = r + 1; break } } }, U.pad.NoPadding = { pad: function () { }, unpad: function () { } }, m = (P = U).lib.CipherParams, C = P.enc.Hex, P.format.Hex = { stringify: function (t) { return t.ciphertext.toString(C) }, parse: function (t) { t = C.parse(t); return m.create({ ciphertext: t }) } }, function () { var t = U, e = t.lib.BlockCipher, r = t.algo, h = [], l = [], f = [], d = [], u = [], p = [], _ = [], y = [], v = [], g = []; !function () { for (var t = [], e = 0; e < 256; e++)t[e] = e < 128 ? e << 1 : e << 1 ^ 283; for (var r = 0, i = 0, e = 0; e < 256; e++) { var n = i ^ i << 1 ^ i << 2 ^ i << 3 ^ i << 4; h[r] = n = n >>> 8 ^ 255 & n ^ 99; var o = t[l[n] = r], s = t[o], c = t[s], a = 257 * t[n] ^ 16843008 * n; f[r] = a << 24 | a >>> 8, d[r] = a << 16 | a >>> 16, u[r] = a << 8 | a >>> 24, p[r] = a, _[n] = (a = 16843009 * c ^ 65537 * s ^ 257 * o ^ 16843008 * r) << 24 | a >>> 8, y[n] = a << 16 | a >>> 16, v[n] = a << 8 | a >>> 24, g[n] = a, r ? (r = o ^ t[t[t[c ^ o]]], i ^= t[t[i]]) : r = i = 1 } }(); var B = [0, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54], r = r.AES = e.extend({ _doReset: function () { if (!this._nRounds || this._keyPriorReset !== this._key) { for (var t = this._keyPriorReset = this._key, e = t.words, r = t.sigBytes / 4, i = 4 * (1 + (this._nRounds = 6 + r)), n = this._keySchedule = [], o = 0; o < i; o++)o < r ? n[o] = e[o] : (a = n[o - 1], o % r ? 6 < r && o % r == 4 && (a = h[a >>> 24] << 24 | h[a >>> 16 & 255] << 16 | h[a >>> 8 & 255] << 8 | h[255 & a]) : (a = h[(a = a << 8 | a >>> 24) >>> 24] << 24 | h[a >>> 16 & 255] << 16 | h[a >>> 8 & 255] << 8 | h[255 & a], a ^= B[o / r | 0] << 24), n[o] = n[o - r] ^ a); for (var s = this._invKeySchedule = [], c = 0; c < i; c++) { var a, o = i - c; a = c % 4 ? n[o] : n[o - 4], s[c] = c < 4 || o <= 4 ? a : _[h[a >>> 24]] ^ y[h[a >>> 16 & 255]] ^ v[h[a >>> 8 & 255]] ^ g[h[255 & a]] } } }, encryptBlock: function (t, e) { this._doCryptBlock(t, e, this._keySchedule, f, d, u, p, h) }, decryptBlock: function (t, e) { var r = t[e + 1]; t[e + 1] = t[e + 3], t[e + 3] = r, this._doCryptBlock(t, e, this._invKeySchedule, _, y, v, g, l); r = t[e + 1]; t[e + 1] = t[e + 3], t[e + 3] = r }, _doCryptBlock: function (t, e, r, i, n, o, s, c) { for (var a = this._nRounds, h = t[e] ^ r[0], l = t[e + 1] ^ r[1], f = t[e + 2] ^ r[2], d = t[e + 3] ^ r[3], u = 4, p = 1; p < a; p++)var _ = i[h >>> 24] ^ n[l >>> 16 & 255] ^ o[f >>> 8 & 255] ^ s[255 & d] ^ r[u++], y = i[l >>> 24] ^ n[f >>> 16 & 255] ^ o[d >>> 8 & 255] ^ s[255 & h] ^ r[u++], v = i[f >>> 24] ^ n[d >>> 16 & 255] ^ o[h >>> 8 & 255] ^ s[255 & l] ^ r[u++], g = i[d >>> 24] ^ n[h >>> 16 & 255] ^ o[l >>> 8 & 255] ^ s[255 & f] ^ r[u++], h = _, l = y, f = v, d = g; _ = (c[h >>> 24] << 24 | c[l >>> 16 & 255] << 16 | c[f >>> 8 & 255] << 8 | c[255 & d]) ^ r[u++], y = (c[l >>> 24] << 24 | c[f >>> 16 & 255] << 16 | c[d >>> 8 & 255] << 8 | c[255 & h]) ^ r[u++], v = (c[f >>> 24] << 24 | c[d >>> 16 & 255] << 16 | c[h >>> 8 & 255] << 8 | c[255 & l]) ^ r[u++], g = (c[d >>> 24] << 24 | c[h >>> 16 & 255] << 16 | c[l >>> 8 & 255] << 8 | c[255 & f]) ^ r[u++]; t[e] = _, t[e + 1] = y, t[e + 2] = v, t[e + 3] = g }, keySize: 8 }); t.AES = e._createHelper(r) }(), function () { var t = U, e = t.lib, i = e.WordArray, r = e.BlockCipher, e = t.algo, h = [57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4], l = [14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32], f = [1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28], d = [{ 0: 8421888, 268435456: 32768, 536870912: 8421378, 805306368: 2, 1073741824: 512, 1342177280: 8421890, 1610612736: 8389122, 1879048192: 8388608, 2147483648: 514, 2415919104: 8389120, 2684354560: 33280, 2952790016: 8421376, 3221225472: 32770, 3489660928: 8388610, 3758096384: 0, 4026531840: 33282, 134217728: 0, 402653184: 8421890, 671088640: 33282, 939524096: 32768, 1207959552: 8421888, 1476395008: 512, 1744830464: 8421378, 2013265920: 2, 2281701376: 8389120, 2550136832: 33280, 2818572288: 8421376, 3087007744: 8389122, 3355443200: 8388610, 3623878656: 32770, 3892314112: 514, 4160749568: 8388608, 1: 32768, 268435457: 2, 536870913: 8421888, 805306369: 8388608, 1073741825: 8421378, 1342177281: 33280, 1610612737: 512, 1879048193: 8389122, 2147483649: 8421890, 2415919105: 8421376, 2684354561: 8388610, 2952790017: 33282, 3221225473: 514, 3489660929: 8389120, 3758096385: 32770, 4026531841: 0, 134217729: 8421890, 402653185: 8421376, 671088641: 8388608, 939524097: 512, 1207959553: 32768, 1476395009: 8388610, 1744830465: 2, 2013265921: 33282, 2281701377: 32770, 2550136833: 8389122, 2818572289: 514, 3087007745: 8421888, 3355443201: 8389120, 3623878657: 0, 3892314113: 33280, 4160749569: 8421378 }, { 0: 1074282512, 16777216: 16384, 33554432: 524288, 50331648: 1074266128, 67108864: 1073741840, 83886080: 1074282496, 100663296: 1073758208, 117440512: 16, 134217728: 540672, 150994944: 1073758224, 167772160: 1073741824, 184549376: 540688, 201326592: 524304, 218103808: 0, 234881024: 16400, 251658240: 1074266112, 8388608: 1073758208, 25165824: 540688, 41943040: 16, 58720256: 1073758224, 75497472: 1074282512, 92274688: 1073741824, 109051904: 524288, 125829120: 1074266128, 142606336: 524304, 159383552: 0, 176160768: 16384, 192937984: 1074266112, 209715200: 1073741840, 226492416: 540672, 243269632: 1074282496, 260046848: 16400, 268435456: 0, 285212672: 1074266128, 301989888: 1073758224, 318767104: 1074282496, 335544320: 1074266112, 352321536: 16, 369098752: 540688, 385875968: 16384, 402653184: 16400, 419430400: 524288, 436207616: 524304, 452984832: 1073741840, 469762048: 540672, 486539264: 1073758208, 503316480: 1073741824, 520093696: 1074282512, 276824064: 540688, 293601280: 524288, 310378496: 1074266112, 327155712: 16384, 343932928: 1073758208, 360710144: 1074282512, 377487360: 16, 394264576: 1073741824, 411041792: 1074282496, 427819008: 1073741840, 444596224: 1073758224, 461373440: 524304, 478150656: 0, 494927872: 16400, 511705088: 1074266128, 528482304: 540672 }, { 0: 260, 1048576: 0, 2097152: 67109120, 3145728: 65796, 4194304: 65540, 5242880: 67108868, 6291456: 67174660, 7340032: 67174400, 8388608: 67108864, 9437184: 67174656, 10485760: 65792, 11534336: 67174404, 12582912: 67109124, 13631488: 65536, 14680064: 4, 15728640: 256, 524288: 67174656, 1572864: 67174404, 2621440: 0, 3670016: 67109120, 4718592: 67108868, 5767168: 65536, 6815744: 65540, 7864320: 260, 8912896: 4, 9961472: 256, 11010048: 67174400, 12058624: 65796, 13107200: 65792, 14155776: 67109124, 15204352: 67174660, 16252928: 67108864, 16777216: 67174656, 17825792: 65540, 18874368: 65536, 19922944: 67109120, 20971520: 256, 22020096: 67174660, 23068672: 67108868, 24117248: 0, 25165824: 67109124, 26214400: 67108864, 27262976: 4, 28311552: 65792, 29360128: 67174400, 30408704: 260, 31457280: 65796, 32505856: 67174404, 17301504: 67108864, 18350080: 260, 19398656: 67174656, 20447232: 0, 21495808: 65540, 22544384: 67109120, 23592960: 256, 24641536: 67174404, 25690112: 65536, 26738688: 67174660, 27787264: 65796, 28835840: 67108868, 29884416: 67109124, 30932992: 67174400, 31981568: 4, 33030144: 65792 }, { 0: 2151682048, 65536: 2147487808, 131072: 4198464, 196608: 2151677952, 262144: 0, 327680: 4198400, 393216: 2147483712, 458752: 4194368, 524288: 2147483648, 589824: 4194304, 655360: 64, 720896: 2147487744, 786432: 2151678016, 851968: 4160, 917504: 4096, 983040: 2151682112, 32768: 2147487808, 98304: 64, 163840: 2151678016, 229376: 2147487744, 294912: 4198400, 360448: 2151682112, 425984: 0, 491520: 2151677952, 557056: 4096, 622592: 2151682048, 688128: 4194304, 753664: 4160, 819200: 2147483648, 884736: 4194368, 950272: 4198464, 1015808: 2147483712, 1048576: 4194368, 1114112: 4198400, 1179648: 2147483712, 1245184: 0, 1310720: 4160, 1376256: 2151678016, 1441792: 2151682048, 1507328: 2147487808, 1572864: 2151682112, 1638400: 2147483648, 1703936: 2151677952, 1769472: 4198464, 1835008: 2147487744, 1900544: 4194304, 1966080: 64, 2031616: 4096, 1081344: 2151677952, 1146880: 2151682112, 1212416: 0, 1277952: 4198400, 1343488: 4194368, 1409024: 2147483648, 1474560: 2147487808, 1540096: 64, 1605632: 2147483712, 1671168: 4096, 1736704: 2147487744, 1802240: 2151678016, 1867776: 4160, 1933312: 2151682048, 1998848: 4194304, 2064384: 4198464 }, { 0: 128, 4096: 17039360, 8192: 262144, 12288: 536870912, 16384: 537133184, 20480: 16777344, 24576: 553648256, 28672: 262272, 32768: 16777216, 36864: 537133056, 40960: 536871040, 45056: 553910400, 49152: 553910272, 53248: 0, 57344: 17039488, 61440: 553648128, 2048: 17039488, 6144: 553648256, 10240: 128, 14336: 17039360, 18432: 262144, 22528: 537133184, 26624: 553910272, 30720: 536870912, 34816: 537133056, 38912: 0, 43008: 553910400, 47104: 16777344, 51200: 536871040, 55296: 553648128, 59392: 16777216, 63488: 262272, 65536: 262144, 69632: 128, 73728: 536870912, 77824: 553648256, 81920: 16777344, 86016: 553910272, 90112: 537133184, 94208: 16777216, 98304: 553910400, 102400: 553648128, 106496: 17039360, 110592: 537133056, 114688: 262272, 118784: 536871040, 122880: 0, 126976: 17039488, 67584: 553648256, 71680: 16777216, 75776: 17039360, 79872: 537133184, 83968: 536870912, 88064: 17039488, 92160: 128, 96256: 553910272, 100352: 262272, 104448: 553910400, 108544: 0, 112640: 553648128, 116736: 16777344, 120832: 262144, 124928: 537133056, 129024: 536871040 }, { 0: 268435464, 256: 8192, 512: 270532608, 768: 270540808, 1024: 268443648, 1280: 2097152, 1536: 2097160, 1792: 268435456, 2048: 0, 2304: 268443656, 2560: 2105344, 2816: 8, 3072: 270532616, 3328: 2105352, 3584: 8200, 3840: 270540800, 128: 270532608, 384: 270540808, 640: 8, 896: 2097152, 1152: 2105352, 1408: 268435464, 1664: 268443648, 1920: 8200, 2176: 2097160, 2432: 8192, 2688: 268443656, 2944: 270532616, 3200: 0, 3456: 270540800, 3712: 2105344, 3968: 268435456, 4096: 268443648, 4352: 270532616, 4608: 270540808, 4864: 8200, 5120: 2097152, 5376: 268435456, 5632: 268435464, 5888: 2105344, 6144: 2105352, 6400: 0, 6656: 8, 6912: 270532608, 7168: 8192, 7424: 268443656, 7680: 270540800, 7936: 2097160, 4224: 8, 4480: 2105344, 4736: 2097152, 4992: 268435464, 5248: 268443648, 5504: 8200, 5760: 270540808, 6016: 270532608, 6272: 270540800, 6528: 270532616, 6784: 8192, 7040: 2105352, 7296: 2097160, 7552: 0, 7808: 268435456, 8064: 268443656 }, { 0: 1048576, 16: 33555457, 32: 1024, 48: 1049601, 64: 34604033, 80: 0, 96: 1, 112: 34603009, 128: 33555456, 144: 1048577, 160: 33554433, 176: 34604032, 192: 34603008, 208: 1025, 224: 1049600, 240: 33554432, 8: 34603009, 24: 0, 40: 33555457, 56: 34604032, 72: 1048576, 88: 33554433, 104: 33554432, 120: 1025, 136: 1049601, 152: 33555456, 168: 34603008, 184: 1048577, 200: 1024, 216: 34604033, 232: 1, 248: 1049600, 256: 33554432, 272: 1048576, 288: 33555457, 304: 34603009, 320: 1048577, 336: 33555456, 352: 34604032, 368: 1049601, 384: 1025, 400: 34604033, 416: 1049600, 432: 1, 448: 0, 464: 34603008, 480: 33554433, 496: 1024, 264: 1049600, 280: 33555457, 296: 34603009, 312: 1, 328: 33554432, 344: 1048576, 360: 1025, 376: 34604032, 392: 33554433, 408: 34603008, 424: 0, 440: 34604033, 456: 1049601, 472: 1024, 488: 33555456, 504: 1048577 }, { 0: 134219808, 1: 131072, 2: 134217728, 3: 32, 4: 131104, 5: 134350880, 6: 134350848, 7: 2048, 8: 134348800, 9: 134219776, 10: 133120, 11: 134348832, 12: 2080, 13: 0, 14: 134217760, 15: 133152, 2147483648: 2048, 2147483649: 134350880, 2147483650: 134219808, 2147483651: 134217728, 2147483652: 134348800, 2147483653: 133120, 2147483654: 133152, 2147483655: 32, 2147483656: 134217760, 2147483657: 2080, 2147483658: 131104, 2147483659: 134350848, 2147483660: 0, 2147483661: 134348832, 2147483662: 134219776, 2147483663: 131072, 16: 133152, 17: 134350848, 18: 32, 19: 2048, 20: 134219776, 21: 134217760, 22: 134348832, 23: 131072, 24: 0, 25: 131104, 26: 134348800, 27: 134219808, 28: 134350880, 29: 133120, 30: 2080, 31: 134217728, 2147483664: 131072, 2147483665: 2048, 2147483666: 134348832, 2147483667: 133152, 2147483668: 32, 2147483669: 134348800, 2147483670: 134217728, 2147483671: 134219808, 2147483672: 134350880, 2147483673: 134217760, 2147483674: 134219776, 2147483675: 0, 2147483676: 133120, 2147483677: 2080, 2147483678: 131104, 2147483679: 134350848 }], u = [4160749569, 528482304, 33030144, 2064384, 129024, 8064, 504, 2147483679], n = e.DES = r.extend({ _doReset: function () { for (var t = this._key.words, e = [], r = 0; r < 56; r++) { var i = h[r] - 1; e[r] = t[i >>> 5] >>> 31 - i % 32 & 1 } for (var n = this._subKeys = [], o = 0; o < 16; o++) { for (var s = n[o] = [], c = f[o], r = 0; r < 24; r++)s[r / 6 | 0] |= e[(l[r] - 1 + c) % 28] << 31 - r % 6, s[4 + (r / 6 | 0)] |= e[28 + (l[r + 24] - 1 + c) % 28] << 31 - r % 6; s[0] = s[0] << 1 | s[0] >>> 31; for (r = 1; r < 7; r++)s[r] = s[r] >>> 4 * (r - 1) + 3; s[7] = s[7] << 5 | s[7] >>> 27 } for (var a = this._invSubKeys = [], r = 0; r < 16; r++)a[r] = n[15 - r] }, encryptBlock: function (t, e) { this._doCryptBlock(t, e, this._subKeys) }, decryptBlock: function (t, e) { this._doCryptBlock(t, e, this._invSubKeys) }, _doCryptBlock: function (t, e, r) { this._lBlock = t[e], this._rBlock = t[e + 1], p.call(this, 4, 252645135), p.call(this, 16, 65535), _.call(this, 2, 858993459), _.call(this, 8, 16711935), p.call(this, 1, 1431655765); for (var i = 0; i < 16; i++) { for (var n = r[i], o = this._lBlock, s = this._rBlock, c = 0, a = 0; a < 8; a++)c |= d[a][((s ^ n[a]) & u[a]) >>> 0]; this._lBlock = s, this._rBlock = o ^ c } var h = this._lBlock; this._lBlock = this._rBlock, this._rBlock = h, p.call(this, 1, 1431655765), _.call(this, 8, 16711935), _.call(this, 2, 858993459), p.call(this, 16, 65535), p.call(this, 4, 252645135), t[e] = this._lBlock, t[e + 1] = this._rBlock }, keySize: 2, ivSize: 2, blockSize: 2 }); function p(t, e) { e = (this._lBlock >>> t ^ this._rBlock) & e; this._rBlock ^= e, this._lBlock ^= e << t } function _(t, e) { e = (this._rBlock >>> t ^ this._lBlock) & e; this._lBlock ^= e, this._rBlock ^= e << t } t.DES = r._createHelper(n); e = e.TripleDES = r.extend({ _doReset: function () { var t = this._key.words; if (2 !== t.length && 4 !== t.length && t.length < 6) throw new Error("Invalid key length - 3DES requires the key length to be 64, 128, 192 or >192."); var e = t.slice(0, 2), r = t.length < 4 ? t.slice(0, 2) : t.slice(2, 4), t = t.length < 6 ? t.slice(0, 2) : t.slice(4, 6); this._des1 = n.createEncryptor(i.create(e)), this._des2 = n.createEncryptor(i.create(r)), this._des3 = n.createEncryptor(i.create(t)) }, encryptBlock: function (t, e) { this._des1.encryptBlock(t, e), this._des2.decryptBlock(t, e), this._des3.encryptBlock(t, e) }, decryptBlock: function (t, e) { this._des3.decryptBlock(t, e), this._des2.encryptBlock(t, e), this._des1.decryptBlock(t, e) }, keySize: 6, ivSize: 2, blockSize: 2 }); t.TripleDES = r._createHelper(e) }(), function () { var t = U, e = t.lib.StreamCipher, r = t.algo, i = r.RC4 = e.extend({ _doReset: function () { for (var t = this._key, e = t.words, r = t.sigBytes, i = this._S = [], n = 0; n < 256; n++)i[n] = n; for (var n = 0, o = 0; n < 256; n++) { var s = n % r, s = e[s >>> 2] >>> 24 - s % 4 * 8 & 255, o = (o + i[n] + s) % 256, s = i[n]; i[n] = i[o], i[o] = s } this._i = this._j = 0 }, _doProcessBlock: function (t, e) { t[e] ^= n.call(this) }, keySize: 8, ivSize: 0 }); function n() { for (var t = this._S, e = this._i, r = this._j, i = 0, n = 0; n < 4; n++) { var r = (r + t[e = (e + 1) % 256]) % 256, o = t[e]; t[e] = t[r], t[r] = o, i |= t[(t[e] + t[r]) % 256] << 24 - 8 * n } return this._i = e, this._j = r, i } t.RC4 = e._createHelper(i); r = r.RC4Drop = i.extend({ cfg: i.cfg.extend({ drop: 192 }), _doReset: function () { i._doReset.call(this); for (var t = this.cfg.drop; 0 < t; t--)n.call(this) } }); t.RC4Drop = e._createHelper(r) }(), F = (M = U).lib.StreamCipher, P = M.algo, D = [], E = [], R = [], P = P.Rabbit = F.extend({ _doReset: function () { for (var t = this._key.words, e = this.cfg.iv, r = 0; r < 4; r++)t[r] = 16711935 & (t[r] << 8 | t[r] >>> 24) | 4278255360 & (t[r] << 24 | t[r] >>> 8); for (var i = this._X = [t[0], t[3] << 16 | t[2] >>> 16, t[1], t[0] << 16 | t[3] >>> 16, t[2], t[1] << 16 | t[0] >>> 16, t[3], t[2] << 16 | t[1] >>> 16], n = this._C = [t[2] << 16 | t[2] >>> 16, 4294901760 & t[0] | 65535 & t[1], t[3] << 16 | t[3] >>> 16, 4294901760 & t[1] | 65535 & t[2], t[0] << 16 | t[0] >>> 16, 4294901760 & t[2] | 65535 & t[3], t[1] << 16 | t[1] >>> 16, 4294901760 & t[3] | 65535 & t[0]], r = this._b = 0; r < 4; r++)N.call(this); for (r = 0; r < 8; r++)n[r] ^= i[r + 4 & 7]; if (e) { var o = e.words, s = o[0], c = o[1], e = 16711935 & (s << 8 | s >>> 24) | 4278255360 & (s << 24 | s >>> 8), o = 16711935 & (c << 8 | c >>> 24) | 4278255360 & (c << 24 | c >>> 8), s = e >>> 16 | 4294901760 & o, c = o << 16 | 65535 & e; n[0] ^= e, n[1] ^= s, n[2] ^= o, n[3] ^= c, n[4] ^= e, n[5] ^= s, n[6] ^= o, n[7] ^= c; for (r = 0; r < 4; r++)N.call(this) } }, _doProcessBlock: function (t, e) { var r = this._X; N.call(this), D[0] = r[0] ^ r[5] >>> 16 ^ r[3] << 16, D[1] = r[2] ^ r[7] >>> 16 ^ r[5] << 16, D[2] = r[4] ^ r[1] >>> 16 ^ r[7] << 16, D[3] = r[6] ^ r[3] >>> 16 ^ r[1] << 16; for (var i = 0; i < 4; i++)D[i] = 16711935 & (D[i] << 8 | D[i] >>> 24) | 4278255360 & (D[i] << 24 | D[i] >>> 8), t[e + i] ^= D[i] }, blockSize: 4, ivSize: 2 }), M.Rabbit = F._createHelper(P), F = (M = U).lib.StreamCipher, P = M.algo, W = [], O = [], I = [], P = P.RabbitLegacy = F.extend({ _doReset: function () { for (var t = this._key.words, e = this.cfg.iv, r = this._X = [t[0], t[3] << 16 | t[2] >>> 16, t[1], t[0] << 16 | t[3] >>> 16, t[2], t[1] << 16 | t[0] >>> 16, t[3], t[2] << 16 | t[1] >>> 16], i = this._C = [t[2] << 16 | t[2] >>> 16, 4294901760 & t[0] | 65535 & t[1], t[3] << 16 | t[3] >>> 16, 4294901760 & t[1] | 65535 & t[2], t[0] << 16 | t[0] >>> 16, 4294901760 & t[2] | 65535 & t[3], t[1] << 16 | t[1] >>> 16, 4294901760 & t[3] | 65535 & t[0]], n = this._b = 0; n < 4; n++)q.call(this); for (n = 0; n < 8; n++)i[n] ^= r[n + 4 & 7]; if (e) { var o = e.words, s = o[0], t = o[1], e = 16711935 & (s << 8 | s >>> 24) | 4278255360 & (s << 24 | s >>> 8), o = 16711935 & (t << 8 | t >>> 24) | 4278255360 & (t << 24 | t >>> 8), s = e >>> 16 | 4294901760 & o, t = o << 16 | 65535 & e; i[0] ^= e, i[1] ^= s, i[2] ^= o, i[3] ^= t, i[4] ^= e, i[5] ^= s, i[6] ^= o, i[7] ^= t; for (n = 0; n < 4; n++)q.call(this) } }, _doProcessBlock: function (t, e) { var r = this._X; q.call(this), W[0] = r[0] ^ r[5] >>> 16 ^ r[3] << 16, W[1] = r[2] ^ r[7] >>> 16 ^ r[5] << 16, W[2] = r[4] ^ r[1] >>> 16 ^ r[7] << 16, W[3] = r[6] ^ r[3] >>> 16 ^ r[1] << 16; for (var i = 0; i < 4; i++)W[i] = 16711935 & (W[i] << 8 | W[i] >>> 24) | 4278255360 & (W[i] << 24 | W[i] >>> 8), t[e + i] ^= W[i] }, blockSize: 4, ivSize: 2 }), M.RabbitLegacy = F._createHelper(P), U }); \ No newline at end of file diff --git a/public/assets/lz-string.min.js b/public/assets/lz-string.min.js new file mode 100644 index 0000000..b2088b1 --- /dev/null +++ b/public/assets/lz-string.min.js @@ -0,0 +1 @@ +var LZString=function(){function o(o,r){if(!t[o]){t[o]={};for(var n=0;ne;e++){var s=r.charCodeAt(e);n[2*e]=s>>>8,n[2*e+1]=s%256}return n},decompressFromUint8Array:function(o){if(null===o||void 0===o)return i.decompress(o);for(var n=new Array(o.length/2),e=0,t=n.length;t>e;e++)n[e]=256*o[2*e]+o[2*e+1];var s=[];return n.forEach(function(o){s.push(r(o))}),i.decompress(s.join(""))},compressToEncodedURIComponent:function(o){return null==o?"":i._compress(o,6,function(o){return e.charAt(o)})},decompressFromEncodedURIComponent:function(r){return null==r?"":""==r?null:(r=r.replace(/ /g,"+"),i._decompress(r.length,32,function(n){return o(e,r.charAt(n))}))},compress:function(o){return i._compress(o,16,function(o){return r(o)})},_compress:function(o,r,n){if(null==o)return"";var e,t,i,s={},p={},u="",c="",a="",l=2,f=3,h=2,d=[],m=0,v=0;for(i=0;ie;e++)m<<=1,v==r-1?(v=0,d.push(n(m)),m=0):v++;for(t=a.charCodeAt(0),e=0;8>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}else{for(t=1,e=0;h>e;e++)m=m<<1|t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t=0;for(t=a.charCodeAt(0),e=0;16>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}l--,0==l&&(l=Math.pow(2,h),h++),delete p[a]}else for(t=s[a],e=0;h>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;l--,0==l&&(l=Math.pow(2,h),h++),s[c]=f++,a=String(u)}if(""!==a){if(Object.prototype.hasOwnProperty.call(p,a)){if(a.charCodeAt(0)<256){for(e=0;h>e;e++)m<<=1,v==r-1?(v=0,d.push(n(m)),m=0):v++;for(t=a.charCodeAt(0),e=0;8>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}else{for(t=1,e=0;h>e;e++)m=m<<1|t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t=0;for(t=a.charCodeAt(0),e=0;16>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}l--,0==l&&(l=Math.pow(2,h),h++),delete p[a]}else for(t=s[a],e=0;h>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;l--,0==l&&(l=Math.pow(2,h),h++)}for(t=2,e=0;h>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;for(;;){if(m<<=1,v==r-1){d.push(n(m));break}v++}return d.join("")},decompress:function(o){return null==o?"":""==o?null:i._decompress(o.length,32768,function(r){return o.charCodeAt(r)})},_decompress:function(o,n,e){var t,i,s,p,u,c,a,l,f=[],h=4,d=4,m=3,v="",w=[],A={val:e(0),position:n,index:1};for(i=0;3>i;i+=1)f[i]=i;for(p=0,c=Math.pow(2,2),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;switch(t=p){case 0:for(p=0,c=Math.pow(2,8),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;l=r(p);break;case 1:for(p=0,c=Math.pow(2,16),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;l=r(p);break;case 2:return""}for(f[3]=l,s=l,w.push(l);;){if(A.index>o)return"";for(p=0,c=Math.pow(2,m),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;switch(l=p){case 0:for(p=0,c=Math.pow(2,8),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;f[d++]=r(p),l=d-1,h--;break;case 1:for(p=0,c=Math.pow(2,16),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;f[d++]=r(p),l=d-1,h--;break;case 2:return w.join("")}if(0==h&&(h=Math.pow(2,m),m++),f[l])v=f[l];else{if(l!==d)return null;v=s+s.charAt(0)}w.push(v),f[d++]=s+v.charAt(0),h--,s=v,0==h&&(h=Math.pow(2,m),m++)}}};return i}();"function"==typeof define&&define.amd?define(function(){return LZString}):"undefined"!=typeof module&&null!=module&&(module.exports=LZString); \ No newline at end of file diff --git a/public/js/interface_functions.js b/public/js/interface_functions.js index 81297cc..7c64494 100644 --- a/public/js/interface_functions.js +++ b/public/js/interface_functions.js @@ -21,6 +21,9 @@ function load(element, filename){ if(filename == "feedback_loader.php"){ voteHover(); } + if(filename == "chat.php"){ + loadMessagesFromLocalStorage(); + } }); @@ -59,10 +62,8 @@ function scrollToLast(forceScroll){ //#endregion -document.querySelectorAll('details').forEach((D,_,A)=>{ - D.ontoggle =_=>{ if(D.open) A.forEach(d =>{ if(d!=D) d.open=false })} -}) +//#region SYSTEM PROMPT let spPanelOpen = false; document.addEventListener('click', function(event) { const isClickOnPanel = document.getElementById('system-prompt-panel').contains(event.target); @@ -85,14 +86,17 @@ function ToggleSystemPrompt(activation){ return } const systemPrompt = msg.querySelector('.message-content').querySelector('.message-text').innerText; - promptText.innerHTML = "″" + systemPrompt.trim() + "”"; - + promptText.innerHTML = systemPrompt.trim(); + promptPanel.style.display = 'block'; requestAnimationFrame(() => { promptPanel.style.opacity = '1'; }); } else{ + if(isEditing){ + toggleSystemPromptEdit(); + } promptPanel.style.opacity = '0'; setTimeout(() => { promptPanel.style.display = 'none'; @@ -114,3 +118,74 @@ function toggleSystemPromptInfo(){ info.style.display = 'none'; } } + +let isEditing = false; + +function confirmSystemPromptEdit(){ + const newPrompt = document.getElementById('system-prompt').innerText; + const msg = document.querySelector('.messages').querySelector('.message'); + msg.querySelector('.message-content').querySelector('.message-text').innerText = newPrompt; + toggleSystemPromptEdit(); +} + +function abortSystemPromptEdit(){ + const msg = document.querySelector('.messages').querySelector('.message'); + const systemPrompt = msg.querySelector('.message-content').querySelector('.message-text').innerText; + document.getElementById('system-prompt').innerText = systemPrompt.trim(); + toggleSystemPromptEdit(); +} + +function toggleSystemPromptEdit(){ + const editButton = document.getElementById('system-prompt-editButton'); + const confirmBar = document.getElementById('system-prompt-edit-control'); + const systemPromptText = document.getElementById('system-prompt'); + + if(isEditing === false){ + editButton.style.display = "none"; + confirmBar.style.display = "grid"; + systemPromptText.setAttribute("contenteditable", true); + systemPromptText.style.fontStyle = "italic"; + systemPromptText.focus(); + + var range,selection; + if(document.createRange)//Firefox, Chrome, Opera, Safari, IE 9+ + { + range = document.createRange(); + range.selectNodeContents(systemPromptText); + range.collapse(false); + selection = window.getSelection(); + selection.removeAllRanges(); + selection.addRange(range); + } + else if(document.selection)//IE 8 and lower + { + range = document.body.createTextRange(); + range.moveToElementText(systemPromptText); + range.collapse(false); + range.select(); + } + }else{ + editButton.style.display = "block"; + confirmBar.style.display = "none"; + systemPromptText.setAttribute("contenteditable", false); + systemPromptText.style.fontStyle = "normal"; + } + isEditing = !isEditing; +} + + +function calculateSystemPromptMaxHeight(){ + const inputWrapper = document.querySelector('.input-wrapper'); + const inputHeight = inputWrapper.getBoundingClientRect().height; + + const spPanel = document.getElementById('system-prompt-panel'); + + const windowHeight = window.innerHeight; + const remInPixels = parseFloat(getComputedStyle(document.documentElement).fontSize); + const margin = 8 * remInPixels; + + const maxHeight = windowHeight - inputHeight - margin; + spPanel.style.maxHeight = `${maxHeight}px`; +} + +//#endregion \ No newline at end of file diff --git a/public/js/scripts.js b/public/js/scripts.js index 77f2c4f..5995c2a 100644 --- a/public/js/scripts.js +++ b/public/js/scripts.js @@ -103,23 +103,23 @@ function SwitchDarkMode(isSet){ if(darkMode === 'enabled'){ document.documentElement.className = 'darkMode'; - icon.setAttribute('src', '/public/img/moon.svg'); - if(hljsTheme != null) hljsTheme.setAttribute('href', "/public/style/hljsDark.css"); + icon.setAttribute('src', 'public/img/moon.svg'); + if(hljsTheme != null) hljsTheme.setAttribute('href', "public/style/hljsDark.css"); if(loginBg != null){ loginBg.style.opacity = "1"; - loginBg.setAttribute('src', '/public/img/HAWKIBG-DM.m4v'); + loginBg.setAttribute('src', 'public/img/HAWKIBG-DM.m4v'); } tog.classList.add('active'); } else{ document.documentElement.className = 'lightMode'; - icon.setAttribute('src', '/public/img/sun.svg'); - if(hljsTheme != null) hljsTheme.setAttribute('href', "/public/style/hljsLight.css"); + icon.setAttribute('src', 'public/img/sun.svg'); + if(hljsTheme != null) hljsTheme.setAttribute('href', "public/style/hljsLight.css"); if(loginBg != null){ loginBg.style.opacity = ".5"; - loginBg.setAttribute('src', '/public/img/HAWKIBG.m4v'); + loginBg.setAttribute('src', 'public/img/HAWKIBG.m4v'); } tog.classList.remove('active'); } diff --git a/public/js/syntax_modifier.js b/public/js/syntax_modifier.js index 266fbd1..b1e86f1 100644 --- a/public/js/syntax_modifier.js +++ b/public/js/syntax_modifier.js @@ -9,47 +9,46 @@ let lastClosingIndex = -1; let lastChunk = ''; let summedText = ''; - function InitializeMessage(){ + + function InitializeMessage() { isInCodeBlock = false; lastClosingIndex = -1; lastChunk = ''; summedText = ''; } - function FormatChunk(chunk){ + + function FormatChunk(chunk) { chunk = escapeHTML(chunk); let formattedText = ''; let prevText = ''; - if(lastClosingIndex != -1){ - prevText = summedText.substring(0 , lastClosingIndex); + if (lastClosingIndex != -1) { + prevText = summedText.substring(0, lastClosingIndex); formattedText = summedText.substring(lastClosingIndex); - } - else{ + } else { formattedText = summedText; } - if(isInCodeBlock){ - //END OF CODE BLOCK - if(chunk == '``'){ + if (isInCodeBlock) { + // END OF CODE BLOCK + if (chunk === '``') { isInCodeBlock = false; - } - else{ + formattedText += ''; + } else { formattedText = formattedText.replace('', ''); formattedText += (chunk + ''); } - }else{ + } else { // START OF CODE BLOCK - //Code Syntax Detected - if(chunk == '```'){ + if (chunk === '```') { isInCodeBlock = true; formattedText += '
';
-			}
-			else{
-				if(chunk.includes('`') && lastChunk == '``'){
+			} else {
+				if (chunk.includes('`') && lastChunk === '``') {
 					chunk = chunk.replace('`', '');
 					lastClosingIndex = summedText.length;
-				}  
-				//Plain Text
+				}
+				// Plain Text
 				formattedText += chunk;
 			}
 		}
@@ -58,37 +57,35 @@
 		return ReplaceMarkdownSyntax(summedText);
 	}
 
-
 	function ReplaceMarkdownSyntax(text) {
-		// Match Markdown code block syntax
 		const codeBlockRegex = /
([\s\S]+?)<\/code><\/pre>/g;
+		const codeBlocks = [];
 
 		// Replace Markdown code blocks with placeholders
-		const codeBlocks = [];
 		text = text.replace(codeBlockRegex, (match, content) => {
 			codeBlocks.push(content);
 			return `[[[[CODEBLOCK_${codeBlocks.length - 1}]]]]`;
 		});
-		
-		//replace bold and italic (*text* or ___text___)
+
+		// Replace bold and italic (*text* or ___text___)
 		text = text.replace(/\*\*\*(.*?)\*\*\*/g, '$1');
 		text = text.replace(/___(.*?)___/g, '$1');
 
-		//replace only bold (text or __text__)
+		// Replace only bold (**text** or __text__)
 		text = text.replace(/\*\*(.*?)\*\*/g, '$1');
 		text = text.replace(/__(.*?)__/g, '$1');
 
-		//replace only italic (*text* or _text_)
+		// Replace only italic (*text* or _text_)
 		text = text.replace(/\*(.*?)\*/g, '$1');
 		text = text.replace(/_(.*?)_/g, '$1');
-		
-		// Replace Striketrough
-		text = text.replace(/~~(.*?)~~/g, "$1");
 
-		// // Links
+		// Replace Strikethrough
+		text = text.replace(/~~(.*?)~~/g, '$1');
+
+		// Links
 		text = text.replace(/\[([^\]]+)\]\(([^\)]+)\)/g, '$1');
 
-		//     // Headings
+		// Headings
 		text = text.replace(/(?$2');
 		text = text.replace(/(?$2');
 		text = text.replace(/(?$2');
@@ -96,35 +93,22 @@
 		text = text.replace(/(?$2');
 		text = text.replace(/(?$2');
 
-		//HANDLE MARKDOWN TABLES
-		// Match Markdown table syntax
+		// HANDLE MARKDOWN TABLES
 		const tableRegex = /(\|.*\|)\n(\|.*\|)(\n\|\s*:?-+:?\s*)*\n((\|.*\|)\n*)+/g;
-
-		// Replace Markdown table with HTML table
 		text = text.replace(tableRegex, (match) => {
-			// Check if inside code block
 			if (match.includes('[[[[CODEBLOCK_')) {
-				return match; // If inside code block, return as is
+				return match;
 			}
 
 			const rows = match.split('\n').filter(Boolean);
-
-			// Remove leading/trailing pipes and split rows into cells
 			const cells = rows.map(row => row.replace(/^\||\|$/g, '').split('|').map(cell => cell.trim()));
-
-
-			// Filter out rows containing only dashes
 			const filteredCells = cells.filter(row => !row.every(cell => /^-+$/.test(cell)));
-
-			// Determine header row
 			const headerRow = filteredCells.shift();
 
-			// Build HTML table
 			let html = '\n\n\n';
 			html += headerRow.map(cell => ``).join('\n');
 			html += '\n\n\n\n';
 
-			// Add rows
 			filteredCells.forEach(row => {
 				html += '\n';
 				row.forEach(cell => {
@@ -133,7 +117,6 @@
 				html += '\n';
 			});
 
-			// Close table tags
 			html += '\n
${cell}
\n'; return html; @@ -147,7 +130,6 @@ return text; } - function escapeHTML(text) { return text.replace(/["&'<>]/g, function (match) { return { @@ -161,21 +143,18 @@ } function FormatMathFormulas() { - element = document.querySelector(".message:last-child").querySelector(".message-text"); - + const element = document.querySelector(".message:last-child").querySelector(".message-text"); + renderMathInElement(element, { - // customised options - // • auto-render specific keys, e.g.: delimiters: [ - {left: '$$', right: '$$', display: true}, - {left: '$', right: '$', display: false}, - {left: '\\(', right: '\\)', display: false}, - {left: '\\[', right: '\\]', display: true} + { left: '$$', right: '$$', display: true }, + { left: '$', right: '$', display: false }, + { left: '\\(', right: '\\)', display: false }, + { left: '\\[', right: '\\]', display: true } ], - displayMode : true, + displayMode: true, ignoredClasses: ["ignore_Format"], - // • rendering keys, e.g.: - throwOnError : true + throwOnError: true }); } @@ -187,4 +166,12 @@ return false; } } - //#endregion + + function FormatWholeMessage(message){ + const codeBlockRegex = /```(.*?)```/gs; + const html = message.replace(codeBlockRegex, (match, p1) => { + return `
${p1}
`; + }); + return ReplaceMarkdownSyntax(html); + } +//#endregion diff --git a/public/style/interface_style.css b/public/style/interface_style.css index 824d091..597cb23 100644 --- a/public/style/interface_style.css +++ b/public/style/interface_style.css @@ -505,6 +505,11 @@ max-height: 60vh; direction: ltr; } +.modal-buttons-bar{ + display: flex; + justify-content: space-between; + margin: 1rem 0; +} .main-header svg { max-width: 24px; @@ -697,21 +702,66 @@ details svg{ color: var(--text-color); } -#system-prompt-btn{ + +.input-controlbar{ position: absolute; - left: 1rem; - top: -1.5rem; + left: 0; + right: 0; + bottom: 100%; + + display: grid; + grid-template-columns: 1fr auto auto; + align-items: center; + margin-bottom: .5rem; + min-height: 2rem; + background-color: transparent; +} +#model-selector{ + background-color: var(--secondary-color); + color: var(--text-color); + min-width: 10rem; + max-width: 13rem; + min-height: 2rem; + border: none; + border-radius: 6px; + padding: .5rem; + box-shadow: 0 0 2rem rgba(0, 0, 0, 0.1); +} + +#delete-chat-confirm{ + display: none; +} +#delete-chat-btn{ + margin-right: 1rem; + width: 1.1rem; + fill: #999; + cursor: pointer; +} +#delete-chat-btn:hover{ + fill: red; +} + + +#system-prompt-btn{ + margin-right: 1rem; width: 1.1rem; fill: #999; cursor: pointer; } + +#system-prompt-btn:hover{ + fill: var(--text-color); +} #system-prompt-panel{ position: absolute; - bottom: 100%; + bottom: calc(100% + 2rem); left: 0; right: 0; margin-bottom: 1rem; height: max-content; + max-height: 70vh; + overflow-y: auto; + padding: 0.5rem 2rem 1rem 2rem; /* font-size: 0.8rem; */ @@ -725,9 +775,29 @@ details svg{ opacity: 0; transition: opacity 300ms; } +#system-prompt-panel::-webkit-scrollbar { + width: 7px; +} + +#system-prompt-panel::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0); +} + +#system-prompt-panel::-webkit-scrollbar-thumb { + background: #cbcbcb; + border-radius: 5px; +} + +#system-prompt-panel::-webkit-scrollbar-thumb:hover { + background: #555; +} + + + + #system-prompt-title{ display: grid; - grid-template-columns: auto 1fr; + grid-template-columns: auto 1fr auto; column-gap: .75rem; align-items: center; margin-top: 1rem; @@ -748,6 +818,15 @@ details svg{ padding: 0 1rem; margin-top: 0.5rem; } +#system-prompt-editButton{ + display: block; +} +#system-prompt-edit-control{ + display: none; + grid-template-columns: 1rem 1rem; + column-gap: 1rem; +} + label { @@ -890,6 +969,8 @@ pre{ padding-bottom: 1rem; } + + .limitations{ padding: 20vmin 1rem; }