From 7a6bcf734c79b625995f340d9edff07c79dc67af Mon Sep 17 00:00:00 2001 From: Daniel Brendel Date: Sun, 5 Jan 2025 22:43:05 +0100 Subject: [PATCH] Resolves #319 --- app/commands/MigrationUpgrade.php | 2 ++ app/controller/api.php | 6 ++++-- app/controller/inventory.php | 6 ++++-- app/lang/da/app.php | 3 ++- app/lang/de/app.php | 3 ++- app/lang/en/app.php | 3 ++- app/lang/es/app.php | 3 ++- app/lang/fr/app.php | 3 ++- app/lang/no/app.php | 3 ++- app/lang/pl/app.php | 3 ++- app/migrations/InventoryModel.php | 1 + app/models/InventoryModel.php | 14 ++++++++------ app/modules/UtilsModule.php | 13 +++++++++++++ app/resources/js/app.js | 11 +++++++---- app/resources/sass/app.scss | 31 +++++++++++++++++++++++++++++++ app/views/inventory.php | 16 ++++++++++++++-- app/views/layout.php | 22 ++++++++++++++++++++++ public/js/app.js | 4 ++-- 18 files changed, 122 insertions(+), 25 deletions(-) diff --git a/app/commands/MigrationUpgrade.php b/app/commands/MigrationUpgrade.php index 5a5492b..796fbad 100644 --- a/app/commands/MigrationUpgrade.php +++ b/app/commands/MigrationUpgrade.php @@ -14,6 +14,8 @@ class MigrationUpgrade implements Asatru\Commands\Command { public function upgradeTo4dot0() { PlantsModel::raw('ALTER TABLE `' . PlantsModel::tableName() . '` ADD COLUMN IF NOT EXISTS last_photo_date DATETIME NULL'); + + InventoryModel::raw('ALTER TABLE `' . InventoryModel::tableName() . '` ADD COLUMN IF NOT EXISTS tags VARCHAR(512) NULL'); } /** diff --git a/app/controller/api.php b/app/controller/api.php index 529623f..ca50419 100644 --- a/app/controller/api.php +++ b/app/controller/api.php @@ -602,11 +602,12 @@ class ApiController extends BaseController { try { $name = $request->params()->query('name', null); $description = $request->params()->query('description', null); + $tags = $request->params()->query('tags', null); $location = $request->params()->query('location', null); $group = $request->params()->query('group', null); $photo = $request->params()->query('photo', null); - $itemid = InventoryModel::addItem($name, $description, $location, $group, $photo, true); + $itemid = InventoryModel::addItem($name, $description, $tags, $location, $group, $photo, true); return json([ 'code' => 200, @@ -632,12 +633,13 @@ class ApiController extends BaseController { $item = $request->params()->query('item', null); $name = $request->params()->query('name', null); $description = $request->params()->query('description', null); + $tags = $request->params()->query('tags', null); $location = $request->params()->query('location', null); $amount = $request->params()->query('amount', null); $group = $request->params()->query('group', null); $photo = $request->params()->query('photo', null); - InventoryModel::editItem($item, $name, $description, $location, $amount, $group, $photo, true); + InventoryModel::editItem($item, $name, $description, $tags, $location, $amount, $group, $photo, true); return json([ 'code' => 200 diff --git a/app/controller/inventory.php b/app/controller/inventory.php index 72f6f46..f0b76e5 100644 --- a/app/controller/inventory.php +++ b/app/controller/inventory.php @@ -71,9 +71,10 @@ class InventoryController extends BaseController { $group = $request->params()->query('group', null); $location = $request->params()->query('location', null); $description = $request->params()->query('description', null); + $tags = $request->params()->query('tags', null); $photo = $request->params()->query('photo', null); - $id = InventoryModel::addItem($name, $description, $location, $group, $photo); + $id = InventoryModel::addItem($name, $description, $tags, $location, $group, $photo); return redirect('/inventory?expand=' . $id . '#anchor-item-' . $id); } @@ -109,9 +110,10 @@ class InventoryController extends BaseController { $location = $request->params()->query('location', null); $amount = $request->params()->query('amount', null); $description = $request->params()->query('description', null); + $tags = $request->params()->query('tags', null); $photo = $request->params()->query('photo', null); - InventoryModel::editItem($id, $name, $description, $location, $amount, $group, $photo); + InventoryModel::editItem($id, $name, $description, $tags, $location, $amount, $group, $photo); return redirect('/inventory?expand=' . $id . '#anchor-item-' . $id); } diff --git a/app/lang/da/app.php b/app/lang/da/app.php index 42b3187..1051ce8 100644 --- a/app/lang/da/app.php +++ b/app/lang/da/app.php @@ -465,5 +465,6 @@ return [ 'confirm_remove_preview_photo' => 'Vil du virkelig fjerne dette billede?', 'move_current_photo_to_gallery' => 'Flyt det aktuelle billede til galleriet', 'created_at' => 'Oprettet', - 'updated_at' => 'Redigeret' + 'updated_at' => 'Redigeret', + 'tags' => 'Tags' ]; \ No newline at end of file diff --git a/app/lang/de/app.php b/app/lang/de/app.php index 4b35df1..50b58a6 100644 --- a/app/lang/de/app.php +++ b/app/lang/de/app.php @@ -465,5 +465,6 @@ return [ 'confirm_remove_preview_photo' => 'Soll dieses Foto wirklich entfernt werden?', 'move_current_photo_to_gallery' => 'Aktuelles Foto in die Galerie verschieben', 'created_at' => 'Erstellt', - 'updated_at' => 'Bearbeitet' + 'updated_at' => 'Bearbeitet', + 'tags' => 'Tags' ]; \ No newline at end of file diff --git a/app/lang/en/app.php b/app/lang/en/app.php index 3c91f9c..fc7c475 100644 --- a/app/lang/en/app.php +++ b/app/lang/en/app.php @@ -465,5 +465,6 @@ return [ 'confirm_remove_preview_photo' => 'Do you really want to remove this photo?', 'move_current_photo_to_gallery' => 'Move current photo to gallery', 'created_at' => 'Created at', - 'updated_at' => 'Updated at' + 'updated_at' => 'Updated at', + 'tags' => 'Tags' ]; \ No newline at end of file diff --git a/app/lang/es/app.php b/app/lang/es/app.php index 4dbbe6f..f89988c 100644 --- a/app/lang/es/app.php +++ b/app/lang/es/app.php @@ -465,5 +465,6 @@ return [ 'confirm_remove_preview_photo' => '¿Realmente quieres eliminar esta foto?', 'move_current_photo_to_gallery' => 'Mover la foto actual a la galería', 'created_at' => 'Creado', - 'updated_at' => 'Editado' + 'updated_at' => 'Editado', + 'tags' => 'Tags' ]; diff --git a/app/lang/fr/app.php b/app/lang/fr/app.php index 1046089..c02196f 100644 --- a/app/lang/fr/app.php +++ b/app/lang/fr/app.php @@ -465,5 +465,6 @@ return [ 'confirm_remove_preview_photo' => 'Voulez-vous vraiment supprimer cette photo?', 'move_current_photo_to_gallery' => 'Déplacer la photo actuelle vers la galerie', 'created_at' => 'Créé', - 'updated_at' => 'Édité' + 'updated_at' => 'Édité', + 'tags' => 'Tags' ]; \ No newline at end of file diff --git a/app/lang/no/app.php b/app/lang/no/app.php index 600b201..39c2415 100644 --- a/app/lang/no/app.php +++ b/app/lang/no/app.php @@ -465,5 +465,6 @@ return [ 'confirm_remove_preview_photo' => 'Er du sikker på at du vil fjerne dette bildet?', 'move_current_photo_to_gallery' => 'Flytt gjeldende bilde til galleriet', 'created_at' => 'Opprettet', - 'updated_at' => 'Redigert' + 'updated_at' => 'Redigert', + 'tags' => 'Tags' ]; \ No newline at end of file diff --git a/app/lang/pl/app.php b/app/lang/pl/app.php index 49c91c4..800e287 100644 --- a/app/lang/pl/app.php +++ b/app/lang/pl/app.php @@ -465,5 +465,6 @@ return [ 'confirm_remove_preview_photo' => 'Czy na pewno chcesz usunąć to zdjęcie?', 'move_current_photo_to_gallery' => 'Przenieś bieżące zdjęcie do galerii', 'created_at' => 'Stworzony', - 'updated_at' => 'Edytowane' + 'updated_at' => 'Edytowane', + 'tags' => 'Tags' ]; \ No newline at end of file diff --git a/app/migrations/InventoryModel.php b/app/migrations/InventoryModel.php index b28b78c..09956b8 100644 --- a/app/migrations/InventoryModel.php +++ b/app/migrations/InventoryModel.php @@ -31,6 +31,7 @@ class InventoryModel_Migration { $this->database->add('name VARCHAR(512) NOT NULL'); $this->database->add('group_ident VARCHAR(512) NOT NULL'); $this->database->add('description TEXT NULL'); + $this->database->add('tags VARCHAR(512) NULL'); $this->database->add('location VARCHAR(512) NULL'); $this->database->add('photo VARCHAR(512) NULL'); $this->database->add('amount INT NOT NULL DEFAULT 0'); diff --git a/app/models/InventoryModel.php b/app/models/InventoryModel.php index 1efca4a..fe92006 100644 --- a/app/models/InventoryModel.php +++ b/app/models/InventoryModel.php @@ -28,6 +28,7 @@ class InventoryModel extends \Asatru\Database\Model { /** * @param $name * @param $description + * @param $tags * @param $location * @param $group * @param $photo @@ -35,7 +36,7 @@ class InventoryModel extends \Asatru\Database\Model { * @return int * @throws \Exception */ - public static function addItem($name, $description, $location, $group, $photo, $api = false) + public static function addItem($name, $description, $tags, $location, $group, $photo, $api = false) { try { $user = UserModel::getAuthUser(); @@ -47,8 +48,8 @@ class InventoryModel extends \Asatru\Database\Model { throw new \Exception('Invalid group token: ' . $group); } - static::raw('INSERT INTO `' . self::tableName() . '` (name, group_ident, description, location, last_edited_user, last_edited_date) VALUES(?, ?, ?, ?, ?, CURRENT_TIMESTAMP)', [ - $name, $group, $description, $location, (($user) ? $user->get('id') : 0) + static::raw('INSERT INTO `' . self::tableName() . '` (name, group_ident, description, tags, location, last_edited_user, last_edited_date) VALUES(?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)', [ + $name, $group, $description, trim($tags), $location, (($user) ? $user->get('id') : 0) ]); $row = static::raw('SELECT * FROM `' . self::tableName() . '` ORDER BY id DESC LIMIT 1')->first(); @@ -94,6 +95,7 @@ class InventoryModel extends \Asatru\Database\Model { * @param $id * @param $name * @param $description + * @param $tags * @param $location * @param $amount * @param $group @@ -102,7 +104,7 @@ class InventoryModel extends \Asatru\Database\Model { * @return void * @throws \Exception */ - public static function editItem($id, $name, $description, $location, $amount, $group, $photo, $api = false) + public static function editItem($id, $name, $description, $tags, $location, $amount, $group, $photo, $api = false) { try { $user = UserModel::getAuthUser(); @@ -115,8 +117,8 @@ class InventoryModel extends \Asatru\Database\Model { throw new \Exception('Invalid item: ' . $id); } - static::raw('UPDATE `' . self::tableName() . '` SET name = ?, group_ident = ?, location = ?, description = ?, amount = ? WHERE id = ?', [ - $name, $group, $location, $description, $amount, $row->get('id') + static::raw('UPDATE `' . self::tableName() . '` SET name = ?, group_ident = ?, location = ?, description = ?, tags = ?, amount = ? WHERE id = ?', [ + $name, $group, $location, $description, $tags, $amount, $row->get('id') ]); if ((isset($_FILES['photo'])) && ($_FILES['photo']['error'] === UPLOAD_ERR_OK)) { diff --git a/app/modules/UtilsModule.php b/app/modules/UtilsModule.php index 2bcc68e..42fc8d4 100644 --- a/app/modules/UtilsModule.php +++ b/app/modules/UtilsModule.php @@ -619,4 +619,17 @@ class UtilsModule { return (bool)$date->format('I'); } + + /** + * @param $expression + * @return array + */ + public static function splitTags($expression) + { + if (!is_string($expression)) { + return []; + } + + return preg_split('/\s+/', trim($expression)); + } } diff --git a/app/resources/js/app.js b/app/resources/js/app.js index 79e6cca..e58e29e 100644 --- a/app/resources/js/app.js +++ b/app/resources/js/app.js @@ -646,13 +646,14 @@ window.vue = new Vue({ }); }, - editInventoryItem: function(id, name, group, location, description, amount) + editInventoryItem: function(id, name, group, location, description, tags, amount) { document.getElementById('inpInventoryItemId').value = id; document.getElementById('inpInventoryItemName').value = document.getElementById(name).children[1].innerText; document.getElementById('inpInventoryItemGroup').value = group; document.getElementById('inpInventoryItemLocation').value = document.getElementById(location).children[0].innerText; document.getElementById('inpInventoryItemDescription').value = document.getElementById(description).innerText; + document.getElementById('inpInventoryItemTags').value = document.getElementById(tags).innerText; document.getElementById('inpInventoryItemAmount').value = amount; window.vue.bShowEditInventoryItem = true; @@ -1001,9 +1002,11 @@ window.vue = new Vue({ let elems = document.getElementsByClassName('inventory-item'); for (let i = 0; i < elems.length; i++) { let elemName = elems[i].children[1].children[0]; - let elemDescription = elems[i].children[2].children[0]; - - if ((elemName.innerText.toLowerCase().includes(token.toLowerCase())) || (elemDescription.innerText.toLowerCase().includes(token.toLowerCase()))) { + let elemDescription = elems[i].children[2].children[1]; + let elemTags = elems[i].children[2].children[0].children[0]; + let elemLocation = elems[i].children[2].children[3].children[0]; + + if ((elemName.innerText.toLowerCase().includes(token.toLowerCase())) || (elemDescription.innerText.toLowerCase().includes(token.toLowerCase())) || (elemTags.innerText.toLowerCase().includes(token.toLowerCase())) || (elemLocation.innerText.toLowerCase().includes(token.toLowerCase()))) { elems[i].classList.remove('is-hidden'); } else { elems[i].classList.add('is-hidden'); diff --git a/app/resources/sass/app.scss b/app/resources/sass/app.scss index 89456e4..6e8a8c7 100644 --- a/app/resources/sass/app.scss +++ b/app/resources/sass/app.scss @@ -2018,6 +2018,37 @@ fieldset .field { text-decoration: underline; } +.inventory-item-tags { + position: relative; + margin-top: 5px; +} + +.inventory-item-tags-tag { + position: relative; + display: inline-block; + padding-left: 10px; + padding-right: 10px; + padding-bottom: 1px; + background-color: rgb(100, 100, 100); + border: 1px solid rgb(200, 200, 200); + border-radius: 5px; + font-size: 0.75em; + color: rgb(250, 250, 250); +} + +.inventory-item-tags-tag:hover { + background-color: rgb(150, 150, 150); + color: rgb(255, 255, 255); +} + +.inventory-item-tags-tag a { + color: rgb(250, 250, 250); +} + +.inventory-item-tags-tag a:hover { + color: rgb(250, 250, 250); +} + .inventory-item-photo { position: relative; text-align: center; diff --git a/app/views/inventory.php b/app/views/inventory.php index f6ae6a8..049e6cc 100644 --- a/app/views/inventory.php +++ b/app/views/inventory.php @@ -16,7 +16,7 @@
- +
@@ -46,12 +46,24 @@
  - +
+
+ + + @foreach (UtilsModule::splitTags($inventory->get($i)->get('tags')) as $tag) + @if (strlen($tag) > 0) + + @endif + @endforeach +
+
                             @if ((is_string($inventory->get($i)->get('description'))) && (strlen($inventory->get($i)->get('description')) > 0))
diff --git a/app/views/layout.php b/app/views/layout.php
index d6e7179..d9e6a0e 100644
--- a/app/views/layout.php
+++ b/app/views/layout.php
@@ -608,6 +608,13 @@
 								
