| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584 | (() => {  var __accessCheck = (obj, member, msg) => {    if (!member.has(obj))      throw TypeError("Cannot " + msg);  };  var __privateGet = (obj, member, getter) => {    __accessCheck(obj, member, "read from private field");    return getter ? getter.call(obj) : member.get(obj);  };  var __privateAdd = (obj, member, value) => {    if (member.has(obj))      throw TypeError("Cannot add the same private member more than once");    member instanceof WeakSet ? member.add(obj) : member.set(obj, value);  };  var __privateSet = (obj, member, value, setter) => {    __accessCheck(obj, member, "write to private field");    setter ? setter.call(obj, value) : member.set(obj, value);    return value;  };  var __privateMethod = (obj, member, method) => {    __accessCheck(obj, member, "access private method");    return method;  };  // application/scripts/height_equaler.js  var height_equaler = class {    #to;    #from;    constructor(from, to) {      this.#from = from;      this.#to = to;      this.#set_styles();      new ResizeObserver(() => {        this.#update();      }).observe(from);      setTimeout(() => {        this.#update();      }, 100);    }    get height() {      return this.#from.offsetHeight;    }    #set_styles() {      this.#to.style.height = "0px";      this.#to.style.transition = "height 0.5s";    }    #update() {      this.#to.style.height = this.height + "px";    }  };  // application/scripts/product.js  var product = class {    name;    description;    author;    image;    stock_count;    barcode;    thumbnail;    on_stock;    constructor(target) {      this.name = null;      this.description = null;      this.author = null;      this.image = null;      this.stock_count = null;      this.barcode = null;      this.thumbnail = null;      this.on_stock = null;      if ("name" in target)        this.name = target["name"];      if ("description" in target)        this.description = target["description"];      if ("author" in target)        this.author = target["author"];      if ("image" in target)        this.image = target["image"];      if ("stock_count" in target)        this.stock_count = target["stock_count"];      if ("barcode" in target)        this.barcode = target["barcode"];      if ("thumbnail" in target)        this.thumbnail = target["thumbnail"];      if ("on_stock" in target)        this.on_stock = target["on_stock"];      try {        this.stock_count = Number(this.stock_count);      } catch {        this.stock_count = 0;      }      try {        this.on_stock = Number(this.on_stock);      } catch {        this.on_stock = 0;      }    }    get dump() {      const dumped = {        "name": new String(this.name),        "description": new String(this.description),        "author": new String(this.author),        "image": new String(this.image),        "barcode": new String(this.barcode),        "thumbnail": new String(this.thumbnail),        "stock_count": new String(this.stock_count)      };      if (this.on_stock !== null) {        dumped["on_stock"] = new String(this.on_stock);      }      return dumped;    }    get ready() {      if (this.name === null || this.description === null)        return false;      if (this.author === null || this.image === null)        return false;      if (this.stock_count === null || this.barcode === null)        return false;      if (this.thumbnail === null)        return false;      return true;    }    copy() {      return new product(this.dump);    }  };  // application/scripts/products_loader.js  var _response_to_collection, response_to_collection_fn, _single_response_to_collection, single_response_to_collection_fn, _list_response_to_collection, list_response_to_collection_fn, _search, search_fn;  var _products_loader = class {    static async all() {      var _a;      const request2 = await fetch("/products/");      const response = await request2.json();      return __privateMethod(_a = _products_loader, _response_to_collection, response_to_collection_fn).call(_a, response);    }    static async search_name(name) {      var _a;      return await __privateMethod(_a = _products_loader, _search, search_fn).call(_a, "/product/search/name", name);    }    static async search_author(author) {      var _a;      return await __privateMethod(_a = _products_loader, _search, search_fn).call(_a, "/product/search/author", author);    }    static async search_barcode(barcode) {      var _a;      return await __privateMethod(_a = _products_loader, _search, search_fn).call(_a, "/product/get/barcode", barcode);    }  };  var products_loader = _products_loader;  _response_to_collection = new WeakSet();  response_to_collection_fn = function(response) {    if (response.result !== "success") {      return new Array();    }    if ("collection" in response) {      return __privateMethod(this, _list_response_to_collection, list_response_to_collection_fn).call(this, response);    }    return __privateMethod(this, _single_response_to_collection, single_response_to_collection_fn).call(this, response);  };  _single_response_to_collection = new WeakSet();  single_response_to_collection_fn = function(response) {    const result = new Array();    result.push(new product(response.product));    return result;  };  _list_response_to_collection = new WeakSet();  list_response_to_collection_fn = function(response) {    const result = new Array();    response.collection.forEach((serialized) => {      result.push(new product(serialized));    });    return result;  };  _search = new WeakSet();  search_fn = async function(path, parameter) {    var _a;    const coded = encodeURI(parameter);    const request2 = await fetch(path + "/" + coded);    const response = await request2.json();    return __privateMethod(_a = _products_loader, _response_to_collection, response_to_collection_fn).call(_a, response);  };  __privateAdd(products_loader, _response_to_collection);  __privateAdd(products_loader, _single_response_to_collection);  __privateAdd(products_loader, _list_response_to_collection);  __privateAdd(products_loader, _search);  // application/scripts/fullscreen.js  var fullscreen = class {    #node;    constructor() {      this.#node = null;    }    get visible() {      return this.#node !== null;    }    _build_node() {      throw new TypeError("This is virtual method!");    }    get #opacity() {      if (!this.visible) {        throw new TypeError("Can not change opacity of not existed.");      }      return Number(this.#node.style.opacity);    }    set #opacity(target) {      if (!this.visible) {        throw new TypeError("Can not change opacity of not existed.");      }      this.#node.style.opacity = String(target);    }    get_query(selector) {      if (!this.visible) {        throw new TypeError("Can not get item from not visible.");      }      return this.#node.querySelector(selector);    }    #prepare() {      const container = document.createElement("div");      container.classList.add("fullscreen-viewer");      container.style.transition = "opacity 0.5s";      container.appendChild(this._build_node());      return container;    }    hide() {      if (!this.visible) {        return;      }      this.#opacity = 0;      setTimeout(() => {        if (!this.visible) {          return;        }        this.#node.remove();        this.#node = null;      }, 500);    }    show() {      if (this.visible) {        return;      }      this.#node = this.#prepare();      this.#opacity = 0;      document.querySelector("body").appendChild(this.#node);      setTimeout(() => {        this.#opacity = 1;      }, 100);    }  };  // application/scripts/product_fullscreen.js  var product_fullscreen = class extends fullscreen {    #target;    constructor(target) {      super();      this.#target = target;    }    get target() {      return this.#target;    }    _build_node() {      const container = document.createElement("div");      container.classList.add("product-fullscreen-viewer");      const image = document.createElement("div");      image.style.backgroundImage = 'url("' + this.target.image + '")';      image.classList.add("image");      container.appendChild(image);      const title = document.createElement("div");      title.classList.add("title");      container.appendChild(title);      const title_content = document.createElement("h1");      title_content.innerText = this.target.name;      title.appendChild(title_content);      const bottom = document.createElement("div");      bottom.classList.add("bottom-side");      container.appendChild(bottom);      const bottom_header = document.createElement("div");      bottom_header.classList.add("bottom-header");      bottom.appendChild(bottom_header);      const barcode_icon = document.createElement("span");      barcode_icon.classList.add("material-icons");      barcode_icon.innerText = "qr_code_scanner";      const barcode_content = document.createElement("span");      barcode_content.innerText = this.target.barcode;      barcode_content.classList.add("numbers");      const barcode = document.createElement("p");      barcode.appendChild(barcode_icon);      barcode.appendChild(barcode_content);      bottom_header.appendChild(barcode);      const author_icon = document.createElement("span");      author_icon.classList.add("material-icons");      author_icon.innerText = "attribution";      const author_content = document.createElement("span");      author_content.innerText = this.target.author;      const author = document.createElement("p");      author.appendChild(author_icon);      author.appendChild(author_content);      bottom_header.appendChild(author);      const description = document.createElement("div");      description.classList.add("description");      bottom.appendChild(description);      const description_content = document.createElement("p");      description_content.innerText = this.target.description;      description.appendChild(description_content);      const close_button = document.createElement("button");      close_button.classList.add("material-icons");      close_button.classList.add("close");      close_button.innerText = "close";      container.appendChild(close_button);      close_button.addEventListener("click", () => {        this.hide();      });      return container;    }  };  // application/scripts/user.js  var user = class {    #nick;    #apikey;    constructor(nick, apikey) {      this.#nick = nick;      this.#apikey = apikey;    }    get nick() {      return this.#nick;    }    get apikey() {      return this.#apikey;    }  };  // application/scripts/login_manager.js  var login_manager = class {    get apikey() {      return localStorage.getItem("apikey");    }    get logged_in() {      return localStorage.getItem("apikey") !== null;    }    #create_request(data) {      return {        method: "POST",        body: JSON.stringify(data),        headers: {          "Content-Type": "application/json"        }      };    }    async get_user() {      if (!this.logged_in) {        return null;      }      const request_data = this.#create_request({        apikey: this.apikey      });      const request2 = await fetch("/user", request_data);      const response = await request2.json();      if (response.result !== "success") {        return null;      }      return new user(        response.nick,        response.apikey      );    }    async login(nick, password) {      const request_data = this.#create_request({        nick,        password      });      const request2 = await fetch("/user/login", request_data);      const response = await request2.json();      if (response.result !== "success") {        return false;      }      localStorage.setItem("apikey", response.apikey);      return true;    }    logout() {      localStorage.removeItem("apikey");    }  };  // application/scripts/confirm_action.js  var confirm_action = class {    #node;    #action;    constructor() {      this.#node = null;      this.#action = true;    }    get _description() {      throw new TypeError("It must be overwriten.");    }    get _title() {      return _("you-must-confirm-it");    }    _action() {      throw new TypeError("It must be overwriten.");    }    get _info() {      return false;    }    show() {      if (this.#node !== null) {        return;      }      this.#action = true;      this.#node = this.#create_window();      document.querySelector("body").appendChild(this.#node);      setTimeout(() => {        this.#node.style.opacity = "1";      }, 100);    }    hide() {      if (this.#node === null) {        return;      }      this.#action = false;      this.#node.style.opacity = "0";      setTimeout(() => {        if (this.#node === null) {          return;        }        this.#node.remove();        this.#node = null;      }, 500);    }    #create_window() {      const container = document.createElement("div");      container.classList.add("confirm-window");      container.style.transition = "opacity 0.5s";      container.style.opacity = "0";      const center = document.createElement("div");      center.classList.add("center");      container.appendChild(center);      const title = document.createElement("div");      title.classList.add("title");      center.appendChild(title);      const title_text = document.createElement("h3");      title_text.innerText = this._title;      title.appendChild(title_text);      const description = document.createElement("div");      description.classList.add("description");      center.appendChild(description);      const description_text = document.createElement("p");      description_text.innerText = this._description;      description.appendChild(description_text);      const buttons = document.createElement("div");      buttons.classList.add("buttons");      center.appendChild(buttons);      const cancel_button = document.createElement("button");      cancel_button.classList.add("cancel");      cancel_button.classList.add("material-icons");      cancel_button.innerText = "close";      buttons.appendChild(cancel_button);      cancel_button.addEventListener("click", () => {        this.hide();      });      if (!this._info) {        const confirm_button = document.createElement("button");        confirm_button.classList.add("confirm");        confirm_button.classList.add("material-icons");        confirm_button.innerText = "send";        buttons.appendChild(confirm_button);        confirm_button.addEventListener("click", () => {          if (this.#action === false) {            return;          }          this._action();          this.hide();        });      }      return container;    }  };  // application/scripts/request.js  var request = class {    get settings() {      const settings = {        "method": this.method,        "headers": this.headers      };      if (this.method === "GET" || this.method === "HEAD") {        return settings;      }      if (this.body === null) {        return settings;      }      settings.body = this.body;      return settings;    }    get _apikey() {      const manager = new login_manager();      if (manager.logged_in) {        return manager.apikey;      }      throw new Error(_("user-must-be-logged-in"));    }    get method() {      throw new TypeError("It must be overwrite.");    }    get url() {      throw new TypeError("It must be overwrite.");    }    get headers() {      if (this.method === "GET" || this.method === "HEAD") {        return {};      }      if (typeof this.data === "string") {        return {          "Content-Type": "text/plain"        };      }      return {        "Content-Type": "application/json"      };    }    get body() {      if (this.data === null) {        return null;      }      if (typeof this.data === "string") {        return this.data;      }      return JSON.stringify(this.data);    }    get _response() {      throw new TypeError("It must be overwrite.");    }    async connect() {      const request2 = await fetch(this.url, this.settings);      if (!request2.ok) {        throw new Error(_("fail-when-request-__url__").format({          url: this.url        }));      }      const response = await request2.json();      if (!("result" in response)) {        throw new Error(_("bad-response-not-contain-result"));      }      return new this._response(response);    }    get data() {      throw new TypeError("This must be overwrite.");    }  };  // application/scripts/bool_response.js  var bool_response = class {    #result;    #cause;    constructor(target) {      this.#result = target.result === "success";      this.#cause = null;      if (!this.result) {        this.#cause = target.cause;      }    }    get cause() {      return this.#cause;    }    get result() {      return this.#result;    }  };  // application/scripts/delete_request.js  var delete_request = class extends request {    #product;    constructor(product2) {      super();      this.#product = product2;    }    get _response() {      return bool_response;    }    get data() {      return {        "apikey": this._apikey      };    }    get url() {      return "/product/barcode/" + this.#product.barcode;    }    get method() {      return "DELETE";    }  };  // application/scripts/product_containers.js  var product_containers = class {    #content;    #where;    #inserted;    constructor(where) {      this.#where = where;      this.#content = new Array();      this.#inserted = new Array();    }    add_list(target) {      target.forEach((count) => {        this.add(count);      });      return this;    }    add(target) {      const current = new product_container(target);      this.#content.push(current);      return this;    }    clean() {      this.#content = new Array();      return this;    }    update() {      this.#hide();      setTimeout(() => {        this.#content.forEach((count) => {          this.#inserted.push(count);          count.add(this.#where);        });      }, 500);      return this;    }    #hide() {      this.#inserted.forEach((count) => {        if (!this.#content.includes(count)) {          count.drop();        }      });      this.#inserted = new Array();      return this;    }  };  // application/scripts/searcher.js  var _input, _category, _manager, _result, _instances, _add, add_fn, _selector_complete, selector_complete_fn, _loader, loader_get, _result_title, result_title_get, result_title_set, _insert, insert_fn;  var _searcher = class {    constructor(search_form, manager, result) {      __privateAdd(this, _selector_complete);      __privateAdd(this, _loader);      __privateAdd(this, _result_title);      __privateAdd(this, _insert);      __privateAdd(this, _input, void 0);      __privateAdd(this, _category, void 0);      __privateAdd(this, _manager, void 0);      __privateAdd(this, _result, void 0);      var _a;      __privateSet(this, _input, search_form.querySelector('input[type="text"]'));      __privateSet(this, _category, search_form.querySelector("select"));      __privateSet(this, _manager, manager);      __privateSet(this, _result, result);      __privateMethod(this, _selector_complete, selector_complete_fn).call(this);      search_form.addEventListener("submit", (target) => {        target.preventDefault();        this.update();      });      __privateMethod(_a = _searcher, _add, add_fn).call(_a, this);    }    static reload() {      if (typeof __privateGet(_searcher, _instances) !== "object") {        return;      }      __privateGet(_searcher, _instances).forEach((instance) => {        instance.update();      });    }    get categories() {      return {        "name": _("name-category"),        "author": _("author-category"),        "barcode": _("barcode-category")      };    }    get category() {      return __privateGet(this, _category).value;    }    get phrase() {      return __privateGet(this, _input).value.trim();    }    async update() {      if (this.phrase.length === 0) {        this.show_all();        return;      }      __privateMethod(this, _insert, insert_fn).call(this, await __privateGet(this, _loader, loader_get).call(this, this.phrase));    }    async show_all() {      __privateMethod(this, _insert, insert_fn).call(this, await products_loader.all());    }  };  var searcher = _searcher;  _input = new WeakMap();  _category = new WeakMap();  _manager = new WeakMap();  _result = new WeakMap();  _instances = new WeakMap();  _add = new WeakSet();  add_fn = function(instance) {    if (typeof __privateGet(_searcher, _instances) !== "object") {      __privateSet(_searcher, _instances, new Array());    }    __privateGet(_searcher, _instances).push(instance);  };  _selector_complete = new WeakSet();  selector_complete_fn = function() {    const category = __privateGet(this, _category);    const categories = this.categories;    Object.keys(categories).forEach((name) => {      const option = document.createElement("option");      option.value = name;      option.innerText = categories[name];      category.appendChild(option);    });  };  _loader = new WeakSet();  loader_get = function() {    return {      "name": products_loader.search_name,      "author": products_loader.search_author,      "barcode": products_loader.search_barcode    }[this.category];  };  _result_title = new WeakSet();  result_title_get = function() {    return __privateGet(this, _result).innerText;  };  result_title_set = function(target) {    __privateGet(this, _result).innerText = target;  };  _insert = new WeakSet();  insert_fn = function(list) {    if (list.length === 0) {      __privateSet(this, _result_title, _("not-found-anything"), result_title_set);    } else {      __privateSet(this, _result_title, _("browse-our-products"), result_title_set);    }    __privateGet(this, _manager).clean().add_list(list).update();  };  __privateAdd(searcher, _add);  __privateAdd(searcher, _instances, void 0);  // application/scripts/delete_product_window.js  var delete_product_window = class extends confirm_action {    #target;    constructor(target) {      super();      this.#target = target;    }    get _title() {      return _("do-you-want-to-remove-it");    }    get _description() {      let content = _("you-try-to-remove-__name__").format({        name: this.#target.name      });      return content;    }    async _action() {      new delete_request(this.#target).connect();      searcher.reload();    }  };  // application/scripts/formscreen.js  var formscreen = class extends fullscreen {    #form;    #result;    constructor() {      super();      this.#form = null;      this.#result = null;    }    get _name() {      throw new TypeError("This is virtual getter!");    }    _process() {      this._error = "This is abstract, and must be overwriten.";    }    _build_form() {      throw new TypeError("This is virtual method!");    }    _get_input(name) {      return this.get_query('input[name="' + name + '"]');    }    get _has_submit() {      return true;    }    _build_node() {      const center = document.createElement("div");      center.classList.add("center");      const title = document.createElement("div");      title.classList.add("title");      center.appendChild(title);      const title_content = document.createElement("h3");      title_content.innerText = this._name;      title.appendChild(title_content);      const form = document.createElement("form");      center.appendChild(form);      form.addEventListener("change", () => {        this._clear_results();      });      this.#form = document.createElement("div");      this.#form.classList.add("content");      form.appendChild(this.#form);      this.#result = document.createElement("div");      this.#result.classList.add("result");      form.appendChild(this.#result);      const bottom = document.createElement("div");      bottom.classList.add("bottom");      form.appendChild(bottom);      const close_button = document.createElement("button");      close_button.classList.add("close");      close_button.classList.add("material-icons");      close_button.innerText = "close";      close_button.type = "button";      bottom.appendChild(close_button);      if (this._has_submit) {        const send_button = document.createElement("button");        send_button.classList.add("send");        send_button.classList.add("material-icons");        send_button.innerText = "send";        send_button.type = "submit";        bottom.appendChild(send_button);      }      close_button.addEventListener("click", () => {        this.hide();      });      form.addEventListener("submit", (target) => {        target.preventDefault();        this._process();      });      this._refresh();      return center;    }    _refresh() {      while (this.#form.lastChild) {        this.#form.lastChild.remove();      }      this._build_form();    }    _create_input(name, label_text, placeholder, worker = null) {      const container = document.createElement("div");      container.classList.add("input-container");      container.classList.add("input-" + name);      const label = document.createElement("label");      label.htmlFor = name;      label.innerText = label_text;      container.appendChild(label);      const input = document.createElement("input");      input.type = "text";      input.placeholder = placeholder;      input.name = name;      input.id = name;      container.appendChild(input);      if (worker !== null) {        worker(input);      }      if (!this.#form) {        throw new Error("Screen is not visible yet!");      }      this._append_child(container);      return (target = null) => {        if (target !== null) {          input.value = target;        }        return input.value;      };    }    _append_child(target) {      this.#form.appendChild(target);    }    _clear_results() {      if (!this.#result) {        return;      }      while (this.#result.lastChild) {        this.#result.lastChild.remove();      }    }    set _info(target) {      this._clear_results();      const info = document.createElement("p");      info.classList.add("info");      info.innerText = target;      if (this.#result) {        this.#result.appendChild(info);      }    }    set _error(target) {      this._clear_results();      const info = document.createElement("p");      info.classList.add("error");      info.innerText = target;      if (this.#result) {        this.#result.appendChild(info);      }    }    set _success(target) {      this._clear_results();      const info = document.createElement("p");      info.classList.add("success");      info.innerText = target;      if (this.#result) {        this.#result.appendChild(info);      }    }  };  // application/scripts/product_base.js  var product_base = class {    name;    description;    author;    barcode;    stock_count;    constructor(target = null) {      this.name = this._extract(target, "name");      this.description = this._extract(target, "description");      this.author = this._extract(target, "author");      this.barcode = this._extract(target, "barcode");      this.stock_count = this._extract(target, "stock_count");      if (this.stock_count !== null) {        try {          this.stock_count = Number(this.stock_count);        } catch {          this.stock_count = 0;        }      }    }    get dump() {      return {        "name": new String(this.name),        "description": new String(this.description),        "author": new String(this.author),        "barcode": new String(this.barcode),        "stock_count": new String(this.stock_count)      };    }    _extract(dict, name) {      if (dict === null) {        return null;      }      if (name in dict) {        return dict[name];      }      return null;    }    get avairable() {      return this.stock_count > 0;    }  };  // application/scripts/edit_request.js  var edit_request = class extends request {    #target;    #updated;    constructor(target, updated) {      super();      this.#target = target;      this.#updated = updated;    }    get _response() {      return bool_response;    }    get data() {      return Object.assign(this.#updated.dump, {        "apikey": this._apikey      });    }    get method() {      return "POST";    }    get url() {      return "/product/update/barcode/" + this.#target.barcode;    }  };  // application/scripts/edit_image_request.js  var edit_image_request = class extends request {    #image;    #target;    constructor(target, image) {      super();      this.#target = target;      this.#image = image;    }    get _response() {      return bool_response;    }    get data() {      return {        "image": this.#image,        "apikey": this._apikey      };    }    get method() {      return "POST";    }    get url() {      return "/product/update/image/barcode/" + this.#target.barcode;    }  };  // application/scripts/product_editor.js  var product_editor = class extends formscreen {    #target;    #name;    #description;    #author;    #barcode;    #stock_count;    #image;    #loaded_image_type;    #loaded_image;    #image_preview;    constructor(target) {      super();      this.#target = target;    }    get target() {      return this.#target;    }    get _name() {      return _("product-editor");    }    _build_form() {      this.#loaded_image = null;      this.#loaded_image_type = null;      this.#name = this._create_input(        "name",        _("name-prompt"),        _("name-sample"),        (input) => {          input.value = this.#target.name;        }      );      this.#description = this._create_input(        "description",        _("description-prompt"),        _("description-sample"),        (input) => {          input.value = this.#target.description;        }      );      this.#author = this._create_input(        "author",        _("author-prompt"),        _("author-sample"),        (input) => {          input.value = this.#target.author;        }      );      this.#barcode = this._create_input(        "barcode",        _("barcode-prompt"),        _("barcode-sample"),        (input) => {          input.type = "number";          input.value = this.#target.barcode;        }      );      this.#stock_count = this._create_input(        "stock_count",        _("stock-count-prompt"),        _("stock-count-sample"),        (input) => {          input.type = "number";          input.value = this.#target.stock_count;        }      );      this._create_input(        "image",        _("change-product-image"),        "",        (input) => {          this.#image = input;          input.type = "file";          input.accept = "image/*";          input.addEventListener("change", () => {            this.#load_image_from_file();          });        }      );      this.#image_preview = document.createElement("img");      this.#image_preview.style.opacity = "1";      this.#image_preview.src = this.#target.image;      this._append_child(this.#image_preview);    }    get #ready_image() {      return this.#loaded_image;    }    #update_image_preview() {      this.#image_preview.src = "data:" + this.#loaded_image_type + ";base64," + this.#loaded_image;      this.#image_preview.style.opacity = "1";    }    #reset_image() {      this.#loaded_image = null;      this.#loaded_image_type = null;      this.#image_preview.style.opacity = "0";      this.#image_preview.src = "";    }    async #load_image_from_file() {      if (this.#image.files.length === 0) {        this.#reset_image();      }      const file = this.#image.files.item(0);      const buffer = await file.arrayBuffer();      let as_string = new String();      new Uint8Array(buffer).forEach((letter) => {        as_string += String.fromCharCode(letter);      });      this.#loaded_image = btoa(as_string);      this.#loaded_image_type = file.type;      this.#update_image_preview();    }    async #submit() {      const copy = this.#target.copy();      copy.name = this.#name();      copy.description = this.#description();      copy.author = this.#author();      copy.barcode = this.#barcode();      copy.stock_count = this.#stock_count();      const request2 = new edit_request(this.#target, copy);      const response = await request2.connect();      if (!response.result) {        throw new Error(response.cause);      }      this.#target = copy;    }    async #image_submit() {      const image = await this.#ready_image;      if (image === null) {        return;      }      const request2 = new edit_image_request(this.#target, image);      const response = await request2.connect();      if (!response.result) {        throw new Error(response.cause);      }    }    async _process() {      try {        this._info = _("updating-product-data");        await this.#submit();        this._info = _("processing-image");        await this.#image_submit();        this._success = _("uploaded-successfull");        searcher.reload();        setTimeout(() => {          this.hide();        }, 500);      } catch (error) {        this._error = new String(error);      }    }  };  // application/scripts/rents_screen.js  var rents_screen = class extends formscreen {    #target;    #email;    #phone;    get _email() {      return this.#email();    }    get _phone() {      return this.#phone();    }    constructor(target) {      super();      this.#target = target;    }    get _target() {      return this.#target;    }    _build_form() {      this.#email = this._create_input(        "email",        _("email-prompt"),        _("email-sample"),        (input) => {          input.type = "email";        }      );      this.#phone = this._create_input(        "phone",        _("phone-number-prompt"),        _("phone-number-sample"),        (input) => {          input.type = "tel";          const add_prefix = () => {            if (input.value.length === 0) {              input.value = "+48 ";            }          };          input.addEventListener("click", add_prefix);          input.addEventListener("focus", add_prefix);        }      );    }  };  // application/scripts/reservation.js  var reservation = class {    email;    phone_number;    product_barcode;    constructor(target = null) {      this.email = null;      this.phone_number = null;      this.product_barcode = null;      if (target === null) {        return;      }      if ("email" in target) {        this.email = target["email"];      }      if ("target_barcode" in target) {        this.product_barcode = target["target_barcode"];      }      if ("phone_number" in target) {        this.phone_number = target["phone_number"];      }    }    get dump() {      const dumped = {        "target_barcode": this.product_barcode      };      if (this.email !== null) {        dumped["email"] = this.email;      }      if (this.phone_number !== null) {        dumped["phone_number"] = this.phone_number;      }      return dumped;    }    get ready() {      if (this.product_barcode === null)        return false;      if (this.email === null && this.phone_number === null)        return false;      return true;    }    copy() {      return new reservation(this.dump);    }  };  // application/scripts/product_rent_request.js  var product_rent_request = class extends request {    #reservation;    constructor(reservation2) {      super();      this.#reservation = reservation2;    }    get data() {      return Object.assign(this.#reservation.dump, {        "apikey": this._apikey      });    }    get _response() {      return bool_response;    }    get method() {      return "POST";    }    get url() {      return "/rent/product/barcode/" + this.#reservation.product_barcode;    }  };  // application/scripts/reservation_factory.js  var reservation_factory = class {    #target;    constructor() {      this.#target = new reservation();    }    phone_number(target) {      target = target.trim().replaceAll("-", "");      if (target.length === 0) {        target = null;      }      this.#target.phone_number = target;      return this;    }    email(target) {      target = target.trim();      if (target.length === 0) {        target = null;      }      this.#target.email = target;      return this;    }    product(target) {      this.#target.product_barcode = target.barcode;      return this;    }    result() {      if (this.#target.ready) {        return this.#target;      }      throw new Error("Target reservation is not ready yet.");    }  };  // application/scripts/product_rent.js  var product_rent = class extends rents_screen {    get _name() {      return _("product-rent");    }    async _process() {      try {        this._info = _("processing");        const target = new reservation_factory().email(this._email).phone_number(this._phone).product(this._target).result();        const request2 = new product_rent_request(target);        const response = await request2.connect();        if (!response.result) {          throw new Error(response.cause);        }        this._success = _("new-rent-added");        searcher.reload();        setTimeout(() => {          this.hide();        }, 500);      } catch (error) {        this._error = String(error);      }    }  };  // application/scripts/product_give_back_request.js  var product_give_back_request = class extends request {    #reservation;    constructor(reservation2) {      super();      this.#reservation = reservation2;    }    get data() {      return Object.assign(this.#reservation.dump, {        "apikey": this._apikey      });    }    get _response() {      return bool_response;    }    get method() {      return "POST";    }    get url() {      return "/give_back/product/barcode/" + this.#reservation.product_barcode;    }  };  // application/scripts/product_give_back.js  var product_give_back = class extends rents_screen {    get _name() {      return _("product-give-back");    }    async _process() {      try {        this._info = _("processing");        const target = new reservation_factory().email(this._email).phone_number(this._phone).product(this._target).result();        const request2 = new product_give_back_request(target);        const response = await request2.connect();        if (!response.result) {          throw new Error(response.cause);        }        this._success = _("give-back-successfull");        searcher.reload();        setTimeout(() => {          this.hide();        }, 500);      } catch (error) {        this._error = String(error);      }    }  };  // application/scripts/reservations_response.js  var reservations_response = class extends bool_response {    #collection;    constructor(target) {      super(target);      if (!this.result) {        return;      }      this.#collection = new Array();      target["reservations"].forEach((count) => {        this.#collection.push(new reservation(count));      });    }    get collection() {      if (!this.result) {        throw new Error(this.cause);      }      return this.#collection;    }  };  // application/scripts/product_reservations_request.js  var product_reservations_request = class extends request {    #target;    constructor(target) {      super();      this.#target = target;    }    get _response() {      return reservations_response;    }    get data() {      return {        "apikey": this._apikey      };    }    get method() {      return "POST";    }    get url() {      return "/reservations/product/barcode/" + this.#target.barcode;    }  };  // application/scripts/product_all_rents.js  var product_all_rents = class extends formscreen {    #target;    constructor(target) {      super();      this.#target = target;    }    get _name() {      return _("all-rents");    }    get _has_submit() {      return false;    }    #create_single(target) {      const container = document.createElement("div");      container.classList.add("reservation-info");      if (target.phone_number !== null) {        const phone_icon = document.createElement("span");        phone_icon.classList.add("material-icons");        phone_icon.innerText = "phone";        const phone_number = document.createElement("span");        phone_number.classList.add("numbers");        phone_number.innerText = target.phone_number;        const phone_number_container = document.createElement("p");        phone_number_container.appendChild(phone_icon);        phone_number_container.appendChild(phone_number);        container.appendChild(phone_number_container);      }      if (target.email !== null) {        const email_icon = document.createElement("span");        email_icon.classList.add("material-icons");        email_icon.innerText = "mail";        const email = document.createElement("span");        email.innerText = target.email;        const email_container = document.createElement("p");        email_container.appendChild(email_icon);        email_container.appendChild(email);        container.appendChild(email_container);      }      return container;    }    #create_single_button(target) {      const button = document.createElement("button");      button.classList.add("material-icons");      button.classList.add("give-back-button");      button.innerText = "save_alt";      button.addEventListener("click", async () => {        try {          this._info = _("processing");          const request2 = new product_give_back_request(target);          const response = await request2.connect();          if (!response.result) {            throw new Error(_(response.cause));          }          this._refresh();          searcher.reload();        } catch (error) {          this._error = String(error);        }      });      return button;    }    _process() {      return;    }    async _build_form() {      try {        this._info = _("loading");        const request2 = new product_reservations_request(this.#target);        const response = await request2.connect();        const list = document.createElement("div");        list.classList.add("reservations-list");        let empty = true;        response.collection.forEach((count) => {          const item = document.createElement("div");          item.classList.add("reservation");          const left = this.#create_single(count);          const right = this.#create_single_button(count);          empty = false;          item.appendChild(left);          item.appendChild(right);          list.appendChild(item);        });        this._append_child(list);        if (empty) {          this._success = "not-found-any-reservations";        } else {          this._clear_results();        }      } catch (error) {        this._error = String(error);      }    }  };  // application/scripts/product_not_avairable.js  var product_not_avairable = class extends confirm_action {    get _title() {      return _("product-not-avairable");    }    get _description() {      return _("this-product-is-not-avairable-yet");    }    get _info() {      return true;    }  };  // application/scripts/product_container.js  var product_container = class {    #target;    #node;    #login;    constructor(target) {      this.#target = new product(target.dump);      this.#node = null;      this.#login = new login_manager().logged_in;    }    get #header() {      const header = document.createElement("div");      header.classList.add("header");      const title = document.createElement("h3");      title.innerText = this.#target.name;      header.appendChild(title);      if (this.#login) {        header.appendChild(this.#manage);      }      return header;    }    get #manage() {      const manage = document.createElement("div");      manage.classList.add("manage");      const all_rents_button = document.createElement("button");      all_rents_button.classList.add("material-icons");      all_rents_button.classList.add("all-rents-button");      all_rents_button.innerText = "list";      manage.appendChild(all_rents_button);      const rent_button = document.createElement("button");      rent_button.classList.add("material-icons");      rent_button.classList.add("rent-button");      rent_button.innerText = "backpack";      manage.appendChild(rent_button);      const give_back_button = document.createElement("button");      give_back_button.classList.add("material-icons");      give_back_button.classList.add("give-back-button");      give_back_button.innerText = "save_alt";      manage.appendChild(give_back_button);      const edit_button = document.createElement("button");      edit_button.classList.add("material-icons");      edit_button.classList.add("edit-button");      edit_button.innerText = "edit";      manage.appendChild(edit_button);      const delete_button = document.createElement("button");      delete_button.classList.add("material-icons");      delete_button.classList.add("delete-button");      delete_button.innerText = "remove_circle_outline";      manage.appendChild(delete_button);      all_rents_button.addEventListener("click", () => {        new product_all_rents(this.#target).show();      });      rent_button.addEventListener("click", () => {        if (this.#target.on_stock > 0) {          new product_rent(this.#target).show();        } else {          new product_not_avairable().show();        }      });      give_back_button.addEventListener("click", () => {        new product_give_back(this.#target).show();      });      edit_button.addEventListener("click", () => {        new product_editor(this.#target).show();      });      delete_button.addEventListener("click", () => {        new delete_product_window(this.#target).show();      });      return manage;    }    get #description() {      const container = document.createElement("div");      container.classList.add("description");      const description = document.createElement("p");      description.innerText = this.#target.description;      description.classList.add("content");      const author_container = document.createElement("div");      author_container.classList.add("author");      const author = document.createElement("span");      author.innerText = this.#target.author;      const author_icon = document.createElement("span");      author_icon.classList.add("material-icons");      author_icon.innerText = "attribution";      author_container.appendChild(author_icon);      author_container.appendChild(author);      const stock_count = document.createElement("p");      stock_count.classList.add("stock-count");      stock_count.classList.add("material-icons");      if (this.#target.on_stock > 0) {        stock_count.innerText = "check_circle";        stock_count.classList.add("avairable");      } else {        stock_count.innerText = "cancel";        stock_count.classList.add("unavairable");      }      const barcode_container = document.createElement("p");      barcode_container.classList.add("barcode");      const barcode = document.createElement("span");      barcode.innerText = this.#target.barcode;      barcode.classList.add("numbers");      const barcode_icon = document.createElement("span");      barcode_icon.classList.add("material-icons");      barcode_icon.innerText = "qr_code_scanner";      barcode_container.appendChild(barcode_icon);      barcode_container.appendChild(barcode);      container.appendChild(description);      container.appendChild(author_container);      container.appendChild(barcode_container);      container.appendChild(stock_count);      return container;    }    get #cache_bypass() {      if (!this.#login) {        return "?cache=1";      }      return "?cache=" + new String(Math.floor(Math.random() * 100));    }    get #image() {      const image = document.createElement("img");      image.classList.add("image");      image.src = this.#target.thumbnail + this.#cache_bypass;      image.alt = this.#target.name;      image.loading = "lazy";      image.addEventListener("click", () => {        new product_fullscreen(this.#target).show();      });      return image;    }    get node() {      if (this.#node !== null) {        return this.#node;      }      const bottom_container = document.createElement("div");      bottom_container.classList.add("bottom-container");      bottom_container.appendChild(this.#description);      bottom_container.appendChild(this.#image);      const container = document.createElement("div");      container.classList.add("product");      container.appendChild(this.#header);      container.appendChild(bottom_container);      return this.#node = container;    }    add(target) {      const node = this.node;      node.style.opacity = "0";      node.style.transition = "opacity 0.5s";      target.appendChild(node);      setTimeout(() => {        node.style.opacity = "1";      }, 50);    }    drop() {      const container = this.#node;      if (container === null) {        throw new TypeError("It is not showed yet.");      }      container.style.opacity = "1";      container.style.transition = "opacity 0.5s";      setTimeout(() => {        container.style.opacity = "0";      }, 50);      setTimeout(() => {        this.#node = null;        container.remove();      }, 550);    }  };  // application/scripts/login_prompt.js  var login_prompt = class extends formscreen {    #nick;    #password;    constructor(target) {      super();      target.addEventListener("click", () => {        this.show();      });    }    get _name() {      return _("login-window");    }    async _process() {      try {        this._info = _("processing");        await this.#login();        this._success = _("logged-in");        setTimeout(() => {          location.reload();        }, 250);      } catch (error) {        this._error = new String(error);      }    }    async #login() {      const manager = new login_manager();      const result = await manager.login(        this.#nick(),        this.#password()      );      if (result) {        return;      }      throw new Error(_("can-not-login-check-nick-and-password"));    }    _build_form() {      this.#nick = this._create_input(        "nick",        _("nick-prompt"),        _("nick-sample")      );      this.#password = this._create_input(        "password",        _("password-prompt"),        _("password-sample"),        (input) => {          input.type = "password";        }      );    }  };  // application/scripts/create_request.js  var create_request = class extends request {    #image;    #product;    constructor(product2, image) {      super();      this.#image = image;      this.#product = product2;    }    get _response() {      return bool_response;    }    get data() {      return Object.assign(this.#product.dump, {        "image": this.#image,        "apikey": this._apikey      });    }    get method() {      return "POST";    }    get url() {      return "/product/create";    }  };  // application/scripts/autocomplete_response.js  var autocomplete_response = class extends bool_response {    #found;    constructor(target) {      super(target);      this.#found = null;      if (this.result) {        this.#found = target["found"];      }    }    get found() {      if (this.#found === null) {        throw new Error("Server response is not complete.");      }      return this.#found;    }  };  // application/scripts/autocomplete_request.js  var autocomplete_request = class extends request {    #barcode;    constructor(barcode) {      super();      this.#barcode = barcode;    }    get _response() {      return autocomplete_response;    }    get data() {      return {        "apikey": this._apikey      };    }    get method() {      return "POST";    }    get url() {      return "/complete/barcode/" + this.#barcode;    }  };  // application/scripts/product_adder.js  var product_adder = class extends formscreen {    #name;    #description;    #author;    #barcode;    #stock_count;    #image;    #loaded_image_type;    #loaded_image;    #image_preview;    get _name() {      return _("add-product");    }    async #autocomplete() {      const barcode = this.#barcode();      if (barcode.length === 0) {        this._info = _("fill-barcode-first");        return;      }      this._info = _("searching-in-the-web");      try {        const request2 = new autocomplete_request(barcode);        const response = await request2.connect();        if (!response.result) {          throw new Error(response.cause);        }        const product2 = response.found;        this.#name(product2.title);        this.#description(product2.description);        this.#author(product2.author);        this.#barcode(product2.barcode);        this.#loaded_image = product2.image;        this.#loaded_image_type = product2.image_type;        this.#update_image_preview();        this._info = _("autocomplete-ready-check-results");      } catch (error) {        this._error = new String(error);      }    }    #update_image_preview() {      this.#image_preview.src = "data:" + this.#loaded_image_type + ";base64," + this.#loaded_image;      this.#image_preview.style.opacity = "1";    }    get #autocomplete_button() {      const button = document.createElement("div");      button.classList.add("autocomplete-button");      button.classList.add("button");      const icon = document.createElement("span");      icon.classList.add("material-icons");      icon.innerText = "auto_fix_normal";      button.appendChild(icon);      const text = document.createElement("span");      text.classList.add("text");      text.innerText = _("autocomplete");      button.appendChild(text);      return button;    }    _build_form() {      this.#loaded_image = null;      this.#loaded_image_type = null;      this.#name = this._create_input(        "name",        _("name-prompt"),        _("name-sample")      );      this.#description = this._create_input(        "description",        _("description-prompt"),        _("description-sample")      );      this.#author = this._create_input(        "author",        _("author-prompt"),        _("author-sample")      );      this.#barcode = this._create_input(        "barcode",        _("barcode-prompt"),        _("barcode-sample"),        (input) => {          input.type = "number";        }      );      this.#stock_count = this._create_input(        "stock_count",        _("stock-count-prompt"),        _("stock-count-sample"),        (input) => {          input.type = "number";        }      );      this._create_input(        "image",        _("image-prompt"),        "",        (input) => {          this.#image = input;          input.type = "file";          input.accept = "image/*";          input.addEventListener("change", () => {            this.#load_image_from_file();          });        }      );      this.#image_preview = document.createElement("img");      this.#image_preview.style.opacity = "0";      this._append_child(this.#image_preview);      const autocomplete = this.#autocomplete_button;      this._append_child(autocomplete);      autocomplete.addEventListener("click", () => {        this.#autocomplete();      });    }    #reset_image() {      this.#loaded_image = null;      this.#loaded_image_type = null;      this.#image_preview.style.opacity = "0";      this.#image_preview.src = "";    }    async #load_image_from_file() {      if (this.#image.files.length === 0) {        this.#reset_image();      }      const file = this.#image.files.item(0);      const buffer = await file.arrayBuffer();      let as_string = new String();      new Uint8Array(buffer).forEach((letter) => {        as_string += String.fromCharCode(letter);      });      this.#loaded_image = btoa(as_string);      this.#loaded_image_type = file.type;      this.#update_image_preview();    }    get #ready_image() {      if (this.#loaded_image === null) {        throw new Error(_("load-any-image-first"));      }      return this.#loaded_image;    }    async #submit() {      const product2 = new product_base();      product2.name = this.#name();      product2.description = this.#description();      product2.author = this.#author();      product2.stock_count = this.#stock_count();      product2.barcode = this.#barcode();      const request2 = new create_request(product2, this.#ready_image);      const response = await request2.connect();      if (!response.result) {        throw new Error(response.cause);      }    }    async _process() {      try {        this._info = _("creating-new-product");        await this.#submit();        this._success = _("created-new-product-success");        searcher.reload();        setTimeout(() => {          this.hide();        }, 500);      } catch (error) {        this._error = new String(error);      }    }  };  // application/scripts/import_process_fail.js  var import_process_fail = class {    #product;    #error;    constructor(product2, error) {      this.#product = product2;      this.#error = error;    }    get error() {      return this.#error;    }    get product() {      return this.#product;    }  };  // application/scripts/database.js  var database = class {    #content;    #processed;    #on_skip;    constructor(content) {      this.#content = content;      this.#processed = /* @__PURE__ */ new Map();      this.#on_skip = null;    }    #append(target) {      if (this.#processed.has(target.barcode)) {        this.#processed.get(target.barcode).stock_count += 1;        return;      }      this.#processed.set(target.barcode, target);    }    #validate(target) {      if (!("id" in target)) {        throw new Error("One of item has no ID.");      }      if (!("title" in target)) {        throw new Error("Product " + target.barcode + " has no title.");      }      if (!("author" in target)) {        throw new Error("Product " + target.barcode + " has no author.");      }    }    #convert(target) {      this.#validate(target);      const product2 = new product_base();      product2.name = target.title;      product2.description = "";      product2.author = target.author;      product2.stock_count = 1;      product2.barcode = target.id;      return product2;    }    on_skip(target) {      this.#on_skip = target;      return this;    }    process() {      this.#processed.clear();      if (!(this.#content instanceof Array)) {        throw new Error("Database woud be array of objects.");      }      this.#content.forEach((count) => {        try {          const product2 = this.#convert(count);          this.#append(product2);        } catch (error) {          if (this.#on_skip === null) {            return;          }          try {            this.#on_skip(new import_process_fail(count, error));          } catch (fail) {            console.log(fail);          }        }      });      return this;    }    results() {      return Array.from(this.#processed.values());    }  };  // application/scripts/product_response.js  var product_response = class extends bool_response {    #product;    constructor(target) {      super(target);      this.#product = null;      if (this.result) {        if (!("product" in target)) {          throw new Error(_("incomplete-request-with-good-status"));        }        this.#product = new product(target.product);      }    }    get product() {      return this.#product;    }  };  // application/scripts/product_get_request.js  var product_get_request = class extends request {    #barcode;    constructor(barcode) {      super();      this.#barcode = barcode;    }    get _response() {      return product_response;    }    get data() {      return null;    }    get method() {      return "GET";    }    get url() {      return "/product/get/barcode/" + new String(this.#barcode);    }  };  // application/scripts/import_loop.js  var import_loop = class {    #content;    #on_autocomplete;    #on_create;    #on_single_fail;    #on_skip;    #on_single_success;    #finally;    on_autocomplete(target) {      this.#on_autocomplete = target;      return this;    }    on_create(target) {      this.#on_create = target;      return this;    }    on_single_fail(target) {      this.#on_single_fail = target;      return this;    }    on_skip(target) {      this.#on_skip = target;      return this;    }    on_single_success(target) {      this.#on_single_success = target;      return this;    }    finally(target) {      this.#finally = target;      return this;    }    constructor(dataset) {      this.#content = dataset;      this.#on_autocomplete = null;      this.#on_create = null;      this.#on_single_fail = null;      this.#on_skip = null;      this.#on_single_success = null;      this.#finally = null;    }    async #autocomplete(target) {      if (this.#on_autocomplete !== null) {        try {          this.#on_autocomplete(target);        } catch (error) {          console.log(error);        }      }      const request2 = new autocomplete_request(target.barcode);      const response = await request2.connect();      if (!response.result) {        throw new Error(response.cause);      }      const found = response.found;      target.description = found.description;      if (found.image.length === 0) {        throw new Error("Image for " + target.barcode + " not found.");      }      return new create_request(target, found.image);    }    async process() {      for (const count of this.#content) {        try {          await this.#create(count);        } catch (error) {          if (this.#on_single_fail !== null) {            try {              const fail = new import_process_fail(count, error);              this.#on_single_fail(fail);            } catch (error2) {              console.log(error2);            }          }        }      }      if (this.#finally !== null) {        try {          this.#finally();        } catch (error) {          console.log(error);        }      }      return this;    }    async #exists(target) {      const request2 = new product_get_request(target.barcode);      const response = await request2.connect();      return response.product !== null;    }    async #create(target) {      if (await this.#exists(target)) {        try {          const result = new import_process_fail(target, null);          this.#on_skip(result);        } catch (error) {          console.log(error);        }        return;      }      const request2 = await this.#autocomplete(target);      if (this.on_create !== null) {        try {          this.#on_create(target);        } catch (error) {          console.log(error);        }      }      const response = await request2.connect();      if (!response.result) {        throw new Error(response.cause);      }      if (this.#on_single_success !== null) {        try {          this.#on_single_success(target);        } catch (error) {          console.log(error);        }      }    }  };  // application/scripts/import_log.js  var import_log = class {    #log;    constructor() {      this.#log = new Array();    }    #append(target) {      this.#log.push(target);    }    #error_dump(error) {      return "Error: " + new String(error) + ".";    }    #product_dump(product2) {      return 'Product: barcode: "' + product2.barcode + '", title: "' + product2.title + '".';    }    fail(target) {      this.#append(        "Fail when processing item. " + this.#product_dump(target.product) + " " + this.#error_dump(target.error)      );    }    skip(target) {      this.#append(        "Skipping not ready item. " + this.#product_dump(target.product) + " " + this.#error_dump(target.error)      );    }    get length() {      return this.#log.length;    }    content() {      return this.#log.join("\n");    }  };  // application/scripts/downloader.js  var downloader = class {    #name;    #content;    #type;    #encode;    constructor() {      this.#name = "download.json";      this.#content = "";      this.#type = "text/plain";      this.#encode = "utf-8";    }    name(target) {      this.#name = target;      return this;    }    content(target) {      this.#content = target;      return this;    }    type(target) {      this.#type = target;      return this;    }    encode(target) {      this.#encode = target;      return this;    }    get #href() {      return "data:" + this.#type + ";charset=" + this.#encode + "," + encodeURIComponent(this.#content);    }    get #link() {      const link = document.createElement("a");      link.style.display = "none";      link.href = this.#href;      link.download = this.#name;      return link;    }    process() {      const link = this.#link;      const body = document.querySelector("body");      body.appendChild(link);      link.click();      body.removeChild(link);      return this;    }  };  // application/scripts/import_products.js  var import_products = class extends formscreen {    #file;    #content;    get _name() {      return _("import-products-json");    }    _build_form() {      this._create_input("file", "Database:", "", (input) => {        this.#file = input;        input.type = "file";        input.accept = "application/json";      });    }    async #load_file() {      if (this.#file.files.length === 0) {        throw new Error("select-products-json-database-first");      }      const file = this.#file.files.item(0);      const text = await file.text();      return JSON.parse(text);    }    async _process() {      try {        this._info = _("loading-file");        this.#content = await this.#load_file();        this._info = _("parsing-file-to-dataset");        const result = new import_log();        const dataset = new database(this.#content).on_skip((fail) => {          this._info = _("skipping-import-product-__barcode__").format({            barcode: fail.product.barcode          });          result.skip(fail);        }).process().results();        const loop = new import_loop(dataset).on_autocomplete((target) => {          this._info = _("searching-for-product-__barcode__").format({            barcode: target.barcode          });        }).on_create((target) => {          this._info = _("creating-product-__barcode__").format({            barcode: target.barcode          });        }).on_single_fail((target) => {          this._info = _("can-not-add-product-__barcode__").format({            barcode: target.product.barcode          });          result.fail(target);        }).on_skip((target) => {          this._info = _("skipping-product-__barcode").format({            barcode: target.product.barcode          });          result.skip(target);        }).on_single_success((target) => {          this._info = _("created-product-__barcode__").format({            barcode: target.barcode          });        }).finally(() => {          searcher.reload();          const log = new downloader().content(result.content()).type("text/plain").encode("utf-8").name("import-json.log").process();          if (result.length === 0) {            this._success = _("all-items-imported");            setTimeout(() => {              this.hide();            });          } else {            this._success = _("not-all-items-imported");          }        }).process();      } catch (error) {        this._error = new String(error);      }    }  };  // application/scripts/login_bar.js  var login_bar = class {    #manager;    constructor(target) {      this.#manager = new login_manager();      if (!this.#manager.logged_in) {        this.#not_logged(target);        return;      }      this.#logged(target);    }    #not_login_propertly() {      this.#manager.logout();      location.reload();    }    async #logged(target) {      const user2 = await this.#manager.get_user();      if (user2 === null) {        this.#not_login_propertly();      }      const info_icon = document.createElement("span");      info_icon.classList.add("icon");      info_icon.classList.add("material-icons");      info_icon.innerText = "account_circle";      const info_content = document.createElement("span");      info_content.innerText = user2.nick;      const info = document.createElement("p");      info.classList.add("login-info");      info.appendChild(info_icon);      info.appendChild(info_content);      target.appendChild(info);      const logout_button = document.createElement("button");      logout_button.innerText = "logout";      logout_button.classList.add("logout-button");      logout_button.classList.add("material-icons");      target.appendChild(logout_button);      const add_product_button = document.createElement("button");      add_product_button.innerText = "add";      add_product_button.classList.add("add-product-button");      add_product_button.classList.add("material-icons");      target.appendChild(add_product_button);      const import_products_button = document.createElement("button");      import_products_button.innerText = "dataset_linked";      import_products_button.classList.add("material-icons");      import_products_button.classList.add("import-products-button");      target.appendChild(import_products_button);      add_product_button.addEventListener("click", () => {        new product_adder().show();      });      import_products_button.addEventListener("click", () => {        new import_products().show();      });      logout_button.addEventListener("click", () => {        this.#manager.logout();        location.reload();      });    }    #not_logged(target) {      const login_button = document.createElement("button");      login_button.innerText = "account_circle";      login_button.classList.add("login-button");      login_button.classList.add("material-icons");      target.appendChild(login_button);      new login_prompt(login_button);    }  };  // application/scripts/scroll_up.js  var scroll_up = class {    #button;    constructor(button) {      this.#button = button;      this.#update();      document.addEventListener("scroll", () => {        this.#update();      });      this.#button.addEventListener("click", () => {        this.scroll();      });    }    scroll() {      this.#position = 0;    }    get #position() {      return document.scrollingElement.scrollTop;    }    set #position(target) {      document.scrollingElement.scrollTop = target;    }    get #visible() {      return Number(this.#button.style.opacity) === 1;    }    set #visible(target) {      this.#button.style.opacity = target ? "1" : "0";    }    get #margin() {      return 20;    }    #update() {      this.#visible = this.#position > this.#margin;    }  };  // application/scripts/color_theme.js  var color_theme = class {    #button;    #themes;    get themes() {      return Object.keys(this.#themes);    }    theme_name(target) {      return this.#themes[target];    }    constructor(button, themes = null) {      this.#button = button;      this.#themes = themes;      if (this.#themes === null) {        this.#themes = {          "dark-theme": "Dark",          "white-theme": "White"        };      }      this.#load();      this.#button.addEventListener("click", () => {        this.change();      });    }    get current() {      if (localStorage.hasOwnProperty("theme")) {        return localStorage.getItem("theme");      }      return this.themes[this.themes.length - 1];    }    #load() {      this.#show(this.current);    }    #save(target) {      localStorage.setItem("theme", target);    }    #show(target) {      const themes = this.themes;      const body = document.querySelector("body");      body.classList.forEach((count) => {        if (themes.indexOf(count) !== -1) {          body.classList.remove(count);        }      });      body.classList.add(target);    }    change() {      const themes = this.themes;      const current = this.current;      let position = themes.indexOf(current) + 1;      if (position === themes.length) {        position = 0;      }      const updated = themes[position];      this.#save(updated);      this.#show(updated);    }  };  // application/scripts/core.js  document.addEventListener("DOMContentLoaded", async () => {    const languages = new cx_libtranslate.languages("app/assets/languages");    await languages.load("index.json");    const preferences = new cx_libtranslate.preferences(languages);    preferences.selector.insert().add_listener(() => {      location.reload();    });    const phrasebook = await preferences.load_choosen_phrasebook();    phrasebook.set_as_default();    const autotranslate = await preferences.get_autotranslate();    autotranslate.connect();    const top_bar_spacing = new height_equaler(      document.querySelector(".top-bar"),      document.querySelector(".top-bar-spacing")    );    const container = document.querySelector(".products");    const search_bar = document.querySelector("form.search");    const search_title = document.querySelector(".search-title");    const login_space = document.querySelector(".top-bar .right");    const scroll_up_button = document.querySelector(".scroll-up-button");    const reverse_colors = document.querySelector(".reverse-colors");    const manager = new product_containers(container);    new login_bar(login_space);    new scroll_up(scroll_up_button);    new color_theme(reverse_colors);    new searcher(search_bar, manager, search_title).show_all();  });})();
 |