+
+ +
+ +
+
+ @@ -697,6 +704,13 @@ +
+ +
+ +
+
+
@@ -1960,6 +1974,14 @@ inventoryFilterSearchInput.addEventListener('input', function() { window.vue.filterInventory(this.value); }); + + @if (isset($_GET['filter'])) + inventoryFilterSearchInput.value = '{{ $_GET['filter'] }}'; + + if (inventoryFilterSearchInput.value.length > 0) { + window.vue.filterInventory('{{ $_GET['filter'] }}'); + } + @endif } @if (app('chat_system')) diff --git a/public/js/app.js b/public/js/app.js index 52752fb..abd65a6 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -16,7 +16,7 @@ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _sass_app_scss__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./../sass/app.scss */ \"./app/resources/sass/app.scss\");\n/* harmony import */ var _sass_app_scss__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_sass_app_scss__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var chart_js_auto__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! chart.js/auto */ \"./node_modules/chart.js/auto/auto.js\");\n/* harmony import */ var chartjs_adapter_date_fns__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! chartjs-adapter-date-fns */ \"./node_modules/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.esm.js\");\n/**\r\n * app.js\r\n * \r\n * Put here your application specific JavaScript implementations\r\n */\r\n\r\n\r\n\r\nwindow.axios = __webpack_require__(/*! axios */ \"./node_modules/axios/dist/browser/axios.cjs\");\r\nwindow.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';\r\n\r\n\r\n\r\n\r\nwindow.constChatMessageQueryRefreshRate = 1000 * 15;\r\nwindow.constChatUserListRefreshRate = 1000 * 15;\r\nwindow.constChatTypingRefreshRate = 2000;\r\n\r\nwindow.vue = new Vue({\r\n el: '#app',\r\n\r\n data: {\r\n bShowAddPlant: false,\r\n bShowEditText: false,\r\n bShowEditMultilineText: false,\r\n bShowEditBoolean: false,\r\n bShowEditInteger: false,\r\n bShowEditDate: false,\r\n bShowEditCombo: false,\r\n bShowEditPhoto: false,\r\n bShowEPUrl: false,\r\n bShowEditLinkText: false,\r\n bShowUploadPhoto: false,\r\n bShowSetPhotoURL: false,\r\n bShowCreateTask: false,\r\n bShowEditTask: false,\r\n bShowEditPreferences: false,\r\n bShowAddInventoryItem: false,\r\n bShowEditInventoryItem: false,\r\n bShowInvItemQRCode: false,\r\n bShowInventoryBulkPrint: false,\r\n bShowInventoryExport: false,\r\n bShowManageGroups: false,\r\n bShowRestorePassword: false,\r\n bShowCreateNewUser: false,\r\n bShowCreateNewLocation: false,\r\n bShowRemoveLocation: false,\r\n bShowPreviewImageModal: false,\r\n bShowSharePhoto: false,\r\n bShowAddFirstLocation: false,\r\n bShowAddCalendarItem: false,\r\n bShowEditCalendarItem: false,\r\n bShowCreateNewCalendarClass: false,\r\n bShowPlantQRCode: false,\r\n bShowPlantBulkPerformUpdate: false,\r\n bShowPlantBulkPrint: false,\r\n bShowAddCustomPlantAttribute: false,\r\n bShowEditCustomPlantAttribute: false,\r\n bShowCreateNewAttributeSchema: false,\r\n bShowAddPlantLogEntry: false,\r\n bShowEditPlantLogEntry: false,\r\n bShowAddLocationLogEntry: false,\r\n bShowEditLocationLogEntry: false,\r\n bShowCreateNewBulkCmd: false,\r\n bShowSelectRecognizedPlant: false,\r\n clsLastImagePreviewAspect: '',\r\n comboLocation: [],\r\n comboCuttingMonth: [],\r\n comboLightLevel: [],\r\n comboHealthState: [],\r\n confirmPhotoRemoval: 'Are you sure you want to remove this photo?',\r\n confirmPlantRemoval: 'Are you sure you want to remove this plant?',\r\n confirmSetAllWatered: 'Are you sure you want to update the last watered date of all these plants?',\r\n confirmSetAllRepotted: 'Are you sure you want to update the last repotted date of all these plants?',\r\n confirmSetAllFertilised: 'Are you sure you want to update the last fertilised date of all these plants?',\r\n confirmInventoryItemRemoval: 'Are you sure you want to remove this item?',\r\n confirmPlantAddHistory: 'Please confirm if you want to do this action.',\r\n confirmPlantRemoveHistory: 'Please confirm if you want to do this action.',\r\n confirmRemovePlantLogEntry: 'Do you really want to remove this entry?',\r\n confirmRemoveLocationLogEntry: 'Do you really want to remove this entry?',\r\n confirmRemoveSharedPlantPhoto: 'Do you really want to remove this item?',\r\n addItem: 'Add',\r\n newChatMessage: 'New',\r\n currentlyOnline: 'Currently online: ',\r\n loadingPleaseWait: 'Please wait...',\r\n noListItemsSelected: 'No items selected',\r\n editProperty: 'Edit property',\r\n loadMore: 'Load more',\r\n operationSucceeded: 'Operation succeeded',\r\n copiedToClipboard: 'Content has been copied to clipboard.',\r\n chatTypingEnable: false,\r\n chatTypingTimer: null,\r\n chatTypingHide: null,\r\n chatTypingCounter: 1\r\n },\r\n\r\n methods: {\r\n ajaxRequest: function (method, url, data = {}, successfunc = function(data){}, finalfunc = function(){}, config = {})\r\n {\r\n let func = window.axios.get;\r\n if (method == 'post') {\r\n func = window.axios.post;\r\n } else if (method == 'patch') {\r\n func = window.axios.patch;\r\n } else if (method == 'delete') {\r\n func = window.axios.delete;\r\n }\r\n\r\n func(url, data, config)\r\n .then(function(response){\r\n successfunc(response.data);\r\n })\r\n .catch(function (error) {\r\n console.log(error);\r\n })\r\n .finally(function(){\r\n finalfunc();\r\n }\r\n );\r\n },\r\n\r\n initNavBar: function()\r\n {\r\n const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);\r\n\r\n if ($navbarBurgers.length > 0) {\r\n $navbarBurgers.forEach( el => {\r\n el.addEventListener('click', () => {\r\n const target = el.dataset.target;\r\n const $target = document.getElementById(target);\r\n\r\n el.classList.toggle('is-active');\r\n $target.classList.toggle('is-active');\r\n });\r\n });\r\n }\r\n },\r\n\r\n showEditText: function(plant, property, defval, anchor = '')\r\n {\r\n document.getElementById('inpEditTextPlantId').value = plant;\r\n document.getElementById('inpEditTextAttribute').value = property;\r\n document.getElementById('inpEditTextValue').value = defval;\r\n document.getElementById('inpEditTextAnchor').value = anchor;\r\n window.vue.bShowEditText = true;\r\n },\r\n\r\n showEditMultilineText: function(plant, property, defval, anchor = '')\r\n {\r\n document.getElementById('inpEditMultilineTextPlantId').value = plant;\r\n document.getElementById('inpEditMultilineTextAttribute').value = property;\r\n document.getElementById('inpEditMultilineTextValue').value = defval;\r\n document.getElementById('inpEditMultilineTextAnchor').value = anchor;\r\n window.vue.bShowEditMultilineText = true;\r\n },\r\n\r\n showEditBoolean: function(plant, property, hint, defval)\r\n {\r\n document.getElementById('inpEditBooleanPlantId').value = plant;\r\n document.getElementById('inpEditBooleanAttribute').value = property;\r\n document.getElementById('property-hint').innerHTML = hint;\r\n\r\n if (defval) {\r\n document.getElementById('inpEditBooleanValue_yes').checked = true;\r\n } else {\r\n document.getElementById('inpEditBooleanValue_no').checked = true;\r\n }\r\n \r\n window.vue.bShowEditBoolean = true;\r\n },\r\n\r\n showEditInteger: function(plant, property, defval)\r\n {\r\n document.getElementById('inpEditIntegerPlantId').value = plant;\r\n document.getElementById('inpEditIntegerAttribute').value = property;\r\n document.getElementById('inpEditIntegerValue').value = defval;\r\n window.vue.bShowEditInteger = true;\r\n },\r\n\r\n showEditDate: function(plant, property, defval)\r\n {\r\n document.getElementById('inpEditDatePlantId').value = plant;\r\n document.getElementById('inpEditDateAttribute').value = property;\r\n document.getElementById('inpEditDateValue').value = defval;\r\n window.vue.bShowEditDate = true;\r\n },\r\n\r\n showEditCombo: function(plant, property, combo, defval)\r\n {\r\n document.getElementById('inpEditComboPlantId').value = plant;\r\n document.getElementById('inpEditComboAttribute').value = property;\r\n \r\n if (typeof combo !== 'object') {\r\n console.error('Invalid combo specified');\r\n return;\r\n }\r\n\r\n let sel = document.getElementById('selEditCombo');\r\n if (sel) {\r\n for (let i = sel.options.length - 1; i >= 0; i--) {\r\n sel.remove(i);\r\n }\r\n\r\n combo.forEach(function(elem, index){\r\n let opt = document.createElement('option');\r\n opt.value = elem.ident;\r\n opt.text = elem.label;\r\n sel.add(opt);\r\n });\r\n }\r\n\r\n document.getElementById('selEditCombo').value = defval;\r\n\r\n window.vue.bShowEditCombo = true;\r\n },\r\n\r\n showEditLinkText: function(plant, text, link)\r\n {\r\n document.getElementById('inpEditLinkTextPlantId').value = plant;\r\n document.getElementById('inpEditLinkTextValue').value = text;\r\n document.getElementById('inpEditLinkTextLink').value = link;\r\n window.vue.bShowEditLinkText = true;\r\n },\r\n\r\n selectDataTypeInputField: function(elem, field) {\r\n if (elem.selectedIndex <= 0) {\r\n return;\r\n }\r\n \r\n field.classList.remove('is-hidden');\r\n\r\n if (!field.children[1].children[0].classList.contains('is-hidden')) {\r\n field.children[1].children[0].classList.add('is-hidden');\r\n }\r\n\r\n if (!field.children[1].children[1].classList.contains('is-hidden')) {\r\n field.children[1].children[1].classList.add('is-hidden');\r\n }\r\n\r\n if (!field.children[1].children[2].classList.contains('is-hidden')) {\r\n field.children[1].children[2].classList.add('is-hidden');\r\n }\r\n\r\n field.children[1].children[0].children[0].children[1].children[0].children[0].disabled = true;\r\n field.children[1].children[0].children[0].children[2].children[0].children[0].disabled = true;\r\n field.children[1].children[1].disabled = true;\r\n field.children[1].children[2].disabled = true;\r\n\r\n if (elem.value === 'bool') {\r\n field.children[1].children[0].classList.remove('is-hidden');\r\n field.children[1].children[0].children[0].children[1].children[0].children[0].disabled = false;\r\n field.children[1].children[0].children[0].children[2].children[0].children[0].disabled = false;\r\n } else if (elem.value === 'datetime') {\r\n field.children[1].children[2].classList.remove('is-hidden');\r\n field.children[1].children[2].disabled = false;\r\n } else {\r\n field.children[1].children[1].classList.remove('is-hidden');\r\n field.children[1].children[1].disabled = false;\r\n }\r\n },\r\n\r\n showEditCustomPlantAttribute: function(id, plant, label, datatype, content, is_global = false)\r\n {\r\n document.getElementById('edit-plant-attribute-attr').value = id;\r\n document.getElementById('edit-plant-attribute-plant').value = plant;\r\n document.getElementById('edit-plant-attribute-label').value = label;\r\n document.getElementById('edit-plant-attribute-datatype').value = datatype;\r\n\r\n let elFieldTarget = document.getElementById('field-custom-edit-attribute-content');\r\n\r\n if (datatype === 'bool') {\r\n if (content == 1) {\r\n elFieldTarget.children[1].children[0].children[0].children[1].children[0].children[0].checked = true;\r\n } else {\r\n elFieldTarget.children[1].children[0].children[0].children[2].children[0].children[0].checked = true;\r\n }\r\n } else if (datatype === 'datetime') {\r\n elFieldTarget.children[1].children[2].value = content;\r\n } else {\r\n elFieldTarget.children[1].children[1].value = content;\r\n }\r\n\r\n window.vue.selectDataTypeInputField(document.querySelector('#edit-plant-attribute-datatype'), elFieldTarget);\r\n\r\n if (is_global) {\r\n document.getElementById('field-custom-edit-attribute-datatype').style.display = 'none';\r\n document.getElementById('plant-custom-attribute-removal-field').style.display = 'none';\r\n } else {\r\n document.getElementById('field-custom-edit-attribute-datatype').style.display = 'inherit';\r\n document.getElementById('plant-custom-attribute-removal-field').style.display = 'inherit';\r\n }\r\n\r\n window.vue.bShowEditCustomPlantAttribute = true;\r\n },\r\n\r\n removeCustomPlantAttribute: function(id, target)\r\n {\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/attributes/remove?id=' + id, {}, function(response){\r\n if (response.code == 200) {\r\n let elem = document.getElementById(target);\r\n if (elem) {\r\n elem.remove();\r\n }\r\n window.vue.bShowEditCustomPlantAttribute = false;\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n saveAllAttributes: function(source) {\r\n const forms = document.querySelector(source).getElementsByTagName('form');\r\n window.vue.bulkSubmitForm(0, forms, 100);\r\n },\r\n\r\n bulkSubmitForm: function(index, forms, delay) {\r\n if (index >= forms.length) {\r\n alert(window.vue.operationSucceeded);\r\n location.reload();\r\n return;\r\n }\r\n\r\n const form = forms[index];\r\n\r\n form.addEventListener('submit', function(event) {\r\n event.preventDefault();\r\n });\r\n\r\n const formData = new FormData(form);\r\n\r\n setTimeout(function() {\r\n fetch(form.action, {\r\n method: form.method || 'POST',\r\n body: formData\r\n }).then(function(response){\r\n return response.text();\r\n }).then(function(data){\r\n window.vue.bulkSubmitForm(index + 1, forms, delay);\r\n }).catch(function(error){\r\n console.error(error);\r\n window.vue.bulkSubmitForm(index + 1, forms, delay);\r\n });\r\n }, delay);\r\n },\r\n\r\n showEditPhoto: function(plant, property, hint = '')\r\n {\r\n document.getElementById('inpEditPhotoPlantId').value = plant;\r\n document.getElementById('inpEditPhotoAttribute').value = property;\r\n\r\n if (hint.length > 0) {\r\n document.getElementById('inpEditPhotoHint').innerHTML = hint;\r\n }\r\n\r\n window.vue.bShowEditPhoto = true;\r\n },\r\n\r\n showPhotoUpload: function(plant)\r\n {\r\n document.getElementById('inpUploadPhotoPlantId').value = plant;\r\n window.vue.bShowUploadPhoto = true;\r\n },\r\n\r\n removePlantPreviewPhoto: function(plant, target) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/details/photo/remove', { plant: plant }, function(response){\r\n if (response.code == 200) {\r\n let elem = document.querySelector(target);\r\n if (elem) {\r\n elem.style.backgroundImage = 'url(' + response.placeholder + ')';\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n deletePhoto: function(photo, plant, target)\r\n {\r\n if (!confirm(window.vue.confirmPhotoRemoval)) {\r\n return;\r\n }\r\n\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/details/gallery/photo/remove', { photo: photo, plant: plant }, function(response){\r\n if (response.code == 200) {\r\n let elem = document.getElementById(target);\r\n if (elem) {\r\n elem.remove();\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n showAddPlantLogEntry: function(plant, anchor = '') {\r\n document.getElementById('inpAddPlantLogEntryPlantId').value = plant;\r\n document.getElementById('inpAddPlantLogEntryAnchor').value = anchor;\r\n window.vue.bShowAddPlantLogEntry = true;\r\n },\r\n\r\n showEditPlantLogEntry: function(id, plant, content, anchor = '') {\r\n document.getElementById('inpEditPlantLogEntryItemId').value = id;\r\n document.getElementById('inpEditPlantLogEntryPlantId').value = plant;\r\n document.getElementById('inpEditPlantLogEntryContent').value = content;\r\n document.getElementById('inpEditPlantLogEntryAnchor').value = anchor;\r\n window.vue.bShowEditPlantLogEntry = true;\r\n },\r\n\r\n removePlantLogEntry: function(id, table_entry) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/log/remove', { item: id }, function(response) {\r\n if (response.code == 200) {\r\n document.getElementById(table_entry).remove();\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n loadNextPlantLogEntries: function(obj, plant, table) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/log/fetch', { plant: plant, paginate: obj.dataset.paginate }, function(response) {\r\n if (response.code == 200) {\r\n let tbody = table.getElementsByTagName('tbody')[0];\r\n\r\n response.data.forEach(function(elem, index) {\r\n let newRow = document.createElement('tr');\r\n newRow.id = 'plant-log-entry-table-row-' + elem.id;\r\n newRow.innerHTML = `\r\n ` + elem.content + `\r\n ` + elem.created_at + ` / ` + elem.updated_at + `\r\n \r\n \r\n  \r\n \r\n \r\n `;\r\n\r\n tbody.appendChild(newRow);\r\n });\r\n\r\n obj.parentNode.parentNode.remove();\r\n\r\n let actionRow = document.createElement('tr');\r\n actionRow.id = 'plant-log-load-more';\r\n actionRow.classList.add('plant-log-paginate');\r\n actionRow.innerHTML = `` + window.vue.loadMore + ``;\r\n tbody.appendChild(actionRow);\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n showAddLocationLogEntry: function(location, anchor = '') {\r\n document.getElementById('inpAddLocationLogEntryLocationId').value = location;\r\n document.getElementById('inpAddLocationLogEntryAnchor').value = anchor;\r\n window.vue.bShowAddLocationLogEntry = true;\r\n },\r\n\r\n showEditLocationLogEntry: function(id, location, content, anchor = '') {\r\n document.getElementById('inpEditLocationLogEntryItemId').value = id;\r\n document.getElementById('inpEditLocationLogEntryLocationId').value = location;\r\n document.getElementById('inpEditLocationLogEntryContent').value = content;\r\n document.getElementById('inpEditLocationLogEntryAnchor').value = anchor;\r\n window.vue.bShowEditLocationLogEntry = true;\r\n },\r\n\r\n removeLocationLogEntry: function(id, table_entry) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/location/log/remove', { item: id }, function(response) {\r\n if (response.code == 200) {\r\n document.getElementById(table_entry).remove();\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n loadNextLocationLogEntries: function(obj, location, table) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/location/log/fetch', { location: location, paginate: obj.dataset.paginate }, function(response) {\r\n if (response.code == 200) {\r\n let tbody = table.getElementsByTagName('tbody')[0];\r\n\r\n response.data.forEach(function(elem, index) {\r\n let newRow = document.createElement('tr');\r\n newRow.id = 'location-log-entry-table-row-' + elem.id;\r\n newRow.innerHTML = `\r\n ` + elem.content + `\r\n ` + elem.created_at + ` / ` + elem.updated_at + `\r\n \r\n \r\n  \r\n \r\n \r\n `;\r\n\r\n tbody.appendChild(newRow);\r\n });\r\n\r\n obj.parentNode.parentNode.remove();\r\n\r\n let actionRow = document.createElement('tr');\r\n actionRow.id = 'location-log-load-more';\r\n actionRow.classList.add('location-log-paginate');\r\n actionRow.innerHTML = `` + window.vue.loadMore + ``;\r\n tbody.appendChild(actionRow);\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n markHistorical: function(plant) {\r\n if (!confirm(window.vue.confirmPlantAddHistory)) {\r\n return;\r\n }\r\n\r\n location.href = window.location.origin + '/plants/history/add?plant=' + plant;\r\n },\r\n\r\n unmarkHistorical: function(plant) {\r\n if (!confirm(window.vue.confirmPlantRemoveHistory)) {\r\n return;\r\n }\r\n\r\n location.href = window.location.origin + '/plants/history/remove?plant=' + plant;\r\n },\r\n\r\n deletePlant: function(plant, retloc)\r\n {\r\n if (!confirm(window.vue.confirmPlantRemoval)) {\r\n return;\r\n }\r\n\r\n location.href = window.location.origin + '/plants/remove?plant=' + plant + '&location=' + retloc;\r\n },\r\n\r\n toggleTaskStatus: function(id)\r\n {\r\n window.vue.ajaxRequest('post', window.location.origin + '/tasks/toggle', { task: id }, function(response){\r\n if (response.code == 200) {\r\n let elem = document.getElementById('task-item-' + id);\r\n if (elem) {\r\n elem.remove();\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n editTask: function(id)\r\n {\r\n document.getElementById('inpEditTaskId').value = id;\r\n document.getElementById('inpEditTaskTitle').value = document.getElementById('task-item-title-' + id).innerText;\r\n document.getElementById('inpEditTaskDescription').value = document.getElementById('task-item-description-' + id).innerText;\r\n document.getElementById('inpEditTaskDueDate').value = document.getElementById('task-item-due-' + id).innerText;\r\n\r\n window.vue.bShowEditTask = true;\r\n },\r\n\r\n removeTask: function(id)\r\n {\r\n window.vue.ajaxRequest('post', window.location.origin + '/tasks/remove', { task: id }, function(response){\r\n if (response.code == 200) {\r\n let elem = document.getElementById('task-item-' + id);\r\n if (elem) {\r\n elem.remove();\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n updateLastWatered: function(id)\r\n {\r\n if (!confirm(window.vue.confirmSetAllWatered)) {\r\n return;\r\n }\r\n\r\n location.href = window.location.origin + '/plants/location/' + id + '/water';\r\n },\r\n\r\n updateLastRepotted: function(id)\r\n {\r\n if (!confirm(window.vue.confirmSetAllRepotted)) {\r\n return;\r\n }\r\n\r\n location.href = window.location.origin + '/plants/location/' + id + '/repot';\r\n },\r\n\r\n updateLastFertilised: function(id)\r\n {\r\n if (!confirm(window.vue.confirmSetAllFertilised)) {\r\n return;\r\n }\r\n\r\n location.href = window.location.origin + '/plants/location/' + id + '/fertilise';\r\n },\r\n\r\n expandInventoryItem: function(id)\r\n {\r\n let elem = document.getElementById(id);\r\n if (elem) {\r\n elem.classList.toggle('expand');\r\n }\r\n },\r\n\r\n incrementInventoryItem: function(id, target)\r\n {\r\n window.vue.ajaxRequest('get', window.location.origin + '/inventory/amount/increment?id=' + id, {}, function(response) {\r\n if (response.code == 200) {\r\n let elem = document.getElementById(target);\r\n if (elem) {\r\n elem.innerHTML = response.amount;\r\n\r\n if (response.amount == 0) {\r\n elem.classList.add('is-inventory-item-empty');\r\n } else {\r\n elem.classList.remove('is-inventory-item-empty');\r\n }\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n decrementInventoryItem: function(id, target)\r\n {\r\n window.vue.ajaxRequest('get', window.location.origin + '/inventory/amount/decrement?id=' + id, {}, function(response) {\r\n if (response.code == 200) {\r\n let elem = document.getElementById(target);\r\n if (elem) {\r\n elem.innerHTML = response.amount;\r\n\r\n if (response.amount == 0) {\r\n elem.classList.add('is-inventory-item-empty');\r\n } else {\r\n elem.classList.remove('is-inventory-item-empty');\r\n }\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n editInventoryItem: function(id, name, group, location, description, amount)\r\n {\r\n document.getElementById('inpInventoryItemId').value = id;\r\n document.getElementById('inpInventoryItemName').value = document.getElementById(name).children[1].innerText;\r\n document.getElementById('inpInventoryItemGroup').value = group;\r\n document.getElementById('inpInventoryItemLocation').value = document.getElementById(location).children[0].innerText;\r\n document.getElementById('inpInventoryItemDescription').value = document.getElementById(description).innerText;\r\n document.getElementById('inpInventoryItemAmount').value = amount;\r\n\r\n window.vue.bShowEditInventoryItem = true;\r\n },\r\n\r\n deleteInventoryItem: function(id, target)\r\n {\r\n if (!confirm(window.vue.confirmInventoryItemRemoval)) {\r\n return;\r\n }\r\n\r\n window.vue.ajaxRequest('get', window.location.origin + '/inventory/remove?id=' + id, {}, function(response) {\r\n if (response.code == 200) {\r\n let elem = document.getElementById(target);\r\n if (elem) {\r\n elem.remove();\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n createInventoryGroup: function(token, label, tbody, button)\r\n {\r\n window.vue.ajaxRequest('post', window.location.origin + '/inventory/group/add', { token: token, label: label }, function(response) {\r\n if (response.code == 200) {\r\n button.innerText = window.vue.addItem;\r\n\r\n let newRow = document.createElement('tr');\r\n newRow.id = 'inventory-group-item-' + response.itemid;\r\n newRow.innerHTML = `\r\n ` + token + `\r\n ` + label + `\r\n \r\n `;\r\n\r\n tbody.appendChild(newRow);\r\n } else {\r\n button.innerText = window.vue.addItem;\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n editInventoryGroupItem: function(id, what, def)\r\n {\r\n let input = prompt(what, def);\r\n\r\n if (input.length > 0) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/inventory/group/edit', {\r\n id: id,\r\n what: what,\r\n value: input\r\n }, function(response) {\r\n if (response.code == 200) {\r\n if (what === 'token') {\r\n document.getElementById('inventory-group-elem-token-' + id).innerText = input;\r\n } else if (what === 'label') {\r\n document.getElementById('inventory-group-elem-label-' + id).innerText = input;\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n }\r\n },\r\n\r\n removeInventoryGroupItem: function(id, target)\r\n {\r\n if (!confirm(window.vue.confirmInventoryItemRemoval)) {\r\n return;\r\n }\r\n\r\n window.vue.ajaxRequest('get', window.location.origin + '/inventory/group/remove?id=' + id, {}, function(response) {\r\n if (response.code == 200) {\r\n let elem = document.getElementById(target);\r\n if (elem) {\r\n elem.remove();\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n refreshChat: function(auth_user)\r\n {\r\n window.vue.ajaxRequest('get', window.location.origin + '/chat/query', {}, function(response) {\r\n if (response.code == 200) {\r\n response.messages.forEach(function(elem, index) {\r\n document.getElementById('chat').innerHTML = window.vue.renderNewChatMessage(elem, auth_user) + document.getElementById('chat').innerHTML;\r\n \r\n let audio = new Audio(window.location.origin + '/snd/new_message.wav');\r\n audio.onloadeddata = function() {\r\n audio.play();\r\n };\r\n });\r\n }\r\n });\r\n\r\n setTimeout(window.vue.refreshChat, window.constChatMessageQueryRefreshRate);\r\n },\r\n\r\n renderNewChatMessage: function(elem, auth_user)\r\n {\r\n let chatmsgright = '';\r\n if (elem.userId == auth_user) {\r\n chatmsgright = 'chat-message-right';\r\n }\r\n\r\n let html = '';\r\n\r\n if (!elem.system) {\r\n html = `\r\n
\r\n
\r\n
` + elem.userName + `
\r\n
` + window.vue.newChatMessage + `
\r\n
\r\n\r\n
\r\n
` + elem.message + `
\r\n
\r\n\r\n
\r\n ` + elem.diffForHumans + `\r\n
\r\n
\r\n `;\r\n } else {\r\n html = `\r\n
\r\n
\r\n
` + ((elem.userName) ? elem.userName : 'System') + ` @ ` + elem.created_at + `
\r\n \r\n
` + elem.message + `
\r\n
\r\n\r\n
\r\n
` + window.vue.newChatMessage + `
\r\n
\r\n
\r\n `;\r\n }\r\n\r\n return html;\r\n },\r\n\r\n refreshUserList: function()\r\n {\r\n window.vue.ajaxRequest('get', window.location.origin + '/chat/user/online', {}, function(response) {\r\n if (response.code == 200) {\r\n let target = document.getElementById('chat-user-list');\r\n target.innerHTML = window.vue.currentlyOnline;\r\n\r\n response.users.forEach(function(elem, index) {\r\n let comma = '';\r\n if (index < response.users.length - 1) {\r\n comma = ', ';\r\n }\r\n \r\n target.innerHTML += elem.name + comma;\r\n });\r\n }\r\n });\r\n\r\n setTimeout(window.vue.refreshUserList, window.constChatUserListRefreshRate);\r\n },\r\n\r\n refreshTypingStatus: function()\r\n {\r\n if (!window.vue.chatTypingEnable) {\r\n return;\r\n }\r\n\r\n window.vue.ajaxRequest('get', window.location.origin + '/chat/typing/update', {}, function(response){\r\n if (response.code != 200) {\r\n console.error(response.msg);\r\n }\r\n });\r\n\r\n setTimeout(function(){\r\n window.vue.chatTypingTimer = null;\r\n }, 5000);\r\n },\r\n\r\n handleChatInput: function()\r\n {\r\n if (!window.vue.chatTypingTimer) {\r\n window.vue.chatTypingTimer = setTimeout(function(){\r\n window.vue.refreshTypingStatus();\r\n }, 1000);\r\n }\r\n },\r\n\r\n handleTypingIndicator: function()\r\n {\r\n window.vue.ajaxRequest('get', window.location.origin + '/chat/typing', {}, function(response){\r\n if (response.code == 200) {\r\n if (response.status) {\r\n let elem = document.getElementsByClassName('chat-typing-indicator')[0];\r\n elem.style.display = 'block';\r\n\r\n window.vue.chatTypingHide = setTimeout(window.vue.hideChatTypingIndicator, 6550);\r\n }\r\n }\r\n });\r\n\r\n setTimeout(window.vue.handleTypingIndicator, window.constChatTypingRefreshRate);\r\n },\r\n\r\n hideChatTypingIndicator: function()\r\n {\r\n if (window.vue.chatTypingHide !== null) {\r\n let elem = document.getElementsByClassName('chat-typing-indicator')[0];\r\n elem.style.display = 'none';\r\n\r\n window.vue.chatTypingHide = null;\r\n }\r\n },\r\n\r\n animateChatTypingIndicator: function()\r\n {\r\n let indicator = document.getElementsByClassName('chat-typing-indicator')[0];\r\n if (indicator.style.display === 'block') {\r\n window.vue.removePreviousChatIndicatorCircleStyle();\r\n\r\n let elem = document.getElementById('chat-typing-circle-' + window.vue.chatTypingCounter.toString());\r\n elem.style.color = 'rgb(50, 50, 50)';\r\n elem.classList.add('fa-lg');\r\n\r\n window.vue.chatTypingCounter++;\r\n if (window.vue.chatTypingCounter > 3) {\r\n window.vue.chatTypingCounter = 1;\r\n }\r\n }\r\n\r\n setTimeout(window.vue.animateChatTypingIndicator, 350);\r\n },\r\n\r\n removePreviousChatIndicatorCircleStyle: function()\r\n {\r\n let previous = window.vue.chatTypingCounter - 1;\r\n if (previous == 0) {\r\n previous = 3;\r\n }\r\n\r\n let elem = document.getElementById('chat-typing-circle-' + previous.toString());\r\n if (elem.classList.contains('fa-lg')) {\r\n elem.classList.remove('fa-lg');\r\n elem.style.color = 'inherit';\r\n }\r\n },\r\n\r\n fetchUnreadMessageCount: function(target) {\r\n window.vue.ajaxRequest('get', window.location.origin + '/chat/messages/count', {}, function(response) {\r\n if (response.code == 200) {\r\n if (response.count > 0) {\r\n target.classList.remove('is-hidden');\r\n target.children[0].innerText = response.count;\r\n } else {\r\n target.classList.add('is-hidden');\r\n }\r\n }\r\n });\r\n\r\n setTimeout(window.vue.fetchUnreadMessageCount.bind(null, target), window.constChatMessageQueryRefreshRate);\r\n },\r\n\r\n fetchNewSystemMessage: function(target) {\r\n window.vue.ajaxRequest('get', window.location.origin + '/chat/system/message/latest', {}, function(response) {\r\n if (response.code == 200) {\r\n if (response.message) {\r\n window.vue.fadeSystemMessage(target, window.vue.renderNewSystemMessage(response.message), response.message.id);\r\n \r\n let audio = new Audio(window.location.origin + '/snd/new_message.wav');\r\n audio.onloadeddata = function() {\r\n audio.play();\r\n };\r\n }\r\n }\r\n });\r\n\r\n setTimeout(window.vue.fetchNewSystemMessage.bind(null, target), window.constChatMessageQueryRefreshRate);\r\n },\r\n\r\n renderNewSystemMessage: function(elem) {\r\n let html = `\r\n
\r\n
` + ((elem.userName) ? elem.userName : 'System') + ` @ ` + elem.created_at + `
\r\n\r\n
` + elem.message + `
\r\n
\r\n `;\r\n\r\n return html;\r\n },\r\n\r\n fadeSystemMessage: function(target, code, id) {\r\n target.innerHTML = code + target.innerHTML;\r\n\r\n let fadeElem = document.getElementById('system-message-small-' + id);\r\n\r\n setTimeout(function() {\r\n fadeElem.classList.replace('fade-out', 'fade-in');\r\n }, 250);\r\n \r\n setTimeout(function() {\r\n fadeElem.classList.replace('fade-in', 'fade-out');\r\n }, 5000);\r\n },\r\n\r\n textFilterElements: function(token) {\r\n let elems = document.getElementsByClassName('plant-filter-text-target');\r\n for (let i = 0; i < elems.length; i++) {\r\n let target = elems[i].parentNode;\r\n \r\n while (!target.classList.contains('plant-filter-text-root')) {\r\n target = target.parentNode;\r\n }\r\n\r\n if (!elems[i].innerText.toLowerCase().includes(token.toLowerCase())) {\r\n target.classList.add('is-hidden');\r\n } else {\r\n target.classList.remove('is-hidden');\r\n }\r\n }\r\n },\r\n\r\n filterTasks: function(token) {\r\n let elems = document.getElementsByClassName('task');\r\n for (let i = 0; i < elems.length; i++) {\r\n let elemTitle = elems[i].children[1].children[0];\r\n let elemDescription = elems[i].children[2].children[0];\r\n\r\n if ((elemTitle.innerText.toLowerCase().includes(token.toLowerCase())) || (elemDescription.innerText.toLowerCase().includes(token.toLowerCase()))) {\r\n elems[i].classList.remove('is-hidden'); \r\n } else {\r\n elems[i].classList.add('is-hidden'); \r\n }\r\n }\r\n },\r\n\r\n filterInventory: function(token) {\r\n let elems = document.getElementsByClassName('inventory-item');\r\n for (let i = 0; i < elems.length; i++) {\r\n let elemName = elems[i].children[1].children[0];\r\n let elemDescription = elems[i].children[2].children[0];\r\n\r\n if ((elemName.innerText.toLowerCase().includes(token.toLowerCase())) || (elemDescription.innerText.toLowerCase().includes(token.toLowerCase()))) {\r\n elems[i].classList.remove('is-hidden'); \r\n } else {\r\n elems[i].classList.add('is-hidden'); \r\n }\r\n }\r\n },\r\n\r\n toggleDropdown: function(elem) {\r\n if (elem.classList.contains('is-active')) {\r\n elem.classList.remove('is-active');\r\n } else {\r\n elem.classList.add('is-active');\r\n }\r\n },\r\n\r\n selectAdminTab: function(tab) {\r\n const tabs = ['environment', 'media', 'users', 'locations', 'attributes', 'calendar', 'mail', 'themes', 'backup', 'weather', 'api', 'info'];\r\n\r\n let selEl = document.querySelector('.admin-' + tab);\r\n if (selEl) {\r\n tabs.forEach(function(elem, index) {\r\n let otherEl = document.querySelector('.admin-' + elem);\r\n if (otherEl) {\r\n otherEl.classList.add('is-hidden');\r\n }\r\n\r\n let otherTabs = document.querySelector('.admin-tab-' + elem);\r\n if (otherTabs) {\r\n otherTabs.classList.remove('is-active');\r\n }\r\n });\r\n\r\n selEl.classList.remove('is-hidden');\r\n\r\n let selTab = document.querySelector('.admin-tab-' + tab);\r\n if (selTab) {\r\n selTab.classList.add('is-active');\r\n }\r\n }\r\n },\r\n\r\n switchAdminTab: function(tab) {\r\n location.href = window.location.origin + '/admin?tab=' + tab;\r\n },\r\n\r\n showImagePreview: function(asset, aspect = 'is-3by5') {\r\n let img = document.getElementById('preview-image-modal-img');\r\n if (img) {\r\n img.src = asset;\r\n\r\n if (window.vue.clsLastImagePreviewAspect.length > 0) {\r\n img.parentNode.classList.remove(window.vue.clsLastImagePreviewAspect);\r\n }\r\n\r\n window.vue.clsLastImagePreviewAspect = aspect;\r\n img.parentNode.classList.add(window.vue.clsLastImagePreviewAspect);\r\n\r\n window.vue.bShowPreviewImageModal = true;\r\n }\r\n },\r\n\r\n showSharePhoto: function(asset, title, type) {\r\n document.getElementById('share-photo-title').value = title;\r\n document.getElementById('share-photo-id').value = asset;\r\n document.getElementById('share-photo-type').value = type;\r\n\r\n document.getElementById('share-photo-result').classList.add('is-hidden');\r\n document.getElementById('share-photo-error').classList.add('is-hidden');\r\n document.getElementById('share-photo-submit-action').classList.remove('is-hidden');\r\n\r\n window.vue.bShowSharePhoto = true;\r\n },\r\n\r\n performPhotoShare: function(asset, title, _public, description, keywords, type, result, button, error) {\r\n let origButtonHtml = button.innerHTML;\r\n button.innerHTML = ' ' + window.vue.loadingPleaseWait;\r\n\r\n window.vue.ajaxRequest('post', window.location.origin + '/share/photo/post', { asset: asset, title: title, public: _public, description: description, keywords: keywords, type: type }, function(response) {\r\n button.innerHTML = origButtonHtml;\r\n\r\n if (response.code == 200) {\r\n result.value = response.data.url;\r\n result.parentNode.parentNode.classList.remove('is-hidden');\r\n button.classList.add('is-hidden');\r\n error.classList.add('is-hidden');\r\n } else {\r\n error.innerHTML = response.msg;\r\n error.classList.remove('is-hidden');\r\n }\r\n });\r\n },\r\n\r\n generateNewToken: function(target, button) {\r\n let oldTxt = button.innerHTML;\r\n button.innerHTML = '';\r\n\r\n window.vue.ajaxRequest('post', window.location.origin + '/admin/cronjob/token', {}, function(response) {\r\n button.innerHTML = oldTxt;\r\n\r\n if (response.code == 200) {\r\n target.value = response.token;\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n startBackup: function(button, plants, gallery, tasks, inventory, calendar) {\r\n let oldText = button.innerHTML;\r\n button.innerHTML = ' ' + oldText;\r\n\r\n window.vue.ajaxRequest('post', window.location.origin + '/export/start', {\r\n plants: plants,\r\n gallery: gallery,\r\n tasks: tasks,\r\n inventory: inventory,\r\n calendar: calendar\r\n }, function(response) {\r\n button.innerHTML = oldText;\r\n\r\n if (response.code == 200) {\r\n let export_result = document.getElementById('export-result');\r\n if (export_result) {\r\n export_result.classList.remove('is-hidden');\r\n\r\n export_result.children[1].href = response.file;\r\n export_result.children[1].innerHTML = response.file;\r\n }\r\n }\r\n });\r\n },\r\n\r\n startImport: function(button, file, locations, plants, gallery, tasks, inventory, calendar) {\r\n let oldText = button.innerHTML;\r\n button.innerHTML = ' ' + oldText;\r\n \r\n let formData = new FormData();\r\n formData.append('import', file.files[0]);\r\n formData.append('locations', ((locations) ? 1 : 0));\r\n formData.append('plants', ((plants) ? 1 : 0));\r\n formData.append('gallery', ((gallery) ? 1 : 0));\r\n formData.append('tasks', ((tasks) ? 1 : 0));\r\n formData.append('inventory', ((inventory) ? 1 : 0));\r\n formData.append('calendar', ((calendar) ? 1 : 0));\r\n\r\n window.vue.ajaxRequest('post', window.location.origin + '/import/start', formData, function(response) {\r\n button.innerHTML = oldText;\r\n\r\n if (response.code == 200) {\r\n let import_result = document.getElementById('import-result');\r\n if (import_result) {\r\n import_result.classList.remove('is-hidden');\r\n }\r\n }\r\n });\r\n },\r\n\r\n startThemeImport: function(file, button) {\r\n let oldText = button.innerHTML;\r\n button.innerHTML = ' ' + oldText;\r\n \r\n let formData = new FormData();\r\n formData.append('theme', file.files[0]);\r\n\r\n window.vue.ajaxRequest('post', window.location.origin + '/admin/themes/import', formData, function(response) {\r\n button.innerHTML = oldText;\r\n \r\n if (response.code == 200) {\r\n let import_result = document.getElementById('themes-import-result');\r\n if (import_result) {\r\n import_result.innerText = import_result.innerText.replace('{count}', response.themes.length);\r\n import_result.classList.remove('is-hidden');\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n removeTheme: function(theme) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/admin/themes/remove', { theme: theme }, function(response) {\r\n if (response.code == 200) {\r\n let tableElem = document.getElementById('admin-themes-list-item-' + theme);\r\n if (tableElem) {\r\n tableElem.remove();\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n renderCalendar: function(elem, date_from, date_till = null) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/calendar/query', { date_from: date_from, date_till: date_till }, function(response){\r\n if (response.code == 200) {\r\n let content = document.getElementById(elem);\r\n if (content) {\r\n let data = response.data;\r\n\r\n data.sort(function (a, b) {\r\n return new Date(a.date_from) - new Date(b.date_from);\r\n });\r\n\r\n const labels = data.map(x => {\r\n return [x.name];\r\n });\r\n\r\n const newData = data.map(x => {\r\n return [x.date_from.split(' ')[0], x.date_till.split(' ')[0], x.class_name, x.id, x.class_descriptor]\r\n });\r\n \r\n let colorsBackground = [];\r\n data.forEach(function(elem, index) {\r\n colorsBackground.push(elem.color_background);\r\n });\r\n \r\n let colorsBorder = [];\r\n data.forEach(function(elem, index) {\r\n colorsBorder.push(elem.color_border);\r\n });\r\n\r\n const config = {\r\n type: 'bar',\r\n data: {\r\n labels: labels,\r\n datasets: [\r\n {\r\n data: newData,\r\n backgroundColor: colorsBackground,\r\n borderColor: colorsBorder,\r\n borderWidth: 1,\r\n fill: false,\r\n barPercentage: 0.3\r\n }\r\n ]\r\n },\r\n options: {\r\n indexAxis: 'y',\r\n responsive: true,\r\n scales: {\r\n x: {\r\n min: response.date_from,\r\n max: response.date_till,\r\n type: 'time',\r\n time: {\r\n unit: 'day'\r\n }\r\n },\r\n y: {\r\n beginAtZero: true\r\n }\r\n },\r\n plugins: {\r\n legend: {\r\n display: false,\r\n },\r\n tooltip: {\r\n callbacks: {\r\n label: function(context) {\r\n return context.dataset.data[context.dataIndex][2];\r\n },\r\n afterBody: function(context) {\r\n return context[0].raw[0] + ' - ' + context[0].raw[1];\r\n }\r\n }\r\n }\r\n },\r\n\r\n }\r\n };\r\n\r\n if (window.calendarChart !== null) {\r\n window.calendarChart.destroy();\r\n }\r\n \r\n window.calendarChart = new chart_js_auto__WEBPACK_IMPORTED_MODULE_1__[\"default\"](\r\n content,\r\n config\r\n );\r\n\r\n content.onclick = function(event) {\r\n let points = window.calendarChart.getElementsAtEventForMode(event, 'nearest', { intersect: true }, true);\r\n if (points.length) {\r\n const firstPoint = points[0];\r\n const label = window.calendarChart.data.labels[firstPoint.index];\r\n const value = window.calendarChart.data.datasets[firstPoint.datasetIndex].data[firstPoint.index];\r\n console.log(value);\r\n if (value.length) {\r\n document.getElementById('inpEditCalendarItemIdent').innerText = '#' + value[3] + ' ' + label;\r\n document.getElementById('inpEditCalendarItemId').value = value[3];\r\n document.getElementById('inpEditCalendarItemName').value = label;\r\n document.getElementById('inpEditCalendarItemDateFrom').value = value[0];\r\n document.getElementById('inpEditCalendarItemDateTill').value = value[1];\r\n document.getElementById('inpEditCalendarItemClass').value = value[4];\r\n window.vue.bShowEditCalendarItem = true;\r\n }\r\n }\r\n };\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n removeCalendarItem: function(ident) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/calendar/remove', { ident: ident }, function(response) {\r\n if (response.code == 200) {\r\n location.reload();\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n removeCalendarClass: function(id) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/admin/calendar/class/remove', { id: id }, function(response) {\r\n if (response.code == 200) {\r\n let elItem = document.getElementById('admin-calendar-class-item-' + id);\r\n if (elItem) {\r\n elItem.remove();\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n clonePlant: function(id) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/clone', { id: id }, function(response) {\r\n if (response.code == 200) {\r\n location.href = window.location.origin + '/plants/details/' + response.clone_id;\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n showPerformBulkUpdate: function(operation, title, button, location, is_custom = false) {\r\n document.getElementById('plant-bulk-perform-operation-operation').value = operation;\r\n document.getElementById('plant-bulk-perform-operation-location').value = location;\r\n document.getElementById('plant-bulk-perform-operation-title').innerText = title;\r\n document.getElementById('plant-bulk-perform-operation-button').innerText = button;\r\n document.getElementById('plant-bulk-perform-operation-custom').checked = is_custom;\r\n\r\n window.vue.bulkChecked('plant-bulk-perform-operation', false);\r\n\r\n window.vue.bShowPlantBulkPerformUpdate = true;\r\n },\r\n\r\n bulkPerformPlantUpdate: function(target, attribute, location, is_custom = false) {\r\n let plantIds = [];\r\n\r\n let elems = document.getElementsByClassName(target);\r\n if (elems) {\r\n Array.prototype.forEach.call(elems, function(elem) {\r\n if (elem.checked) {\r\n plantIds.push([elem.dataset.plantid, elem.dataset.plantname]);\r\n }\r\n });\r\n \r\n if (plantIds.length > 0) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/update/bulk', { attribute: attribute, list: JSON.stringify(plantIds), location: location, custom: is_custom }, function(response) {\r\n if (response.code == 200) {\r\n alert(window.vue.operationSucceeded);\r\n window.vue.bShowPlantBulkPerformUpdate = false;\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n } else {\r\n alert(window.vue.noListItemsSelected); \r\n }\r\n }\r\n },\r\n\r\n generateAndShowQRCode: function(plant) {\r\n window.vue.ajaxRequest('get', window.location.origin + '/plants/qrcode?plant=' + plant, {}, function(response) {\r\n if (response.code == 200) {\r\n let elTarget = document.getElementById('image-plant-qr-code');\r\n if (elTarget) {\r\n elTarget.src = response.qrcode;\r\n window.vue.bShowPlantQRCode = true;\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n printQRCode: function(content, title) {\r\n let wnd = window.open('', title, 'height=auto, width=auto');\r\n\r\n wnd.document.write('' + title + '');\r\n wnd.document.write('');\r\n wnd.document.write('');\r\n\r\n wnd.print();\r\n wnd.close();\r\n },\r\n\r\n bulkChecked: function(target, flag) {\r\n let elems = document.getElementsByClassName(target);\r\n \r\n if (elems) {\r\n Array.prototype.forEach.call(elems, function(elem){ \r\n elem.checked = flag; \r\n });\r\n }\r\n },\r\n\r\n bulkPrintQRCodes: function(target, location) {\r\n let plantIds = [];\r\n\r\n let elems = document.getElementsByClassName(target);\r\n if (elems) {\r\n Array.prototype.forEach.call(elems, function(elem) {\r\n if (elem.checked) {\r\n plantIds.push([elem.dataset.plantid, elem.dataset.plantname]);\r\n }\r\n });\r\n\r\n if (plantIds.length > 0) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/qrcode/bulk', { list: JSON.stringify(plantIds) }, function(response) {\r\n if (response.code == 200) {\r\n let wnd = window.open('', location, 'height=auto, width=auto');\r\n\r\n wnd.document.write('' + location + '');\r\n\r\n response.list.forEach(function(elem, index) {\r\n wnd.document.write('
#' + elem.plantid + ' ' + elem.plantname + '
');\r\n });\r\n\r\n wnd.document.write('');\r\n\r\n wnd.print();\r\n wnd.close();\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n } else {\r\n alert(window.vue.noListItemsSelected); \r\n }\r\n }\r\n },\r\n\r\n queryInvQrCode: function(item) {\r\n window.vue.ajaxRequest('get', window.location.origin + '/inventory/qrcode?item=' + item, {}, function(response) {\r\n if (response.code == 200) {\r\n let elTarget = document.getElementById('image-inventory-qr-code');\r\n if (elTarget) {\r\n elTarget.src = response.qrcode;\r\n window.vue.bShowInvItemQRCode = true;\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n bulkPrintInvQRCodes: function(target, title) {\r\n let invIds = [];\r\n\r\n let elems = document.getElementsByClassName(target);\r\n if (elems) {\r\n Array.prototype.forEach.call(elems, function(elem) {\r\n if (elem.checked) {\r\n invIds.push([elem.dataset.invitemid, elem.dataset.invitemname, elem.dataset.invgroup]);\r\n }\r\n });\r\n\r\n if (invIds.length > 0) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/inventory/qrcode/bulk', { list: JSON.stringify(invIds) }, function(response) {\r\n if (response.code == 200) {\r\n let wnd = window.open('', title, 'height=auto, width=auto');\r\n\r\n wnd.document.write('' + title + '');\r\n\r\n response.list.forEach(function(elem, index) {\r\n wnd.document.write('
#' + elem.invitemid + ' [' + elem.invgroup + '] ' + elem.invitemname + '
');\r\n });\r\n\r\n wnd.document.write('');\r\n\r\n wnd.print();\r\n wnd.close();\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n } else {\r\n alert(window.vue.noListItemsSelected); \r\n }\r\n }\r\n },\r\n\r\n bulkExportInventory: function(target, format, title) {\r\n let invIds = [];\r\n\r\n let elems = document.getElementsByClassName(target);\r\n if (elems) {\r\n Array.prototype.forEach.call(elems, function(elem) {\r\n if (elem.checked) {\r\n invIds.push([elem.dataset.invitemid, elem.dataset.invitemname, document.getElementById(elem.dataset.invdescription).innerText, elem.dataset.invgroup, elem.dataset.invamount, elem.dataset.invlocation, elem.dataset.invphoto, elem.dataset.invcreated, elem.dataset.invupdated]);\r\n }\r\n });\r\n\r\n if (invIds.length > 0) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/inventory/export', { list: JSON.stringify(invIds), format: document.getElementById(format).value }, function(response) {\r\n if (response.code == 200) {\r\n const dlanchor = document.createElement('a');\r\n dlanchor.href = response.resource;\r\n dlanchor.target = '_blank';\r\n dlanchor.setAttribute('download', response.resource);\r\n dlanchor.click();\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n } else {\r\n alert(window.vue.noListItemsSelected); \r\n }\r\n }\r\n },\r\n\r\n editGalleryPhotoLabel: function(id, plant, old) {\r\n let newLabel = prompt(window.vue.editProperty, old);\r\n if (newLabel.length) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/details/gallery/photo/label/edit', { id: id, label: newLabel, plant: plant }, function(response) {\r\n if (response.code == 200) {\r\n document.getElementById('photo-gallery-item-' + id).children[0].children[0].innerHTML = newLabel;\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n }\r\n },\r\n\r\n removeSharedPhoto: function(ident) {\r\n window.vue.ajaxRequest('get', window.location.origin + '/share/photo/remove?ident=' + ident, {}, function(response) {\r\n if (response.code == 200) {\r\n let elem = document.getElementById('photo-share-entry-' + ident);\r\n if (elem) {\r\n elem.remove();\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n loadNextShareLogEntries: function(table, action) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/profile/sharelog/fetch', { paginate: action.dataset.paginate }, function(response) {\r\n if (response.code == 200) {\r\n let tbody = table.getElementsByTagName('tbody')[0];\r\n\r\n response.data.forEach(function(elem, index) {\r\n let newRow = document.createElement('tr');\r\n newRow.id = 'photo-share-entry-' + elem.id;\r\n newRow.innerHTML = `\r\n ` + elem.title + `\r\n ` + elem.diffForHumans + `\r\n \r\n `;\r\n\r\n tbody.appendChild(newRow);\r\n });\r\n\r\n action.parentNode.parentNode.remove();\r\n\r\n let actionRow = document.createElement('tr');\r\n actionRow.id = 'share-log-load-more';\r\n actionRow.classList.add('share-log-paginate');\r\n actionRow.innerHTML = `` + window.vue.loadMore + ``;\r\n tbody.appendChild(actionRow);\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n acquireGeoPosition: function(destLatitude, destLongitude, button) {\r\n let oldText = button.innerHTML;\r\n button.innerHTML = ' ' + button.innerHTML;\r\n\r\n if (navigator.geolocation) {\r\n navigator.geolocation.getCurrentPosition(function(position) {\r\n destLatitude.value = position.coords.latitude;\r\n destLongitude.value = position.coords.longitude;\r\n\r\n button.innerHTML = oldText;\r\n });\r\n } else {\r\n button.innerHTML = oldText;\r\n \r\n alert('Geolocation is not available');\r\n }\r\n },\r\n\r\n toggleApiKey: function(id) {\r\n window.vue.ajaxRequest('get', window.location.origin + '/admin/api/' + id + '/toggle', {}, function(response) {\r\n if (response.code == 200) {\r\n document.getElementById('api-key-checkbox-' + id).checked = response.active;\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n toggleAdminPlantAttribute: function(name) {\r\n window.vue.ajaxRequest('get', window.location.origin + '/admin/attribute/update?name=' + name, {}, function(response) {\r\n if (response.code == 200) {\r\n document.getElementById('admin-attributes-checkbox-' + name).checked = response.active;\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n toggleAdminBoolSetting: function(name) {\r\n window.vue.ajaxRequest('get', window.location.origin + '/admin/environment/boolean/toggle?name=' + name, {}, function(response) {\r\n if (response.code == 200) {\r\n document.getElementById('admin-attributes-checkbox-allow-custom-attributes').checked = response.value;\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n toggleAdminAuthInfoMessages: function(checked, warning, caution) {\r\n let elWarning = document.querySelector(warning);\r\n let elCaution = document.querySelector(caution);\r\n\r\n if (checked) {\r\n if (elWarning) {\r\n elWarning.style.display = 'block';\r\n }\r\n\r\n if (elCaution) {\r\n elCaution.style.display = 'block';\r\n }\r\n } else {\r\n if (elWarning) {\r\n elWarning.style.display = 'none';\r\n }\r\n\r\n if (elCaution) {\r\n elCaution.style.display = 'none';\r\n }\r\n }\r\n },\r\n\r\n performPlantRecognition: function(target, plantid) {\r\n const form = document.getElementById(target);\r\n const data = new FormData(form);\r\n\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/details/identify', data, function(response) {\r\n if (response.code == 200) {\r\n let dest = document.getElementById('recognized-plant-selection');\r\n\r\n dest.innerHTML = '
';\r\n\r\n response.data.forEach(function(elem, index) {\r\n dest.innerHTML += `\r\n
\r\n
\r\n  ` + elem.species.scientificNameWithoutAuthor + ` (` + (elem.score * 100).toFixed(2) + '%)' + `\r\n
\r\n
\r\n `;\r\n });\r\n\r\n dest.innerHTML += '
';\r\n\r\n document.getElementById('plant-rec-action-icon').classList.remove('fa-spinner');\r\n document.getElementById('plant-rec-action-icon').classList.remove('fa-spin');\r\n document.getElementById('plant-rec-action-icon').classList.add('fa-microscope');\r\n\r\n window.vue.bShowSelectRecognizedPlant = true;\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n storeRecognizedPlantData: function(target) {\r\n const selection = document.getElementById(target).getElementsByTagName('input');\r\n\r\n for (let i = 0; i < selection.length; i++) {\r\n if (selection[i].checked) {\r\n const item = selection[i];\r\n\r\n window.plantRecStorageStep = 0;\r\n window.plantRecErrorCount = 0;\r\n\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/details/edit/ajax', {\r\n plant: item.dataset.plantid,\r\n attribute: 'name',\r\n value: item.dataset.plantname\r\n }, function(response) {\r\n window.plantRecStorageStep++;\r\n \r\n if (response.code == 500) {\r\n window.plantRecErrorCount++;\r\n alert(response.msg);\r\n }\r\n });\r\n\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/details/edit/ajax', {\r\n plant: item.dataset.plantid,\r\n attribute: 'scientific_name',\r\n value: item.dataset.plantscientificname\r\n }, function(response) {\r\n window.plantRecStorageStep++;\r\n\r\n if (response.code == 500) {\r\n window.plantRecErrorCount++;\r\n alert(response.msg);\r\n }\r\n });\r\n\r\n setTimeout(function awaitPlantAttributeStorage() {\r\n if (window.plantRecStorageStep < 2) {\r\n setTimeout(awaitPlantAttributeStorage, 1000);\r\n } else {\r\n location.reload();\r\n }\r\n }, 100);\r\n\r\n break;\r\n }\r\n }\r\n },\r\n\r\n copyToClipboard: function(text) {\r\n const el = document.createElement('textarea');\r\n el.value = text;\r\n document.body.appendChild(el);\r\n el.select();\r\n document.execCommand('copy');\r\n document.body.removeChild(el);\r\n alert(window.vue.copiedToClipboard);\r\n },\r\n\r\n isProgressiveWebApp: function() {\r\n return window.matchMedia('(display-mode: standalone)').matches;\r\n },\r\n }\r\n});\n\n//# sourceURL=webpack://asatruphp/./app/resources/js/app.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _sass_app_scss__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./../sass/app.scss */ \"./app/resources/sass/app.scss\");\n/* harmony import */ var _sass_app_scss__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_sass_app_scss__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var chart_js_auto__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! chart.js/auto */ \"./node_modules/chart.js/auto/auto.js\");\n/* harmony import */ var chartjs_adapter_date_fns__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! chartjs-adapter-date-fns */ \"./node_modules/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.esm.js\");\n/**\r\n * app.js\r\n * \r\n * Put here your application specific JavaScript implementations\r\n */\r\n\r\n\r\n\r\nwindow.axios = __webpack_require__(/*! axios */ \"./node_modules/axios/dist/browser/axios.cjs\");\r\nwindow.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';\r\n\r\n\r\n\r\n\r\nwindow.constChatMessageQueryRefreshRate = 1000 * 15;\r\nwindow.constChatUserListRefreshRate = 1000 * 15;\r\nwindow.constChatTypingRefreshRate = 2000;\r\n\r\nwindow.vue = new Vue({\r\n el: '#app',\r\n\r\n data: {\r\n bShowAddPlant: false,\r\n bShowEditText: false,\r\n bShowEditMultilineText: false,\r\n bShowEditBoolean: false,\r\n bShowEditInteger: false,\r\n bShowEditDate: false,\r\n bShowEditCombo: false,\r\n bShowEditPhoto: false,\r\n bShowEPUrl: false,\r\n bShowEditLinkText: false,\r\n bShowUploadPhoto: false,\r\n bShowSetPhotoURL: false,\r\n bShowCreateTask: false,\r\n bShowEditTask: false,\r\n bShowEditPreferences: false,\r\n bShowAddInventoryItem: false,\r\n bShowEditInventoryItem: false,\r\n bShowInvItemQRCode: false,\r\n bShowInventoryBulkPrint: false,\r\n bShowInventoryExport: false,\r\n bShowManageGroups: false,\r\n bShowRestorePassword: false,\r\n bShowCreateNewUser: false,\r\n bShowCreateNewLocation: false,\r\n bShowRemoveLocation: false,\r\n bShowPreviewImageModal: false,\r\n bShowSharePhoto: false,\r\n bShowAddFirstLocation: false,\r\n bShowAddCalendarItem: false,\r\n bShowEditCalendarItem: false,\r\n bShowCreateNewCalendarClass: false,\r\n bShowPlantQRCode: false,\r\n bShowPlantBulkPerformUpdate: false,\r\n bShowPlantBulkPrint: false,\r\n bShowAddCustomPlantAttribute: false,\r\n bShowEditCustomPlantAttribute: false,\r\n bShowCreateNewAttributeSchema: false,\r\n bShowAddPlantLogEntry: false,\r\n bShowEditPlantLogEntry: false,\r\n bShowAddLocationLogEntry: false,\r\n bShowEditLocationLogEntry: false,\r\n bShowCreateNewBulkCmd: false,\r\n bShowSelectRecognizedPlant: false,\r\n clsLastImagePreviewAspect: '',\r\n comboLocation: [],\r\n comboCuttingMonth: [],\r\n comboLightLevel: [],\r\n comboHealthState: [],\r\n confirmPhotoRemoval: 'Are you sure you want to remove this photo?',\r\n confirmPlantRemoval: 'Are you sure you want to remove this plant?',\r\n confirmSetAllWatered: 'Are you sure you want to update the last watered date of all these plants?',\r\n confirmSetAllRepotted: 'Are you sure you want to update the last repotted date of all these plants?',\r\n confirmSetAllFertilised: 'Are you sure you want to update the last fertilised date of all these plants?',\r\n confirmInventoryItemRemoval: 'Are you sure you want to remove this item?',\r\n confirmPlantAddHistory: 'Please confirm if you want to do this action.',\r\n confirmPlantRemoveHistory: 'Please confirm if you want to do this action.',\r\n confirmRemovePlantLogEntry: 'Do you really want to remove this entry?',\r\n confirmRemoveLocationLogEntry: 'Do you really want to remove this entry?',\r\n confirmRemoveSharedPlantPhoto: 'Do you really want to remove this item?',\r\n addItem: 'Add',\r\n newChatMessage: 'New',\r\n currentlyOnline: 'Currently online: ',\r\n loadingPleaseWait: 'Please wait...',\r\n noListItemsSelected: 'No items selected',\r\n editProperty: 'Edit property',\r\n loadMore: 'Load more',\r\n operationSucceeded: 'Operation succeeded',\r\n copiedToClipboard: 'Content has been copied to clipboard.',\r\n chatTypingEnable: false,\r\n chatTypingTimer: null,\r\n chatTypingHide: null,\r\n chatTypingCounter: 1\r\n },\r\n\r\n methods: {\r\n ajaxRequest: function (method, url, data = {}, successfunc = function(data){}, finalfunc = function(){}, config = {})\r\n {\r\n let func = window.axios.get;\r\n if (method == 'post') {\r\n func = window.axios.post;\r\n } else if (method == 'patch') {\r\n func = window.axios.patch;\r\n } else if (method == 'delete') {\r\n func = window.axios.delete;\r\n }\r\n\r\n func(url, data, config)\r\n .then(function(response){\r\n successfunc(response.data);\r\n })\r\n .catch(function (error) {\r\n console.log(error);\r\n })\r\n .finally(function(){\r\n finalfunc();\r\n }\r\n );\r\n },\r\n\r\n initNavBar: function()\r\n {\r\n const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);\r\n\r\n if ($navbarBurgers.length > 0) {\r\n $navbarBurgers.forEach( el => {\r\n el.addEventListener('click', () => {\r\n const target = el.dataset.target;\r\n const $target = document.getElementById(target);\r\n\r\n el.classList.toggle('is-active');\r\n $target.classList.toggle('is-active');\r\n });\r\n });\r\n }\r\n },\r\n\r\n showEditText: function(plant, property, defval, anchor = '')\r\n {\r\n document.getElementById('inpEditTextPlantId').value = plant;\r\n document.getElementById('inpEditTextAttribute').value = property;\r\n document.getElementById('inpEditTextValue').value = defval;\r\n document.getElementById('inpEditTextAnchor').value = anchor;\r\n window.vue.bShowEditText = true;\r\n },\r\n\r\n showEditMultilineText: function(plant, property, defval, anchor = '')\r\n {\r\n document.getElementById('inpEditMultilineTextPlantId').value = plant;\r\n document.getElementById('inpEditMultilineTextAttribute').value = property;\r\n document.getElementById('inpEditMultilineTextValue').value = defval;\r\n document.getElementById('inpEditMultilineTextAnchor').value = anchor;\r\n window.vue.bShowEditMultilineText = true;\r\n },\r\n\r\n showEditBoolean: function(plant, property, hint, defval)\r\n {\r\n document.getElementById('inpEditBooleanPlantId').value = plant;\r\n document.getElementById('inpEditBooleanAttribute').value = property;\r\n document.getElementById('property-hint').innerHTML = hint;\r\n\r\n if (defval) {\r\n document.getElementById('inpEditBooleanValue_yes').checked = true;\r\n } else {\r\n document.getElementById('inpEditBooleanValue_no').checked = true;\r\n }\r\n \r\n window.vue.bShowEditBoolean = true;\r\n },\r\n\r\n showEditInteger: function(plant, property, defval)\r\n {\r\n document.getElementById('inpEditIntegerPlantId').value = plant;\r\n document.getElementById('inpEditIntegerAttribute').value = property;\r\n document.getElementById('inpEditIntegerValue').value = defval;\r\n window.vue.bShowEditInteger = true;\r\n },\r\n\r\n showEditDate: function(plant, property, defval)\r\n {\r\n document.getElementById('inpEditDatePlantId').value = plant;\r\n document.getElementById('inpEditDateAttribute').value = property;\r\n document.getElementById('inpEditDateValue').value = defval;\r\n window.vue.bShowEditDate = true;\r\n },\r\n\r\n showEditCombo: function(plant, property, combo, defval)\r\n {\r\n document.getElementById('inpEditComboPlantId').value = plant;\r\n document.getElementById('inpEditComboAttribute').value = property;\r\n \r\n if (typeof combo !== 'object') {\r\n console.error('Invalid combo specified');\r\n return;\r\n }\r\n\r\n let sel = document.getElementById('selEditCombo');\r\n if (sel) {\r\n for (let i = sel.options.length - 1; i >= 0; i--) {\r\n sel.remove(i);\r\n }\r\n\r\n combo.forEach(function(elem, index){\r\n let opt = document.createElement('option');\r\n opt.value = elem.ident;\r\n opt.text = elem.label;\r\n sel.add(opt);\r\n });\r\n }\r\n\r\n document.getElementById('selEditCombo').value = defval;\r\n\r\n window.vue.bShowEditCombo = true;\r\n },\r\n\r\n showEditLinkText: function(plant, text, link)\r\n {\r\n document.getElementById('inpEditLinkTextPlantId').value = plant;\r\n document.getElementById('inpEditLinkTextValue').value = text;\r\n document.getElementById('inpEditLinkTextLink').value = link;\r\n window.vue.bShowEditLinkText = true;\r\n },\r\n\r\n selectDataTypeInputField: function(elem, field) {\r\n if (elem.selectedIndex <= 0) {\r\n return;\r\n }\r\n \r\n field.classList.remove('is-hidden');\r\n\r\n if (!field.children[1].children[0].classList.contains('is-hidden')) {\r\n field.children[1].children[0].classList.add('is-hidden');\r\n }\r\n\r\n if (!field.children[1].children[1].classList.contains('is-hidden')) {\r\n field.children[1].children[1].classList.add('is-hidden');\r\n }\r\n\r\n if (!field.children[1].children[2].classList.contains('is-hidden')) {\r\n field.children[1].children[2].classList.add('is-hidden');\r\n }\r\n\r\n field.children[1].children[0].children[0].children[1].children[0].children[0].disabled = true;\r\n field.children[1].children[0].children[0].children[2].children[0].children[0].disabled = true;\r\n field.children[1].children[1].disabled = true;\r\n field.children[1].children[2].disabled = true;\r\n\r\n if (elem.value === 'bool') {\r\n field.children[1].children[0].classList.remove('is-hidden');\r\n field.children[1].children[0].children[0].children[1].children[0].children[0].disabled = false;\r\n field.children[1].children[0].children[0].children[2].children[0].children[0].disabled = false;\r\n } else if (elem.value === 'datetime') {\r\n field.children[1].children[2].classList.remove('is-hidden');\r\n field.children[1].children[2].disabled = false;\r\n } else {\r\n field.children[1].children[1].classList.remove('is-hidden');\r\n field.children[1].children[1].disabled = false;\r\n }\r\n },\r\n\r\n showEditCustomPlantAttribute: function(id, plant, label, datatype, content, is_global = false)\r\n {\r\n document.getElementById('edit-plant-attribute-attr').value = id;\r\n document.getElementById('edit-plant-attribute-plant').value = plant;\r\n document.getElementById('edit-plant-attribute-label').value = label;\r\n document.getElementById('edit-plant-attribute-datatype').value = datatype;\r\n\r\n let elFieldTarget = document.getElementById('field-custom-edit-attribute-content');\r\n\r\n if (datatype === 'bool') {\r\n if (content == 1) {\r\n elFieldTarget.children[1].children[0].children[0].children[1].children[0].children[0].checked = true;\r\n } else {\r\n elFieldTarget.children[1].children[0].children[0].children[2].children[0].children[0].checked = true;\r\n }\r\n } else if (datatype === 'datetime') {\r\n elFieldTarget.children[1].children[2].value = content;\r\n } else {\r\n elFieldTarget.children[1].children[1].value = content;\r\n }\r\n\r\n window.vue.selectDataTypeInputField(document.querySelector('#edit-plant-attribute-datatype'), elFieldTarget);\r\n\r\n if (is_global) {\r\n document.getElementById('field-custom-edit-attribute-datatype').style.display = 'none';\r\n document.getElementById('plant-custom-attribute-removal-field').style.display = 'none';\r\n } else {\r\n document.getElementById('field-custom-edit-attribute-datatype').style.display = 'inherit';\r\n document.getElementById('plant-custom-attribute-removal-field').style.display = 'inherit';\r\n }\r\n\r\n window.vue.bShowEditCustomPlantAttribute = true;\r\n },\r\n\r\n removeCustomPlantAttribute: function(id, target)\r\n {\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/attributes/remove?id=' + id, {}, function(response){\r\n if (response.code == 200) {\r\n let elem = document.getElementById(target);\r\n if (elem) {\r\n elem.remove();\r\n }\r\n window.vue.bShowEditCustomPlantAttribute = false;\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n saveAllAttributes: function(source) {\r\n const forms = document.querySelector(source).getElementsByTagName('form');\r\n window.vue.bulkSubmitForm(0, forms, 100);\r\n },\r\n\r\n bulkSubmitForm: function(index, forms, delay) {\r\n if (index >= forms.length) {\r\n alert(window.vue.operationSucceeded);\r\n location.reload();\r\n return;\r\n }\r\n\r\n const form = forms[index];\r\n\r\n form.addEventListener('submit', function(event) {\r\n event.preventDefault();\r\n });\r\n\r\n const formData = new FormData(form);\r\n\r\n setTimeout(function() {\r\n fetch(form.action, {\r\n method: form.method || 'POST',\r\n body: formData\r\n }).then(function(response){\r\n return response.text();\r\n }).then(function(data){\r\n window.vue.bulkSubmitForm(index + 1, forms, delay);\r\n }).catch(function(error){\r\n console.error(error);\r\n window.vue.bulkSubmitForm(index + 1, forms, delay);\r\n });\r\n }, delay);\r\n },\r\n\r\n showEditPhoto: function(plant, property, hint = '')\r\n {\r\n document.getElementById('inpEditPhotoPlantId').value = plant;\r\n document.getElementById('inpEditPhotoAttribute').value = property;\r\n\r\n if (hint.length > 0) {\r\n document.getElementById('inpEditPhotoHint').innerHTML = hint;\r\n }\r\n\r\n window.vue.bShowEditPhoto = true;\r\n },\r\n\r\n showPhotoUpload: function(plant)\r\n {\r\n document.getElementById('inpUploadPhotoPlantId').value = plant;\r\n window.vue.bShowUploadPhoto = true;\r\n },\r\n\r\n removePlantPreviewPhoto: function(plant, target) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/details/photo/remove', { plant: plant }, function(response){\r\n if (response.code == 200) {\r\n let elem = document.querySelector(target);\r\n if (elem) {\r\n elem.style.backgroundImage = 'url(' + response.placeholder + ')';\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n deletePhoto: function(photo, plant, target)\r\n {\r\n if (!confirm(window.vue.confirmPhotoRemoval)) {\r\n return;\r\n }\r\n\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/details/gallery/photo/remove', { photo: photo, plant: plant }, function(response){\r\n if (response.code == 200) {\r\n let elem = document.getElementById(target);\r\n if (elem) {\r\n elem.remove();\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n showAddPlantLogEntry: function(plant, anchor = '') {\r\n document.getElementById('inpAddPlantLogEntryPlantId').value = plant;\r\n document.getElementById('inpAddPlantLogEntryAnchor').value = anchor;\r\n window.vue.bShowAddPlantLogEntry = true;\r\n },\r\n\r\n showEditPlantLogEntry: function(id, plant, content, anchor = '') {\r\n document.getElementById('inpEditPlantLogEntryItemId').value = id;\r\n document.getElementById('inpEditPlantLogEntryPlantId').value = plant;\r\n document.getElementById('inpEditPlantLogEntryContent').value = content;\r\n document.getElementById('inpEditPlantLogEntryAnchor').value = anchor;\r\n window.vue.bShowEditPlantLogEntry = true;\r\n },\r\n\r\n removePlantLogEntry: function(id, table_entry) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/log/remove', { item: id }, function(response) {\r\n if (response.code == 200) {\r\n document.getElementById(table_entry).remove();\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n loadNextPlantLogEntries: function(obj, plant, table) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/log/fetch', { plant: plant, paginate: obj.dataset.paginate }, function(response) {\r\n if (response.code == 200) {\r\n let tbody = table.getElementsByTagName('tbody')[0];\r\n\r\n response.data.forEach(function(elem, index) {\r\n let newRow = document.createElement('tr');\r\n newRow.id = 'plant-log-entry-table-row-' + elem.id;\r\n newRow.innerHTML = `\r\n ` + elem.content + `\r\n ` + elem.created_at + ` / ` + elem.updated_at + `\r\n \r\n \r\n  \r\n \r\n \r\n `;\r\n\r\n tbody.appendChild(newRow);\r\n });\r\n\r\n obj.parentNode.parentNode.remove();\r\n\r\n let actionRow = document.createElement('tr');\r\n actionRow.id = 'plant-log-load-more';\r\n actionRow.classList.add('plant-log-paginate');\r\n actionRow.innerHTML = `` + window.vue.loadMore + ``;\r\n tbody.appendChild(actionRow);\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n showAddLocationLogEntry: function(location, anchor = '') {\r\n document.getElementById('inpAddLocationLogEntryLocationId').value = location;\r\n document.getElementById('inpAddLocationLogEntryAnchor').value = anchor;\r\n window.vue.bShowAddLocationLogEntry = true;\r\n },\r\n\r\n showEditLocationLogEntry: function(id, location, content, anchor = '') {\r\n document.getElementById('inpEditLocationLogEntryItemId').value = id;\r\n document.getElementById('inpEditLocationLogEntryLocationId').value = location;\r\n document.getElementById('inpEditLocationLogEntryContent').value = content;\r\n document.getElementById('inpEditLocationLogEntryAnchor').value = anchor;\r\n window.vue.bShowEditLocationLogEntry = true;\r\n },\r\n\r\n removeLocationLogEntry: function(id, table_entry) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/location/log/remove', { item: id }, function(response) {\r\n if (response.code == 200) {\r\n document.getElementById(table_entry).remove();\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n loadNextLocationLogEntries: function(obj, location, table) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/location/log/fetch', { location: location, paginate: obj.dataset.paginate }, function(response) {\r\n if (response.code == 200) {\r\n let tbody = table.getElementsByTagName('tbody')[0];\r\n\r\n response.data.forEach(function(elem, index) {\r\n let newRow = document.createElement('tr');\r\n newRow.id = 'location-log-entry-table-row-' + elem.id;\r\n newRow.innerHTML = `\r\n ` + elem.content + `\r\n ` + elem.created_at + ` / ` + elem.updated_at + `\r\n \r\n \r\n  \r\n \r\n \r\n `;\r\n\r\n tbody.appendChild(newRow);\r\n });\r\n\r\n obj.parentNode.parentNode.remove();\r\n\r\n let actionRow = document.createElement('tr');\r\n actionRow.id = 'location-log-load-more';\r\n actionRow.classList.add('location-log-paginate');\r\n actionRow.innerHTML = `` + window.vue.loadMore + ``;\r\n tbody.appendChild(actionRow);\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n markHistorical: function(plant) {\r\n if (!confirm(window.vue.confirmPlantAddHistory)) {\r\n return;\r\n }\r\n\r\n location.href = window.location.origin + '/plants/history/add?plant=' + plant;\r\n },\r\n\r\n unmarkHistorical: function(plant) {\r\n if (!confirm(window.vue.confirmPlantRemoveHistory)) {\r\n return;\r\n }\r\n\r\n location.href = window.location.origin + '/plants/history/remove?plant=' + plant;\r\n },\r\n\r\n deletePlant: function(plant, retloc)\r\n {\r\n if (!confirm(window.vue.confirmPlantRemoval)) {\r\n return;\r\n }\r\n\r\n location.href = window.location.origin + '/plants/remove?plant=' + plant + '&location=' + retloc;\r\n },\r\n\r\n toggleTaskStatus: function(id)\r\n {\r\n window.vue.ajaxRequest('post', window.location.origin + '/tasks/toggle', { task: id }, function(response){\r\n if (response.code == 200) {\r\n let elem = document.getElementById('task-item-' + id);\r\n if (elem) {\r\n elem.remove();\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n editTask: function(id)\r\n {\r\n document.getElementById('inpEditTaskId').value = id;\r\n document.getElementById('inpEditTaskTitle').value = document.getElementById('task-item-title-' + id).innerText;\r\n document.getElementById('inpEditTaskDescription').value = document.getElementById('task-item-description-' + id).innerText;\r\n document.getElementById('inpEditTaskDueDate').value = document.getElementById('task-item-due-' + id).innerText;\r\n\r\n window.vue.bShowEditTask = true;\r\n },\r\n\r\n removeTask: function(id)\r\n {\r\n window.vue.ajaxRequest('post', window.location.origin + '/tasks/remove', { task: id }, function(response){\r\n if (response.code == 200) {\r\n let elem = document.getElementById('task-item-' + id);\r\n if (elem) {\r\n elem.remove();\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n updateLastWatered: function(id)\r\n {\r\n if (!confirm(window.vue.confirmSetAllWatered)) {\r\n return;\r\n }\r\n\r\n location.href = window.location.origin + '/plants/location/' + id + '/water';\r\n },\r\n\r\n updateLastRepotted: function(id)\r\n {\r\n if (!confirm(window.vue.confirmSetAllRepotted)) {\r\n return;\r\n }\r\n\r\n location.href = window.location.origin + '/plants/location/' + id + '/repot';\r\n },\r\n\r\n updateLastFertilised: function(id)\r\n {\r\n if (!confirm(window.vue.confirmSetAllFertilised)) {\r\n return;\r\n }\r\n\r\n location.href = window.location.origin + '/plants/location/' + id + '/fertilise';\r\n },\r\n\r\n expandInventoryItem: function(id)\r\n {\r\n let elem = document.getElementById(id);\r\n if (elem) {\r\n elem.classList.toggle('expand');\r\n }\r\n },\r\n\r\n incrementInventoryItem: function(id, target)\r\n {\r\n window.vue.ajaxRequest('get', window.location.origin + '/inventory/amount/increment?id=' + id, {}, function(response) {\r\n if (response.code == 200) {\r\n let elem = document.getElementById(target);\r\n if (elem) {\r\n elem.innerHTML = response.amount;\r\n\r\n if (response.amount == 0) {\r\n elem.classList.add('is-inventory-item-empty');\r\n } else {\r\n elem.classList.remove('is-inventory-item-empty');\r\n }\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n decrementInventoryItem: function(id, target)\r\n {\r\n window.vue.ajaxRequest('get', window.location.origin + '/inventory/amount/decrement?id=' + id, {}, function(response) {\r\n if (response.code == 200) {\r\n let elem = document.getElementById(target);\r\n if (elem) {\r\n elem.innerHTML = response.amount;\r\n\r\n if (response.amount == 0) {\r\n elem.classList.add('is-inventory-item-empty');\r\n } else {\r\n elem.classList.remove('is-inventory-item-empty');\r\n }\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n editInventoryItem: function(id, name, group, location, description, tags, amount)\r\n {\r\n document.getElementById('inpInventoryItemId').value = id;\r\n document.getElementById('inpInventoryItemName').value = document.getElementById(name).children[1].innerText;\r\n document.getElementById('inpInventoryItemGroup').value = group;\r\n document.getElementById('inpInventoryItemLocation').value = document.getElementById(location).children[0].innerText;\r\n document.getElementById('inpInventoryItemDescription').value = document.getElementById(description).innerText;\r\n document.getElementById('inpInventoryItemTags').value = document.getElementById(tags).innerText;\r\n document.getElementById('inpInventoryItemAmount').value = amount;\r\n\r\n window.vue.bShowEditInventoryItem = true;\r\n },\r\n\r\n deleteInventoryItem: function(id, target)\r\n {\r\n if (!confirm(window.vue.confirmInventoryItemRemoval)) {\r\n return;\r\n }\r\n\r\n window.vue.ajaxRequest('get', window.location.origin + '/inventory/remove?id=' + id, {}, function(response) {\r\n if (response.code == 200) {\r\n let elem = document.getElementById(target);\r\n if (elem) {\r\n elem.remove();\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n createInventoryGroup: function(token, label, tbody, button)\r\n {\r\n window.vue.ajaxRequest('post', window.location.origin + '/inventory/group/add', { token: token, label: label }, function(response) {\r\n if (response.code == 200) {\r\n button.innerText = window.vue.addItem;\r\n\r\n let newRow = document.createElement('tr');\r\n newRow.id = 'inventory-group-item-' + response.itemid;\r\n newRow.innerHTML = `\r\n ` + token + `\r\n ` + label + `\r\n \r\n `;\r\n\r\n tbody.appendChild(newRow);\r\n } else {\r\n button.innerText = window.vue.addItem;\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n editInventoryGroupItem: function(id, what, def)\r\n {\r\n let input = prompt(what, def);\r\n\r\n if (input.length > 0) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/inventory/group/edit', {\r\n id: id,\r\n what: what,\r\n value: input\r\n }, function(response) {\r\n if (response.code == 200) {\r\n if (what === 'token') {\r\n document.getElementById('inventory-group-elem-token-' + id).innerText = input;\r\n } else if (what === 'label') {\r\n document.getElementById('inventory-group-elem-label-' + id).innerText = input;\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n }\r\n },\r\n\r\n removeInventoryGroupItem: function(id, target)\r\n {\r\n if (!confirm(window.vue.confirmInventoryItemRemoval)) {\r\n return;\r\n }\r\n\r\n window.vue.ajaxRequest('get', window.location.origin + '/inventory/group/remove?id=' + id, {}, function(response) {\r\n if (response.code == 200) {\r\n let elem = document.getElementById(target);\r\n if (elem) {\r\n elem.remove();\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n refreshChat: function(auth_user)\r\n {\r\n window.vue.ajaxRequest('get', window.location.origin + '/chat/query', {}, function(response) {\r\n if (response.code == 200) {\r\n response.messages.forEach(function(elem, index) {\r\n document.getElementById('chat').innerHTML = window.vue.renderNewChatMessage(elem, auth_user) + document.getElementById('chat').innerHTML;\r\n \r\n let audio = new Audio(window.location.origin + '/snd/new_message.wav');\r\n audio.onloadeddata = function() {\r\n audio.play();\r\n };\r\n });\r\n }\r\n });\r\n\r\n setTimeout(window.vue.refreshChat, window.constChatMessageQueryRefreshRate);\r\n },\r\n\r\n renderNewChatMessage: function(elem, auth_user)\r\n {\r\n let chatmsgright = '';\r\n if (elem.userId == auth_user) {\r\n chatmsgright = 'chat-message-right';\r\n }\r\n\r\n let html = '';\r\n\r\n if (!elem.system) {\r\n html = `\r\n
\r\n
\r\n
` + elem.userName + `
\r\n
` + window.vue.newChatMessage + `
\r\n
\r\n\r\n
\r\n
` + elem.message + `
\r\n
\r\n\r\n
\r\n ` + elem.diffForHumans + `\r\n
\r\n
\r\n `;\r\n } else {\r\n html = `\r\n
\r\n
\r\n
` + ((elem.userName) ? elem.userName : 'System') + ` @ ` + elem.created_at + `
\r\n \r\n
` + elem.message + `
\r\n
\r\n\r\n
\r\n
` + window.vue.newChatMessage + `
\r\n
\r\n
\r\n `;\r\n }\r\n\r\n return html;\r\n },\r\n\r\n refreshUserList: function()\r\n {\r\n window.vue.ajaxRequest('get', window.location.origin + '/chat/user/online', {}, function(response) {\r\n if (response.code == 200) {\r\n let target = document.getElementById('chat-user-list');\r\n target.innerHTML = window.vue.currentlyOnline;\r\n\r\n response.users.forEach(function(elem, index) {\r\n let comma = '';\r\n if (index < response.users.length - 1) {\r\n comma = ', ';\r\n }\r\n \r\n target.innerHTML += elem.name + comma;\r\n });\r\n }\r\n });\r\n\r\n setTimeout(window.vue.refreshUserList, window.constChatUserListRefreshRate);\r\n },\r\n\r\n refreshTypingStatus: function()\r\n {\r\n if (!window.vue.chatTypingEnable) {\r\n return;\r\n }\r\n\r\n window.vue.ajaxRequest('get', window.location.origin + '/chat/typing/update', {}, function(response){\r\n if (response.code != 200) {\r\n console.error(response.msg);\r\n }\r\n });\r\n\r\n setTimeout(function(){\r\n window.vue.chatTypingTimer = null;\r\n }, 5000);\r\n },\r\n\r\n handleChatInput: function()\r\n {\r\n if (!window.vue.chatTypingTimer) {\r\n window.vue.chatTypingTimer = setTimeout(function(){\r\n window.vue.refreshTypingStatus();\r\n }, 1000);\r\n }\r\n },\r\n\r\n handleTypingIndicator: function()\r\n {\r\n window.vue.ajaxRequest('get', window.location.origin + '/chat/typing', {}, function(response){\r\n if (response.code == 200) {\r\n if (response.status) {\r\n let elem = document.getElementsByClassName('chat-typing-indicator')[0];\r\n elem.style.display = 'block';\r\n\r\n window.vue.chatTypingHide = setTimeout(window.vue.hideChatTypingIndicator, 6550);\r\n }\r\n }\r\n });\r\n\r\n setTimeout(window.vue.handleTypingIndicator, window.constChatTypingRefreshRate);\r\n },\r\n\r\n hideChatTypingIndicator: function()\r\n {\r\n if (window.vue.chatTypingHide !== null) {\r\n let elem = document.getElementsByClassName('chat-typing-indicator')[0];\r\n elem.style.display = 'none';\r\n\r\n window.vue.chatTypingHide = null;\r\n }\r\n },\r\n\r\n animateChatTypingIndicator: function()\r\n {\r\n let indicator = document.getElementsByClassName('chat-typing-indicator')[0];\r\n if (indicator.style.display === 'block') {\r\n window.vue.removePreviousChatIndicatorCircleStyle();\r\n\r\n let elem = document.getElementById('chat-typing-circle-' + window.vue.chatTypingCounter.toString());\r\n elem.style.color = 'rgb(50, 50, 50)';\r\n elem.classList.add('fa-lg');\r\n\r\n window.vue.chatTypingCounter++;\r\n if (window.vue.chatTypingCounter > 3) {\r\n window.vue.chatTypingCounter = 1;\r\n }\r\n }\r\n\r\n setTimeout(window.vue.animateChatTypingIndicator, 350);\r\n },\r\n\r\n removePreviousChatIndicatorCircleStyle: function()\r\n {\r\n let previous = window.vue.chatTypingCounter - 1;\r\n if (previous == 0) {\r\n previous = 3;\r\n }\r\n\r\n let elem = document.getElementById('chat-typing-circle-' + previous.toString());\r\n if (elem.classList.contains('fa-lg')) {\r\n elem.classList.remove('fa-lg');\r\n elem.style.color = 'inherit';\r\n }\r\n },\r\n\r\n fetchUnreadMessageCount: function(target) {\r\n window.vue.ajaxRequest('get', window.location.origin + '/chat/messages/count', {}, function(response) {\r\n if (response.code == 200) {\r\n if (response.count > 0) {\r\n target.classList.remove('is-hidden');\r\n target.children[0].innerText = response.count;\r\n } else {\r\n target.classList.add('is-hidden');\r\n }\r\n }\r\n });\r\n\r\n setTimeout(window.vue.fetchUnreadMessageCount.bind(null, target), window.constChatMessageQueryRefreshRate);\r\n },\r\n\r\n fetchNewSystemMessage: function(target) {\r\n window.vue.ajaxRequest('get', window.location.origin + '/chat/system/message/latest', {}, function(response) {\r\n if (response.code == 200) {\r\n if (response.message) {\r\n window.vue.fadeSystemMessage(target, window.vue.renderNewSystemMessage(response.message), response.message.id);\r\n \r\n let audio = new Audio(window.location.origin + '/snd/new_message.wav');\r\n audio.onloadeddata = function() {\r\n audio.play();\r\n };\r\n }\r\n }\r\n });\r\n\r\n setTimeout(window.vue.fetchNewSystemMessage.bind(null, target), window.constChatMessageQueryRefreshRate);\r\n },\r\n\r\n renderNewSystemMessage: function(elem) {\r\n let html = `\r\n
\r\n
` + ((elem.userName) ? elem.userName : 'System') + ` @ ` + elem.created_at + `
\r\n\r\n
` + elem.message + `
\r\n
\r\n `;\r\n\r\n return html;\r\n },\r\n\r\n fadeSystemMessage: function(target, code, id) {\r\n target.innerHTML = code + target.innerHTML;\r\n\r\n let fadeElem = document.getElementById('system-message-small-' + id);\r\n\r\n setTimeout(function() {\r\n fadeElem.classList.replace('fade-out', 'fade-in');\r\n }, 250);\r\n \r\n setTimeout(function() {\r\n fadeElem.classList.replace('fade-in', 'fade-out');\r\n }, 5000);\r\n },\r\n\r\n textFilterElements: function(token) {\r\n let elems = document.getElementsByClassName('plant-filter-text-target');\r\n for (let i = 0; i < elems.length; i++) {\r\n let target = elems[i].parentNode;\r\n \r\n while (!target.classList.contains('plant-filter-text-root')) {\r\n target = target.parentNode;\r\n }\r\n\r\n if (!elems[i].innerText.toLowerCase().includes(token.toLowerCase())) {\r\n target.classList.add('is-hidden');\r\n } else {\r\n target.classList.remove('is-hidden');\r\n }\r\n }\r\n },\r\n\r\n filterTasks: function(token) {\r\n let elems = document.getElementsByClassName('task');\r\n for (let i = 0; i < elems.length; i++) {\r\n let elemTitle = elems[i].children[1].children[0];\r\n let elemDescription = elems[i].children[2].children[0];\r\n\r\n if ((elemTitle.innerText.toLowerCase().includes(token.toLowerCase())) || (elemDescription.innerText.toLowerCase().includes(token.toLowerCase()))) {\r\n elems[i].classList.remove('is-hidden'); \r\n } else {\r\n elems[i].classList.add('is-hidden'); \r\n }\r\n }\r\n },\r\n\r\n filterInventory: function(token) {\r\n let elems = document.getElementsByClassName('inventory-item');\r\n for (let i = 0; i < elems.length; i++) {\r\n let elemName = elems[i].children[1].children[0];\r\n let elemDescription = elems[i].children[2].children[1];\r\n let elemTags = elems[i].children[2].children[0].children[0];\r\n let elemLocation = elems[i].children[2].children[3].children[0];\r\n \r\n if ((elemName.innerText.toLowerCase().includes(token.toLowerCase())) || (elemDescription.innerText.toLowerCase().includes(token.toLowerCase())) || (elemTags.innerText.toLowerCase().includes(token.toLowerCase())) || (elemLocation.innerText.toLowerCase().includes(token.toLowerCase()))) {\r\n elems[i].classList.remove('is-hidden'); \r\n } else {\r\n elems[i].classList.add('is-hidden'); \r\n }\r\n }\r\n },\r\n\r\n toggleDropdown: function(elem) {\r\n if (elem.classList.contains('is-active')) {\r\n elem.classList.remove('is-active');\r\n } else {\r\n elem.classList.add('is-active');\r\n }\r\n },\r\n\r\n selectAdminTab: function(tab) {\r\n const tabs = ['environment', 'media', 'users', 'locations', 'attributes', 'calendar', 'mail', 'themes', 'backup', 'weather', 'api', 'info'];\r\n\r\n let selEl = document.querySelector('.admin-' + tab);\r\n if (selEl) {\r\n tabs.forEach(function(elem, index) {\r\n let otherEl = document.querySelector('.admin-' + elem);\r\n if (otherEl) {\r\n otherEl.classList.add('is-hidden');\r\n }\r\n\r\n let otherTabs = document.querySelector('.admin-tab-' + elem);\r\n if (otherTabs) {\r\n otherTabs.classList.remove('is-active');\r\n }\r\n });\r\n\r\n selEl.classList.remove('is-hidden');\r\n\r\n let selTab = document.querySelector('.admin-tab-' + tab);\r\n if (selTab) {\r\n selTab.classList.add('is-active');\r\n }\r\n }\r\n },\r\n\r\n switchAdminTab: function(tab) {\r\n location.href = window.location.origin + '/admin?tab=' + tab;\r\n },\r\n\r\n showImagePreview: function(asset, aspect = 'is-3by5') {\r\n let img = document.getElementById('preview-image-modal-img');\r\n if (img) {\r\n img.src = asset;\r\n\r\n if (window.vue.clsLastImagePreviewAspect.length > 0) {\r\n img.parentNode.classList.remove(window.vue.clsLastImagePreviewAspect);\r\n }\r\n\r\n window.vue.clsLastImagePreviewAspect = aspect;\r\n img.parentNode.classList.add(window.vue.clsLastImagePreviewAspect);\r\n\r\n window.vue.bShowPreviewImageModal = true;\r\n }\r\n },\r\n\r\n showSharePhoto: function(asset, title, type) {\r\n document.getElementById('share-photo-title').value = title;\r\n document.getElementById('share-photo-id').value = asset;\r\n document.getElementById('share-photo-type').value = type;\r\n\r\n document.getElementById('share-photo-result').classList.add('is-hidden');\r\n document.getElementById('share-photo-error').classList.add('is-hidden');\r\n document.getElementById('share-photo-submit-action').classList.remove('is-hidden');\r\n\r\n window.vue.bShowSharePhoto = true;\r\n },\r\n\r\n performPhotoShare: function(asset, title, _public, description, keywords, type, result, button, error) {\r\n let origButtonHtml = button.innerHTML;\r\n button.innerHTML = ' ' + window.vue.loadingPleaseWait;\r\n\r\n window.vue.ajaxRequest('post', window.location.origin + '/share/photo/post', { asset: asset, title: title, public: _public, description: description, keywords: keywords, type: type }, function(response) {\r\n button.innerHTML = origButtonHtml;\r\n\r\n if (response.code == 200) {\r\n result.value = response.data.url;\r\n result.parentNode.parentNode.classList.remove('is-hidden');\r\n button.classList.add('is-hidden');\r\n error.classList.add('is-hidden');\r\n } else {\r\n error.innerHTML = response.msg;\r\n error.classList.remove('is-hidden');\r\n }\r\n });\r\n },\r\n\r\n generateNewToken: function(target, button) {\r\n let oldTxt = button.innerHTML;\r\n button.innerHTML = '';\r\n\r\n window.vue.ajaxRequest('post', window.location.origin + '/admin/cronjob/token', {}, function(response) {\r\n button.innerHTML = oldTxt;\r\n\r\n if (response.code == 200) {\r\n target.value = response.token;\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n startBackup: function(button, plants, gallery, tasks, inventory, calendar) {\r\n let oldText = button.innerHTML;\r\n button.innerHTML = ' ' + oldText;\r\n\r\n window.vue.ajaxRequest('post', window.location.origin + '/export/start', {\r\n plants: plants,\r\n gallery: gallery,\r\n tasks: tasks,\r\n inventory: inventory,\r\n calendar: calendar\r\n }, function(response) {\r\n button.innerHTML = oldText;\r\n\r\n if (response.code == 200) {\r\n let export_result = document.getElementById('export-result');\r\n if (export_result) {\r\n export_result.classList.remove('is-hidden');\r\n\r\n export_result.children[1].href = response.file;\r\n export_result.children[1].innerHTML = response.file;\r\n }\r\n }\r\n });\r\n },\r\n\r\n startImport: function(button, file, locations, plants, gallery, tasks, inventory, calendar) {\r\n let oldText = button.innerHTML;\r\n button.innerHTML = ' ' + oldText;\r\n \r\n let formData = new FormData();\r\n formData.append('import', file.files[0]);\r\n formData.append('locations', ((locations) ? 1 : 0));\r\n formData.append('plants', ((plants) ? 1 : 0));\r\n formData.append('gallery', ((gallery) ? 1 : 0));\r\n formData.append('tasks', ((tasks) ? 1 : 0));\r\n formData.append('inventory', ((inventory) ? 1 : 0));\r\n formData.append('calendar', ((calendar) ? 1 : 0));\r\n\r\n window.vue.ajaxRequest('post', window.location.origin + '/import/start', formData, function(response) {\r\n button.innerHTML = oldText;\r\n\r\n if (response.code == 200) {\r\n let import_result = document.getElementById('import-result');\r\n if (import_result) {\r\n import_result.classList.remove('is-hidden');\r\n }\r\n }\r\n });\r\n },\r\n\r\n startThemeImport: function(file, button) {\r\n let oldText = button.innerHTML;\r\n button.innerHTML = ' ' + oldText;\r\n \r\n let formData = new FormData();\r\n formData.append('theme', file.files[0]);\r\n\r\n window.vue.ajaxRequest('post', window.location.origin + '/admin/themes/import', formData, function(response) {\r\n button.innerHTML = oldText;\r\n \r\n if (response.code == 200) {\r\n let import_result = document.getElementById('themes-import-result');\r\n if (import_result) {\r\n import_result.innerText = import_result.innerText.replace('{count}', response.themes.length);\r\n import_result.classList.remove('is-hidden');\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n removeTheme: function(theme) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/admin/themes/remove', { theme: theme }, function(response) {\r\n if (response.code == 200) {\r\n let tableElem = document.getElementById('admin-themes-list-item-' + theme);\r\n if (tableElem) {\r\n tableElem.remove();\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n renderCalendar: function(elem, date_from, date_till = null) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/calendar/query', { date_from: date_from, date_till: date_till }, function(response){\r\n if (response.code == 200) {\r\n let content = document.getElementById(elem);\r\n if (content) {\r\n let data = response.data;\r\n\r\n data.sort(function (a, b) {\r\n return new Date(a.date_from) - new Date(b.date_from);\r\n });\r\n\r\n const labels = data.map(x => {\r\n return [x.name];\r\n });\r\n\r\n const newData = data.map(x => {\r\n return [x.date_from.split(' ')[0], x.date_till.split(' ')[0], x.class_name, x.id, x.class_descriptor]\r\n });\r\n \r\n let colorsBackground = [];\r\n data.forEach(function(elem, index) {\r\n colorsBackground.push(elem.color_background);\r\n });\r\n \r\n let colorsBorder = [];\r\n data.forEach(function(elem, index) {\r\n colorsBorder.push(elem.color_border);\r\n });\r\n\r\n const config = {\r\n type: 'bar',\r\n data: {\r\n labels: labels,\r\n datasets: [\r\n {\r\n data: newData,\r\n backgroundColor: colorsBackground,\r\n borderColor: colorsBorder,\r\n borderWidth: 1,\r\n fill: false,\r\n barPercentage: 0.3\r\n }\r\n ]\r\n },\r\n options: {\r\n indexAxis: 'y',\r\n responsive: true,\r\n scales: {\r\n x: {\r\n min: response.date_from,\r\n max: response.date_till,\r\n type: 'time',\r\n time: {\r\n unit: 'day'\r\n }\r\n },\r\n y: {\r\n beginAtZero: true\r\n }\r\n },\r\n plugins: {\r\n legend: {\r\n display: false,\r\n },\r\n tooltip: {\r\n callbacks: {\r\n label: function(context) {\r\n return context.dataset.data[context.dataIndex][2];\r\n },\r\n afterBody: function(context) {\r\n return context[0].raw[0] + ' - ' + context[0].raw[1];\r\n }\r\n }\r\n }\r\n },\r\n\r\n }\r\n };\r\n\r\n if (window.calendarChart !== null) {\r\n window.calendarChart.destroy();\r\n }\r\n \r\n window.calendarChart = new chart_js_auto__WEBPACK_IMPORTED_MODULE_1__[\"default\"](\r\n content,\r\n config\r\n );\r\n\r\n content.onclick = function(event) {\r\n let points = window.calendarChart.getElementsAtEventForMode(event, 'nearest', { intersect: true }, true);\r\n if (points.length) {\r\n const firstPoint = points[0];\r\n const label = window.calendarChart.data.labels[firstPoint.index];\r\n const value = window.calendarChart.data.datasets[firstPoint.datasetIndex].data[firstPoint.index];\r\n console.log(value);\r\n if (value.length) {\r\n document.getElementById('inpEditCalendarItemIdent').innerText = '#' + value[3] + ' ' + label;\r\n document.getElementById('inpEditCalendarItemId').value = value[3];\r\n document.getElementById('inpEditCalendarItemName').value = label;\r\n document.getElementById('inpEditCalendarItemDateFrom').value = value[0];\r\n document.getElementById('inpEditCalendarItemDateTill').value = value[1];\r\n document.getElementById('inpEditCalendarItemClass').value = value[4];\r\n window.vue.bShowEditCalendarItem = true;\r\n }\r\n }\r\n };\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n removeCalendarItem: function(ident) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/calendar/remove', { ident: ident }, function(response) {\r\n if (response.code == 200) {\r\n location.reload();\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n removeCalendarClass: function(id) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/admin/calendar/class/remove', { id: id }, function(response) {\r\n if (response.code == 200) {\r\n let elItem = document.getElementById('admin-calendar-class-item-' + id);\r\n if (elItem) {\r\n elItem.remove();\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n clonePlant: function(id) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/clone', { id: id }, function(response) {\r\n if (response.code == 200) {\r\n location.href = window.location.origin + '/plants/details/' + response.clone_id;\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n showPerformBulkUpdate: function(operation, title, button, location, is_custom = false) {\r\n document.getElementById('plant-bulk-perform-operation-operation').value = operation;\r\n document.getElementById('plant-bulk-perform-operation-location').value = location;\r\n document.getElementById('plant-bulk-perform-operation-title').innerText = title;\r\n document.getElementById('plant-bulk-perform-operation-button').innerText = button;\r\n document.getElementById('plant-bulk-perform-operation-custom').checked = is_custom;\r\n\r\n window.vue.bulkChecked('plant-bulk-perform-operation', false);\r\n\r\n window.vue.bShowPlantBulkPerformUpdate = true;\r\n },\r\n\r\n bulkPerformPlantUpdate: function(target, attribute, location, is_custom = false) {\r\n let plantIds = [];\r\n\r\n let elems = document.getElementsByClassName(target);\r\n if (elems) {\r\n Array.prototype.forEach.call(elems, function(elem) {\r\n if (elem.checked) {\r\n plantIds.push([elem.dataset.plantid, elem.dataset.plantname]);\r\n }\r\n });\r\n \r\n if (plantIds.length > 0) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/update/bulk', { attribute: attribute, list: JSON.stringify(plantIds), location: location, custom: is_custom }, function(response) {\r\n if (response.code == 200) {\r\n alert(window.vue.operationSucceeded);\r\n window.vue.bShowPlantBulkPerformUpdate = false;\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n } else {\r\n alert(window.vue.noListItemsSelected); \r\n }\r\n }\r\n },\r\n\r\n generateAndShowQRCode: function(plant) {\r\n window.vue.ajaxRequest('get', window.location.origin + '/plants/qrcode?plant=' + plant, {}, function(response) {\r\n if (response.code == 200) {\r\n let elTarget = document.getElementById('image-plant-qr-code');\r\n if (elTarget) {\r\n elTarget.src = response.qrcode;\r\n window.vue.bShowPlantQRCode = true;\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n printQRCode: function(content, title) {\r\n let wnd = window.open('', title, 'height=auto, width=auto');\r\n\r\n wnd.document.write('' + title + '');\r\n wnd.document.write('');\r\n wnd.document.write('');\r\n\r\n wnd.print();\r\n wnd.close();\r\n },\r\n\r\n bulkChecked: function(target, flag) {\r\n let elems = document.getElementsByClassName(target);\r\n \r\n if (elems) {\r\n Array.prototype.forEach.call(elems, function(elem){ \r\n elem.checked = flag; \r\n });\r\n }\r\n },\r\n\r\n bulkPrintQRCodes: function(target, location) {\r\n let plantIds = [];\r\n\r\n let elems = document.getElementsByClassName(target);\r\n if (elems) {\r\n Array.prototype.forEach.call(elems, function(elem) {\r\n if (elem.checked) {\r\n plantIds.push([elem.dataset.plantid, elem.dataset.plantname]);\r\n }\r\n });\r\n\r\n if (plantIds.length > 0) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/qrcode/bulk', { list: JSON.stringify(plantIds) }, function(response) {\r\n if (response.code == 200) {\r\n let wnd = window.open('', location, 'height=auto, width=auto');\r\n\r\n wnd.document.write('' + location + '');\r\n\r\n response.list.forEach(function(elem, index) {\r\n wnd.document.write('
#' + elem.plantid + ' ' + elem.plantname + '
');\r\n });\r\n\r\n wnd.document.write('');\r\n\r\n wnd.print();\r\n wnd.close();\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n } else {\r\n alert(window.vue.noListItemsSelected); \r\n }\r\n }\r\n },\r\n\r\n queryInvQrCode: function(item) {\r\n window.vue.ajaxRequest('get', window.location.origin + '/inventory/qrcode?item=' + item, {}, function(response) {\r\n if (response.code == 200) {\r\n let elTarget = document.getElementById('image-inventory-qr-code');\r\n if (elTarget) {\r\n elTarget.src = response.qrcode;\r\n window.vue.bShowInvItemQRCode = true;\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n bulkPrintInvQRCodes: function(target, title) {\r\n let invIds = [];\r\n\r\n let elems = document.getElementsByClassName(target);\r\n if (elems) {\r\n Array.prototype.forEach.call(elems, function(elem) {\r\n if (elem.checked) {\r\n invIds.push([elem.dataset.invitemid, elem.dataset.invitemname, elem.dataset.invgroup]);\r\n }\r\n });\r\n\r\n if (invIds.length > 0) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/inventory/qrcode/bulk', { list: JSON.stringify(invIds) }, function(response) {\r\n if (response.code == 200) {\r\n let wnd = window.open('', title, 'height=auto, width=auto');\r\n\r\n wnd.document.write('' + title + '');\r\n\r\n response.list.forEach(function(elem, index) {\r\n wnd.document.write('
#' + elem.invitemid + ' [' + elem.invgroup + '] ' + elem.invitemname + '
');\r\n });\r\n\r\n wnd.document.write('');\r\n\r\n wnd.print();\r\n wnd.close();\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n } else {\r\n alert(window.vue.noListItemsSelected); \r\n }\r\n }\r\n },\r\n\r\n bulkExportInventory: function(target, format, title) {\r\n let invIds = [];\r\n\r\n let elems = document.getElementsByClassName(target);\r\n if (elems) {\r\n Array.prototype.forEach.call(elems, function(elem) {\r\n if (elem.checked) {\r\n invIds.push([elem.dataset.invitemid, elem.dataset.invitemname, document.getElementById(elem.dataset.invdescription).innerText, elem.dataset.invgroup, elem.dataset.invamount, elem.dataset.invlocation, elem.dataset.invphoto, elem.dataset.invcreated, elem.dataset.invupdated]);\r\n }\r\n });\r\n\r\n if (invIds.length > 0) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/inventory/export', { list: JSON.stringify(invIds), format: document.getElementById(format).value }, function(response) {\r\n if (response.code == 200) {\r\n const dlanchor = document.createElement('a');\r\n dlanchor.href = response.resource;\r\n dlanchor.target = '_blank';\r\n dlanchor.setAttribute('download', response.resource);\r\n dlanchor.click();\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n } else {\r\n alert(window.vue.noListItemsSelected); \r\n }\r\n }\r\n },\r\n\r\n editGalleryPhotoLabel: function(id, plant, old) {\r\n let newLabel = prompt(window.vue.editProperty, old);\r\n if (newLabel.length) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/details/gallery/photo/label/edit', { id: id, label: newLabel, plant: plant }, function(response) {\r\n if (response.code == 200) {\r\n document.getElementById('photo-gallery-item-' + id).children[0].children[0].innerHTML = newLabel;\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n }\r\n },\r\n\r\n removeSharedPhoto: function(ident) {\r\n window.vue.ajaxRequest('get', window.location.origin + '/share/photo/remove?ident=' + ident, {}, function(response) {\r\n if (response.code == 200) {\r\n let elem = document.getElementById('photo-share-entry-' + ident);\r\n if (elem) {\r\n elem.remove();\r\n }\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n loadNextShareLogEntries: function(table, action) {\r\n window.vue.ajaxRequest('post', window.location.origin + '/profile/sharelog/fetch', { paginate: action.dataset.paginate }, function(response) {\r\n if (response.code == 200) {\r\n let tbody = table.getElementsByTagName('tbody')[0];\r\n\r\n response.data.forEach(function(elem, index) {\r\n let newRow = document.createElement('tr');\r\n newRow.id = 'photo-share-entry-' + elem.id;\r\n newRow.innerHTML = `\r\n ` + elem.title + `\r\n ` + elem.diffForHumans + `\r\n \r\n `;\r\n\r\n tbody.appendChild(newRow);\r\n });\r\n\r\n action.parentNode.parentNode.remove();\r\n\r\n let actionRow = document.createElement('tr');\r\n actionRow.id = 'share-log-load-more';\r\n actionRow.classList.add('share-log-paginate');\r\n actionRow.innerHTML = `` + window.vue.loadMore + ``;\r\n tbody.appendChild(actionRow);\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n acquireGeoPosition: function(destLatitude, destLongitude, button) {\r\n let oldText = button.innerHTML;\r\n button.innerHTML = ' ' + button.innerHTML;\r\n\r\n if (navigator.geolocation) {\r\n navigator.geolocation.getCurrentPosition(function(position) {\r\n destLatitude.value = position.coords.latitude;\r\n destLongitude.value = position.coords.longitude;\r\n\r\n button.innerHTML = oldText;\r\n });\r\n } else {\r\n button.innerHTML = oldText;\r\n \r\n alert('Geolocation is not available');\r\n }\r\n },\r\n\r\n toggleApiKey: function(id) {\r\n window.vue.ajaxRequest('get', window.location.origin + '/admin/api/' + id + '/toggle', {}, function(response) {\r\n if (response.code == 200) {\r\n document.getElementById('api-key-checkbox-' + id).checked = response.active;\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n toggleAdminPlantAttribute: function(name) {\r\n window.vue.ajaxRequest('get', window.location.origin + '/admin/attribute/update?name=' + name, {}, function(response) {\r\n if (response.code == 200) {\r\n document.getElementById('admin-attributes-checkbox-' + name).checked = response.active;\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n toggleAdminBoolSetting: function(name) {\r\n window.vue.ajaxRequest('get', window.location.origin + '/admin/environment/boolean/toggle?name=' + name, {}, function(response) {\r\n if (response.code == 200) {\r\n document.getElementById('admin-attributes-checkbox-allow-custom-attributes').checked = response.value;\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n toggleAdminAuthInfoMessages: function(checked, warning, caution) {\r\n let elWarning = document.querySelector(warning);\r\n let elCaution = document.querySelector(caution);\r\n\r\n if (checked) {\r\n if (elWarning) {\r\n elWarning.style.display = 'block';\r\n }\r\n\r\n if (elCaution) {\r\n elCaution.style.display = 'block';\r\n }\r\n } else {\r\n if (elWarning) {\r\n elWarning.style.display = 'none';\r\n }\r\n\r\n if (elCaution) {\r\n elCaution.style.display = 'none';\r\n }\r\n }\r\n },\r\n\r\n performPlantRecognition: function(target, plantid) {\r\n const form = document.getElementById(target);\r\n const data = new FormData(form);\r\n\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/details/identify', data, function(response) {\r\n if (response.code == 200) {\r\n let dest = document.getElementById('recognized-plant-selection');\r\n\r\n dest.innerHTML = '
';\r\n\r\n response.data.forEach(function(elem, index) {\r\n dest.innerHTML += `\r\n
\r\n
\r\n  ` + elem.species.scientificNameWithoutAuthor + ` (` + (elem.score * 100).toFixed(2) + '%)' + `\r\n
\r\n
\r\n `;\r\n });\r\n\r\n dest.innerHTML += '
';\r\n\r\n document.getElementById('plant-rec-action-icon').classList.remove('fa-spinner');\r\n document.getElementById('plant-rec-action-icon').classList.remove('fa-spin');\r\n document.getElementById('plant-rec-action-icon').classList.add('fa-microscope');\r\n\r\n window.vue.bShowSelectRecognizedPlant = true;\r\n } else {\r\n alert(response.msg);\r\n }\r\n });\r\n },\r\n\r\n storeRecognizedPlantData: function(target) {\r\n const selection = document.getElementById(target).getElementsByTagName('input');\r\n\r\n for (let i = 0; i < selection.length; i++) {\r\n if (selection[i].checked) {\r\n const item = selection[i];\r\n\r\n window.plantRecStorageStep = 0;\r\n window.plantRecErrorCount = 0;\r\n\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/details/edit/ajax', {\r\n plant: item.dataset.plantid,\r\n attribute: 'name',\r\n value: item.dataset.plantname\r\n }, function(response) {\r\n window.plantRecStorageStep++;\r\n \r\n if (response.code == 500) {\r\n window.plantRecErrorCount++;\r\n alert(response.msg);\r\n }\r\n });\r\n\r\n window.vue.ajaxRequest('post', window.location.origin + '/plants/details/edit/ajax', {\r\n plant: item.dataset.plantid,\r\n attribute: 'scientific_name',\r\n value: item.dataset.plantscientificname\r\n }, function(response) {\r\n window.plantRecStorageStep++;\r\n\r\n if (response.code == 500) {\r\n window.plantRecErrorCount++;\r\n alert(response.msg);\r\n }\r\n });\r\n\r\n setTimeout(function awaitPlantAttributeStorage() {\r\n if (window.plantRecStorageStep < 2) {\r\n setTimeout(awaitPlantAttributeStorage, 1000);\r\n } else {\r\n location.reload();\r\n }\r\n }, 100);\r\n\r\n break;\r\n }\r\n }\r\n },\r\n\r\n copyToClipboard: function(text) {\r\n const el = document.createElement('textarea');\r\n el.value = text;\r\n document.body.appendChild(el);\r\n el.select();\r\n document.execCommand('copy');\r\n document.body.removeChild(el);\r\n alert(window.vue.copiedToClipboard);\r\n },\r\n\r\n isProgressiveWebApp: function() {\r\n return window.matchMedia('(display-mode: standalone)').matches;\r\n },\r\n }\r\n});\n\n//# sourceURL=webpack://asatruphp/./app/resources/js/app.js?"); /***/ }), @@ -27,7 +27,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _sas /***/ ((module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__);\n// Imports\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default()(function(i){return i[1]});\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \"/*\\n app.scss\\n*/\\nhtml {\\n overflow-y: hidden;\\n}\\n\\nhtml, body {\\n width: 100%;\\n height: 100%;\\n padding: 0;\\n margin: 0;\\n background-color: rgb(48, 52, 55);\\n}\\n\\nbody {\\n overflow-x: hidden;\\n}\\n\\n.is-image-container {\\n background-repeat: no-repeat;\\n background-size: cover;\\n padding: unset;\\n}\\n\\n.column-overlay {\\n width: 100%;\\n height: 100%;\\n padding: 20px;\\n background-color: rgba(0, 0, 0, 0.5);\\n}\\n\\nh1 {\\n font-size: 2.5em;\\n color: rgb(250, 250, 250);\\n}\\n\\nh2 {\\n font-size: 2em;\\n margin-bottom: 30px;\\n color: rgb(200, 200, 200);\\n}\\n\\n.smaller-headline {\\n font-size: 1.2em;\\n margin-bottom: 15px;\\n}\\n\\n.is-default-link {\\n color: rgb(79, 134, 202);\\n}\\n\\n.is-default-link:hover {\\n color: rgb(79, 134, 202);\\n text-decoration: underline;\\n}\\n\\n.is-yellow-link {\\n color: rgb(156, 115, 67);\\n}\\n\\n.is-yellow-link:hover {\\n color: rgb(156, 115, 67);\\n text-decoration: underline;\\n}\\n\\n.is-gray-link {\\n color: rgb(150, 150, 150);\\n}\\n\\n.is-gray-link:hover {\\n color: rgb(150, 150, 150);\\n text-decoration: underline;\\n}\\n\\n.is-dark-delimiter hr {\\n background-color: rgb(100, 100, 100);\\n}\\n\\n.is-fixed-button-link {\\n position: relative;\\n top: 5px;\\n}\\n\\n@media screen and (max-width: 512px) {\\n .is-fixed-margin-left-mobile {\\n margin-left: 2px;\\n }\\n}\\n\\n.is-default-text-color {\\n color: rgb(150, 150, 150);\\n}\\n\\n.is-color-darker {\\n color: rgb(100, 100, 100);\\n}\\n\\n.is-color-error {\\n color: rgb(154, 73, 69);\\n}\\n\\n.is-input-dark {\\n background-color: rgba(90, 90, 90, 0.5);\\n color: rgb(200, 200, 200);\\n border: 1px solid rgb(100, 100, 100);\\n}\\n\\n.is-action-button-margin {\\n margin-right: 10px;\\n margin-bottom: 10px;\\n}\\n@media screen and (max-width: 376px) {\\n .is-action-button-margin {\\n margin-right: 15px;\\n }\\n}\\n\\n.is-underlined {\\n text-decoration: underline;\\n}\\n\\n.is-stretched {\\n width: 100%;\\n}\\n\\n.is-pointer {\\n cursor: pointer;\\n}\\n\\n.is-centered {\\n text-align: center !important;\\n}\\n\\n.is-indicator {\\n position: absolute;\\n width: 10px;\\n height: 10px;\\n top: 17px;\\n left: 20px;\\n background-color: rgb(223, 50, 50);\\n border-radius: 50%;\\n z-index: 5;\\n}\\n@media screen and (max-width: 1087px) {\\n .is-indicator {\\n top: 10px;\\n left: 22px;\\n }\\n}\\n\\n.is-indicator-tab {\\n position: relative;\\n width: 10px;\\n height: 10px;\\n top: -4px;\\n left: -3px;\\n background-color: rgb(223, 50, 50);\\n border-radius: 50%;\\n z-index: 5;\\n}\\n\\n.is-background-success-light {\\n background-color: rgb(215, 253, 200);\\n}\\n\\n.is-chocolate {\\n background-color: rgb(179, 105, 62);\\n border-color: transparent;\\n}\\n\\n.is-chocolate:hover {\\n background-color: rgb(167, 95, 55);\\n border-color: transparent;\\n}\\n\\n.float-right {\\n float: right;\\n}\\n\\n.belongs-to-previous-field {\\n position: relative;\\n top: -5px;\\n margin-bottom: 20px !important;\\n}\\n\\n.is-next-to-elem {\\n position: relative;\\n top: 5px;\\n margin-left: 10px;\\n}\\n@media screen and (max-width: 453px) {\\n .is-next-to-elem {\\n top: -3px;\\n margin-bottom: 20px !important;\\n margin-left: unset;\\n }\\n}\\n\\n.is-margin-bottom-20 {\\n margin-bottom: 20px !important;\\n}\\n\\n.field small {\\n color: rgb(120, 120, 120);\\n}\\n\\n.form-paragraph-modal a, .modal-anchors a {\\n color: rgb(52, 105, 215);\\n}\\n\\n.form-paragraph-modal a:hover, .modal-anchors a:hover {\\n color: rgb(52, 105, 215);\\n text-decoration: underline;\\n}\\n\\n@media screen and (max-width: 1087px) {\\n .navbar-menu {\\n max-height: calc(100vh - 3.25rem);\\n overflow-y: auto;\\n }\\n}\\n\\n@media screen and (max-width: 1087px) {\\n .navbar-end {\\n margin-bottom: 100px;\\n }\\n}\\n\\n.navbar-item a {\\n color: rgb(200, 200, 200);\\n}\\n\\n.navbar-item a:hover {\\n color: rgb(250, 250, 250);\\n}\\n\\na.navbar-item:hover, a.navbar-item.is-active, .navbar-link:hover, .navbar-link.is-active {\\n background-color: rgba(255, 255, 255, 0) !important;\\n color: rgb(180, 180, 180) !important;\\n}\\n\\n.navbar-item, .navbar-burger, .navbar-link {\\n color: rgb(190, 190, 190);\\n}\\n\\n.navbar-dropdown {\\n background-color: rgb(50, 50, 48);\\n padding-top: unset;\\n}\\n\\n.navbar-item.has-dropdown:hover .navbar-link, .navbar-item.has-dropdown.is-active .navbar-link {\\n background-color: rgba(0, 0, 0, 0);\\n}\\n\\n@media screen and (max-width: 1087px) {\\n .navbar-menu {\\n background-color: rgb(50, 50, 48);\\n }\\n}\\na.navbar-burger:hover {\\n color: rgb(200, 200, 200);\\n}\\n\\n@media screen and (min-width: 1088px) {\\n .navbar-start {\\n flex-grow: 1;\\n justify-content: center;\\n }\\n}\\n\\n@media screen and (min-width: 1089px) {\\n .navbar-item-only-mobile {\\n display: none;\\n }\\n}\\n\\n@media screen and (min-width: 1089px) {\\n .navbar-dropdown-minwidth {\\n display: block;\\n top: 5px;\\n min-width: 135px;\\n text-align: center;\\n }\\n}\\n\\n@media screen and (min-width: 1089px) {\\n .navbar-dropdown-minwidth:not(.is-multiple):not(.is-loading)::after {\\n top: 20px !important;\\n }\\n}\\n\\n@media screen and (max-width: 1087px) {\\n .navbar-item-brand-mobile-right {\\n position: absolute;\\n top: 10px;\\n right: 45px;\\n }\\n}\\n@media screen and (min-width: 1089px) {\\n .navbar-item-brand-mobile-right {\\n display: none;\\n }\\n}\\n\\n@media screen and (max-width: 1087px) {\\n .navbar.is-fixed-top-pwa {\\n position: fixed;\\n top: 0;\\n left: 0;\\n right: 0;\\n z-index: 30;\\n }\\n}\\n\\n@media screen and (min-width: 768px) {\\n .column h1 {\\n margin-top: 20px;\\n }\\n}\\n\\n#frmEditMultilineText textarea {\\n min-height: 200px;\\n}\\n\\n.banner {\\n width: 100%;\\n height: 250px;\\n background-repeat: no-repeat;\\n background-size: 100% 100%;\\n}\\n@media screen and (max-width: 768px) {\\n .banner {\\n display: none;\\n }\\n}\\n\\n.banner-icon {\\n position: relative;\\n top: 210px;\\n left: 195px;\\n}\\n\\n.banner-icon img {\\n width: 72px;\\n height: 72px;\\n}\\n\\n.banner-accessory {\\n position: relative;\\n top: 172px;\\n right: -83%;\\n}\\n\\n.banner-accessory img {\\n width: 256px;\\n height: 256px;\\n}\\n\\n.content-inner {\\n position: relative;\\n padding: 15px;\\n}\\n\\n.modal {\\n z-index: 105;\\n}\\n\\n.modal-card {\\n color: rgb(150, 150, 150);\\n}\\n\\n.modal-card-head {\\n background-color: rgb(55, 59, 62);\\n border-bottom: 1px solid rgb(59, 59, 59);\\n}\\n\\n.modal-card-title {\\n color: rgb(190, 190, 190);\\n}\\n\\n.modal-card-body {\\n background-color: rgb(48, 52, 55);\\n}\\n\\n.modal-card-body label {\\n color: rgb(150, 150, 150);\\n}\\n\\n.modal-card-body input, .modal-card-body select, .modal-card-body textarea, .modal-card-body table {\\n background-color: rgb(57, 59, 63);\\n color: rgb(150, 150, 150);\\n border: 1px solid rgb(100, 100, 100);\\n}\\n\\n.modal-card-body input::placeholder, .modal-card-body select::placeholder, .modal-card-body textarea::placeholder {\\n color: rgb(250, 250, 250);\\n}\\n\\n.modal-card-body hr {\\n background-color: rgb(100, 100, 100);\\n}\\n\\n.modal-card-foot {\\n background-color: rgb(50, 50, 50);\\n border-top: 1px solid rgb(59, 59, 59);\\n}\\n\\n.fade {\\n transition: opacity 0.65s linear;\\n}\\n\\n.fade-in {\\n opacity: 1;\\n}\\n\\n.fade-out {\\n opacity: 0;\\n}\\n\\n@media screen and (max-width: 1087px) {\\n .app-padding-pwa {\\n padding-top: 65px;\\n padding-bottom: 87px;\\n }\\n}\\n@media screen and (max-width: 768px) {\\n .app-padding-pwa {\\n padding-top: 41px;\\n padding-bottom: 87px;\\n }\\n}\\n\\nfieldset legend {\\n margin-bottom: 5px !important;\\n}\\n\\nfieldset .field {\\n margin-bottom: unset !important;\\n}\\n\\n.legend-title {\\n font-size: 1.2em;\\n margin-bottom: 15px !important;\\n}\\n\\n.notification-badge {\\n color: rgb(255, 255, 255);\\n text-decoration: none;\\n border-radius: 2px;\\n}\\n\\n.notification-badge .notify-badge {\\n padding-top: 4px;\\n padding-bottom: 4px;\\n padding-left: 10px;\\n padding-right: 10px;\\n border-radius: 50%;\\n background: rgba(255, 0, 0, 0.9);\\n color: rgb(255, 255, 255);\\n font-size: 0.8em;\\n}\\n@media screen and (min-width: 1089px) {\\n .notification-badge .notify-badge {\\n position: absolute;\\n right: -7px;\\n top: 4px;\\n }\\n}\\n@media screen and (max-width: 1087px) {\\n .notification-badge .notify-badge {\\n position: relative;\\n right: -2px;\\n top: -10px;\\n }\\n}\\n\\n.notify-badge .notify-badge-count {\\n position: relative;\\n top: -1px;\\n}\\n\\n.dashboard-header {\\n position: relative;\\n}\\n\\n.dashboard-welcome {\\n display: inline-block;\\n}\\n\\n.dashboard-weather {\\n display: inline-block;\\n position: relative;\\n top: 20px;\\n float: right;\\n color: rgb(200, 200, 200);\\n}\\n@media screen and (max-width: 525px) {\\n .dashboard-weather {\\n top: -20px;\\n float: unset;\\n }\\n}\\n\\n.dashboard-weather-content {\\n position: relative;\\n margin-top: 10px;\\n}\\n@media screen and (max-width: 525px) {\\n .dashboard-weather-content {\\n left: -10px;\\n }\\n}\\n\\n.dashboard-weather-left {\\n position: relative;\\n display: inline-block;\\n left: 10px;\\n}\\n@media screen and (max-width: 525px) {\\n .dashboard-weather-left {\\n left: unset;\\n }\\n}\\n\\n.dashboard-weather-right {\\n display: inline-block;\\n position: relative;\\n top: -32px;\\n}\\n@media screen and (max-width: 525px) {\\n .dashboard-weather-right {\\n left: -10px;\\n float: unset;\\n }\\n}\\n\\n.locations {\\n text-align: center;\\n}\\n\\n.locations a {\\n color: rgb(100, 100, 100);\\n}\\n\\n.locations a:hover {\\n color: rgb(100, 100, 100);\\n}\\n\\n.location {\\n position: relative;\\n display: inline-block;\\n width: 245px;\\n min-height: 250px;\\n margin-left: 10px;\\n margin-right: 10px;\\n margin-bottom: 30px;\\n background-color: rgb(55, 59, 62);\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);\\n}\\n@media screen and (max-width: 830px) {\\n .location {\\n width: 134px;\\n min-height: 137px;\\n }\\n}\\n\\n.location:hover {\\n box-shadow: 0 0 20px 0 rgba(105, 165, 85, 0.95);\\n}\\n\\n.location-title {\\n text-align: center;\\n font-size: 2em;\\n padding-bottom: 4px;\\n margin-bottom: 20px;\\n background-color: rgba(115, 143, 100, 0.9);\\n color: #c3e4a3;\\n}\\n@media screen and (max-width: 830px) {\\n .location-title {\\n font-size: 1em;\\n padding-top: 2px;\\n padding-bottom: 5px;\\n }\\n}\\n@media screen and (min-width: 831px) {\\n .location-title {\\n padding-bottom: 7px;\\n }\\n}\\n\\n.location-icon {\\n text-align: center;\\n}\\n\\n.location-icon i {\\n color: #99ac97;\\n font-size: 5em;\\n}\\n@media screen and (max-width: 830px) {\\n .location-icon i {\\n font-size: 2em;\\n }\\n}\\n@media screen and (min-width: 831px) {\\n .location-icon i {\\n margin-top: 25px;\\n }\\n}\\n\\n.location-footer {\\n position: relative;\\n bottom: -30px;\\n padding-top: 10px;\\n padding-left: 10px;\\n padding-bottom: 10px;\\n font-size: 0.9em;\\n text-align: left;\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 54, 59);\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);\\n}\\n@media screen and (max-width: 830px) {\\n .location-footer {\\n font-size: 0.75em;\\n bottom: -15px;\\n }\\n}\\n\\n.location-footer-count-desktop {\\n display: none;\\n}\\n@media screen and (min-width: 850px) {\\n .location-footer-count-desktop {\\n display: inherit;\\n }\\n}\\n\\n.location-footer-count-mobile {\\n display: none;\\n}\\n@media screen and (max-width: 850px) {\\n .location-footer-count-mobile {\\n display: inherit;\\n }\\n}\\n\\n.upcoming-tasks-overview {\\n position: relative;\\n text-align: center;\\n margin-bottom: 63px;\\n}\\n\\n.upcoming-tasks-overview h3 {\\n padding-top: 25px;\\n font-size: 2em;\\n color: rgb(150, 150, 150);\\n}\\n\\n.upcoming-tasks-overview-items {\\n margin-top: 25px;\\n}\\n\\n.last-added-or-authored-plants {\\n margin-top: 20px;\\n margin-bottom: 40px;\\n margin-left: -20px;\\n margin-right: -20px;\\n padding-bottom: 5px;\\n background-color: rgb(55, 59, 62);\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);\\n text-align: center;\\n}\\n\\n.last-added-or-authored-plants h3 {\\n padding-top: 15px;\\n font-size: 2em;\\n color: rgb(150, 150, 150);\\n}\\n\\n.margin-vertical {\\n margin-top: 20px;\\n margin-bottom: 20px;\\n}\\n\\n.margin-bottom {\\n margin-bottom: 20px;\\n}\\n\\n.action-strip {\\n position: relative;\\n display: inline-block;\\n}\\n\\n@media screen and (max-width: 1111px) {\\n .action-strip-left {\\n width: 83%;\\n }\\n}\\n\\n.action-strip-right {\\n position: relative;\\n float: right;\\n}\\n\\n.sorting {\\n position: relative;\\n top: 10px;\\n margin-left: 10px;\\n}\\n\\n.sorting-control {\\n position: relative;\\n display: inline-block;\\n margin-bottom: 10px;\\n}\\n\\n.sorting-control a {\\n color: rgb(150, 150, 150);\\n}\\n\\n.sorting-control a.is-selected {\\n color: rgb(200, 200, 200);\\n}\\n\\n.sorting-control i {\\n margin-right: 5px;\\n}\\n\\n.sorting-control select, .sorting-control input[type=text] {\\n color: rgb(200, 200, 200);\\n background-color: rgba(50, 50, 50, 0.9);\\n border: 1px solid rgb(100, 100, 100);\\n margin-right: 5px;\\n}\\n\\n.sorting-control input[type=text] {\\n height: 27px;\\n border-radius: 290486px;\\n padding-left: 1em;\\n}\\n\\n.sorting-mobile-only {\\n margin-right: 10px;\\n}\\n\\n.sorting-mobile-only-last-elem {\\n margin-bottom: 20px;\\n}\\n\\n@media screen and (min-width: 501px) {\\n .sorting-mobile-only span {\\n display: none;\\n }\\n}\\n\\n.select:not(.is-multiple):not(.is-loading)::after {\\n border-color: rgb(50, 115, 220) !important;\\n}\\n\\n.plants {\\n margin-top: 30px;\\n}\\n@media screen and (max-width: 552px) {\\n .plants {\\n text-align: center;\\n }\\n}\\n\\n.plants-empty {\\n position: relative;\\n margin-top: 50px;\\n text-align: center;\\n}\\n\\n.plants-empty-image img {\\n width: 256px;\\n height: 256px;\\n}\\n\\n.plants-empty-text {\\n position: relative;\\n top: -20px;\\n color: rgb(150, 150, 150);\\n font-style: italic;\\n font-size: 1.4em;\\n}\\n\\n.plant-card {\\n position: relative;\\n display: inline-block;\\n width: 245px;\\n height: 375px;\\n margin-left: 10px;\\n margin-right: 10px;\\n margin-bottom: 20px;\\n background-repeat: no-repeat;\\n background-size: cover;\\n border-radius: 10px;\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.3);\\n}\\n@media screen and (max-width: 552px) {\\n .plant-card {\\n width: 141px;\\n height: 222px;\\n }\\n}\\n\\n.plant-card:hover {\\n box-shadow: 0 0 20px 0 rgba(105, 165, 85, 0.95);\\n}\\n\\n.plant-card-overlay {\\n width: 100%;\\n height: 100%;\\n background: transparent;\\n border-radius: 10px;\\n}\\n\\n.plant-card-overlay:hover {\\n background-color: rgba(0, 0, 0, 0.05);\\n}\\n\\n.plant-card-title {\\n position: absolute;\\n bottom: 0;\\n z-index: 2;\\n width: 100%;\\n height: 69px;\\n padding-top: 17px;\\n background-color: rgba(0, 0, 0, 0.5);\\n color: rgb(200, 200, 200);\\n text-align: center;\\n font-size: 1.2em;\\n border-bottom-left-radius: 10px;\\n border-bottom-right-radius: 10px;\\n}\\n@media screen and (max-width: 552px) {\\n .plant-card-title {\\n padding-top: 22px;\\n font-size: 0.9em;\\n }\\n}\\n\\n.plant-card-title-with-hint {\\n padding-top: 7px;\\n}\\n\\n.plant-card-title-longtext {\\n padding-top: 5px;\\n padding-left: 5px;\\n padding-right: 5px;\\n}\\n@media screen and (max-width: 552px) {\\n .plant-card-title-longtext {\\n padding-top: 12px;\\n padding-left: 2px;\\n padding-right: 2px;\\n }\\n}\\n\\n.plant-card-title-second {\\n color: rgb(150, 150, 150);\\n font-size: 0.8em;\\n}\\n\\n.plant-card-title-plant-id {\\n position: relative;\\n top: -1px;\\n background-color: rgb(232, 215, 87);\\n color: rgb(10, 10, 10);\\n padding-top: 5px;\\n padding-left: 10px;\\n padding-right: 10px;\\n padding-bottom: 5px;\\n border-radius: 5px;\\n font-size: 0.67em;\\n}\\n\\n.plant-card-sorting {\\n position: absolute;\\n top: 7px;\\n left: 8px;\\n z-index: 2;\\n padding-left: 10px;\\n padding-right: 10px;\\n padding-bottom: 1px;\\n background-color: rgba(240, 65, 205, 0.75);\\n border: 1px solid rgb(255, 80, 230);\\n border-radius: 5px;\\n font-size: 0.76em;\\n color: rgb(250, 250, 250);\\n}\\n\\n.plant-card-health-state, .plant-card-options {\\n position: absolute;\\n top: 7px;\\n right: 8px;\\n z-index: 2;\\n}\\n\\n.plant-card-options {\\n color: rgb(200, 200, 200);\\n}\\n\\n.plant-card-health-state i, .plant-card-options i {\\n background-color: rgba(0, 0, 0, 0.5);\\n padding: 5px;\\n border-radius: 32%;\\n}\\n\\n.plant-list-item {\\n position: relative;\\n width: 100%;\\n color: rgb(150, 150, 150);\\n background-color: rgba(50, 50, 50, 0.76);\\n border: 1px solid rgb(90, 90, 90);\\n padding-top: 5px;\\n padding-left: 10px;\\n padding-right: 10px;\\n padding-bottom: 5px;\\n text-align: left;\\n}\\n\\n@media screen and (max-width: 512px) {\\n .plant-list-item-hide-small-devices {\\n display: none !important;\\n }\\n}\\n\\n.plant-list-id {\\n position: relative;\\n display: inline-block;\\n width: 50px;\\n color: rgb(100, 100, 100);\\n}\\n\\n.plant-list-name-full {\\n position: relative;\\n display: inline-block;\\n}\\n@media screen and (max-width: 452px) {\\n .plant-list-name-full {\\n display: none !important;\\n }\\n}\\n\\n.plant-list-name-short {\\n position: relative;\\n display: inline-block;\\n}\\n@media screen and (min-width: 452px) {\\n .plant-list-name-short {\\n display: none !important;\\n }\\n}\\n\\n.plant-list-scientific-name {\\n position: relative;\\n display: inline-block;\\n padding-left: 5px;\\n padding-right: 5px;\\n}\\n\\n.plant-list-last-edited {\\n position: relative;\\n display: inline-block;\\n float: right;\\n}\\n\\n.plant-list-sorting {\\n position: relative;\\n display: inline-block;\\n float: right;\\n padding-left: 10px;\\n padding-right: 10px;\\n padding-bottom: 1px;\\n color: rgb(200, 200, 200);\\n background-color: rgba(240, 65, 205, 0.75);\\n border: 1px solid rgb(255, 80, 230);\\n border-radius: 5px;\\n}\\n\\n@media screen and (min-width: 520px) {\\n .plant-column {\\n padding: 20px;\\n }\\n}\\n@media screen and (max-width: 520px) {\\n .plant-column {\\n display: inline-block;\\n width: 100%;\\n padding-left: 15px;\\n padding-right: 15px;\\n }\\n}\\n@media screen and (max-width: 365px) {\\n .plant-column {\\n display: inline-block;\\n padding-left: unset;\\n padding-right: unset;\\n width: 107% !important;\\n }\\n}\\n\\n.plant-column table {\\n width: 80%;\\n color: rgb(200, 200, 200);\\n}\\n@media screen and (max-width: 1471px) {\\n .plant-column table {\\n width: 75%;\\n }\\n}\\n@media screen and (max-width: 925px) {\\n .plant-column table {\\n width: 73%;\\n }\\n}\\n@media screen and (max-width: 786px) {\\n .plant-column table {\\n width: 100%;\\n }\\n}\\n\\n.plant-column table strong {\\n color: rgb(200, 200, 200);\\n}\\n\\n.plant-column thead {\\n background-color: rgba(104, 145, 194, 0.5);\\n}\\n\\n.plant-column table td {\\n border: 1px solid rgb(200, 200, 200);\\n padding: 10px;\\n}\\n\\n.plant-custom-attribute {\\n position: relative;\\n margin-top: 10px;\\n}\\n\\n.plant-custom-attribute a {\\n color: rgb(0, 145, 215);\\n}\\n\\n.plant-custom-attribute a:hover {\\n color: rgb(0, 145, 215);\\n}\\n\\n.plant-custom-attribute-removal {\\n position: relative;\\n top: 10px;\\n float: right;\\n color: rgb(200, 105, 105) !important;\\n}\\n\\n.plant-custom-attribute-removal:hover {\\n color: rgb(200, 105, 105) !important;\\n text-decoration: underline;\\n}\\n\\n.plant-details-title {\\n position: relative;\\n}\\n\\n.plant-details-title h1 {\\n display: inline-block;\\n}\\n\\n.plant-details-title h2 {\\n position: relative;\\n display: inline-block;\\n top: 14px;\\n font-size: 1.5em;\\n color: rgb(100, 100, 100);\\n float: right;\\n}\\n\\n.is-color-yes, .is-color-ok {\\n color: rgb(115, 214, 103);\\n}\\n\\n.is-color-no, .is-color-danger {\\n color: rgb(212, 67, 67);\\n}\\n\\n.is-not-available {\\n color: rgb(100, 100, 100);\\n font-style: italic;\\n}\\n\\n.is-half-percent {\\n width: 50%;\\n}\\n\\n.plant-notes {\\n position: relative;\\n width: 100%;\\n min-width: 300px;\\n min-height: 75px;\\n padding: 10px;\\n color: rgb(200, 200, 200);\\n background-color: rgba(90, 90, 90, 0.5);\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);\\n font-size: 1em;\\n border: 1px solid rgb(100, 100, 100);\\n border-left: 3px solid rgb(163, 122, 61);\\n border-radius: 4px;\\n}\\n\\n.plant-notes-content {\\n position: relative;\\n display: inline-block;\\n width: 90%;\\n}\\n\\n.plant-notes-content pre {\\n background-color: inherit;\\n color: inherit;\\n white-space: pre-wrap;\\n word-wrap: break-word;\\n}\\n\\n.plant-notes-content a {\\n color: rgb(111, 185, 235);\\n}\\n\\n.plant-notes-content a:hover {\\n text-decoration: underline;\\n}\\n\\n.plant-notes-edit {\\n position: relative;\\n display: inline-block;\\n float: right;\\n}\\n\\n.plant-photo {\\n position: relative;\\n width: 473px;\\n height: 631px;\\n background-repeat: no-repeat;\\n background-size: cover;\\n float: right;\\n}\\n@media screen and (max-width: 1471px) {\\n .plant-photo {\\n width: 405px;\\n }\\n}\\n@media screen and (max-width: 1279px) {\\n .plant-photo {\\n width: 353px;\\n }\\n}\\n@media screen and (max-width: 935px) {\\n .plant-photo {\\n width: 320px;\\n }\\n}\\n@media screen and (max-width: 768px) {\\n .plant-photo {\\n width: 100%;\\n height: 439px;\\n }\\n}\\n\\n.plant-photo-overlay {\\n width: 100%;\\n height: 45px;\\n background-color: rgba(0, 0, 0, 0.8);\\n}\\n\\n.plant-photo-view {\\n position: absolute;\\n top: 10px;\\n left: 10px;\\n}\\n\\n.plant-photo-edit {\\n position: absolute;\\n top: 10px;\\n left: 40px;\\n}\\n\\n.plant-photo-clear {\\n position: absolute;\\n top: 10px;\\n left: 70px;\\n}\\n\\n.plant-photo-share {\\n position: absolute;\\n top: 10px;\\n right: 10px;\\n}\\n\\n#share-photo-result {\\n margin-top: 25px;\\n padding: 15px;\\n background-color: rgb(115, 215, 105);\\n border: 1px solid rgb(50, 255, 25);\\n border-radius: 4px;\\n}\\n\\n.plant-photo-edit i, .plant-photo-view i, .plant-photo-share i, .plant-photo-clear i {\\n color: rgb(200, 200, 200);\\n}\\n\\n.plant-state-in-good-standing {\\n color: rgb(115, 214, 103);\\n}\\n\\n.plant-state-overwatered {\\n color: rgb(54, 105, 201);\\n}\\n\\n.plant-state-withering {\\n color: rgb(156, 115, 67);\\n}\\n\\n.plant-state-infected {\\n color: rgb(205, 111, 205);\\n}\\n\\n.plant-state-pest_infestation {\\n color: rgb(173, 83, 83);\\n}\\n\\n.plant-state-transplant_shock {\\n color: rgb(143, 215, 195);\\n}\\n\\n.plant-state-nutritional_deficiency {\\n color: rgb(175, 125, 155);\\n}\\n\\n.plant-state-sunburn {\\n color: rgb(222, 220, 80);\\n}\\n\\n.plant-state-frostbite {\\n color: rgb(255, 255, 255);\\n}\\n\\n.plant-state-root_rot {\\n color: rgb(123, 130, 102);\\n}\\n\\n.plant-button-group a {\\n position: relative;\\n margin-bottom: 10px;\\n}\\n\\n.plant-warning {\\n margin-top: 10px;\\n margin-bottom: 10px;\\n color: rgb(212, 50, 50);\\n}\\n@media screen and (max-width: 510px) {\\n .plant-warning {\\n margin-bottom: 30px;\\n }\\n}\\n\\n.plant-bulk-update-list {\\n position: relative;\\n text-align: center;\\n}\\n\\n.plant-bulk-update-item {\\n position: relative;\\n display: inline-block;\\n width: 195px;\\n height: 300px;\\n margin-top: 10px;\\n margin-left: 15px;\\n margin-right: 15px;\\n margin-bottom: 50px !important;\\n}\\n@media screen and (max-width: 430px) {\\n .plant-bulk-update-item {\\n width: 295px;\\n height: 453px;\\n }\\n}\\n\\n.plant-bulk-update-item div:first-child {\\n width: 100%;\\n height: 100%;\\n}\\n\\n.plant-bulk-update-image {\\n position: relative;\\n display: inline-block;\\n width: 100%;\\n height: 100%;\\n background-repeat: no-repeat;\\n background-size: cover;\\n}\\n\\n.plant-bulk-update-selection {\\n text-align: center;\\n}\\n\\n@media screen and (min-width: 795px) {\\n .line-up-frames {\\n display: flex;\\n }\\n}\\n\\n.warning-plants {\\n position: relative;\\n flex: 1;\\n width: 45%;\\n margin-top: -10px;\\n margin-bottom: 45px;\\n margin-right: 5px;\\n margin-left: 10px;\\n padding: 15px 15px 15px 15px;\\n padding-left: 25px;\\n padding-bottom: 20px;\\n background-color: rgb(55, 59, 62);\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);\\n border-radius: 4px;\\n}\\n@media screen and (max-width: 796px) {\\n .warning-plants {\\n flex: unset;\\n display: inline-block;\\n width: 100%;\\n }\\n}\\n@media screen and (max-width: 512px) {\\n .warning-plants {\\n padding-left: 15px;\\n margin-left: unset;\\n }\\n}\\n\\n.has-warnings {\\n color: rgb(200, 105, 105) !important;\\n}\\n\\n.is-all-ok {\\n padding-top: 41px;\\n}\\n\\n.table-bright-color {\\n background-color: rgb(63, 70, 75);\\n}\\n\\n.warning-plants-title {\\n margin-top: -2px;\\n margin-bottom: 20px;\\n font-size: 1.3em;\\n color: rgb(200, 200, 200);\\n}\\n\\n.warning-plants-title-no-margin-bottom {\\n margin-bottom: unset;\\n}\\n\\n.warning-plants-title-centered {\\n position: relative;\\n top: 50%;\\n transform: translateY(-50%);\\n text-align: center;\\n margin-top: 2px;\\n}\\n@media screen and (max-width: 753px) {\\n .warning-plants-title-centered {\\n margin-top: 23px;\\n top: unset;\\n transform: unset;\\n }\\n}\\n\\n.warning-plants-content {\\n position: relative;\\n}\\n\\n.warning-plants-content table {\\n width: 100%;\\n}\\n\\n.warning-plants-content thead {\\n display: none;\\n}\\n\\n.warning-plants-content td {\\n color: rgb(150, 150, 150);\\n border: 1px solid rgb(100, 100, 100);\\n padding-top: 5px;\\n padding-left: 5px;\\n padding-right: 5px;\\n padding-bottom: 5px;\\n}\\n\\n.history-years {\\n position: relative;\\n margin-top: 30px;\\n margin-bottom: 40px;\\n margin-left: 10px;\\n}\\n\\n.history-year {\\n position: relative;\\n display: inline-block;\\n margin-right: 5px;\\n margin-bottom: 20px;\\n}\\n\\n.history-year a {\\n padding-top: 5px;\\n padding-bottom: 5px;\\n padding-left: 20px;\\n padding-right: 20px;\\n color: rgb(30, 30, 30);\\n background-color: rgba(200, 200, 200, 0.5);\\n border: 1px solid rgb(150, 150, 150);\\n border-radius: 20px;\\n}\\n\\n.history-year a:hover {\\n color: rgb(30, 30, 30);\\n background-color: rgba(200, 200, 200, 0.7);\\n}\\n\\n.history-year-selected a {\\n color: rgb(30, 30, 30);\\n background-color: rgba(220, 220, 220, 0.95);\\n}\\n\\n.history-year-selected a:hover {\\n color: rgb(30, 30, 30);\\n background-color: rgba(250, 250, 250, 0.95);\\n}\\n\\n.overdue-tasks {\\n position: relative;\\n flex: 1;\\n width: 45%;\\n margin-top: -10px;\\n margin-bottom: 45px;\\n margin-left: 5px;\\n margin-right: 10px;\\n padding-top: 2px;\\n padding-left: 30px;\\n padding-right: 30px;\\n padding-bottom: 20px;\\n background-color: rgb(55, 59, 62);\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);\\n border-radius: 4px;\\n}\\n@media screen and (max-width: 796px) {\\n .overdue-tasks {\\n flex: unset;\\n display: inline-block;\\n width: 100%;\\n margin-left: unset;\\n }\\n}\\n@media screen and (max-width: 512px) {\\n .overdue-tasks {\\n padding-left: 15px;\\n padding-right: 2px;\\n }\\n}\\n\\n.overdue-tasks-title {\\n margin-top: 10px;\\n margin-bottom: 20px;\\n font-size: 1.3em;\\n color: rgb(200, 105, 105);\\n}\\n\\n.overdue-tasks-content {\\n position: relative;\\n}\\n\\n.overdue-tasks-content table {\\n width: 100%;\\n}\\n\\n.overdue-tasks-content thead {\\n display: none;\\n}\\n\\n.overdue-tasks-content td {\\n color: rgb(150, 150, 150);\\n border: 1px solid rgb(100, 100, 100);\\n padding-top: 5px;\\n padding-left: 5px;\\n padding-right: 5px;\\n padding-bottom: 5px;\\n}\\n\\n.overdue-tasks-item {\\n color: rgb(150, 150, 150);\\n margin-bottom: 10px;\\n}\\n\\n.log {\\n position: relative;\\n width: 100%;\\n margin-top: 23px;\\n margin-bottom: 45px;\\n padding: 0 15px 15px 15px;\\n border: 1px solid rgb(43, 43, 43);\\n background-color: rgb(50, 54, 59);\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);\\n border-radius: 4px;\\n}\\n\\n.log-title {\\n margin-top: 10px;\\n margin-bottom: 10px;\\n font-size: 1.3em;\\n color: rgb(0, 145, 215);\\n}\\n\\n.log-content {\\n max-height: 200px;\\n overflow-y: auto;\\n}\\n\\n.log-item {\\n color: rgb(150, 150, 150);\\n margin-bottom: 10px;\\n}\\n\\n.log-item a {\\n color: rgb(150, 150, 150);\\n}\\n\\n.log-item a:hover {\\n color: rgb(200, 200, 200);\\n}\\n\\n.plant-gallery {\\n position: relative;\\n margin-top: 10px;\\n margin-bottom: 10px;\\n}\\n\\n.plant-gallery-title {\\n margin-bottom: 20px;\\n font-size: 1.5em;\\n color: rgb(150, 150, 150);\\n}\\n\\n.plant-gallery-upload {\\n margin-bottom: 20px;\\n}\\n\\n.plant-gallery-photos {\\n margin-top: 30px;\\n}\\n\\n.plant-gallery-photos strong {\\n color: rgb(100, 100, 100);\\n}\\n\\n.plant-gallery-item {\\n position: relative;\\n display: inline-block;\\n width: 315px;\\n height: auto;\\n margin-left: 10px;\\n margin-right: 10px;\\n margin-bottom: 30px;\\n background-color: rgb(73, 79, 83);\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);\\n border-radius: 4px;\\n}\\n\\n.plant-gallery-item-header {\\n padding: 10px;\\n}\\n\\n.plant-gallery-item-header-label {\\n display: inline-block;\\n color: rgb(230, 230, 230);\\n}\\n\\n.plant-gallery-item-header-action {\\n display: inline-block;\\n float: right;\\n}\\n\\n.plant-gallery-item-header-action i.is-action-share, .is-action-edit {\\n color: rgb(200, 200, 200);\\n}\\n\\n.plant-gallery-item-header-action i.is-action-share:hover, i.is-action-edit:hover {\\n color: rgb(220, 220, 220);\\n}\\n\\n.plant-gallery-item-header-action i.is-action-delete {\\n color: rgb(173, 86, 86);\\n}\\n\\n.plant-gallery-item-header-action i.is-action-delete:hover {\\n color: rgb(173, 90, 90);\\n}\\n\\n.plant-gallery-item-photo {\\n position: relative;\\n}\\n\\n.plant-gallery-item-photo-overlay {\\n position: absolute;\\n z-index: 2;\\n width: 100%;\\n height: 97%;\\n}\\n\\n.plant-gallery-item-photo-overlay:hover {\\n background-color: rgba(0, 0, 0, 0.5);\\n}\\n\\n.plant-gallery-item-photo-overlay .plant-gallery-item-photo-image {\\n visibility: hidden;\\n}\\n\\n.plant-gallery-item-photo-overlay:hover .plant-gallery-item-photo-image {\\n visibility: visible;\\n}\\n\\n.plant-gallery-item-footer {\\n position: relative;\\n top: -3px;\\n padding: 10px;\\n color: rgb(135, 135, 135);\\n}\\n\\n.plant-log {\\n position: relative;\\n margin-top: 10px;\\n margin-bottom: 10px;\\n}\\n@media screen and (max-width: 410px) {\\n .plant-log {\\n width: 100%;\\n overflow-x: auto;\\n }\\n}\\n\\n.plant-log-title {\\n margin-bottom: 20px;\\n font-size: 1.5em;\\n color: rgb(150, 150, 150);\\n}\\n\\n.plant-log table {\\n width: 100%;\\n}\\n\\n.plant-log strong {\\n color: rgb(100, 100, 100);\\n}\\n\\n.plant-log-action {\\n margin-top: 20px;\\n}\\n\\n.plant-log-paginate {\\n position: relative;\\n}\\n\\n.plant-log-paginate td {\\n text-align: center;\\n}\\n\\n.plant-log-paginate a {\\n color: rgb(0, 145, 215);\\n}\\n\\n.plant-log-paginate a:hover {\\n color: rgb(0, 145, 215);\\n text-decoration: underline;\\n}\\n\\n.location-log {\\n position: relative;\\n margin-top: 10px;\\n margin-bottom: 10px;\\n}\\n@media screen and (max-width: 410px) {\\n .location-log {\\n width: 100%;\\n overflow-x: auto;\\n }\\n}\\n\\n.location-log-title {\\n margin-bottom: 20px;\\n font-size: 1.5em;\\n color: rgb(150, 150, 150);\\n}\\n\\n.location-log table {\\n width: 100%;\\n color: rgb(200, 200, 200);\\n}\\n\\n.location-log table strong {\\n color: rgb(200, 200, 200);\\n}\\n\\n.location-log thead {\\n background-color: rgba(104, 145, 194, 0.5);\\n}\\n\\n.location-log table td {\\n border: 1px solid rgb(200, 200, 200);\\n padding: 10px;\\n}\\n\\n.location-log strong {\\n color: rgb(100, 100, 100);\\n}\\n\\n.location-log-action {\\n margin-top: 20px;\\n}\\n\\n.location-log-paginate {\\n position: relative;\\n}\\n\\n.location-log-paginate td {\\n text-align: center;\\n}\\n\\n.location-log-paginate a {\\n color: rgb(0, 145, 215);\\n}\\n\\n.location-log-paginate a:hover {\\n color: rgb(0, 145, 215);\\n text-decoration: underline;\\n}\\n\\n.share-log-action {\\n margin-top: 20px;\\n}\\n\\n.share-log-paginate {\\n position: relative;\\n}\\n\\n.share-log-paginate td {\\n text-align: center;\\n}\\n\\n.share-log-paginate a {\\n color: rgb(0, 145, 215);\\n}\\n\\n.share-log-paginate a:hover {\\n color: rgb(0, 145, 215);\\n text-decoration: underline;\\n}\\n\\n.stats {\\n position: relative;\\n margin-top: 10px;\\n margin-bottom: 25px;\\n text-align: center;\\n}\\n\\n.stats-item {\\n position: relative;\\n display: inline-block;\\n width: 243.9px;\\n height: 130px;\\n margin-left: 12px;\\n margin-right: 12px;\\n margin-bottom: 20px;\\n padding: 20px;\\n background-color: rgb(55, 59, 62);\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);\\n border-radius: 4px;\\n border-left: 2px solid rgb(159, 165, 45);\\n}\\n@media screen and (max-width: 512px) {\\n .stats-item {\\n width: 135px;\\n }\\n}\\n\\n.stats-item-count {\\n color: rgb(250, 250, 250);\\n font-size: 2em;\\n text-align: center;\\n}\\n\\n.stats-item-label {\\n color: rgb(200, 200, 200);\\n font-size: 1.4em;\\n text-align: center;\\n}\\n\\n.plant-tags {\\n position: relative;\\n}\\n\\n.plant-tags-content {\\n position: relative;\\n display: inline-block;\\n width: 90%;\\n}\\n\\n.plant-tags-edit {\\n position: relative;\\n display: inline-block;\\n float: right;\\n}\\n\\n.plant-tags-item {\\n position: relative;\\n display: inline-block;\\n min-width: 125px;\\n padding-left: 10px;\\n padding-right: 10px;\\n padding-top: 5px;\\n padding-bottom: 9px;\\n margin-left: 5px;\\n margin-right: 5px;\\n margin-bottom: 16px;\\n text-align: center;\\n background-color: rgba(123, 123, 123, 0.3);\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);\\n border-radius: 10px;\\n}\\n\\n.plant-tags-item:hover {\\n background-color: rgba(150, 150, 150, 0.5);\\n}\\n\\n.plant-tags-item a {\\n color: rgb(190, 190, 190);\\n}\\n\\n.plant-tags-item a:hover {\\n color: rgb(230, 230, 230);\\n}\\n\\n.tasks {\\n margin-bottom: 50px;\\n}\\n\\n.task {\\n position: relative;\\n display: inline-block;\\n width: 45%;\\n height: auto;\\n margin-left: 10px;\\n margin-right: 10px;\\n margin-bottom: 29px;\\n background-color: rgb(55, 59, 62);\\n border: 1px solid rgb(80, 80, 80);\\n border-radius: 4px;\\n}\\n@media screen and (max-width: 580px) {\\n .task {\\n width: 95%;\\n }\\n}\\n\\n.task-header {\\n position: relative;\\n width: 100%;\\n height: 50px;\\n padding: 10px;\\n border-top-left-radius: 4px;\\n border-top-right-radius: 4px;\\n background-color: rgb(25, 25, 25);\\n}\\n\\n.task-header-title {\\n position: relative;\\n display: inline-block;\\n font-size: 1.2em;\\n color: rgb(200, 200, 200);\\n}\\n\\n.task-header-title span {\\n color: rgb(100, 100, 100);\\n}\\n\\n.task-header-action {\\n position: relative;\\n display: inline-block;\\n float: right;\\n}\\n\\n.task-header-action a {\\n color: rgb(150, 150, 150);\\n}\\n\\n.task-description {\\n position: relative;\\n height: 150px;\\n margin-bottom: 43px;\\n padding: 10px;\\n font-size: 1em;\\n color: rgb(150, 150, 150);\\n overflow-y: auto;\\n}\\n\\n.task-description pre {\\n background-color: inherit;\\n color: inherit;\\n white-space: pre-wrap;\\n word-wrap: break-word;\\n}\\n\\n.task-description a {\\n color: rgb(111, 185, 235);\\n}\\n\\n.task-description a:hover {\\n text-decoration: underline;\\n}\\n\\n.task-footer {\\n position: absolute;\\n bottom: 0;\\n padding: 10px;\\n width: 100%;\\n background-color: rgb(10, 10, 10);\\n border-bottom-left-radius: 4px;\\n border-bottom-right-radius: 4px;\\n font-size: 0.8em;\\n}\\n\\n.task-footer-date {\\n position: relative;\\n display: inline-block;\\n width: 43%;\\n}\\n\\n.task-footer-due {\\n position: relative;\\n display: inline-block;\\n}\\n\\n.is-task-overdue {\\n color: rgb(212, 50, 50);\\n}\\n\\n.task-footer-action {\\n position: relative;\\n display: inline-block;\\n float: right;\\n}\\n\\n.task-footer-action a {\\n color: rgb(150, 150, 150);\\n}\\n\\n.tasks-all-done {\\n position: relative;\\n margin-top: 30px;\\n text-align: center;\\n}\\n\\n.tasks-all-done-image img {\\n width: 256px;\\n height: 256px;\\n}\\n\\n.tasks-all-done-text {\\n color: rgb(120, 215, 105);\\n font-size: 2em;\\n}\\n\\n.inventory {\\n margin-bottom: 50px;\\n}\\n\\n.inventory-item-group {\\n position: relative;\\n width: 100%;\\n padding-left: 10px;\\n padding-right: 10px;\\n padding-top: 5px;\\n padding-bottom: 5px;\\n background-color: rgba(200, 200, 200, 0.76);\\n border: 1px solid rgb(90, 90, 90);\\n}\\n\\n.inventory-item {\\n position: relative;\\n width: 100%;\\n padding-left: 10px;\\n padding-right: 10px;\\n padding-top: 5px;\\n padding-bottom: 5px;\\n background-color: rgba(50, 50, 50, 0.76);\\n border: 1px solid rgb(90, 90, 90);\\n}\\n\\n.inventory-item-header {\\n position: relative;\\n}\\n\\n.inventory-item-name {\\n position: relative;\\n display: inline-block;\\n min-width: 50%;\\n}\\n\\n.inventory-item-name span {\\n color: rgb(100, 100, 100);\\n}\\n\\n.inventory-item-name a {\\n color: rgb(150, 150, 150);\\n}\\n\\n.inventory-item-name a:hover {\\n color: rgb(150, 150, 150);\\n}\\n\\n.inventory-item-amount {\\n position: relative;\\n display: inline-block;\\n}\\n\\n.inventory-item-amount i {\\n color: rgb(150, 150, 150);\\n}\\n\\n.inventory-item-amount span {\\n color: rgb(215, 215, 215);\\n}\\n\\n.is-inventory-item-empty {\\n color: rgb(212, 50, 50) !important;\\n}\\n\\n.inventory-item-actions {\\n position: relative;\\n display: inline-block;\\n float: right;\\n}\\n\\n.inventory-item-actions i {\\n color: rgb(100, 100, 100);\\n}\\n\\n.inventory-item-body {\\n position: relative;\\n height: 0;\\n opacity: 0;\\n overflow: hidden;\\n -webkit-transition: opacity 1s ease-out;\\n -moz-transition: opacity 1s ease-out;\\n transition: opacity 1s ease-out;\\n}\\n\\n.inventory-item-body.expand {\\n height: auto;\\n opacity: 1;\\n}\\n\\n.inventory-item-description {\\n position: relative;\\n color: rgb(130, 130, 130);\\n margin-top: 10px;\\n margin-bottom: 10px;\\n}\\n\\n.inventory-item-description pre {\\n background-color: inherit;\\n color: inherit;\\n white-space: normal;\\n}\\n\\n.inventory-item-description a {\\n color: rgb(111, 185, 235);\\n}\\n\\n.inventory-item-description a:hover {\\n text-decoration: underline;\\n}\\n\\n.inventory-item-photo {\\n position: relative;\\n text-align: center;\\n margin-bottom: 20px;\\n}\\n\\n.inventory-item-footer {\\n position: relative;\\n color: rgb(120, 120, 120);\\n margin-top: 10px;\\n}\\n\\n.inventory-item-location {\\n position: relative;\\n display: inline-block;\\n}\\n\\n.inventory-item-author {\\n position: relative;\\n display: inline-block;\\n float: right;\\n}\\n\\n.inventory-groups {\\n width: 100%;\\n}\\n\\n.inventory-groups thead td {\\n color: rgb(150, 150, 150);\\n}\\n\\n.inventory-groups thead td:last-child {\\n width: 5%;\\n}\\n\\n.inventory-groups.table td {\\n border: 1px solid rgb(100, 100, 100);\\n}\\n\\n.inventory-groups a {\\n color: rgb(150, 150, 150);\\n}\\n\\n.inventory-groups a:hover {\\n color: rgb(150, 150, 150);\\n text-decoration: underline;\\n}\\n\\n.calendar-add {\\n position: relative;\\n margin-top: 40px;\\n margin-bottom: 25px;\\n}\\n\\n.calendar-add a {\\n width: 200px;\\n}\\n\\n.calendar-menu {\\n position: relative;\\n}\\n\\n.calendar-menu span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.calendar-input {\\n padding: 8px;\\n color: rgb(250, 250, 250);\\n background-color: rgb(50, 50, 50);\\n border: 1px solid rgb(100, 100, 100);\\n border-radius: 5px;\\n}\\n\\n.calendar-content {\\n position: relative;\\n margin-top: 30px;\\n}\\n\\n.calendar-link-removal {\\n position: relative;\\n top: 10px;\\n float: right;\\n color: rgb(200, 105, 105);\\n}\\n\\n.calendar-link-removal:hover {\\n color: rgb(200, 105, 105);\\n text-decoration: underline;\\n}\\n\\n.calendar-view {\\n position: relative;\\n margin-top: 10px;\\n margin-bottom: 59px;\\n}\\n\\n.calendar-view h3 {\\n color: rgb(150, 150, 150);\\n font-size: 2em;\\n padding-bottom: 10px;\\n}\\n\\n.weather-forecast {\\n position: relative;\\n margin-top: 40px;\\n}\\n@media screen and (max-width: 768px) {\\n .weather-forecast {\\n width: 100%;\\n overflow-x: scroll;\\n white-space: nowrap;\\n }\\n}\\n\\n.weather-header {\\n position: relative;\\n margin-bottom: 20px;\\n}\\n\\n.weather-header-item {\\n position: relative;\\n display: inline-block;\\n margin-left: 15px;\\n margin-right: 15px;\\n padding-top: 10px;\\n padding-left: 10px;\\n padding-right: 10px;\\n padding-bottom: 10px;\\n color: rgb(150, 150, 150);\\n text-align: center;\\n background-color: rgb(100, 100, 100);\\n border-radius: 5px;\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);\\n}\\n\\n.weather-header-item strong {\\n color: rgb(200, 200, 200);\\n}\\n\\n.weather-day {\\n position: relative;\\n display: inline-block;\\n margin-left: 10px;\\n margin-right: 10px;\\n padding-left: 10px;\\n padding-right: 10px;\\n}\\n\\n.weather-day-data {\\n position: relative;\\n text-align: center;\\n margin-bottom: 50px;\\n}\\n\\n.weather-day-data-title {\\n position: relative;\\n color: rgb(200, 200, 200);\\n font-weight: bold;\\n}\\n\\n.weather-day-data-icon {\\n position: relative;\\n}\\n\\n.weather-day-data-attribute {\\n position: relative;\\n color: rgb(150, 150, 150);\\n}\\n\\n.is-weather-fill-data {\\n color: rgb(100, 100, 100);\\n}\\n\\n.chat-message {\\n position: relative;\\n width: 90%;\\n padding: 15px;\\n margin-bottom: 20px;\\n background-color: rgba(200, 200, 200, 0.5);\\n border-radius: 10px;\\n}\\n\\n.chat-message-right {\\n margin-left: 10%;\\n background-color: rgba(115, 143, 100, 0.9);\\n}\\n\\n.chat-message-user {\\n position: relative;\\n font-size: 1.2em;\\n margin-bottom: 10px;\\n}\\n\\n.chat-message-new {\\n position: relative;\\n display: inline-block;\\n background-color: rgb(212, 130, 67);\\n border: 1px solid rgb(92, 64, 25);\\n color: rgb(250, 250, 250);\\n border-radius: 4px;\\n padding: 5px;\\n font-size: 0.5em;\\n text-transform: uppercase;\\n float: right;\\n}\\n\\n.chat-message-content {\\n position: relative;\\n}\\n\\n.chat-message-content pre {\\n background-color: transparent;\\n color: rgb(255, 255, 255);\\n}\\n\\n.chat-message-content a {\\n color: rgb(111, 185, 235);\\n}\\n\\n.chat-message-content a:hover {\\n text-decoration: underline;\\n}\\n\\n.chat-message-info {\\n position: relative;\\n margin-top: 10px;\\n font-size: 0.76em;\\n color: rgb(200, 200, 200);\\n}\\n\\n.chat-typing-indicator {\\n display: none;\\n background-color: rgba(50, 50, 50, 0.5);\\n}\\n\\n.chat-typing-indicator.visible {\\n display: block;\\n}\\n\\n.chat-user-list {\\n position: relative;\\n margin-top: 10px;\\n margin-bottom: 23px;\\n color: rgb(92, 255, 0);\\n}\\n\\n.system-message {\\n position: relative;\\n background-color: rgb(205, 202, 165);\\n border-radius: 10px;\\n padding: 20px;\\n margin-bottom: 20px;\\n}\\n\\n.system-message-left {\\n position: relative;\\n display: inline-block;\\n width: 93%;\\n}\\n@media screen and (max-width: 1000px) {\\n .system-message-left {\\n width: 80%;\\n }\\n}\\n\\n.system-message-left-new {\\n top: -3px;\\n}\\n\\n.system-message-right {\\n position: relative;\\n display: inline-block;\\n top: 3px;\\n}\\n@media screen and (max-width: 520px) {\\n .system-message-right {\\n top: 55px;\\n vertical-align: top;\\n right: -25px;\\n }\\n}\\n\\n.system-message-context {\\n position: relative;\\n display: inline-block;\\n top: -1px;\\n font-size: 0.9em;\\n font-weight: bold;\\n}\\n\\n.system-message-content {\\n position: relative;\\n display: inline-block;\\n}\\n@media screen and (max-width: 768px) {\\n .system-message-content {\\n margin-top: 10px;\\n }\\n}\\n\\n.system-message-content a {\\n color: rgb(135, 75, 5);\\n}\\n\\n.system-message-content a:hover {\\n color: rgb(135, 75, 5);\\n text-decoration: underline;\\n}\\n\\n@media screen and (max-width: 768px) {\\n .system-message-new {\\n top: -58px;\\n }\\n}\\n\\n#small-system-messages {\\n position: fixed;\\n z-index: 3;\\n top: 55px;\\n}\\n@media screen and (max-width: 512px) {\\n #small-system-messages {\\n width: 100%;\\n }\\n}\\n\\n.system-message-small {\\n position: relative;\\n top: 12px;\\n left: 12px;\\n background-color: rgb(205, 202, 165);\\n border-radius: 10px;\\n border: 1px solid rgb(250, 250, 250);\\n padding: 20px;\\n margin-bottom: 10px;\\n}\\n@media screen and (max-width: 512px) {\\n .system-message-small {\\n width: 100%;\\n left: 0;\\n }\\n}\\n\\n.system-message-small-context {\\n font-weight: bold;\\n}\\n\\n.system-message-small-content a {\\n color: rgb(135, 75, 5);\\n}\\n\\n.system-message-small-content a:hover {\\n color: rgb(135, 75, 5);\\n text-decoration: underline;\\n}\\n\\n.scroll-to-top {\\n position: fixed;\\n z-index: 102;\\n bottom: 12px;\\n right: 12px;\\n}\\n\\n.scroll-to-top-inner {\\n background-color: rgb(80, 80, 80);\\n border-radius: 50%;\\n padding: 12px;\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);\\n}\\n\\n.scroll-to-top-inner a {\\n color: rgb(200, 200, 200);\\n}\\n\\n.auth-main {\\n width: 100%;\\n height: 100%;\\n background-repeat: no-repeat;\\n background-size: cover;\\n}\\n\\n.auth-overlay {\\n width: 100%;\\n height: 100%;\\n background-color: rgba(0, 0, 0, 0.5);\\n}\\n\\n.auth-content {\\n position: absolute;\\n top: 50%;\\n left: 50%;\\n transform: translate(-50%, -50%);\\n text-align: center;\\n padding: 20px;\\n}\\n\\n.auth-header {\\n position: relative;\\n margin-bottom: 20px;\\n}\\n\\n.auth-header img {\\n position: relative;\\n width: 128px;\\n height: 128px;\\n border-radius: 50%;\\n}\\n\\n.auth-header h1 {\\n font-size: 2.5em;\\n font-family: Verdana, Geneva, Tahoma, sans-serif;\\n font-weight: bold;\\n color: rgb(150, 150, 150);\\n}\\n\\n.auth-info {\\n position: relative;\\n margin-bottom: 43px;\\n}\\n\\n.auth-info-error {\\n color: rgb(154, 73, 69);\\n}\\n\\n.auth-info-success {\\n color: rgb(69, 154, 83);\\n}\\n\\n.auth-form {\\n position: relative;\\n}\\n\\n.auth-form input[type=email], .auth-form input[type=password] {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.auth-form input[type=email]::placeholder, .auth-form input[type=password]::placeholder {\\n color: rgb(200, 200, 200);\\n}\\n\\n.auth-form input[type=submit] {\\n width: 100%;\\n}\\n\\n.auth-help {\\n position: relative;\\n margin-top: 20px;\\n}\\n\\n.auth-help a {\\n color: rgb(54, 105, 203);\\n}\\n\\n.auth-help a:hover {\\n color: rgb(54, 105, 203);\\n text-decoration: underline;\\n}\\n\\n.reset-main {\\n width: 100%;\\n height: 100%;\\n background-repeat: no-repeat;\\n background-size: cover;\\n}\\n\\n.reset-overlay {\\n width: 100%;\\n height: 100%;\\n background-color: rgba(0, 0, 0, 0.5);\\n}\\n\\n.reset-content {\\n position: absolute;\\n top: 50%;\\n left: 50%;\\n transform: translate(-50%, -50%);\\n text-align: center;\\n padding: 20px;\\n}\\n\\n.reset-content h1 {\\n margin-bottom: 30px;\\n line-height: 1;\\n}\\n\\n.reset-info {\\n position: relative;\\n margin-bottom: 43px;\\n}\\n\\n.reset-info-error {\\n color: rgb(154, 73, 69);\\n}\\n\\n.reset-info-success {\\n color: rgb(69, 154, 83);\\n}\\n\\n.reset-form {\\n position: relative;\\n}\\n\\n.reset-form input[type=email], .reset-form input[type=password] {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.reset-form input[type=email]::placeholder, .reset-form input[type=password]::placeholder {\\n color: rgb(200, 200, 200);\\n}\\n\\n.reset-form input[type=submit] {\\n width: 100%;\\n}\\n\\n.preferences-header {\\n position: relative;\\n}\\n\\n.preferences-header i {\\n color: rgb(150, 150, 150);\\n}\\n\\n.profile-shared-photos table {\\n width: 100%;\\n}\\n\\n.profile-shared-photos thead {\\n background-color: rgba(104, 145, 194, 0.5);\\n}\\n\\n.profile-shared-photos thead:hover {\\n background-color: rgba(104, 145, 194, 0.5);\\n}\\n\\n.profile-shared-photos td {\\n padding: 10px;\\n color: rgb(150, 150, 150);\\n border: 1px solid rgb(200, 200, 200);\\n}\\n\\n.profile-shared-photos td a {\\n color: rgb(111, 143, 225);\\n}\\n\\n.profile-shared-photos td a:hover {\\n color: rgb(111, 143, 225);\\n text-decoration: underline;\\n}\\n\\n.profile-shared-photos td i {\\n color: rgb(150, 150, 150);\\n}\\n\\n.profile-shared-photos td i:hover {\\n color: rgb(150, 150, 150);\\n}\\n\\n.profile-shared-photos td:last-child {\\n width: 5%;\\n text-align: center;\\n}\\n\\n.admin-tabs {\\n margin-top: 23px;\\n}\\n\\n.admin-tabs a {\\n color: rgb(200, 200, 200);\\n}\\n\\n.admin-tabs a:hover {\\n color: rgb(230, 230, 230);\\n border-bottom-color: rgb(111, 172, 243);\\n}\\n\\n.admin-environment {\\n position: relative;\\n}\\n\\n.admin-environment h2 {\\n margin-top: 20px;\\n margin-bottom: 10px;\\n}\\n\\n.admin-environment label, .admin-environment span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-environment input, .admin-environment textarea, .admin-environment select {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-environment hr {\\n background-color: rgb(100, 100, 100);\\n}\\n\\n.admin-media {\\n position: relative;\\n width: 100%;\\n}\\n\\n.admin-media h2 {\\n margin-top: 20px;\\n margin-bottom: 20px;\\n}\\n\\n.admin-media label {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-media input, .admin-backup input {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-media input[type=submit] {\\n margin-top: 10px;\\n margin-bottom: 20px;\\n}\\n\\n.admin-users {\\n position: relative;\\n width: 100%;\\n}\\n\\n.admin-users h2 {\\n margin-top: 20px;\\n margin-bottom: 20px;\\n}\\n\\n.admin-users-list {\\n position: relative;\\n}\\n\\n.admin-user-account {\\n position: relative;\\n margin-bottom: 15px;\\n}\\n\\n.admin-user-account label, .admin-user-account span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-user-account input, .admin-user-account select {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-user-account-item {\\n position: relative;\\n display: inline-block;\\n margin-left: 5px;\\n margin-right: 5px;\\n}\\n\\n.admin-user-account-item-input {\\n width: 30%;\\n}\\n\\n.admin-user-account-actions {\\n position: relative;\\n display: inline-block;\\n}\\n\\n.admin-user-account-item-centered {\\n text-align: center;\\n}\\n\\n.admin-user-account-action-item {\\n position: relative;\\n}\\n\\n.admin-users-created-password {\\n position: relative;\\n color: rgb(220, 220, 220);\\n background-color: rgb(180, 103, 0);\\n border: 1px solid rgb(245, 185, 105);\\n border-radius: 10px;\\n padding: 20px;\\n}\\n\\n.admin-users-created-password strong {\\n color: rgb(250, 250, 250);\\n}\\n\\n.admin-users-actions {\\n position: relative;\\n margin-top: 20px;\\n}\\n\\n.admin-locations {\\n position: relative;\\n width: 100%;\\n}\\n\\n.admin-locations h2 {\\n margin-top: 20px;\\n margin-bottom: 20px;\\n}\\n\\n.admin-locations-list {\\n position: relative;\\n}\\n\\n.admin-location {\\n position: relative;\\n margin-bottom: 15px;\\n}\\n\\n.admin-location label, .admin-location span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-location input {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-location-item {\\n position: relative;\\n display: inline-block;\\n margin-left: 5px;\\n margin-right: 5px;\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-location-item-input {\\n width: 30%;\\n}\\n\\n.admin-location-actions {\\n position: relative;\\n display: inline-block;\\n}\\n\\n.admin-location-item-centered {\\n text-align: center;\\n}\\n\\n.admin-location-action-item {\\n position: relative;\\n}\\n\\n.admin-locations-actions {\\n position: relative;\\n margin-top: 20px;\\n}\\n\\n.admin-auth {\\n position: relative;\\n}\\n\\n.admin-auth h2 {\\n margin-top: 20px;\\n margin-bottom: 10px;\\n}\\n\\n.admin-auth label, .admin-auth span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-auth input, .admin-auth textarea {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-auth-warning {\\n position: relative;\\n display: none;\\n padding: 20px;\\n margin-top: 30px;\\n margin-bottom: 25px;\\n color: rgb(250, 250, 250);\\n background-color: rgba(202, 102, 102, 0.76);\\n border: 1px solid rgb(235, 150, 150);\\n border-radius: 5px;\\n}\\n\\n.admin-auth-caution {\\n position: relative;\\n display: none;\\n padding: 20px;\\n margin-top: 30px;\\n margin-bottom: 25px;\\n color: rgb(250, 250, 250);\\n background-color: rgba(255, 220, 87, 0.5);\\n border: 1px solid rgb(255, 220, 87);\\n border-radius: 5px;\\n}\\n\\n.admin-attribute-schema-list {\\n position: relative;\\n}\\n\\n.admin-attribute-schema {\\n position: relative;\\n margin-bottom: 15px;\\n}\\n\\n.admin-attribute-schema label, .admin-attribute-schema span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-attribute-schema input, .admin-attribute-schema select {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-attribute-schema-item {\\n position: relative;\\n display: inline-block;\\n margin-left: 5px;\\n margin-right: 5px;\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-attribute-schema-item-input {\\n width: 30%;\\n}\\n\\n.admin-attribute-schema-actions {\\n position: relative;\\n display: inline-block;\\n}\\n\\n.admin-attribute-schema-item-centered {\\n text-align: center;\\n}\\n\\n.admin-attribute-schema-action-item {\\n position: relative;\\n}\\n\\n.admin-attribute-schema-actions {\\n position: relative;\\n margin-top: 20px;\\n}\\n\\n.admin-attributes {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-attributes p {\\n color: rgb(150, 150, 150);\\n margin-bottom: 30px;\\n}\\n\\n.admin-bulk-commands-list {\\n position: relative;\\n}\\n\\n.admin-bulk-command {\\n position: relative;\\n margin-bottom: 15px;\\n}\\n\\n.admin-bulk-command label, .admin-bulk-command span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-bulk-command input, .admin-bulk-command select {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-bulk-command-item {\\n position: relative;\\n display: inline-block;\\n margin-left: 5px;\\n margin-right: 5px;\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-bulk-command-item-input {\\n width: 30%;\\n}\\n\\n.admin-bulk-command-actions {\\n position: relative;\\n display: inline-block;\\n}\\n\\n.admin-bulk-command-item-centered {\\n text-align: center;\\n}\\n\\n.admin-bulk-command-action-item {\\n position: relative;\\n}\\n\\n.admin-bulk-command-actions {\\n position: relative;\\n margin-top: 20px;\\n}\\n\\n.admin-bulk-command-actions {\\n position: relative;\\n margin-top: 20px;\\n}\\n\\n.admin-calendar-classes {\\n position: relative;\\n width: 100%;\\n}\\n\\n.admin-calendar-classes h2 {\\n margin-top: 20px;\\n margin-bottom: 20px;\\n}\\n\\n.admin-calendar-classes-list {\\n position: relative;\\n}\\n\\n.admin-calendar-class {\\n position: relative;\\n margin-bottom: 15px;\\n}\\n\\n.admin-calendar-class label, .admin-calendar-class span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-calendar-class input {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-calendar-class-item {\\n position: relative;\\n display: inline-block;\\n margin-left: 5px;\\n margin-right: 5px;\\n}\\n\\n.admin-calendar-class-item-input {\\n width: 30%;\\n}\\n\\n.admin-calendar-class-actions {\\n position: relative;\\n display: inline-block;\\n}\\n\\n.admin-calendar-class-item-centered {\\n text-align: center;\\n}\\n\\n.admin-calendar-class-action-item {\\n position: relative;\\n}\\n\\n.admin-calendar-classes-actions {\\n position: relative;\\n margin-top: 20px;\\n}\\n\\n.admin-mail {\\n position: relative;\\n}\\n\\n.admin-mail h2 {\\n margin-top: 20px;\\n margin-bottom: 10px;\\n}\\n\\n.admin-mail label, .admin-mail span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-mail input, .admin-mail select {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-themes p {\\n color: rgb(150, 150, 150);\\n margin-bottom: 30px;\\n font-size: 1.2em;\\n}\\n\\n.admin-themes input, .admin-themes select {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-themes-result {\\n position: relative;\\n padding: 10px;\\n border-radius: 5px;\\n border: 1px solid rgb(255, 255, 255);\\n background-color: rgb(185, 255, 164);\\n}\\n\\n.admin-themes-result i {\\n color: rgb(50, 50, 50);\\n}\\n\\n.admin-themes-list {\\n position: relative;\\n}\\n\\n.admin-themes-list table {\\n width: 100%;\\n}\\n\\n.admin-themes-list thead {\\n background-color: rgba(104, 145, 194, 0.5);\\n}\\n\\n.admin-themes-list thead:hover {\\n background-color: rgba(104, 145, 194, 0.5);\\n}\\n\\n.admin-themes-list td {\\n padding: 10px;\\n color: rgb(150, 150, 150);\\n border: 1px solid rgb(200, 200, 200);\\n}\\n\\n.admin-themes-list td i {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-themes-list td i:hover {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-theme-list-right {\\n width: 5%;\\n text-align: center;\\n}\\n\\n.admin-backup label, .admin-backup span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-backup-result {\\n position: relative;\\n padding: 10px;\\n border-radius: 5px;\\n border: 1px solid rgb(255, 255, 255);\\n background-color: rgb(185, 255, 164);\\n}\\n\\n.admin-backup-result i {\\n color: rgb(50, 50, 50);\\n}\\n\\n.admin-backup-result a {\\n color: rgb(15, 150, 43);\\n}\\n\\n.admin-backup-result a:hover {\\n color: rgb(15, 150, 43);\\n text-decoration: underline;\\n}\\n\\n.admin-weather label, .admin-weather span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-weather input, .admin-weather select {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-api p {\\n color: rgb(150, 150, 150);\\n margin-bottom: 30px;\\n font-size: 1.2em;\\n}\\n\\n.admin-api table {\\n width: 100%;\\n margin-top: 15px;\\n color: rgb(200, 200, 200);\\n}\\n\\n.admin-api table strong {\\n color: rgb(200, 200, 200);\\n}\\n\\n.admin-api thead {\\n background-color: rgba(104, 145, 194, 0.5);\\n}\\n\\n.admin-api table td {\\n border: 1px solid rgb(200, 200, 200);\\n padding: 10px;\\n}\\n\\n.admin-api table td a {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-api table td a:hover {\\n color: rgb(200, 200, 200);\\n}\\n\\n.admin-api table td:last-child {\\n width: 5%;\\n text-align: center;\\n}\\n\\n.admin-info {\\n position: relative;\\n}\\n\\n.admin-info-version {\\n color: rgb(200, 200, 200);\\n font-size: 1.5em;\\n}\\n\\n.admin-info-version-smaller {\\n color: rgb(150, 150, 150);\\n font-size: 0.76em;\\n}\\n\\n.admin-info-support {\\n position: relative;\\n margin-top: 43px;\\n}\\n\\n.admin-info-support a {\\n width: 465px;\\n}\\n@media screen and (max-width: 495px) {\\n .admin-info-support a {\\n width: 100%;\\n height: 50px;\\n font-size: 1.4em;\\n }\\n}\\n\\n.admin-info-sponsor {\\n position: relative;\\n margin-top: 15px;\\n margin-bottom: 15px;\\n}\\n\\n.admin-info-sponsor a {\\n width: 465px;\\n background-color: rgb(30, 150, 183) !important;\\n}\\n@media screen and (max-width: 495px) {\\n .admin-info-sponsor a {\\n width: 100%;\\n height: 50px;\\n font-size: 1.4em;\\n }\\n}\\n\\n.admin-info-sponsor a:hover {\\n background-color: rgb(35, 167, 202) !important;\\n}\\n\\n.admin-info-sponsor i {\\n color: rgb(205, 50, 50);\\n}\\n\\n.admin-info-sponsor i:hover {\\n color: rgb(205, 50, 50);\\n}\\n\\n.admin-info-donation {\\n position: relative;\\n margin-top: 15px;\\n margin-bottom: 15px;\\n}\\n\\n.admin-info-donation a {\\n width: 465px;\\n background-color: rgb(170, 135, 85) !important;\\n}\\n@media screen and (max-width: 495px) {\\n .admin-info-donation a {\\n width: 100%;\\n height: 50px;\\n font-size: 1.4em;\\n }\\n}\\n\\n.admin-info-donation a:hover {\\n background-color: rgb(195, 150, 95) !important;\\n}\\n\\n.admin-info-donation i {\\n color: rgb(90, 67, 10);\\n}\\n\\n.admin-info-donation i:hover {\\n color: rgb(90, 67, 10);\\n}\\n\\n.admin-info-social {\\n position: relative;\\n margin-top: 15px;\\n margin-bottom: 35px;\\n}\\n\\n.admin-info-social img {\\n width: 152px;\\n height: 35px;\\n}\\n@media screen and (max-width: 495px) {\\n .admin-info-social img {\\n width: 32%;\\n height: 30px;\\n }\\n}\\n\\n.admin-info-extensions {\\n position: relative;\\n}\\n\\n.admin-info-extensions h3 {\\n color: rgb(200, 200, 200);\\n font-size: 1.4em;\\n margin-top: 20px;\\n margin-bottom: 20px;\\n}\\n\\n.admin-info-extensions a {\\n color: rgb(0, 145, 215);\\n}\\n\\n.admin-info-extensions a:hover {\\n color: rgb(0, 145, 215);\\n text-decoration: underline;\\n}\\n\\n.admin-info-extensions table {\\n width: 100%;\\n margin-top: 15px;\\n color: rgb(200, 200, 200);\\n}\\n\\n.admin-info-extensions table strong {\\n color: rgb(200, 200, 200);\\n}\\n\\n.admin-info-extensions thead {\\n background-color: rgba(104, 145, 194, 0.5);\\n}\\n\\n.admin-info-extensions table td {\\n border: 1px solid rgb(200, 200, 200);\\n padding: 10px;\\n}\\n\\n.admin-info-extensions table td:first-child {\\n width: 10%;\\n}\\n\\n.version-check {\\n position: relative;\\n margin-top: 30px;\\n}\\n\\n.version-info {\\n position: relative;\\n padding: 20px;\\n margin-top: 30px;\\n color: rgb(250, 250, 250);\\n background-color: rgba(102, 202, 160, 0.76);\\n border: 1px solid rgb(150, 235, 200);\\n border-radius: 10px;\\n}\\n\\n.version-info a {\\n color: rgb(132, 255, 123);\\n font-weight: bold;\\n}\\n\\n.version-info a:hover {\\n color: rgb(132, 255, 123);\\n text-decoration: underline;\\n}\\n\\n.bottomnav {\\n position: fixed;\\n bottom: 0;\\n width: 100%;\\n height: 70px;\\n z-index: 100;\\n padding-left: 5px;\\n padding-right: 5px;\\n background-color: rgb(30, 30, 30);\\n}\\n@media screen and (min-width: 1087px) {\\n .bottomnav {\\n display: none;\\n }\\n}\\n\\n.bottomnav-items {\\n position: relative;\\n display: block;\\n top: 10px;\\n width: 100%;\\n height: 100%;\\n margin-left: auto;\\n margin-right: auto;\\n text-align: center;\\n}\\n\\n.bottomnav-item {\\n position: relative;\\n display: inline-block;\\n width: 65px;\\n height: 50px;\\n margin-top: 6px;\\n color: rgb(150, 150, 150);\\n text-align: center;\\n font-size: 0.8em;\\n}\\n\\n.bottomnav-item a {\\n color: rgb(150, 150, 150);\\n}\\n\\n.bottomnav-item a:hover {\\n color: rgb(200, 200, 200);\\n text-decoration: none;\\n}\\n\\n.button-margin-left {\\n margin-left: 5px;\\n}\", \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://asatruphp/./app/resources/sass/app.scss?./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__);\n// Imports\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default()(function(i){return i[1]});\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \"/*\\n app.scss\\n*/\\nhtml {\\n overflow-y: hidden;\\n}\\n\\nhtml, body {\\n width: 100%;\\n height: 100%;\\n padding: 0;\\n margin: 0;\\n background-color: rgb(48, 52, 55);\\n}\\n\\nbody {\\n overflow-x: hidden;\\n}\\n\\n.is-image-container {\\n background-repeat: no-repeat;\\n background-size: cover;\\n padding: unset;\\n}\\n\\n.column-overlay {\\n width: 100%;\\n height: 100%;\\n padding: 20px;\\n background-color: rgba(0, 0, 0, 0.5);\\n}\\n\\nh1 {\\n font-size: 2.5em;\\n color: rgb(250, 250, 250);\\n}\\n\\nh2 {\\n font-size: 2em;\\n margin-bottom: 30px;\\n color: rgb(200, 200, 200);\\n}\\n\\n.smaller-headline {\\n font-size: 1.2em;\\n margin-bottom: 15px;\\n}\\n\\n.is-default-link {\\n color: rgb(79, 134, 202);\\n}\\n\\n.is-default-link:hover {\\n color: rgb(79, 134, 202);\\n text-decoration: underline;\\n}\\n\\n.is-yellow-link {\\n color: rgb(156, 115, 67);\\n}\\n\\n.is-yellow-link:hover {\\n color: rgb(156, 115, 67);\\n text-decoration: underline;\\n}\\n\\n.is-gray-link {\\n color: rgb(150, 150, 150);\\n}\\n\\n.is-gray-link:hover {\\n color: rgb(150, 150, 150);\\n text-decoration: underline;\\n}\\n\\n.is-dark-delimiter hr {\\n background-color: rgb(100, 100, 100);\\n}\\n\\n.is-fixed-button-link {\\n position: relative;\\n top: 5px;\\n}\\n\\n@media screen and (max-width: 512px) {\\n .is-fixed-margin-left-mobile {\\n margin-left: 2px;\\n }\\n}\\n\\n.is-default-text-color {\\n color: rgb(150, 150, 150);\\n}\\n\\n.is-color-darker {\\n color: rgb(100, 100, 100);\\n}\\n\\n.is-color-error {\\n color: rgb(154, 73, 69);\\n}\\n\\n.is-input-dark {\\n background-color: rgba(90, 90, 90, 0.5);\\n color: rgb(200, 200, 200);\\n border: 1px solid rgb(100, 100, 100);\\n}\\n\\n.is-action-button-margin {\\n margin-right: 10px;\\n margin-bottom: 10px;\\n}\\n@media screen and (max-width: 376px) {\\n .is-action-button-margin {\\n margin-right: 15px;\\n }\\n}\\n\\n.is-underlined {\\n text-decoration: underline;\\n}\\n\\n.is-stretched {\\n width: 100%;\\n}\\n\\n.is-pointer {\\n cursor: pointer;\\n}\\n\\n.is-centered {\\n text-align: center !important;\\n}\\n\\n.is-indicator {\\n position: absolute;\\n width: 10px;\\n height: 10px;\\n top: 17px;\\n left: 20px;\\n background-color: rgb(223, 50, 50);\\n border-radius: 50%;\\n z-index: 5;\\n}\\n@media screen and (max-width: 1087px) {\\n .is-indicator {\\n top: 10px;\\n left: 22px;\\n }\\n}\\n\\n.is-indicator-tab {\\n position: relative;\\n width: 10px;\\n height: 10px;\\n top: -4px;\\n left: -3px;\\n background-color: rgb(223, 50, 50);\\n border-radius: 50%;\\n z-index: 5;\\n}\\n\\n.is-background-success-light {\\n background-color: rgb(215, 253, 200);\\n}\\n\\n.is-chocolate {\\n background-color: rgb(179, 105, 62);\\n border-color: transparent;\\n}\\n\\n.is-chocolate:hover {\\n background-color: rgb(167, 95, 55);\\n border-color: transparent;\\n}\\n\\n.float-right {\\n float: right;\\n}\\n\\n.belongs-to-previous-field {\\n position: relative;\\n top: -5px;\\n margin-bottom: 20px !important;\\n}\\n\\n.is-next-to-elem {\\n position: relative;\\n top: 5px;\\n margin-left: 10px;\\n}\\n@media screen and (max-width: 453px) {\\n .is-next-to-elem {\\n top: -3px;\\n margin-bottom: 20px !important;\\n margin-left: unset;\\n }\\n}\\n\\n.is-margin-bottom-20 {\\n margin-bottom: 20px !important;\\n}\\n\\n.field small {\\n color: rgb(120, 120, 120);\\n}\\n\\n.form-paragraph-modal a, .modal-anchors a {\\n color: rgb(52, 105, 215);\\n}\\n\\n.form-paragraph-modal a:hover, .modal-anchors a:hover {\\n color: rgb(52, 105, 215);\\n text-decoration: underline;\\n}\\n\\n@media screen and (max-width: 1087px) {\\n .navbar-menu {\\n max-height: calc(100vh - 3.25rem);\\n overflow-y: auto;\\n }\\n}\\n\\n@media screen and (max-width: 1087px) {\\n .navbar-end {\\n margin-bottom: 100px;\\n }\\n}\\n\\n.navbar-item a {\\n color: rgb(200, 200, 200);\\n}\\n\\n.navbar-item a:hover {\\n color: rgb(250, 250, 250);\\n}\\n\\na.navbar-item:hover, a.navbar-item.is-active, .navbar-link:hover, .navbar-link.is-active {\\n background-color: rgba(255, 255, 255, 0) !important;\\n color: rgb(180, 180, 180) !important;\\n}\\n\\n.navbar-item, .navbar-burger, .navbar-link {\\n color: rgb(190, 190, 190);\\n}\\n\\n.navbar-dropdown {\\n background-color: rgb(50, 50, 48);\\n padding-top: unset;\\n}\\n\\n.navbar-item.has-dropdown:hover .navbar-link, .navbar-item.has-dropdown.is-active .navbar-link {\\n background-color: rgba(0, 0, 0, 0);\\n}\\n\\n@media screen and (max-width: 1087px) {\\n .navbar-menu {\\n background-color: rgb(50, 50, 48);\\n }\\n}\\na.navbar-burger:hover {\\n color: rgb(200, 200, 200);\\n}\\n\\n@media screen and (min-width: 1088px) {\\n .navbar-start {\\n flex-grow: 1;\\n justify-content: center;\\n }\\n}\\n\\n@media screen and (min-width: 1089px) {\\n .navbar-item-only-mobile {\\n display: none;\\n }\\n}\\n\\n@media screen and (min-width: 1089px) {\\n .navbar-dropdown-minwidth {\\n display: block;\\n top: 5px;\\n min-width: 135px;\\n text-align: center;\\n }\\n}\\n\\n@media screen and (min-width: 1089px) {\\n .navbar-dropdown-minwidth:not(.is-multiple):not(.is-loading)::after {\\n top: 20px !important;\\n }\\n}\\n\\n@media screen and (max-width: 1087px) {\\n .navbar-item-brand-mobile-right {\\n position: absolute;\\n top: 10px;\\n right: 45px;\\n }\\n}\\n@media screen and (min-width: 1089px) {\\n .navbar-item-brand-mobile-right {\\n display: none;\\n }\\n}\\n\\n@media screen and (max-width: 1087px) {\\n .navbar.is-fixed-top-pwa {\\n position: fixed;\\n top: 0;\\n left: 0;\\n right: 0;\\n z-index: 30;\\n }\\n}\\n\\n@media screen and (min-width: 768px) {\\n .column h1 {\\n margin-top: 20px;\\n }\\n}\\n\\n#frmEditMultilineText textarea {\\n min-height: 200px;\\n}\\n\\n.banner {\\n width: 100%;\\n height: 250px;\\n background-repeat: no-repeat;\\n background-size: 100% 100%;\\n}\\n@media screen and (max-width: 768px) {\\n .banner {\\n display: none;\\n }\\n}\\n\\n.banner-icon {\\n position: relative;\\n top: 210px;\\n left: 195px;\\n}\\n\\n.banner-icon img {\\n width: 72px;\\n height: 72px;\\n}\\n\\n.banner-accessory {\\n position: relative;\\n top: 172px;\\n right: -83%;\\n}\\n\\n.banner-accessory img {\\n width: 256px;\\n height: 256px;\\n}\\n\\n.content-inner {\\n position: relative;\\n padding: 15px;\\n}\\n\\n.modal {\\n z-index: 105;\\n}\\n\\n.modal-card {\\n color: rgb(150, 150, 150);\\n}\\n\\n.modal-card-head {\\n background-color: rgb(55, 59, 62);\\n border-bottom: 1px solid rgb(59, 59, 59);\\n}\\n\\n.modal-card-title {\\n color: rgb(190, 190, 190);\\n}\\n\\n.modal-card-body {\\n background-color: rgb(48, 52, 55);\\n}\\n\\n.modal-card-body label {\\n color: rgb(150, 150, 150);\\n}\\n\\n.modal-card-body input, .modal-card-body select, .modal-card-body textarea, .modal-card-body table {\\n background-color: rgb(57, 59, 63);\\n color: rgb(150, 150, 150);\\n border: 1px solid rgb(100, 100, 100);\\n}\\n\\n.modal-card-body input::placeholder, .modal-card-body select::placeholder, .modal-card-body textarea::placeholder {\\n color: rgb(250, 250, 250);\\n}\\n\\n.modal-card-body hr {\\n background-color: rgb(100, 100, 100);\\n}\\n\\n.modal-card-foot {\\n background-color: rgb(50, 50, 50);\\n border-top: 1px solid rgb(59, 59, 59);\\n}\\n\\n.fade {\\n transition: opacity 0.65s linear;\\n}\\n\\n.fade-in {\\n opacity: 1;\\n}\\n\\n.fade-out {\\n opacity: 0;\\n}\\n\\n@media screen and (max-width: 1087px) {\\n .app-padding-pwa {\\n padding-top: 65px;\\n padding-bottom: 87px;\\n }\\n}\\n@media screen and (max-width: 768px) {\\n .app-padding-pwa {\\n padding-top: 41px;\\n padding-bottom: 87px;\\n }\\n}\\n\\nfieldset legend {\\n margin-bottom: 5px !important;\\n}\\n\\nfieldset .field {\\n margin-bottom: unset !important;\\n}\\n\\n.legend-title {\\n font-size: 1.2em;\\n margin-bottom: 15px !important;\\n}\\n\\n.notification-badge {\\n color: rgb(255, 255, 255);\\n text-decoration: none;\\n border-radius: 2px;\\n}\\n\\n.notification-badge .notify-badge {\\n padding-top: 4px;\\n padding-bottom: 4px;\\n padding-left: 10px;\\n padding-right: 10px;\\n border-radius: 50%;\\n background: rgba(255, 0, 0, 0.9);\\n color: rgb(255, 255, 255);\\n font-size: 0.8em;\\n}\\n@media screen and (min-width: 1089px) {\\n .notification-badge .notify-badge {\\n position: absolute;\\n right: -7px;\\n top: 4px;\\n }\\n}\\n@media screen and (max-width: 1087px) {\\n .notification-badge .notify-badge {\\n position: relative;\\n right: -2px;\\n top: -10px;\\n }\\n}\\n\\n.notify-badge .notify-badge-count {\\n position: relative;\\n top: -1px;\\n}\\n\\n.dashboard-header {\\n position: relative;\\n}\\n\\n.dashboard-welcome {\\n display: inline-block;\\n}\\n\\n.dashboard-weather {\\n display: inline-block;\\n position: relative;\\n top: 20px;\\n float: right;\\n color: rgb(200, 200, 200);\\n}\\n@media screen and (max-width: 525px) {\\n .dashboard-weather {\\n top: -20px;\\n float: unset;\\n }\\n}\\n\\n.dashboard-weather-content {\\n position: relative;\\n margin-top: 10px;\\n}\\n@media screen and (max-width: 525px) {\\n .dashboard-weather-content {\\n left: -10px;\\n }\\n}\\n\\n.dashboard-weather-left {\\n position: relative;\\n display: inline-block;\\n left: 10px;\\n}\\n@media screen and (max-width: 525px) {\\n .dashboard-weather-left {\\n left: unset;\\n }\\n}\\n\\n.dashboard-weather-right {\\n display: inline-block;\\n position: relative;\\n top: -32px;\\n}\\n@media screen and (max-width: 525px) {\\n .dashboard-weather-right {\\n left: -10px;\\n float: unset;\\n }\\n}\\n\\n.locations {\\n text-align: center;\\n}\\n\\n.locations a {\\n color: rgb(100, 100, 100);\\n}\\n\\n.locations a:hover {\\n color: rgb(100, 100, 100);\\n}\\n\\n.location {\\n position: relative;\\n display: inline-block;\\n width: 245px;\\n min-height: 250px;\\n margin-left: 10px;\\n margin-right: 10px;\\n margin-bottom: 30px;\\n background-color: rgb(55, 59, 62);\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);\\n}\\n@media screen and (max-width: 830px) {\\n .location {\\n width: 134px;\\n min-height: 137px;\\n }\\n}\\n\\n.location:hover {\\n box-shadow: 0 0 20px 0 rgba(105, 165, 85, 0.95);\\n}\\n\\n.location-title {\\n text-align: center;\\n font-size: 2em;\\n padding-bottom: 4px;\\n margin-bottom: 20px;\\n background-color: rgba(115, 143, 100, 0.9);\\n color: #c3e4a3;\\n}\\n@media screen and (max-width: 830px) {\\n .location-title {\\n font-size: 1em;\\n padding-top: 2px;\\n padding-bottom: 5px;\\n }\\n}\\n@media screen and (min-width: 831px) {\\n .location-title {\\n padding-bottom: 7px;\\n }\\n}\\n\\n.location-icon {\\n text-align: center;\\n}\\n\\n.location-icon i {\\n color: #99ac97;\\n font-size: 5em;\\n}\\n@media screen and (max-width: 830px) {\\n .location-icon i {\\n font-size: 2em;\\n }\\n}\\n@media screen and (min-width: 831px) {\\n .location-icon i {\\n margin-top: 25px;\\n }\\n}\\n\\n.location-footer {\\n position: relative;\\n bottom: -30px;\\n padding-top: 10px;\\n padding-left: 10px;\\n padding-bottom: 10px;\\n font-size: 0.9em;\\n text-align: left;\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 54, 59);\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);\\n}\\n@media screen and (max-width: 830px) {\\n .location-footer {\\n font-size: 0.75em;\\n bottom: -15px;\\n }\\n}\\n\\n.location-footer-count-desktop {\\n display: none;\\n}\\n@media screen and (min-width: 850px) {\\n .location-footer-count-desktop {\\n display: inherit;\\n }\\n}\\n\\n.location-footer-count-mobile {\\n display: none;\\n}\\n@media screen and (max-width: 850px) {\\n .location-footer-count-mobile {\\n display: inherit;\\n }\\n}\\n\\n.upcoming-tasks-overview {\\n position: relative;\\n text-align: center;\\n margin-bottom: 63px;\\n}\\n\\n.upcoming-tasks-overview h3 {\\n padding-top: 25px;\\n font-size: 2em;\\n color: rgb(150, 150, 150);\\n}\\n\\n.upcoming-tasks-overview-items {\\n margin-top: 25px;\\n}\\n\\n.last-added-or-authored-plants {\\n margin-top: 20px;\\n margin-bottom: 40px;\\n margin-left: -20px;\\n margin-right: -20px;\\n padding-bottom: 5px;\\n background-color: rgb(55, 59, 62);\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);\\n text-align: center;\\n}\\n\\n.last-added-or-authored-plants h3 {\\n padding-top: 15px;\\n font-size: 2em;\\n color: rgb(150, 150, 150);\\n}\\n\\n.margin-vertical {\\n margin-top: 20px;\\n margin-bottom: 20px;\\n}\\n\\n.margin-bottom {\\n margin-bottom: 20px;\\n}\\n\\n.action-strip {\\n position: relative;\\n display: inline-block;\\n}\\n\\n@media screen and (max-width: 1111px) {\\n .action-strip-left {\\n width: 83%;\\n }\\n}\\n\\n.action-strip-right {\\n position: relative;\\n float: right;\\n}\\n\\n.sorting {\\n position: relative;\\n top: 10px;\\n margin-left: 10px;\\n}\\n\\n.sorting-control {\\n position: relative;\\n display: inline-block;\\n margin-bottom: 10px;\\n}\\n\\n.sorting-control a {\\n color: rgb(150, 150, 150);\\n}\\n\\n.sorting-control a.is-selected {\\n color: rgb(200, 200, 200);\\n}\\n\\n.sorting-control i {\\n margin-right: 5px;\\n}\\n\\n.sorting-control select, .sorting-control input[type=text] {\\n color: rgb(200, 200, 200);\\n background-color: rgba(50, 50, 50, 0.9);\\n border: 1px solid rgb(100, 100, 100);\\n margin-right: 5px;\\n}\\n\\n.sorting-control input[type=text] {\\n height: 27px;\\n border-radius: 290486px;\\n padding-left: 1em;\\n}\\n\\n.sorting-mobile-only {\\n margin-right: 10px;\\n}\\n\\n.sorting-mobile-only-last-elem {\\n margin-bottom: 20px;\\n}\\n\\n@media screen and (min-width: 501px) {\\n .sorting-mobile-only span {\\n display: none;\\n }\\n}\\n\\n.select:not(.is-multiple):not(.is-loading)::after {\\n border-color: rgb(50, 115, 220) !important;\\n}\\n\\n.plants {\\n margin-top: 30px;\\n}\\n@media screen and (max-width: 552px) {\\n .plants {\\n text-align: center;\\n }\\n}\\n\\n.plants-empty {\\n position: relative;\\n margin-top: 50px;\\n text-align: center;\\n}\\n\\n.plants-empty-image img {\\n width: 256px;\\n height: 256px;\\n}\\n\\n.plants-empty-text {\\n position: relative;\\n top: -20px;\\n color: rgb(150, 150, 150);\\n font-style: italic;\\n font-size: 1.4em;\\n}\\n\\n.plant-card {\\n position: relative;\\n display: inline-block;\\n width: 245px;\\n height: 375px;\\n margin-left: 10px;\\n margin-right: 10px;\\n margin-bottom: 20px;\\n background-repeat: no-repeat;\\n background-size: cover;\\n border-radius: 10px;\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.3);\\n}\\n@media screen and (max-width: 552px) {\\n .plant-card {\\n width: 141px;\\n height: 222px;\\n }\\n}\\n\\n.plant-card:hover {\\n box-shadow: 0 0 20px 0 rgba(105, 165, 85, 0.95);\\n}\\n\\n.plant-card-overlay {\\n width: 100%;\\n height: 100%;\\n background: transparent;\\n border-radius: 10px;\\n}\\n\\n.plant-card-overlay:hover {\\n background-color: rgba(0, 0, 0, 0.05);\\n}\\n\\n.plant-card-title {\\n position: absolute;\\n bottom: 0;\\n z-index: 2;\\n width: 100%;\\n height: 69px;\\n padding-top: 17px;\\n background-color: rgba(0, 0, 0, 0.5);\\n color: rgb(200, 200, 200);\\n text-align: center;\\n font-size: 1.2em;\\n border-bottom-left-radius: 10px;\\n border-bottom-right-radius: 10px;\\n}\\n@media screen and (max-width: 552px) {\\n .plant-card-title {\\n padding-top: 22px;\\n font-size: 0.9em;\\n }\\n}\\n\\n.plant-card-title-with-hint {\\n padding-top: 7px;\\n}\\n\\n.plant-card-title-longtext {\\n padding-top: 5px;\\n padding-left: 5px;\\n padding-right: 5px;\\n}\\n@media screen and (max-width: 552px) {\\n .plant-card-title-longtext {\\n padding-top: 12px;\\n padding-left: 2px;\\n padding-right: 2px;\\n }\\n}\\n\\n.plant-card-title-second {\\n color: rgb(150, 150, 150);\\n font-size: 0.8em;\\n}\\n\\n.plant-card-title-plant-id {\\n position: relative;\\n top: -1px;\\n background-color: rgb(232, 215, 87);\\n color: rgb(10, 10, 10);\\n padding-top: 5px;\\n padding-left: 10px;\\n padding-right: 10px;\\n padding-bottom: 5px;\\n border-radius: 5px;\\n font-size: 0.67em;\\n}\\n\\n.plant-card-sorting {\\n position: absolute;\\n top: 7px;\\n left: 8px;\\n z-index: 2;\\n padding-left: 10px;\\n padding-right: 10px;\\n padding-bottom: 1px;\\n background-color: rgba(240, 65, 205, 0.75);\\n border: 1px solid rgb(255, 80, 230);\\n border-radius: 5px;\\n font-size: 0.76em;\\n color: rgb(250, 250, 250);\\n}\\n\\n.plant-card-health-state, .plant-card-options {\\n position: absolute;\\n top: 7px;\\n right: 8px;\\n z-index: 2;\\n}\\n\\n.plant-card-options {\\n color: rgb(200, 200, 200);\\n}\\n\\n.plant-card-health-state i, .plant-card-options i {\\n background-color: rgba(0, 0, 0, 0.5);\\n padding: 5px;\\n border-radius: 32%;\\n}\\n\\n.plant-list-item {\\n position: relative;\\n width: 100%;\\n color: rgb(150, 150, 150);\\n background-color: rgba(50, 50, 50, 0.76);\\n border: 1px solid rgb(90, 90, 90);\\n padding-top: 5px;\\n padding-left: 10px;\\n padding-right: 10px;\\n padding-bottom: 5px;\\n text-align: left;\\n}\\n\\n@media screen and (max-width: 512px) {\\n .plant-list-item-hide-small-devices {\\n display: none !important;\\n }\\n}\\n\\n.plant-list-id {\\n position: relative;\\n display: inline-block;\\n width: 50px;\\n color: rgb(100, 100, 100);\\n}\\n\\n.plant-list-name-full {\\n position: relative;\\n display: inline-block;\\n}\\n@media screen and (max-width: 452px) {\\n .plant-list-name-full {\\n display: none !important;\\n }\\n}\\n\\n.plant-list-name-short {\\n position: relative;\\n display: inline-block;\\n}\\n@media screen and (min-width: 452px) {\\n .plant-list-name-short {\\n display: none !important;\\n }\\n}\\n\\n.plant-list-scientific-name {\\n position: relative;\\n display: inline-block;\\n padding-left: 5px;\\n padding-right: 5px;\\n}\\n\\n.plant-list-last-edited {\\n position: relative;\\n display: inline-block;\\n float: right;\\n}\\n\\n.plant-list-sorting {\\n position: relative;\\n display: inline-block;\\n float: right;\\n padding-left: 10px;\\n padding-right: 10px;\\n padding-bottom: 1px;\\n color: rgb(200, 200, 200);\\n background-color: rgba(240, 65, 205, 0.75);\\n border: 1px solid rgb(255, 80, 230);\\n border-radius: 5px;\\n}\\n\\n@media screen and (min-width: 520px) {\\n .plant-column {\\n padding: 20px;\\n }\\n}\\n@media screen and (max-width: 520px) {\\n .plant-column {\\n display: inline-block;\\n width: 100%;\\n padding-left: 15px;\\n padding-right: 15px;\\n }\\n}\\n@media screen and (max-width: 365px) {\\n .plant-column {\\n display: inline-block;\\n padding-left: unset;\\n padding-right: unset;\\n width: 107% !important;\\n }\\n}\\n\\n.plant-column table {\\n width: 80%;\\n color: rgb(200, 200, 200);\\n}\\n@media screen and (max-width: 1471px) {\\n .plant-column table {\\n width: 75%;\\n }\\n}\\n@media screen and (max-width: 925px) {\\n .plant-column table {\\n width: 73%;\\n }\\n}\\n@media screen and (max-width: 786px) {\\n .plant-column table {\\n width: 100%;\\n }\\n}\\n\\n.plant-column table strong {\\n color: rgb(200, 200, 200);\\n}\\n\\n.plant-column thead {\\n background-color: rgba(104, 145, 194, 0.5);\\n}\\n\\n.plant-column table td {\\n border: 1px solid rgb(200, 200, 200);\\n padding: 10px;\\n}\\n\\n.plant-custom-attribute {\\n position: relative;\\n margin-top: 10px;\\n}\\n\\n.plant-custom-attribute a {\\n color: rgb(0, 145, 215);\\n}\\n\\n.plant-custom-attribute a:hover {\\n color: rgb(0, 145, 215);\\n}\\n\\n.plant-custom-attribute-removal {\\n position: relative;\\n top: 10px;\\n float: right;\\n color: rgb(200, 105, 105) !important;\\n}\\n\\n.plant-custom-attribute-removal:hover {\\n color: rgb(200, 105, 105) !important;\\n text-decoration: underline;\\n}\\n\\n.plant-details-title {\\n position: relative;\\n}\\n\\n.plant-details-title h1 {\\n display: inline-block;\\n}\\n\\n.plant-details-title h2 {\\n position: relative;\\n display: inline-block;\\n top: 14px;\\n font-size: 1.5em;\\n color: rgb(100, 100, 100);\\n float: right;\\n}\\n\\n.is-color-yes, .is-color-ok {\\n color: rgb(115, 214, 103);\\n}\\n\\n.is-color-no, .is-color-danger {\\n color: rgb(212, 67, 67);\\n}\\n\\n.is-not-available {\\n color: rgb(100, 100, 100);\\n font-style: italic;\\n}\\n\\n.is-half-percent {\\n width: 50%;\\n}\\n\\n.plant-notes {\\n position: relative;\\n width: 100%;\\n min-width: 300px;\\n min-height: 75px;\\n padding: 10px;\\n color: rgb(200, 200, 200);\\n background-color: rgba(90, 90, 90, 0.5);\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);\\n font-size: 1em;\\n border: 1px solid rgb(100, 100, 100);\\n border-left: 3px solid rgb(163, 122, 61);\\n border-radius: 4px;\\n}\\n\\n.plant-notes-content {\\n position: relative;\\n display: inline-block;\\n width: 90%;\\n}\\n\\n.plant-notes-content pre {\\n background-color: inherit;\\n color: inherit;\\n white-space: pre-wrap;\\n word-wrap: break-word;\\n}\\n\\n.plant-notes-content a {\\n color: rgb(111, 185, 235);\\n}\\n\\n.plant-notes-content a:hover {\\n text-decoration: underline;\\n}\\n\\n.plant-notes-edit {\\n position: relative;\\n display: inline-block;\\n float: right;\\n}\\n\\n.plant-photo {\\n position: relative;\\n width: 473px;\\n height: 631px;\\n background-repeat: no-repeat;\\n background-size: cover;\\n float: right;\\n}\\n@media screen and (max-width: 1471px) {\\n .plant-photo {\\n width: 405px;\\n }\\n}\\n@media screen and (max-width: 1279px) {\\n .plant-photo {\\n width: 353px;\\n }\\n}\\n@media screen and (max-width: 935px) {\\n .plant-photo {\\n width: 320px;\\n }\\n}\\n@media screen and (max-width: 768px) {\\n .plant-photo {\\n width: 100%;\\n height: 439px;\\n }\\n}\\n\\n.plant-photo-overlay {\\n width: 100%;\\n height: 45px;\\n background-color: rgba(0, 0, 0, 0.8);\\n}\\n\\n.plant-photo-view {\\n position: absolute;\\n top: 10px;\\n left: 10px;\\n}\\n\\n.plant-photo-edit {\\n position: absolute;\\n top: 10px;\\n left: 40px;\\n}\\n\\n.plant-photo-clear {\\n position: absolute;\\n top: 10px;\\n left: 70px;\\n}\\n\\n.plant-photo-share {\\n position: absolute;\\n top: 10px;\\n right: 10px;\\n}\\n\\n#share-photo-result {\\n margin-top: 25px;\\n padding: 15px;\\n background-color: rgb(115, 215, 105);\\n border: 1px solid rgb(50, 255, 25);\\n border-radius: 4px;\\n}\\n\\n.plant-photo-edit i, .plant-photo-view i, .plant-photo-share i, .plant-photo-clear i {\\n color: rgb(200, 200, 200);\\n}\\n\\n.plant-state-in-good-standing {\\n color: rgb(115, 214, 103);\\n}\\n\\n.plant-state-overwatered {\\n color: rgb(54, 105, 201);\\n}\\n\\n.plant-state-withering {\\n color: rgb(156, 115, 67);\\n}\\n\\n.plant-state-infected {\\n color: rgb(205, 111, 205);\\n}\\n\\n.plant-state-pest_infestation {\\n color: rgb(173, 83, 83);\\n}\\n\\n.plant-state-transplant_shock {\\n color: rgb(143, 215, 195);\\n}\\n\\n.plant-state-nutritional_deficiency {\\n color: rgb(175, 125, 155);\\n}\\n\\n.plant-state-sunburn {\\n color: rgb(222, 220, 80);\\n}\\n\\n.plant-state-frostbite {\\n color: rgb(255, 255, 255);\\n}\\n\\n.plant-state-root_rot {\\n color: rgb(123, 130, 102);\\n}\\n\\n.plant-button-group a {\\n position: relative;\\n margin-bottom: 10px;\\n}\\n\\n.plant-warning {\\n margin-top: 10px;\\n margin-bottom: 10px;\\n color: rgb(212, 50, 50);\\n}\\n@media screen and (max-width: 510px) {\\n .plant-warning {\\n margin-bottom: 30px;\\n }\\n}\\n\\n.plant-bulk-update-list {\\n position: relative;\\n text-align: center;\\n}\\n\\n.plant-bulk-update-item {\\n position: relative;\\n display: inline-block;\\n width: 195px;\\n height: 300px;\\n margin-top: 10px;\\n margin-left: 15px;\\n margin-right: 15px;\\n margin-bottom: 50px !important;\\n}\\n@media screen and (max-width: 430px) {\\n .plant-bulk-update-item {\\n width: 295px;\\n height: 453px;\\n }\\n}\\n\\n.plant-bulk-update-item div:first-child {\\n width: 100%;\\n height: 100%;\\n}\\n\\n.plant-bulk-update-image {\\n position: relative;\\n display: inline-block;\\n width: 100%;\\n height: 100%;\\n background-repeat: no-repeat;\\n background-size: cover;\\n}\\n\\n.plant-bulk-update-selection {\\n text-align: center;\\n}\\n\\n@media screen and (min-width: 795px) {\\n .line-up-frames {\\n display: flex;\\n }\\n}\\n\\n.warning-plants {\\n position: relative;\\n flex: 1;\\n width: 45%;\\n margin-top: -10px;\\n margin-bottom: 45px;\\n margin-right: 5px;\\n margin-left: 10px;\\n padding: 15px 15px 15px 15px;\\n padding-left: 25px;\\n padding-bottom: 20px;\\n background-color: rgb(55, 59, 62);\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);\\n border-radius: 4px;\\n}\\n@media screen and (max-width: 796px) {\\n .warning-plants {\\n flex: unset;\\n display: inline-block;\\n width: 100%;\\n }\\n}\\n@media screen and (max-width: 512px) {\\n .warning-plants {\\n padding-left: 15px;\\n margin-left: unset;\\n }\\n}\\n\\n.has-warnings {\\n color: rgb(200, 105, 105) !important;\\n}\\n\\n.is-all-ok {\\n padding-top: 41px;\\n}\\n\\n.table-bright-color {\\n background-color: rgb(63, 70, 75);\\n}\\n\\n.warning-plants-title {\\n margin-top: -2px;\\n margin-bottom: 20px;\\n font-size: 1.3em;\\n color: rgb(200, 200, 200);\\n}\\n\\n.warning-plants-title-no-margin-bottom {\\n margin-bottom: unset;\\n}\\n\\n.warning-plants-title-centered {\\n position: relative;\\n top: 50%;\\n transform: translateY(-50%);\\n text-align: center;\\n margin-top: 2px;\\n}\\n@media screen and (max-width: 753px) {\\n .warning-plants-title-centered {\\n margin-top: 23px;\\n top: unset;\\n transform: unset;\\n }\\n}\\n\\n.warning-plants-content {\\n position: relative;\\n}\\n\\n.warning-plants-content table {\\n width: 100%;\\n}\\n\\n.warning-plants-content thead {\\n display: none;\\n}\\n\\n.warning-plants-content td {\\n color: rgb(150, 150, 150);\\n border: 1px solid rgb(100, 100, 100);\\n padding-top: 5px;\\n padding-left: 5px;\\n padding-right: 5px;\\n padding-bottom: 5px;\\n}\\n\\n.history-years {\\n position: relative;\\n margin-top: 30px;\\n margin-bottom: 40px;\\n margin-left: 10px;\\n}\\n\\n.history-year {\\n position: relative;\\n display: inline-block;\\n margin-right: 5px;\\n margin-bottom: 20px;\\n}\\n\\n.history-year a {\\n padding-top: 5px;\\n padding-bottom: 5px;\\n padding-left: 20px;\\n padding-right: 20px;\\n color: rgb(30, 30, 30);\\n background-color: rgba(200, 200, 200, 0.5);\\n border: 1px solid rgb(150, 150, 150);\\n border-radius: 20px;\\n}\\n\\n.history-year a:hover {\\n color: rgb(30, 30, 30);\\n background-color: rgba(200, 200, 200, 0.7);\\n}\\n\\n.history-year-selected a {\\n color: rgb(30, 30, 30);\\n background-color: rgba(220, 220, 220, 0.95);\\n}\\n\\n.history-year-selected a:hover {\\n color: rgb(30, 30, 30);\\n background-color: rgba(250, 250, 250, 0.95);\\n}\\n\\n.overdue-tasks {\\n position: relative;\\n flex: 1;\\n width: 45%;\\n margin-top: -10px;\\n margin-bottom: 45px;\\n margin-left: 5px;\\n margin-right: 10px;\\n padding-top: 2px;\\n padding-left: 30px;\\n padding-right: 30px;\\n padding-bottom: 20px;\\n background-color: rgb(55, 59, 62);\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);\\n border-radius: 4px;\\n}\\n@media screen and (max-width: 796px) {\\n .overdue-tasks {\\n flex: unset;\\n display: inline-block;\\n width: 100%;\\n margin-left: unset;\\n }\\n}\\n@media screen and (max-width: 512px) {\\n .overdue-tasks {\\n padding-left: 15px;\\n padding-right: 2px;\\n }\\n}\\n\\n.overdue-tasks-title {\\n margin-top: 10px;\\n margin-bottom: 20px;\\n font-size: 1.3em;\\n color: rgb(200, 105, 105);\\n}\\n\\n.overdue-tasks-content {\\n position: relative;\\n}\\n\\n.overdue-tasks-content table {\\n width: 100%;\\n}\\n\\n.overdue-tasks-content thead {\\n display: none;\\n}\\n\\n.overdue-tasks-content td {\\n color: rgb(150, 150, 150);\\n border: 1px solid rgb(100, 100, 100);\\n padding-top: 5px;\\n padding-left: 5px;\\n padding-right: 5px;\\n padding-bottom: 5px;\\n}\\n\\n.overdue-tasks-item {\\n color: rgb(150, 150, 150);\\n margin-bottom: 10px;\\n}\\n\\n.log {\\n position: relative;\\n width: 100%;\\n margin-top: 23px;\\n margin-bottom: 45px;\\n padding: 0 15px 15px 15px;\\n border: 1px solid rgb(43, 43, 43);\\n background-color: rgb(50, 54, 59);\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);\\n border-radius: 4px;\\n}\\n\\n.log-title {\\n margin-top: 10px;\\n margin-bottom: 10px;\\n font-size: 1.3em;\\n color: rgb(0, 145, 215);\\n}\\n\\n.log-content {\\n max-height: 200px;\\n overflow-y: auto;\\n}\\n\\n.log-item {\\n color: rgb(150, 150, 150);\\n margin-bottom: 10px;\\n}\\n\\n.log-item a {\\n color: rgb(150, 150, 150);\\n}\\n\\n.log-item a:hover {\\n color: rgb(200, 200, 200);\\n}\\n\\n.plant-gallery {\\n position: relative;\\n margin-top: 10px;\\n margin-bottom: 10px;\\n}\\n\\n.plant-gallery-title {\\n margin-bottom: 20px;\\n font-size: 1.5em;\\n color: rgb(150, 150, 150);\\n}\\n\\n.plant-gallery-upload {\\n margin-bottom: 20px;\\n}\\n\\n.plant-gallery-photos {\\n margin-top: 30px;\\n}\\n\\n.plant-gallery-photos strong {\\n color: rgb(100, 100, 100);\\n}\\n\\n.plant-gallery-item {\\n position: relative;\\n display: inline-block;\\n width: 315px;\\n height: auto;\\n margin-left: 10px;\\n margin-right: 10px;\\n margin-bottom: 30px;\\n background-color: rgb(73, 79, 83);\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);\\n border-radius: 4px;\\n}\\n\\n.plant-gallery-item-header {\\n padding: 10px;\\n}\\n\\n.plant-gallery-item-header-label {\\n display: inline-block;\\n color: rgb(230, 230, 230);\\n}\\n\\n.plant-gallery-item-header-action {\\n display: inline-block;\\n float: right;\\n}\\n\\n.plant-gallery-item-header-action i.is-action-share, .is-action-edit {\\n color: rgb(200, 200, 200);\\n}\\n\\n.plant-gallery-item-header-action i.is-action-share:hover, i.is-action-edit:hover {\\n color: rgb(220, 220, 220);\\n}\\n\\n.plant-gallery-item-header-action i.is-action-delete {\\n color: rgb(173, 86, 86);\\n}\\n\\n.plant-gallery-item-header-action i.is-action-delete:hover {\\n color: rgb(173, 90, 90);\\n}\\n\\n.plant-gallery-item-photo {\\n position: relative;\\n}\\n\\n.plant-gallery-item-photo-overlay {\\n position: absolute;\\n z-index: 2;\\n width: 100%;\\n height: 97%;\\n}\\n\\n.plant-gallery-item-photo-overlay:hover {\\n background-color: rgba(0, 0, 0, 0.5);\\n}\\n\\n.plant-gallery-item-photo-overlay .plant-gallery-item-photo-image {\\n visibility: hidden;\\n}\\n\\n.plant-gallery-item-photo-overlay:hover .plant-gallery-item-photo-image {\\n visibility: visible;\\n}\\n\\n.plant-gallery-item-footer {\\n position: relative;\\n top: -3px;\\n padding: 10px;\\n color: rgb(135, 135, 135);\\n}\\n\\n.plant-log {\\n position: relative;\\n margin-top: 10px;\\n margin-bottom: 10px;\\n}\\n@media screen and (max-width: 410px) {\\n .plant-log {\\n width: 100%;\\n overflow-x: auto;\\n }\\n}\\n\\n.plant-log-title {\\n margin-bottom: 20px;\\n font-size: 1.5em;\\n color: rgb(150, 150, 150);\\n}\\n\\n.plant-log table {\\n width: 100%;\\n}\\n\\n.plant-log strong {\\n color: rgb(100, 100, 100);\\n}\\n\\n.plant-log-action {\\n margin-top: 20px;\\n}\\n\\n.plant-log-paginate {\\n position: relative;\\n}\\n\\n.plant-log-paginate td {\\n text-align: center;\\n}\\n\\n.plant-log-paginate a {\\n color: rgb(0, 145, 215);\\n}\\n\\n.plant-log-paginate a:hover {\\n color: rgb(0, 145, 215);\\n text-decoration: underline;\\n}\\n\\n.location-log {\\n position: relative;\\n margin-top: 10px;\\n margin-bottom: 10px;\\n}\\n@media screen and (max-width: 410px) {\\n .location-log {\\n width: 100%;\\n overflow-x: auto;\\n }\\n}\\n\\n.location-log-title {\\n margin-bottom: 20px;\\n font-size: 1.5em;\\n color: rgb(150, 150, 150);\\n}\\n\\n.location-log table {\\n width: 100%;\\n color: rgb(200, 200, 200);\\n}\\n\\n.location-log table strong {\\n color: rgb(200, 200, 200);\\n}\\n\\n.location-log thead {\\n background-color: rgba(104, 145, 194, 0.5);\\n}\\n\\n.location-log table td {\\n border: 1px solid rgb(200, 200, 200);\\n padding: 10px;\\n}\\n\\n.location-log strong {\\n color: rgb(100, 100, 100);\\n}\\n\\n.location-log-action {\\n margin-top: 20px;\\n}\\n\\n.location-log-paginate {\\n position: relative;\\n}\\n\\n.location-log-paginate td {\\n text-align: center;\\n}\\n\\n.location-log-paginate a {\\n color: rgb(0, 145, 215);\\n}\\n\\n.location-log-paginate a:hover {\\n color: rgb(0, 145, 215);\\n text-decoration: underline;\\n}\\n\\n.share-log-action {\\n margin-top: 20px;\\n}\\n\\n.share-log-paginate {\\n position: relative;\\n}\\n\\n.share-log-paginate td {\\n text-align: center;\\n}\\n\\n.share-log-paginate a {\\n color: rgb(0, 145, 215);\\n}\\n\\n.share-log-paginate a:hover {\\n color: rgb(0, 145, 215);\\n text-decoration: underline;\\n}\\n\\n.stats {\\n position: relative;\\n margin-top: 10px;\\n margin-bottom: 25px;\\n text-align: center;\\n}\\n\\n.stats-item {\\n position: relative;\\n display: inline-block;\\n width: 243.9px;\\n height: 130px;\\n margin-left: 12px;\\n margin-right: 12px;\\n margin-bottom: 20px;\\n padding: 20px;\\n background-color: rgb(55, 59, 62);\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);\\n border-radius: 4px;\\n border-left: 2px solid rgb(159, 165, 45);\\n}\\n@media screen and (max-width: 512px) {\\n .stats-item {\\n width: 135px;\\n }\\n}\\n\\n.stats-item-count {\\n color: rgb(250, 250, 250);\\n font-size: 2em;\\n text-align: center;\\n}\\n\\n.stats-item-label {\\n color: rgb(200, 200, 200);\\n font-size: 1.4em;\\n text-align: center;\\n}\\n\\n.plant-tags {\\n position: relative;\\n}\\n\\n.plant-tags-content {\\n position: relative;\\n display: inline-block;\\n width: 90%;\\n}\\n\\n.plant-tags-edit {\\n position: relative;\\n display: inline-block;\\n float: right;\\n}\\n\\n.plant-tags-item {\\n position: relative;\\n display: inline-block;\\n min-width: 125px;\\n padding-left: 10px;\\n padding-right: 10px;\\n padding-top: 5px;\\n padding-bottom: 9px;\\n margin-left: 5px;\\n margin-right: 5px;\\n margin-bottom: 16px;\\n text-align: center;\\n background-color: rgba(123, 123, 123, 0.3);\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);\\n border-radius: 10px;\\n}\\n\\n.plant-tags-item:hover {\\n background-color: rgba(150, 150, 150, 0.5);\\n}\\n\\n.plant-tags-item a {\\n color: rgb(190, 190, 190);\\n}\\n\\n.plant-tags-item a:hover {\\n color: rgb(230, 230, 230);\\n}\\n\\n.tasks {\\n margin-bottom: 50px;\\n}\\n\\n.task {\\n position: relative;\\n display: inline-block;\\n width: 45%;\\n height: auto;\\n margin-left: 10px;\\n margin-right: 10px;\\n margin-bottom: 29px;\\n background-color: rgb(55, 59, 62);\\n border: 1px solid rgb(80, 80, 80);\\n border-radius: 4px;\\n}\\n@media screen and (max-width: 580px) {\\n .task {\\n width: 95%;\\n }\\n}\\n\\n.task-header {\\n position: relative;\\n width: 100%;\\n height: 50px;\\n padding: 10px;\\n border-top-left-radius: 4px;\\n border-top-right-radius: 4px;\\n background-color: rgb(25, 25, 25);\\n}\\n\\n.task-header-title {\\n position: relative;\\n display: inline-block;\\n font-size: 1.2em;\\n color: rgb(200, 200, 200);\\n}\\n\\n.task-header-title span {\\n color: rgb(100, 100, 100);\\n}\\n\\n.task-header-action {\\n position: relative;\\n display: inline-block;\\n float: right;\\n}\\n\\n.task-header-action a {\\n color: rgb(150, 150, 150);\\n}\\n\\n.task-description {\\n position: relative;\\n height: 150px;\\n margin-bottom: 43px;\\n padding: 10px;\\n font-size: 1em;\\n color: rgb(150, 150, 150);\\n overflow-y: auto;\\n}\\n\\n.task-description pre {\\n background-color: inherit;\\n color: inherit;\\n white-space: pre-wrap;\\n word-wrap: break-word;\\n}\\n\\n.task-description a {\\n color: rgb(111, 185, 235);\\n}\\n\\n.task-description a:hover {\\n text-decoration: underline;\\n}\\n\\n.task-footer {\\n position: absolute;\\n bottom: 0;\\n padding: 10px;\\n width: 100%;\\n background-color: rgb(10, 10, 10);\\n border-bottom-left-radius: 4px;\\n border-bottom-right-radius: 4px;\\n font-size: 0.8em;\\n}\\n\\n.task-footer-date {\\n position: relative;\\n display: inline-block;\\n width: 43%;\\n}\\n\\n.task-footer-due {\\n position: relative;\\n display: inline-block;\\n}\\n\\n.is-task-overdue {\\n color: rgb(212, 50, 50);\\n}\\n\\n.task-footer-action {\\n position: relative;\\n display: inline-block;\\n float: right;\\n}\\n\\n.task-footer-action a {\\n color: rgb(150, 150, 150);\\n}\\n\\n.tasks-all-done {\\n position: relative;\\n margin-top: 30px;\\n text-align: center;\\n}\\n\\n.tasks-all-done-image img {\\n width: 256px;\\n height: 256px;\\n}\\n\\n.tasks-all-done-text {\\n color: rgb(120, 215, 105);\\n font-size: 2em;\\n}\\n\\n.inventory {\\n margin-bottom: 50px;\\n}\\n\\n.inventory-item-group {\\n position: relative;\\n width: 100%;\\n padding-left: 10px;\\n padding-right: 10px;\\n padding-top: 5px;\\n padding-bottom: 5px;\\n background-color: rgba(200, 200, 200, 0.76);\\n border: 1px solid rgb(90, 90, 90);\\n}\\n\\n.inventory-item {\\n position: relative;\\n width: 100%;\\n padding-left: 10px;\\n padding-right: 10px;\\n padding-top: 5px;\\n padding-bottom: 5px;\\n background-color: rgba(50, 50, 50, 0.76);\\n border: 1px solid rgb(90, 90, 90);\\n}\\n\\n.inventory-item-header {\\n position: relative;\\n}\\n\\n.inventory-item-name {\\n position: relative;\\n display: inline-block;\\n min-width: 50%;\\n}\\n\\n.inventory-item-name span {\\n color: rgb(100, 100, 100);\\n}\\n\\n.inventory-item-name a {\\n color: rgb(150, 150, 150);\\n}\\n\\n.inventory-item-name a:hover {\\n color: rgb(150, 150, 150);\\n}\\n\\n.inventory-item-amount {\\n position: relative;\\n display: inline-block;\\n}\\n\\n.inventory-item-amount i {\\n color: rgb(150, 150, 150);\\n}\\n\\n.inventory-item-amount span {\\n color: rgb(215, 215, 215);\\n}\\n\\n.is-inventory-item-empty {\\n color: rgb(212, 50, 50) !important;\\n}\\n\\n.inventory-item-actions {\\n position: relative;\\n display: inline-block;\\n float: right;\\n}\\n\\n.inventory-item-actions i {\\n color: rgb(100, 100, 100);\\n}\\n\\n.inventory-item-body {\\n position: relative;\\n height: 0;\\n opacity: 0;\\n overflow: hidden;\\n -webkit-transition: opacity 1s ease-out;\\n -moz-transition: opacity 1s ease-out;\\n transition: opacity 1s ease-out;\\n}\\n\\n.inventory-item-body.expand {\\n height: auto;\\n opacity: 1;\\n}\\n\\n.inventory-item-description {\\n position: relative;\\n color: rgb(130, 130, 130);\\n margin-top: 10px;\\n margin-bottom: 10px;\\n}\\n\\n.inventory-item-description pre {\\n background-color: inherit;\\n color: inherit;\\n white-space: normal;\\n}\\n\\n.inventory-item-description a {\\n color: rgb(111, 185, 235);\\n}\\n\\n.inventory-item-description a:hover {\\n text-decoration: underline;\\n}\\n\\n.inventory-item-tags {\\n position: relative;\\n margin-top: 5px;\\n}\\n\\n.inventory-item-tags-tag {\\n position: relative;\\n display: inline-block;\\n padding-left: 10px;\\n padding-right: 10px;\\n padding-bottom: 1px;\\n background-color: rgb(100, 100, 100);\\n border: 1px solid rgb(200, 200, 200);\\n border-radius: 5px;\\n font-size: 0.75em;\\n color: rgb(250, 250, 250);\\n}\\n\\n.inventory-item-tags-tag:hover {\\n background-color: rgb(150, 150, 150);\\n color: rgb(255, 255, 255);\\n}\\n\\n.inventory-item-tags-tag a {\\n color: rgb(250, 250, 250);\\n}\\n\\n.inventory-item-tags-tag a:hover {\\n color: rgb(250, 250, 250);\\n}\\n\\n.inventory-item-photo {\\n position: relative;\\n text-align: center;\\n margin-bottom: 20px;\\n}\\n\\n.inventory-item-footer {\\n position: relative;\\n color: rgb(120, 120, 120);\\n margin-top: 10px;\\n}\\n\\n.inventory-item-location {\\n position: relative;\\n display: inline-block;\\n}\\n\\n.inventory-item-author {\\n position: relative;\\n display: inline-block;\\n float: right;\\n}\\n\\n.inventory-groups {\\n width: 100%;\\n}\\n\\n.inventory-groups thead td {\\n color: rgb(150, 150, 150);\\n}\\n\\n.inventory-groups thead td:last-child {\\n width: 5%;\\n}\\n\\n.inventory-groups.table td {\\n border: 1px solid rgb(100, 100, 100);\\n}\\n\\n.inventory-groups a {\\n color: rgb(150, 150, 150);\\n}\\n\\n.inventory-groups a:hover {\\n color: rgb(150, 150, 150);\\n text-decoration: underline;\\n}\\n\\n.calendar-add {\\n position: relative;\\n margin-top: 40px;\\n margin-bottom: 25px;\\n}\\n\\n.calendar-add a {\\n width: 200px;\\n}\\n\\n.calendar-menu {\\n position: relative;\\n}\\n\\n.calendar-menu span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.calendar-input {\\n padding: 8px;\\n color: rgb(250, 250, 250);\\n background-color: rgb(50, 50, 50);\\n border: 1px solid rgb(100, 100, 100);\\n border-radius: 5px;\\n}\\n\\n.calendar-content {\\n position: relative;\\n margin-top: 30px;\\n}\\n\\n.calendar-link-removal {\\n position: relative;\\n top: 10px;\\n float: right;\\n color: rgb(200, 105, 105);\\n}\\n\\n.calendar-link-removal:hover {\\n color: rgb(200, 105, 105);\\n text-decoration: underline;\\n}\\n\\n.calendar-view {\\n position: relative;\\n margin-top: 10px;\\n margin-bottom: 59px;\\n}\\n\\n.calendar-view h3 {\\n color: rgb(150, 150, 150);\\n font-size: 2em;\\n padding-bottom: 10px;\\n}\\n\\n.weather-forecast {\\n position: relative;\\n margin-top: 40px;\\n}\\n@media screen and (max-width: 768px) {\\n .weather-forecast {\\n width: 100%;\\n overflow-x: scroll;\\n white-space: nowrap;\\n }\\n}\\n\\n.weather-header {\\n position: relative;\\n margin-bottom: 20px;\\n}\\n\\n.weather-header-item {\\n position: relative;\\n display: inline-block;\\n margin-left: 15px;\\n margin-right: 15px;\\n padding-top: 10px;\\n padding-left: 10px;\\n padding-right: 10px;\\n padding-bottom: 10px;\\n color: rgb(150, 150, 150);\\n text-align: center;\\n background-color: rgb(100, 100, 100);\\n border-radius: 5px;\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);\\n}\\n\\n.weather-header-item strong {\\n color: rgb(200, 200, 200);\\n}\\n\\n.weather-day {\\n position: relative;\\n display: inline-block;\\n margin-left: 10px;\\n margin-right: 10px;\\n padding-left: 10px;\\n padding-right: 10px;\\n}\\n\\n.weather-day-data {\\n position: relative;\\n text-align: center;\\n margin-bottom: 50px;\\n}\\n\\n.weather-day-data-title {\\n position: relative;\\n color: rgb(200, 200, 200);\\n font-weight: bold;\\n}\\n\\n.weather-day-data-icon {\\n position: relative;\\n}\\n\\n.weather-day-data-attribute {\\n position: relative;\\n color: rgb(150, 150, 150);\\n}\\n\\n.is-weather-fill-data {\\n color: rgb(100, 100, 100);\\n}\\n\\n.chat-message {\\n position: relative;\\n width: 90%;\\n padding: 15px;\\n margin-bottom: 20px;\\n background-color: rgba(200, 200, 200, 0.5);\\n border-radius: 10px;\\n}\\n\\n.chat-message-right {\\n margin-left: 10%;\\n background-color: rgba(115, 143, 100, 0.9);\\n}\\n\\n.chat-message-user {\\n position: relative;\\n font-size: 1.2em;\\n margin-bottom: 10px;\\n}\\n\\n.chat-message-new {\\n position: relative;\\n display: inline-block;\\n background-color: rgb(212, 130, 67);\\n border: 1px solid rgb(92, 64, 25);\\n color: rgb(250, 250, 250);\\n border-radius: 4px;\\n padding: 5px;\\n font-size: 0.5em;\\n text-transform: uppercase;\\n float: right;\\n}\\n\\n.chat-message-content {\\n position: relative;\\n}\\n\\n.chat-message-content pre {\\n background-color: transparent;\\n color: rgb(255, 255, 255);\\n}\\n\\n.chat-message-content a {\\n color: rgb(111, 185, 235);\\n}\\n\\n.chat-message-content a:hover {\\n text-decoration: underline;\\n}\\n\\n.chat-message-info {\\n position: relative;\\n margin-top: 10px;\\n font-size: 0.76em;\\n color: rgb(200, 200, 200);\\n}\\n\\n.chat-typing-indicator {\\n display: none;\\n background-color: rgba(50, 50, 50, 0.5);\\n}\\n\\n.chat-typing-indicator.visible {\\n display: block;\\n}\\n\\n.chat-user-list {\\n position: relative;\\n margin-top: 10px;\\n margin-bottom: 23px;\\n color: rgb(92, 255, 0);\\n}\\n\\n.system-message {\\n position: relative;\\n background-color: rgb(205, 202, 165);\\n border-radius: 10px;\\n padding: 20px;\\n margin-bottom: 20px;\\n}\\n\\n.system-message-left {\\n position: relative;\\n display: inline-block;\\n width: 93%;\\n}\\n@media screen and (max-width: 1000px) {\\n .system-message-left {\\n width: 80%;\\n }\\n}\\n\\n.system-message-left-new {\\n top: -3px;\\n}\\n\\n.system-message-right {\\n position: relative;\\n display: inline-block;\\n top: 3px;\\n}\\n@media screen and (max-width: 520px) {\\n .system-message-right {\\n top: 55px;\\n vertical-align: top;\\n right: -25px;\\n }\\n}\\n\\n.system-message-context {\\n position: relative;\\n display: inline-block;\\n top: -1px;\\n font-size: 0.9em;\\n font-weight: bold;\\n}\\n\\n.system-message-content {\\n position: relative;\\n display: inline-block;\\n}\\n@media screen and (max-width: 768px) {\\n .system-message-content {\\n margin-top: 10px;\\n }\\n}\\n\\n.system-message-content a {\\n color: rgb(135, 75, 5);\\n}\\n\\n.system-message-content a:hover {\\n color: rgb(135, 75, 5);\\n text-decoration: underline;\\n}\\n\\n@media screen and (max-width: 768px) {\\n .system-message-new {\\n top: -58px;\\n }\\n}\\n\\n#small-system-messages {\\n position: fixed;\\n z-index: 3;\\n top: 55px;\\n}\\n@media screen and (max-width: 512px) {\\n #small-system-messages {\\n width: 100%;\\n }\\n}\\n\\n.system-message-small {\\n position: relative;\\n top: 12px;\\n left: 12px;\\n background-color: rgb(205, 202, 165);\\n border-radius: 10px;\\n border: 1px solid rgb(250, 250, 250);\\n padding: 20px;\\n margin-bottom: 10px;\\n}\\n@media screen and (max-width: 512px) {\\n .system-message-small {\\n width: 100%;\\n left: 0;\\n }\\n}\\n\\n.system-message-small-context {\\n font-weight: bold;\\n}\\n\\n.system-message-small-content a {\\n color: rgb(135, 75, 5);\\n}\\n\\n.system-message-small-content a:hover {\\n color: rgb(135, 75, 5);\\n text-decoration: underline;\\n}\\n\\n.scroll-to-top {\\n position: fixed;\\n z-index: 102;\\n bottom: 12px;\\n right: 12px;\\n}\\n\\n.scroll-to-top-inner {\\n background-color: rgb(80, 80, 80);\\n border-radius: 50%;\\n padding: 12px;\\n box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);\\n}\\n\\n.scroll-to-top-inner a {\\n color: rgb(200, 200, 200);\\n}\\n\\n.auth-main {\\n width: 100%;\\n height: 100%;\\n background-repeat: no-repeat;\\n background-size: cover;\\n}\\n\\n.auth-overlay {\\n width: 100%;\\n height: 100%;\\n background-color: rgba(0, 0, 0, 0.5);\\n}\\n\\n.auth-content {\\n position: absolute;\\n top: 50%;\\n left: 50%;\\n transform: translate(-50%, -50%);\\n text-align: center;\\n padding: 20px;\\n}\\n\\n.auth-header {\\n position: relative;\\n margin-bottom: 20px;\\n}\\n\\n.auth-header img {\\n position: relative;\\n width: 128px;\\n height: 128px;\\n border-radius: 50%;\\n}\\n\\n.auth-header h1 {\\n font-size: 2.5em;\\n font-family: Verdana, Geneva, Tahoma, sans-serif;\\n font-weight: bold;\\n color: rgb(150, 150, 150);\\n}\\n\\n.auth-info {\\n position: relative;\\n margin-bottom: 43px;\\n}\\n\\n.auth-info-error {\\n color: rgb(154, 73, 69);\\n}\\n\\n.auth-info-success {\\n color: rgb(69, 154, 83);\\n}\\n\\n.auth-form {\\n position: relative;\\n}\\n\\n.auth-form input[type=email], .auth-form input[type=password] {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.auth-form input[type=email]::placeholder, .auth-form input[type=password]::placeholder {\\n color: rgb(200, 200, 200);\\n}\\n\\n.auth-form input[type=submit] {\\n width: 100%;\\n}\\n\\n.auth-help {\\n position: relative;\\n margin-top: 20px;\\n}\\n\\n.auth-help a {\\n color: rgb(54, 105, 203);\\n}\\n\\n.auth-help a:hover {\\n color: rgb(54, 105, 203);\\n text-decoration: underline;\\n}\\n\\n.reset-main {\\n width: 100%;\\n height: 100%;\\n background-repeat: no-repeat;\\n background-size: cover;\\n}\\n\\n.reset-overlay {\\n width: 100%;\\n height: 100%;\\n background-color: rgba(0, 0, 0, 0.5);\\n}\\n\\n.reset-content {\\n position: absolute;\\n top: 50%;\\n left: 50%;\\n transform: translate(-50%, -50%);\\n text-align: center;\\n padding: 20px;\\n}\\n\\n.reset-content h1 {\\n margin-bottom: 30px;\\n line-height: 1;\\n}\\n\\n.reset-info {\\n position: relative;\\n margin-bottom: 43px;\\n}\\n\\n.reset-info-error {\\n color: rgb(154, 73, 69);\\n}\\n\\n.reset-info-success {\\n color: rgb(69, 154, 83);\\n}\\n\\n.reset-form {\\n position: relative;\\n}\\n\\n.reset-form input[type=email], .reset-form input[type=password] {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.reset-form input[type=email]::placeholder, .reset-form input[type=password]::placeholder {\\n color: rgb(200, 200, 200);\\n}\\n\\n.reset-form input[type=submit] {\\n width: 100%;\\n}\\n\\n.preferences-header {\\n position: relative;\\n}\\n\\n.preferences-header i {\\n color: rgb(150, 150, 150);\\n}\\n\\n.profile-shared-photos table {\\n width: 100%;\\n}\\n\\n.profile-shared-photos thead {\\n background-color: rgba(104, 145, 194, 0.5);\\n}\\n\\n.profile-shared-photos thead:hover {\\n background-color: rgba(104, 145, 194, 0.5);\\n}\\n\\n.profile-shared-photos td {\\n padding: 10px;\\n color: rgb(150, 150, 150);\\n border: 1px solid rgb(200, 200, 200);\\n}\\n\\n.profile-shared-photos td a {\\n color: rgb(111, 143, 225);\\n}\\n\\n.profile-shared-photos td a:hover {\\n color: rgb(111, 143, 225);\\n text-decoration: underline;\\n}\\n\\n.profile-shared-photos td i {\\n color: rgb(150, 150, 150);\\n}\\n\\n.profile-shared-photos td i:hover {\\n color: rgb(150, 150, 150);\\n}\\n\\n.profile-shared-photos td:last-child {\\n width: 5%;\\n text-align: center;\\n}\\n\\n.admin-tabs {\\n margin-top: 23px;\\n}\\n\\n.admin-tabs a {\\n color: rgb(200, 200, 200);\\n}\\n\\n.admin-tabs a:hover {\\n color: rgb(230, 230, 230);\\n border-bottom-color: rgb(111, 172, 243);\\n}\\n\\n.admin-environment {\\n position: relative;\\n}\\n\\n.admin-environment h2 {\\n margin-top: 20px;\\n margin-bottom: 10px;\\n}\\n\\n.admin-environment label, .admin-environment span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-environment input, .admin-environment textarea, .admin-environment select {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-environment hr {\\n background-color: rgb(100, 100, 100);\\n}\\n\\n.admin-media {\\n position: relative;\\n width: 100%;\\n}\\n\\n.admin-media h2 {\\n margin-top: 20px;\\n margin-bottom: 20px;\\n}\\n\\n.admin-media label {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-media input, .admin-backup input {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-media input[type=submit] {\\n margin-top: 10px;\\n margin-bottom: 20px;\\n}\\n\\n.admin-users {\\n position: relative;\\n width: 100%;\\n}\\n\\n.admin-users h2 {\\n margin-top: 20px;\\n margin-bottom: 20px;\\n}\\n\\n.admin-users-list {\\n position: relative;\\n}\\n\\n.admin-user-account {\\n position: relative;\\n margin-bottom: 15px;\\n}\\n\\n.admin-user-account label, .admin-user-account span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-user-account input, .admin-user-account select {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-user-account-item {\\n position: relative;\\n display: inline-block;\\n margin-left: 5px;\\n margin-right: 5px;\\n}\\n\\n.admin-user-account-item-input {\\n width: 30%;\\n}\\n\\n.admin-user-account-actions {\\n position: relative;\\n display: inline-block;\\n}\\n\\n.admin-user-account-item-centered {\\n text-align: center;\\n}\\n\\n.admin-user-account-action-item {\\n position: relative;\\n}\\n\\n.admin-users-created-password {\\n position: relative;\\n color: rgb(220, 220, 220);\\n background-color: rgb(180, 103, 0);\\n border: 1px solid rgb(245, 185, 105);\\n border-radius: 10px;\\n padding: 20px;\\n}\\n\\n.admin-users-created-password strong {\\n color: rgb(250, 250, 250);\\n}\\n\\n.admin-users-actions {\\n position: relative;\\n margin-top: 20px;\\n}\\n\\n.admin-locations {\\n position: relative;\\n width: 100%;\\n}\\n\\n.admin-locations h2 {\\n margin-top: 20px;\\n margin-bottom: 20px;\\n}\\n\\n.admin-locations-list {\\n position: relative;\\n}\\n\\n.admin-location {\\n position: relative;\\n margin-bottom: 15px;\\n}\\n\\n.admin-location label, .admin-location span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-location input {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-location-item {\\n position: relative;\\n display: inline-block;\\n margin-left: 5px;\\n margin-right: 5px;\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-location-item-input {\\n width: 30%;\\n}\\n\\n.admin-location-actions {\\n position: relative;\\n display: inline-block;\\n}\\n\\n.admin-location-item-centered {\\n text-align: center;\\n}\\n\\n.admin-location-action-item {\\n position: relative;\\n}\\n\\n.admin-locations-actions {\\n position: relative;\\n margin-top: 20px;\\n}\\n\\n.admin-auth {\\n position: relative;\\n}\\n\\n.admin-auth h2 {\\n margin-top: 20px;\\n margin-bottom: 10px;\\n}\\n\\n.admin-auth label, .admin-auth span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-auth input, .admin-auth textarea {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-auth-warning {\\n position: relative;\\n display: none;\\n padding: 20px;\\n margin-top: 30px;\\n margin-bottom: 25px;\\n color: rgb(250, 250, 250);\\n background-color: rgba(202, 102, 102, 0.76);\\n border: 1px solid rgb(235, 150, 150);\\n border-radius: 5px;\\n}\\n\\n.admin-auth-caution {\\n position: relative;\\n display: none;\\n padding: 20px;\\n margin-top: 30px;\\n margin-bottom: 25px;\\n color: rgb(250, 250, 250);\\n background-color: rgba(255, 220, 87, 0.5);\\n border: 1px solid rgb(255, 220, 87);\\n border-radius: 5px;\\n}\\n\\n.admin-attribute-schema-list {\\n position: relative;\\n}\\n\\n.admin-attribute-schema {\\n position: relative;\\n margin-bottom: 15px;\\n}\\n\\n.admin-attribute-schema label, .admin-attribute-schema span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-attribute-schema input, .admin-attribute-schema select {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-attribute-schema-item {\\n position: relative;\\n display: inline-block;\\n margin-left: 5px;\\n margin-right: 5px;\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-attribute-schema-item-input {\\n width: 30%;\\n}\\n\\n.admin-attribute-schema-actions {\\n position: relative;\\n display: inline-block;\\n}\\n\\n.admin-attribute-schema-item-centered {\\n text-align: center;\\n}\\n\\n.admin-attribute-schema-action-item {\\n position: relative;\\n}\\n\\n.admin-attribute-schema-actions {\\n position: relative;\\n margin-top: 20px;\\n}\\n\\n.admin-attributes {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-attributes p {\\n color: rgb(150, 150, 150);\\n margin-bottom: 30px;\\n}\\n\\n.admin-bulk-commands-list {\\n position: relative;\\n}\\n\\n.admin-bulk-command {\\n position: relative;\\n margin-bottom: 15px;\\n}\\n\\n.admin-bulk-command label, .admin-bulk-command span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-bulk-command input, .admin-bulk-command select {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-bulk-command-item {\\n position: relative;\\n display: inline-block;\\n margin-left: 5px;\\n margin-right: 5px;\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-bulk-command-item-input {\\n width: 30%;\\n}\\n\\n.admin-bulk-command-actions {\\n position: relative;\\n display: inline-block;\\n}\\n\\n.admin-bulk-command-item-centered {\\n text-align: center;\\n}\\n\\n.admin-bulk-command-action-item {\\n position: relative;\\n}\\n\\n.admin-bulk-command-actions {\\n position: relative;\\n margin-top: 20px;\\n}\\n\\n.admin-bulk-command-actions {\\n position: relative;\\n margin-top: 20px;\\n}\\n\\n.admin-calendar-classes {\\n position: relative;\\n width: 100%;\\n}\\n\\n.admin-calendar-classes h2 {\\n margin-top: 20px;\\n margin-bottom: 20px;\\n}\\n\\n.admin-calendar-classes-list {\\n position: relative;\\n}\\n\\n.admin-calendar-class {\\n position: relative;\\n margin-bottom: 15px;\\n}\\n\\n.admin-calendar-class label, .admin-calendar-class span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-calendar-class input {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-calendar-class-item {\\n position: relative;\\n display: inline-block;\\n margin-left: 5px;\\n margin-right: 5px;\\n}\\n\\n.admin-calendar-class-item-input {\\n width: 30%;\\n}\\n\\n.admin-calendar-class-actions {\\n position: relative;\\n display: inline-block;\\n}\\n\\n.admin-calendar-class-item-centered {\\n text-align: center;\\n}\\n\\n.admin-calendar-class-action-item {\\n position: relative;\\n}\\n\\n.admin-calendar-classes-actions {\\n position: relative;\\n margin-top: 20px;\\n}\\n\\n.admin-mail {\\n position: relative;\\n}\\n\\n.admin-mail h2 {\\n margin-top: 20px;\\n margin-bottom: 10px;\\n}\\n\\n.admin-mail label, .admin-mail span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-mail input, .admin-mail select {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-themes p {\\n color: rgb(150, 150, 150);\\n margin-bottom: 30px;\\n font-size: 1.2em;\\n}\\n\\n.admin-themes input, .admin-themes select {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-themes-result {\\n position: relative;\\n padding: 10px;\\n border-radius: 5px;\\n border: 1px solid rgb(255, 255, 255);\\n background-color: rgb(185, 255, 164);\\n}\\n\\n.admin-themes-result i {\\n color: rgb(50, 50, 50);\\n}\\n\\n.admin-themes-list {\\n position: relative;\\n}\\n\\n.admin-themes-list table {\\n width: 100%;\\n}\\n\\n.admin-themes-list thead {\\n background-color: rgba(104, 145, 194, 0.5);\\n}\\n\\n.admin-themes-list thead:hover {\\n background-color: rgba(104, 145, 194, 0.5);\\n}\\n\\n.admin-themes-list td {\\n padding: 10px;\\n color: rgb(150, 150, 150);\\n border: 1px solid rgb(200, 200, 200);\\n}\\n\\n.admin-themes-list td i {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-themes-list td i:hover {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-theme-list-right {\\n width: 5%;\\n text-align: center;\\n}\\n\\n.admin-backup label, .admin-backup span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-backup-result {\\n position: relative;\\n padding: 10px;\\n border-radius: 5px;\\n border: 1px solid rgb(255, 255, 255);\\n background-color: rgb(185, 255, 164);\\n}\\n\\n.admin-backup-result i {\\n color: rgb(50, 50, 50);\\n}\\n\\n.admin-backup-result a {\\n color: rgb(15, 150, 43);\\n}\\n\\n.admin-backup-result a:hover {\\n color: rgb(15, 150, 43);\\n text-decoration: underline;\\n}\\n\\n.admin-weather label, .admin-weather span {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-weather input, .admin-weather select {\\n color: rgb(150, 150, 150);\\n background-color: rgb(50, 50, 50);\\n}\\n\\n.admin-api p {\\n color: rgb(150, 150, 150);\\n margin-bottom: 30px;\\n font-size: 1.2em;\\n}\\n\\n.admin-api table {\\n width: 100%;\\n margin-top: 15px;\\n color: rgb(200, 200, 200);\\n}\\n\\n.admin-api table strong {\\n color: rgb(200, 200, 200);\\n}\\n\\n.admin-api thead {\\n background-color: rgba(104, 145, 194, 0.5);\\n}\\n\\n.admin-api table td {\\n border: 1px solid rgb(200, 200, 200);\\n padding: 10px;\\n}\\n\\n.admin-api table td a {\\n color: rgb(150, 150, 150);\\n}\\n\\n.admin-api table td a:hover {\\n color: rgb(200, 200, 200);\\n}\\n\\n.admin-api table td:last-child {\\n width: 5%;\\n text-align: center;\\n}\\n\\n.admin-info {\\n position: relative;\\n}\\n\\n.admin-info-version {\\n color: rgb(200, 200, 200);\\n font-size: 1.5em;\\n}\\n\\n.admin-info-version-smaller {\\n color: rgb(150, 150, 150);\\n font-size: 0.76em;\\n}\\n\\n.admin-info-support {\\n position: relative;\\n margin-top: 43px;\\n}\\n\\n.admin-info-support a {\\n width: 465px;\\n}\\n@media screen and (max-width: 495px) {\\n .admin-info-support a {\\n width: 100%;\\n height: 50px;\\n font-size: 1.4em;\\n }\\n}\\n\\n.admin-info-sponsor {\\n position: relative;\\n margin-top: 15px;\\n margin-bottom: 15px;\\n}\\n\\n.admin-info-sponsor a {\\n width: 465px;\\n background-color: rgb(30, 150, 183) !important;\\n}\\n@media screen and (max-width: 495px) {\\n .admin-info-sponsor a {\\n width: 100%;\\n height: 50px;\\n font-size: 1.4em;\\n }\\n}\\n\\n.admin-info-sponsor a:hover {\\n background-color: rgb(35, 167, 202) !important;\\n}\\n\\n.admin-info-sponsor i {\\n color: rgb(205, 50, 50);\\n}\\n\\n.admin-info-sponsor i:hover {\\n color: rgb(205, 50, 50);\\n}\\n\\n.admin-info-donation {\\n position: relative;\\n margin-top: 15px;\\n margin-bottom: 15px;\\n}\\n\\n.admin-info-donation a {\\n width: 465px;\\n background-color: rgb(170, 135, 85) !important;\\n}\\n@media screen and (max-width: 495px) {\\n .admin-info-donation a {\\n width: 100%;\\n height: 50px;\\n font-size: 1.4em;\\n }\\n}\\n\\n.admin-info-donation a:hover {\\n background-color: rgb(195, 150, 95) !important;\\n}\\n\\n.admin-info-donation i {\\n color: rgb(90, 67, 10);\\n}\\n\\n.admin-info-donation i:hover {\\n color: rgb(90, 67, 10);\\n}\\n\\n.admin-info-social {\\n position: relative;\\n margin-top: 15px;\\n margin-bottom: 35px;\\n}\\n\\n.admin-info-social img {\\n width: 152px;\\n height: 35px;\\n}\\n@media screen and (max-width: 495px) {\\n .admin-info-social img {\\n width: 32%;\\n height: 30px;\\n }\\n}\\n\\n.admin-info-extensions {\\n position: relative;\\n}\\n\\n.admin-info-extensions h3 {\\n color: rgb(200, 200, 200);\\n font-size: 1.4em;\\n margin-top: 20px;\\n margin-bottom: 20px;\\n}\\n\\n.admin-info-extensions a {\\n color: rgb(0, 145, 215);\\n}\\n\\n.admin-info-extensions a:hover {\\n color: rgb(0, 145, 215);\\n text-decoration: underline;\\n}\\n\\n.admin-info-extensions table {\\n width: 100%;\\n margin-top: 15px;\\n color: rgb(200, 200, 200);\\n}\\n\\n.admin-info-extensions table strong {\\n color: rgb(200, 200, 200);\\n}\\n\\n.admin-info-extensions thead {\\n background-color: rgba(104, 145, 194, 0.5);\\n}\\n\\n.admin-info-extensions table td {\\n border: 1px solid rgb(200, 200, 200);\\n padding: 10px;\\n}\\n\\n.admin-info-extensions table td:first-child {\\n width: 10%;\\n}\\n\\n.version-check {\\n position: relative;\\n margin-top: 30px;\\n}\\n\\n.version-info {\\n position: relative;\\n padding: 20px;\\n margin-top: 30px;\\n color: rgb(250, 250, 250);\\n background-color: rgba(102, 202, 160, 0.76);\\n border: 1px solid rgb(150, 235, 200);\\n border-radius: 10px;\\n}\\n\\n.version-info a {\\n color: rgb(132, 255, 123);\\n font-weight: bold;\\n}\\n\\n.version-info a:hover {\\n color: rgb(132, 255, 123);\\n text-decoration: underline;\\n}\\n\\n.bottomnav {\\n position: fixed;\\n bottom: 0;\\n width: 100%;\\n height: 70px;\\n z-index: 100;\\n padding-left: 5px;\\n padding-right: 5px;\\n background-color: rgb(30, 30, 30);\\n}\\n@media screen and (min-width: 1087px) {\\n .bottomnav {\\n display: none;\\n }\\n}\\n\\n.bottomnav-items {\\n position: relative;\\n display: block;\\n top: 10px;\\n width: 100%;\\n height: 100%;\\n margin-left: auto;\\n margin-right: auto;\\n text-align: center;\\n}\\n\\n.bottomnav-item {\\n position: relative;\\n display: inline-block;\\n width: 65px;\\n height: 50px;\\n margin-top: 6px;\\n color: rgb(150, 150, 150);\\n text-align: center;\\n font-size: 0.8em;\\n}\\n\\n.bottomnav-item a {\\n color: rgb(150, 150, 150);\\n}\\n\\n.bottomnav-item a:hover {\\n color: rgb(200, 200, 200);\\n text-decoration: none;\\n}\\n\\n.button-margin-left {\\n margin-left: 5px;\\n}\", \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://asatruphp/./app/resources/sass/app.scss?./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js"); /***/ }),