@aegis-framework/artemis 0.3.24 → 0.3.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +2 -2
- package/dist/artemis.js +2 -0
- package/dist/artemis.js.map +1 -0
- package/dist/artemis.min.js +2 -36
- package/dist/artemis.min.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +47 -15
- package/src/DOM.js +154 -14
- package/src/FileSystem.js +4 -0
- package/src/Platform.js +1 -0
- package/src/SpaceAdapter/IndexedDB.js +25 -5
- package/dist/artemis.min.map +0 -1
|
@@ -32,9 +32,11 @@ export class IndexedDB {
|
|
|
32
32
|
this.name = name;
|
|
33
33
|
this.version = version;
|
|
34
34
|
this.store = store;
|
|
35
|
-
this.props = props;
|
|
35
|
+
this.props = props || {};
|
|
36
36
|
this.index = index;
|
|
37
37
|
|
|
38
|
+
this.keyPath = props.keyPath || 'id';
|
|
39
|
+
|
|
38
40
|
this.upgrades = {};
|
|
39
41
|
|
|
40
42
|
if (this.version === '') {
|
|
@@ -90,7 +92,7 @@ export class IndexedDB {
|
|
|
90
92
|
} else {
|
|
91
93
|
// Check what upgrade functions have been declared in their respective order
|
|
92
94
|
const availableUpgrades = Object.keys (this.upgrades).sort ();
|
|
93
|
-
|
|
95
|
+
|
|
94
96
|
// Find the first update that needs to be applied to the database given
|
|
95
97
|
// the old version it currently has.
|
|
96
98
|
const startFrom = availableUpgrades.findIndex (u => {
|
|
@@ -138,7 +140,9 @@ export class IndexedDB {
|
|
|
138
140
|
const transaction = this.storage.transaction (this.store, 'readwrite').objectStore (this.store);
|
|
139
141
|
let op;
|
|
140
142
|
if (key !== null) {
|
|
141
|
-
|
|
143
|
+
const temp = {};
|
|
144
|
+
temp[this.keyPath] = key;
|
|
145
|
+
op = transaction.put (Object.assign ({}, temp, value));
|
|
142
146
|
} else {
|
|
143
147
|
op = transaction.add (value);
|
|
144
148
|
}
|
|
@@ -187,7 +191,14 @@ export class IndexedDB {
|
|
|
187
191
|
const transaction = this.storage.transaction (this.store).objectStore (this.store);
|
|
188
192
|
const op = transaction.get (key);
|
|
189
193
|
|
|
190
|
-
op.addEventListener ('success', (event) => {
|
|
194
|
+
op.addEventListener ('success', (event) => {
|
|
195
|
+
const value = event.target.result;
|
|
196
|
+
if (typeof value !== 'undefined' && value !== null) {
|
|
197
|
+
resolve (value);
|
|
198
|
+
} else {
|
|
199
|
+
reject ();
|
|
200
|
+
}
|
|
201
|
+
});
|
|
191
202
|
op.addEventListener ('error', (event) => {reject (event);});
|
|
192
203
|
});
|
|
193
204
|
});
|
|
@@ -204,7 +215,16 @@ export class IndexedDB {
|
|
|
204
215
|
const transaction = this.storage.transaction (this.store).objectStore (this.store);
|
|
205
216
|
const op = transaction.getAll ();
|
|
206
217
|
|
|
207
|
-
op.addEventListener ('success', (event) => {
|
|
218
|
+
op.addEventListener ('success', (event) => {
|
|
219
|
+
const results = {};
|
|
220
|
+
event.target.result.forEach((item) => {
|
|
221
|
+
const id = item[this.keyPath];
|
|
222
|
+
delete item[this.keyPath];
|
|
223
|
+
|
|
224
|
+
results[id] = item;
|
|
225
|
+
});
|
|
226
|
+
resolve (results);
|
|
227
|
+
});
|
|
208
228
|
op.addEventListener ('error', (event) => {reject (event);});
|
|
209
229
|
});
|
|
210
230
|
});
|
package/dist/artemis.min.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["src/Util.js","src/Component.js","src/Debug.js","src/DOM.js","src/Request.js","src/FileSystem.js","src/Form.js","src/Platform.js","src/Preload.js","src/SpaceAdapter/LocalStorage.js","src/SpaceAdapter/SessionStorage.js","src/SpaceAdapter/IndexedDB.js","src/SpaceAdapter/RemoteStorage.js","src/Space.js","src/Text.js","index.js"],"names":["Util","callAsync","callable","context","args","result","apply","Promise","resolve","e","reject","uuid","window","crypto","replace","c","getRandomValues","Uint8Array","toString","generate","Math","floor","random","substring","Component","HTMLElement","register","customElements","define","_id","_registered","instantiate","props","element","document","createElement","_setProps","constructor","_state","_props","state","Proxy","get","target","key","set","value","hasAttribute","getAttribute","setAttribute","setState","oldState","Object","assign","keys","attributeChangedCallback","console","log","willUpdate","origin","property","oldValue","newValue","update","didUpdate","onStateUpdate","render","willMount","didMount","willUnmount","unmount","didUnmount","forceRender","_render","then","html","innerHTML","connectedCallback","disconnectedCallback","shouldUpdate","catch","_html","DebugLevel","NONE","ERROR","WARNING","INFO","DEBUG","ALL","Debug","level","_level","debug","info","error","warning","warn","table","group","groupCollapsed","groupEnd","time","timeLog","timeEnd","trace","DOM","selector","collection","querySelectorAll","length","NodeList","hide","style","display","show","addClass","newClass","classList","add","removeClass","oldClass","remove","item","toggleClass","classes","split","j","toggle","hasClass","classToCheck","contains","focus","click","callback","addEventListener","keyup","keydown","submit","change","scroll","on","event","$_","matches","call","filter","querySelector","data","name","dataset","text","textContent","append","div","trim","appendChild","firstChild","prepend","childNodes","insertBefore","each","index","first","last","isVisible","offsetWidth","offsetHeight","parent","parentElement","find","offset","rect","getBoundingClientRect","top","body","scrollTop","left","scrollLeft","closest","found","search","attribute","after","content","insertAdjacentHTML","before","properties","i","animate","start","Date","getTime","timer","initialValue","setInterval","step","min","clearInterval","fadeIn","opacity","tick","requestAnimationFrame","setTimeout","fadeOut","check","Element","prototype","polyfill","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","indexOf","parentNode","removeChild","replaceWith","newElement","replaceElement","replaceChild","reset","$_ready","Request","serialize","map","encodeURIComponent","join","url","options","query","fetch","post","formData","headers","contentType","FormData","JSON","stringify","method","put","delete","json","response","blob","FileSystem","readRemote","type","file","read","reader","FileReader","onload","onerror","readAsDataURL","readAsArrayBuffer","readAsText","create","File","extension","pop","isImage","extensions","toLowerCase","Form","fill","field","values","files","Platform","retina","devicePixelRatio","portrait","orientation","landscape","electron","process","cordova","desktop","platform","match","navigator","includes","mobile","test","userAgent","serviceWorkers","location","protocol","Preload","image","route","Image","src","LocalStorage","version","store","upgrades","numericVersion","parseInt","id","open","storage","upgradesToApply","versionless","storedVersions","localStorage","sort","oldVersion","oldVersionNumeric","availableUpgrades","startFrom","findIndex","u","old","slice","next","previousId","previous","getItem","setItem","removeItem","_upgrade","currentValue","o","parse","exception","getAll","promises","push","all","upgrade","newVersion","rename","oldId","full","clear","SessionStorage","sessionStorage","IndexedDB","IDBDatabase","indexedDB","onsuccess","onupgradeneeded","createObjectStore","createIndex","transaction","objectStore","op","getAllKeys","RemoteStorage","endpoint","SpaceAdapter","Space","adapter","configuration","_configuration","callbacks","transformations","object","onCreate","onUpdate","onDelete","addTransformation","removeTransformation","Text","capitalize","txt","charAt","toUpperCase","substr","suffix","position","selection","getSelection","createRange","prefix","friendly","regex","replacements","RegExp"],"mappings":"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","file":"artemis.min.map","sourceRoot":"..","sourcesContent":["/**\n* ==============================\n* Util\n* ==============================\n*/\n\n/**\n * Provides diverse utility functions\n * @class\n */\nexport class Util {\n\n\n\t/**\n\t * @static callAsync - Calls any function using promises to keep a standard\n\t * behavior between async and sync functions.\n\t *\n\t * @param {funcion} callable - The function to run\n\t * @param {Object} context - The object `this` will be mapped to\n\t * @param {any} ...args - List of parameters to pass to the function when called\n\t * @return {Promise} - A promise that resolves to the result of the function\n\t */\n\tstatic callAsync (callable, context, ...args) {\n\t\ttry {\n\t\t\t// Call the provided function using the context and arguments given\n\t\t\tconst result = callable.apply (context, args);\n\n\t\t\t// Check if the function returned a simple value or a Promise\n\t\t\tif (result instanceof Promise) {\n\t\t\t\treturn result;\n\t\t\t} else {\n\t\t\t\treturn Promise.resolve (result);\n\t\t\t}\n\t\t} catch (e) {\n\t\t\treturn Promise.reject (e);\n\t\t}\n\t}\n\n\t/**\n\t * @static uuid - Creates a UUID. This UUIDs should not be trusted for uniqueness\n\t *\n\t * @return {string} - Generated UUID\n\t */\n\tstatic uuid () {\n\t\tif (window.crypto) {\n\t\t\treturn ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, (c) =>\n\t\t\t\t(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString (16)\n\t\t\t);\n\t\t} else {\n\t\t\tconst generate = () => Math.floor ((1 + Math.random()) * 0x10000).toString (16).substring (1);\n\t\t\treturn generate () + generate () + '-' + generate () + '-' + generate () + '-' +\n\t\t\tgenerate () + '-' + generate () + generate () + generate ();\n\t\t}\n\t}\n}","import { Util } from './Util';\n\nexport class Component extends HTMLElement {\n\n\tstatic register () {\n\t\twindow.customElements.define (this._id, this);\n\t\tthis._registered = true;\n\t}\n\n\tstatic instantiate (props) {\n\t\tif (this._registered === false) {\n\t\t\tthis.register ();\n\t\t}\n\n\t\tconst element = document.createElement (this._id);\n\t\telement._setProps (props);\n\n\t\treturn element;\n\t}\n\n\tconstructor () {\n\t\tsuper ();\n\n\t\tthis._state = {};\n\t\tthis._props = {};\n\n\t\tthis.state = new Proxy (this._state, {\n\t\t\tget: (target, key) => {\n\t\t\t\treturn target[key];\n\t\t\t},\n\t\t\tset: (target, key, value) => {\n\t\t\t\tthrow 'Component state should be set using the `setState` function.';\n\t\t\t}\n\t\t});\n\n\t\tthis.props = new Proxy (this, {\n\t\t\tget: (target, key) => {\n\t\t\t\tif (this.hasAttribute (key)) {\n\t\t\t\t\treturn this.getAttribute (key);\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\tset: (target, key, value) => {\n\t\t\t\tif (this.hasAttribute (key)) {\n\t\t\t\t\tthis.setAttribute (key, value);\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t}\n\t\t});\n\t}\n\n\t// /**\n\t// * @static html - A simple function providing access to the basic HTML\n\t// * structure of the component.\n\t// *\n\t// * @param {function|string} html - A string or function that renders the\n\t// * component into a valid HTML structure.\n\t// * @param {*} params - Any additional params that should be used when calling\n\t// * the rendering function\n\t// *\n\t// * @returns {void|string} - Void or the HTML structure in a string\n\t// */\n\t// template (html = null) {\n\t// \tif (html !== null) {\n\t// \t\tthis._template = html;\n\t// \t} else {\n\t// \t\t// Check if additional parameters have been sent to a rendering function\n\t// \t\tif (params.length > 0 && typeof this._html === 'function') {\n\t// \t\t\tif (html === null) {\n\t// \t\t\t\treturn this._html.call (this, ...params);\n\t// \t\t\t} else {\n\t// \t\t\t\treturn this._html.call (html, ...params);\n\t// \t\t\t}\n\t// \t\t}\n\n\t// \t\t// Check if no parameters were set but the HTML is still a function to be called\n\t// \t\tif (params.length === 0 && html === null && typeof this._html === 'function') {\n\t// \t\t\treturn this._html.call (this);\n\t// \t\t}\n\n\t// \t\t// If this is reached, the HTML was just a string\n\t// \t\treturn this._html;\n\t// \t}\n\t// }\n\n\tsetState (state) {\n\t\tif (typeof state !== 'undefined') {\n\t\t\tconst oldState = Object.assign ({}, this._state);\n\n\t\t\tthis._state = Object.assign ({}, this._state, state);\n\n\t\t\tfor (const key of Object.keys (state)) {\n\t\t\t\tthis.attributeChangedCallback (key, oldState[key], this._state[key], 'state');\n\t\t\t}\n\t\t}\n\t}\n\n\t_setProps (props) {\n\t\tconsole.log ('props');\n\t\tthis._props = props;\n\t}\n\n\twillUpdate (origin, property, oldValue, newValue) {\n\t\treturn Promise.resolve ();\n\t}\n\n\tupdate (origin, property, oldValue, newValue) {\n\t\treturn Promise.resolve ();\n\t}\n\n\tdidUpdate (origin, property, oldValue, newValue) {\n\t\treturn Promise.resolve ();\n\t}\n\n\tonStateUpdate () {\n\t\treturn this.render ();\n\t}\n\n\twillMount () {\n\t\treturn Promise.resolve ();\n\t}\n\n\tdidMount () {\n\t\treturn Promise.resolve ();\n\t}\n\n\twillUnmount () {\n\t\treturn Promise.resolve ();\n\t}\n\n\tunmount () {\n\t\treturn Promise.resolve ();\n\t}\n\n\tdidUnmount () {\n\t\treturn Promise.resolve ();\n\t}\n\n\tforceRender () {\n\t\treturn this._render ();\n\t}\n\n\trender () {\n\t\treturn '';\n\t}\n\n\t_render () {\n\t\treturn Util.callAsync (this.render, this).then ((html) => {\n\t\t\tthis.innerHTML = html;\n\t\t});\n\t}\n\n\tconnectedCallback () {\n\t\tconsole.log ('Connected');\n\n\t\tfor (const key of Object.keys (this._props)) {\n\t\t\tthis.setAttribute (key, this._props[key]);\n\t\t}\n\n\t\treturn this.willMount ().then (() => {\n\t\t\treturn this._render ().then (() => {\n\t\t\t\treturn this.didMount ();\n\t\t\t});\n\t\t});\n\t}\n\n\tdisconnectedCallback () {\n\t\treturn this.willUnmount ().then (() => {\n\t\t\treturn this.unmount ().then (() => {\n\t\t\t\treturn this.didUnmount ();\n\t\t\t});\n\t\t});\n\t}\n\n\tattributeChangedCallback (property, oldValue, newValue, origin) {\n\t\tif (typeof origin === 'undefined') {\n\t\t\torigin = 'props';\n\t\t}\n\n\t\treturn this.shouldUpdate (origin, property, oldValue, newValue).then (() => {\n\t\t\treturn this.update (origin, property, oldValue, newValue).then (() => {\n\t\t\t\treturn this.didUpdate (origin, property, oldValue, newValue);\n\t\t\t});\n\t\t}).catch (() => {\n\t\t\t// Component should not update\n\t\t});\n\t}\n}\n\nComponent._registered = false;\n\nComponent._html = '';\n\n/**\n * All components must have an unique ID, with this ID the developers will be\n * able to access the component classes, remove components or register new ones.\n */\nComponent._id = '';","/**\n * ==============================\n * Debug\n * ==============================\n */\n\n/* eslint no-console: \"off\" */\n\n/**\n * List of Log Levels available.\n */\nexport const DebugLevel = {\n\tNONE: 0,\n\tERROR: 1,\n\tWARNING: 2,\n\tINFO: 3,\n\tDEBUG: 4,\n\tALL: 5\n};\n\n/**\n * This class acts as a proxy for the console. It shares the same methods as the\n * web console but they are conditioned to a debug level.\n *\n * @class\n */\nexport class Debug {\n\n\t/**\n\t * @static level - Set the log level\n\t *\n\t * @param {DebugLevel} level The debug level to use\n\t *\n\t * @return {void}\n\t */\n\tstatic level (level) {\n\t\tif (typeof level === 'number') {\n\t\t\tthis._level = level;\n\t\t}\n\t\treturn this._level;\n\t}\n\n\t/**\n\t * @static log - Log the given elements.\n\t *\n\t * Logs will only be made if the level is set to DEBUG or above\n\t *\n\t * @param {...any} args\n\t *\n\t * @return {void}\n\t */\n\tstatic log (...args) {\n\t\tif (this.level () >= DebugLevel.DEBUG) {\n\t\t\tconsole.log (...args);\n\t\t}\n\t}\n\n\t/**\n\t * @static debug - Show a debugging log\n\t *\n\t * Logs will only be made if the level is set DEBUG or above\n\t *\n\t * @param {...any} args\n\t *\n\t * @return {void}\n\t */\n\tstatic debug (...args) {\n\t\tif (this.level () >= DebugLevel.DEBUG) {\n\t\t\tconsole.debug (...args);\n\t\t}\n\t}\n\n\t/**\n\t * @static info - Show an info log\n\t *\n\t * Logs will only be made if the level is set to INFO or above\n\t *\n\t * @param {...any} args\n\t *\n\t * @return {void}\n\t */\n\tstatic info (...args) {\n\t\tif (this.level () >= DebugLevel.INFO) {\n\t\t\tconsole.info (...args);\n\t\t}\n\t}\n\n\t/**\n\t * @static error - Show an error log\n\t *\n\t * Logs will only be made if the level is set to ERROR or above\n\t *\n\t * @param {...any} args\n\t *\n\t * @return {void}\n\t */\n\tstatic error (...args) {\n\t\tif (this.level () >= DebugLevel.ERROR) {\n\t\t\tconsole.error (...args);\n\t\t}\n\t}\n\n\t/**\n\t * @static warning - Show an warning log\n\t *\n\t * Logs will only be made if the level is set to WARNING or above\n\t *\n\t * @param {...any} args\n\t *\n\t * @return {void}\n\t */\n\tstatic warning (...args) {\n\t\tif (this.level () >= DebugLevel.WARNING) {\n\t\t\tconsole.warn (...args);\n\t\t}\n\t}\n\n\t/**\n\t * @static table - Show data as a table\n\t *\n\t * Table will only be made if the level is set to DEBUG or above\n\t *\n\t * @param {...any} args\n\t *\n\t * @return {void}\n\t */\n\tstatic table (...args) {\n\t\tif (this.level () >= DebugLevel.DEBUG) {\n\t\t\tconsole.table (...args);\n\t\t}\n\t}\n\n\t/**\n\t * @static group - Start an indented group\n\t *\n\t * @param {...any} args\n\t *\n\t * @return {void}\n\t */\n\tstatic group (...args) {\n\t\tif (this.level () >= DebugLevel.DEBUG) {\n\t\t\tconsole.group (...args);\n\t\t}\n\t}\n\n\t/**\n\t * @static groupCollapsed - Start an indented group collapsed by default\n\t *\n\t * @param {...any} args\n\t *\n\t * @return {void}\n\t */\n\tstatic groupCollapsed (...args) {\n\t\tif (this.level () >= DebugLevel.DEBUG) {\n\t\t\tconsole.groupCollapsed (...args);\n\t\t}\n\t}\n\n\t/**\n\t * @static groupEnd - End a previously started group\n\t *\n\t * @param {...any} args\n\t *\n\t * @return {void}\n\t */\n\tstatic groupEnd (...args) {\n\t\tif (this.level () >= DebugLevel.DEBUG) {\n\t\t\tconsole.groupEnd (...args);\n\t\t}\n\t}\n\n\t/**\n\t * @static time - Start a timer\n\t *\n\t * The timer will only start if the level is set to DEBUG or above\n\t *\n\t * @param {...any} args\n\t *\n\t * @return {void}\n\t */\n\tstatic time (...args) {\n\t\tif (this.level () >= DebugLevel.DEBUG) {\n\t\t\tconsole.time (...args);\n\t\t}\n\t}\n\n\t/**\n\t * @static timeLog - Log the time a timer has been running for\n\t *\n\t * The time will only be logged if the level is set to DEBUG or above\n\t *\n\t * @param {...any} args\n\t *\n\t * @return {void}\n\t */\n\tstatic timeLog (...args) {\n\t\tif (this.level () >= DebugLevel.DEBUG) {\n\t\t\tconsole.timeLog (...args);\n\t\t}\n\t}\n\n\t/**\n\t * @static timeEnd - End a timer\n\t *\n\t * The timer will only be available if the level is set to DEBUG or above\n\t *\n\t * @param {...any} args\n\t *\n\t * @return {void}\n\t */\n\tstatic timeEnd (...args) {\n\t\tif (this.level () >= DebugLevel.DEBUG) {\n\t\t\tconsole.timeEnd (...args);\n\t\t}\n\t}\n\n\t/**\n\t * @static trace - Show the stack trace\n\t *\n\t * The stack trace will only be available if the level is set to DEBUG or above\n\t *\n\t * @param {...any} args\n\t *\n\t * @return {void}\n\t */\n\tstatic trace (...args) {\n\t\tif (this.level () >= DebugLevel.DEBUG) {\n\t\t\tconsole.trace (...args);\n\t\t}\n\t}\n}\n\nDebug._level = DebugLevel.NONE;","/**\n * ==============================\n * DOM\n * ==============================\n */\n\n/**\n * Simple DOM manipulation functions\n *\n * @class\n */\nexport class DOM {\n\n\t/**\n\t * Create a new DOM object\n\t *\n\t * @constructor\n\t * @param {string|Object|array} selector - Selector or DOM element to use\n\t * @return {DOM} - New instance of DOM\n\t */\n\tconstructor (selector) {\n\t\tif (typeof selector == 'string') {\n\t\t\tthis.collection = document.querySelectorAll (selector);\n\t\t\tthis.length = this.collection.length;\n\t\t} else if (selector instanceof NodeList) {\n\t\t\tthis.collection = selector;\n\t\t\tthis.length = selector.length;\n\t\t} else if (typeof selector == 'object') {\n\t\t\tif (selector.length >= 1) {\n\t\t\t\tthis.collection = selector;\n\t\t\t} else {\n\t\t\t\tthis.collection = [selector];\n\t\t\t}\n\t\t\tthis.length = this.collection.length;\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Hide elements by setting their `display` property to 'none'.\n\t */\n\thide () {\n\t\tfor (const element of this.collection) {\n\t\t\telement.style.display = 'none';\n\t\t}\n\t}\n\n\t/**\n\t * Show elements by setting their `display` property to the given value.\n\t *\n\t * @param {string} [display='block'] - Display property to set\n\t */\n\tshow (display = 'block') {\n\t\tfor (const element of this.collection) {\n\t\t\telement.style.display = display;\n\t\t}\n\t}\n\n\t/**\n\t * Add a class to the classList object\n\t *\n\t * @param {string} newClass - Class name to add\n\t */\n\taddClass (newClass) {\n\t\tfor (const element of this.collection) {\n\t\t\telement.classList.add (newClass);\n\t\t}\n\t}\n\n\t/**\n\t * Remove a given class from the classList object\n\t *\n\t * @param {string} [oldClass=null] - Class to remove. If it's empty or null,\n\t * all classes will be removed\n\t */\n\tremoveClass (oldClass = null) {\n\t\tif (oldClass !== null) {\n\t\t\tfor (const element of this.collection) {\n\t\t\t\telement.classList.remove (oldClass);\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const element of this.collection) {\n\t\t\t\twhile (element.classList.length > 0) {\n\t\t\t\t\telement.classList.remove (element.classList.item (0));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Toggle between two classes\n\t *\n\t * @param {string} classes - Space separated class names\n\t */\n\ttoggleClass (classes) {\n\t\tclasses = classes.split (' ');\n\t\tfor (const element of this.collection) {\n\t\t\tfor (let j = 0; j < classes.length; j++) {\n\t\t\t\telement.classList.toggle (classes[j]);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Check if the first element matching the selector has the given class\n\t *\n\t * @param {string} classToCheck - Class name to check for\n\t * @return {boolean} - Whether the class is present or not\n\t */\n\thasClass (classToCheck) {\n\t\tfor (const element of this.collection) {\n\t\t\tif (!element.classList.contains (classToCheck)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Get or set the value from the first element matching the selector\n\t *\n\t * @param {string} value - Value to set to the element.\n\t * @return {string} - If no value was provided, this returns the value of the\n\t * element instead of setting it\n\t */\n\tvalue (value) {\n\t\tif (typeof value !== 'undefined') {\n\t\t\tfor (const element of this.collection) {\n\t\t\t\telement.value = value;\n\t\t\t}\n\t\t} else {\n\t\t\tif (this.collection[0]) {\n\t\t\t\treturn this.collection[0].value;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Focus on the first element matching the selector\n\t */\n\tfocus () {\n\t\tif (this.length > 0) {\n\t\t\tthis.collection[0].focus ();\n\t\t}\n\t}\n\n\t/**\n\t * Add a callback for the 'click' event on every element matching the selector\n\t *\n\t * @param {function} callback - Callback function to run when the event is triggered\n\t */\n\tclick (callback) {\n\t\tfor (const element of this.collection) {\n\t\t\telement.addEventListener ('click', callback, false);\n\t\t}\n\t}\n\n\t/**\n\t * Add a callback for the 'keyup' event on every element matching the selector\n\t *\n\t * @param {function} callback - Callback function to run when the event is triggered\n\t */\n\tkeyup (callback) {\n\t\tfor (const element of this.collection) {\n\t\t\telement.addEventListener ('keyup', callback, false);\n\t\t}\n\t}\n\n\t/**\n\t * Add a callback for the 'keydown' event on every element matching the selector\n\t *\n\t * @param {function} callback - Callback function to run when the event is triggered\n\t */\n\tkeydown (callback) {\n\t\tfor (const element of this.collection) {\n\t\t\telement.addEventListener ('keydown', callback, false);\n\t\t}\n\t}\n\n\t/**\n\t * Add a callback for the 'submit' event on every element matching the selector\n\t *\n\t * @param {function} callback - Callback function to run when the event is triggered\n\t */\n\tsubmit (callback) {\n\t\tfor (const element of this.collection) {\n\t\t\telement.addEventListener ('submit', callback, false);\n\t\t}\n\t}\n\n\t/**\n\t * Add a callback for the 'change' event on every element matching the selector\n\t *\n\t * @param {function} callback - Callback function to run when the event is triggered\n\t */\n\tchange (callback) {\n\t\tfor (const element of this.collection) {\n\t\t\telement.addEventListener ('change', callback, false);\n\t\t}\n\t}\n\n\t/**\n\t * Add a callback for the 'scroll' event on every element matching the selector\n\t *\n\t * @param {function} callback - Callback function to run when the event is triggered\n\t */\n\tscroll (callback) {\n\t\tfor (const element of this.collection) {\n\t\t\telement.addEventListener ('scroll', callback, false);\n\t\t}\n\t}\n\n\t/**\n\t * Add a callback function to a given event\n\t *\n\t * @param {string} event - Event to add the listener to\n\t * @param {string} target - Target element on which to detect the event\n\t * @param {function} callback - Callback function to run when the event is triggered\n\t */\n\ton (event, target, callback) {\n\t\tevent = event.split(' ');\n\t\tfor (const element of this.collection) {\n\t\t\tfor (let j = 0; j < event.length; j++) {\n\n\t\t\t\t// Check if no target was defined and just a function was provided\n\t\t\t\tif (typeof target === 'function') {\n\t\t\t\t\telement.addEventListener(event[j], target, false);\n\t\t\t\t} else if (typeof target === 'string' && typeof callback === 'function') {\n\t\t\t\t\telement.addEventListener(event[j], (e) => {\n\t\t\t\t\t\tif (e.target && $_(e.target).matches (target)) {\n\t\t\t\t\t\t\tcallback.call (e.target, e);\n\t\t\t\t\t\t}\n\t\t\t\t\t}, false);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Filter from the current collection to only those matching the new selector\n\t *\n\t * @param {string} element - Selector to filter the collection with\n\t * @return {DOM} - New DOM instance with the filtered collection\n\t */\n\tfilter (selector) {\n\t\tif (this.length > 0) {\n\t\t\treturn new DOM (this.collection[0].querySelector (selector));\n\t\t}\n\t}\n\n\t/**\n\t * Get or set a `data` property\n\t *\n\t * @param {string} name - Name of the data property\n\t * @param {string} [value] - Value of the property\n\t * @return {string} - If no value is set, this function returns it's current value\n\t */\n\tdata (name, value) {\n\t\tif (typeof value !== 'undefined') {\n\t\t\tfor (const element of this.collection) {\n\t\t\t\telement.dataset[name] = value;\n\t\t\t}\n\t\t} else {\n\t\t\tif (this.collection[0]) {\n\t\t\t\treturn this.collection[0].dataset[name];\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get or set the text of the first element matching the selector\n\t *\n\t * @param {string} [value] - Value to set the text to\n\t * @return {type} - If no value is present, this function returns its the\n\t * element's current text.\n\t */\n\ttext (value) {\n\t\tif (typeof value !== 'undefined') {\n\t\t\tfor (const element of this.collection) {\n\t\t\t\telement.textContent = value;\n\t\t\t}\n\t\t} else {\n\t\t\tif (this.collection[0]) {\n\t\t\t\treturn this.collection[0].textContent;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get or set the inner HTML of the first element matching the selector\n\t *\n\t * @param {string} [value] - Value to set the HTML to\n\t * @return {type} - If no value is present, this function returns its the\n\t * element's current HTML.\n\t */\n\thtml (value) {\n\t\tif (typeof value !== 'undefined') {\n\t\t\tfor (const element of this.collection) {\n\t\t\t\telement.innerHTML = value;\n\t\t\t}\n\t\t} else {\n\t\t\tif (this.collection[0]) {\n\t\t\t\treturn this.collection[0].innerHTML;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Append an element to the first element matching the selector\n\t *\n\t * @param {string} element - String representation of the element to add\n\t */\n\tappend (element) {\n\t\tif (this.length > 0) {\n\t\t\tif (typeof element === 'string') {\n\t\t\t\tconst div = document.createElement ('div');\n\t\t\t\tif (typeof element === 'string') {\n\t\t\t\t\tdiv.innerHTML = element.trim ();\n\t\t\t\t} else {\n\t\t\t\t\tdiv.innerHTML = element;\n\t\t\t\t}\n\t\t\t\tthis.collection[0].appendChild (div.firstChild);\n\t\t\t} else {\n\t\t\t\tthis.collection[0].appendChild (element);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Prepend an element to the first element matching the selector\n\t *\n\t * @param {string} element - String representation of the element to add\n\t */\n\tprepend (element) {\n\t\tif (this.length > 0) {\n\t\t\tif (typeof element === 'string') {\n\t\t\t\tconst div = document.createElement ('div');\n\t\t\t\tif (typeof element === 'string') {\n\t\t\t\t\tdiv.innerHTML = element.trim ();\n\t\t\t\t} else {\n\t\t\t\t\tdiv.innerHTML = element;\n\t\t\t\t}\n\t\t\t\tif (this.collection[0].childNodes.length > 0) {\n\t\t\t\t\tthis.collection[0].insertBefore (div.firstChild, this.collection[0].childNodes[0]);\n\t\t\t\t} else {\n\t\t\t\t\tthis.collection[0].appendChild (div.firstChild);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (this.collection[0].childNodes.length > 0) {\n\t\t\t\t\tthis.collection[0].insertBefore (element, this.collection[0].childNodes[0]);\n\t\t\t\t} else {\n\t\t\t\t\tthis.collection[0].appendChild (element);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Iterate over the collection of elements matching the selector\n\t *\n\t * @param {function} callback - Callback to run for every element\n\t */\n\teach (callback) {\n\t\tfor (const element of this.collection) {\n\t\t\tcallback (element);\n\t\t}\n\t}\n\n\t/**\n\t * Get an element from the collection given it's index\n\t *\n\t * @param {int} index - Index of the element to retrieve\n\t * @return {HTMLElement} - HTML Element in the position indicated by the index\n\t */\n\tget (index) {\n\t\treturn this.collection[index];\n\t}\n\n\t/**\n\t * Get the first element in the collection\n\t *\n\t * @return {DOM} - DOM instance with the first element\n\t */\n\tfirst () {\n\t\tif (this.length > 0) {\n\t\t\treturn new DOM (this.collection[0]);\n\t\t}\n\t}\n\n\t/**\n\t * Get the last element in the collection\n\t *\n\t * @return {DOM} - DOM instance with the last element\n\t */\n\tlast () {\n\t\tif (this.length > 0) {\n\t\t\treturn new DOM (this.collection[this.collection.length - 1]);\n\t\t}\n\t}\n\n\t/**\n\t * Check if the elements in the collection are visible by checking their\n\t * display, offsetWidth and offsetHeight properties\n\t *\n\t * @return {boolean} - Whether the elements are visible or not\n\t */\n\tisVisible () {\n\t\tfor (const element of this.collection) {\n\t\t\tif (element.display != 'none' && element.offsetWidth > 0 && element.offsetHeight > 0) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Get the parent of the first element matching the selector\n\t *\n\t * @return {DOM} - DOM instance of the parent element\n\t */\n\tparent () {\n\t\tif (this.collection[0]) {\n\t\t\treturn new DOM (this.collection[0].parentElement);\n\t\t}\n\t}\n\n\t/**\n\t * Find an element that matches the given selector in the first element of the collection\n\t *\n\t * @param {string} selector - Selector to find the element with\n\t * @return {DOM} - Aegis instance with the element if found\n\t */\n\tfind (selector) {\n\t\tif (this.collection[0]) {\n\t\t\treturn new DOM (this.collection[0].querySelectorAll (selector));\n\t\t}\n\t}\n\n\t/**\n\t * Get the top and left offsets of the first element matching the selector\n\t *\n\t * @return {Object} - Object with `top` and `left` offsets\n\t */\n\toffset () {\n\t\tif (this.collection[0]) {\n\t\t\tconst rect = this.collection[0].getBoundingClientRect ();\n\t\t\treturn {\n\t\t\t\ttop: rect.top + document.body.scrollTop,\n\t\t\t\tleft: rect.left + document.body.scrollLeft\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Find the closest element matching the given selector. This bubbles up\n\t * from the initial object and then follows to its parents.\n\t *\n\t * @param {string} selector - Selector to match the closest element with\n\t * @return {DOM} - DOM instance with the closest HTML element matching the selector\n\t */\n\tclosest (selector) {\n\t\tlet found = null;\n\t\tlet element = this;\n\t\twhile (typeof element.get (0) !== 'undefined' && found === null) {\n\t\t\t// Check if the current element matches the selector\n\t\t\tconst matches = element.matches (selector);\n\n\t\t\tif (matches === true) {\n\t\t\t\treturn element;\n\t\t\t}\n\n\t\t\tconst search = element.find (selector);\n\t\t\tif (search.length > 0) {\n\t\t\t\tfound = search;\n\t\t\t}\n\t\t\telement = element.parent ();\n\t\t}\n\n\t\tif (found !== null) {\n\t\t\treturn found;\n\t\t}\n\n\t\treturn element;\n\t}\n\n\t/**\n\t * Get or set the value of a given attribute\n\t *\n\t * @param {string} attribute - Attribute's name\n\t * @param {string|Number} [value] - Value to set the attribute to\n\t * @return {type} - If no value is provided, this function returns the current\n\t * value of the provided attribute\n\t */\n\tattribute (attribute, value) {\n\t\tif (typeof value !== 'undefined') {\n\t\t\tfor (const element of this.collection) {\n\t\t\t\telement.setAttribute (attribute, value);\n\t\t\t}\n\t\t} else {\n\t\t\tif (this.collection[0]) {\n\t\t\t\treturn this.collection[0].getAttribute (attribute);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Check whether an element has an attribute or not\n\t *\n\t * @param {string} attribute - The name of the attribute to check existance for\n\t * @returns {boolean} - Whether or not the attribute is present\n\t */\n\thasAttribute (attribute) {\n\t\tfor (const element of this.collection) {\n\t\t\tif (!element.hasAttribute (attribute)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Insert content to the `after` property of an element\n\t *\n\t * @param {string} content - String representation of the content to add\n\t */\n\tafter (content) {\n\t\tfor (const element of this.collection) {\n\t\t\telement.insertAdjacentHTML ('afterend', content);\n\t\t}\n\t}\n\n\t/**\n\t * Insert content to the `before` property of an element\n\t *\n\t * @param {string} content - String representation of the content to add\n\t */\n\tbefore (content) {\n\t\tfor (const element of this.collection) {\n\t\t\telement.insertAdjacentHTML ('beforebegin', content);\n\t\t}\n\t}\n\n\t/**\n\t * Get or modify the `style` properties of the elements matching the selector\n\t *\n\t * @param {string|Object} properties - Properties to change or get. Can be\n\t * either an individual property or a JSON object with key-value pairs\n\t * @param {string} [value] - Value to set the property to when only changing\n\t * one property\n\t * @return {string} - If a property is given but not a value for it, this\n\t * function will return its current value\n\t */\n\tstyle (properties, value) {\n\t\tfor (let i = 0; i < this.collection.length; i++) {\n\t\t\tif (typeof properties === 'string' && value !== 'undefined') {\n\t\t\t\tthis.collection[i].style[properties] = value;\n\t\t\t} else if (typeof properties === 'string' && value === 'undefined') {\n\t\t\t\treturn this.collection[i].style[properties];\n\t\t\t} else if (typeof properties === 'object') {\n\t\t\t\tfor (const property in properties) {\n\t\t\t\t\tthis.collection[i].style[property] = properties[property];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Animate the given `style` properties on all elements in the collection in\n\t * with a given time duration\n\t *\n\t * @param {Object} style - JSON object with the key-value pairs of properties\n\t * to animate\n\t * @param {int} time - Time in milliseconds during which the properties will\n\t * be animated\n\t */\n\tanimate (style, time) {\n\t\tfor (let i = 0; i < this.collection.length; i++) {\n\t\t\tfor (const property in style) {\n\n\t\t\t\tconst start = new Date().getTime();\n\t\t\t\tconst collection = this.collection;\n\t\t\t\tlet timer;\n\t\t\t\tlet initialValue;\n\t\t\t\tif (typeof this.collection[i].style[property] !== 'undefined') {\n\t\t\t\t\tinitialValue = this.collection[i].style[property];\n\n\t\t\t\t\ttimer = setInterval (() => {\n\t\t\t\t\t\tconst step = Math.min (1, (new Date ().getTime () - start) / time);\n\n\t\t\t\t\t\tcollection[i].style[property] = (initialValue + step * (style[property] - initialValue));\n\n\t\t\t\t\t\tif (step == 1) {\n\t\t\t\t\t\t\tclearInterval (timer);\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 25);\n\t\t\t\t\tthis.collection[i].style[property] = initialValue;\n\n\t\t\t\t} else if (typeof (this.collection[i])[property] !== 'undefined') {\n\t\t\t\t\tinitialValue = (this.collection[i])[property];\n\n\t\t\t\t\ttimer = setInterval(() => {\n\t\t\t\t\t\tconst step = Math.min (1, (new Date ().getTime () - start) / time);\n\n\t\t\t\t\t\t(collection[i])[property] = (initialValue + step * (style[property] - initialValue));\n\n\t\t\t\t\t\tif (step == 1) {\n\t\t\t\t\t\t\tclearInterval (timer);\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 25);\n\t\t\t\t\t(this.collection[i])[property] = initialValue;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Use a fade in animation i the first element matching the selector\n\t *\n\t * @param {type} [time=400] - Time duration for the animation\n\t * @param {type} callback - Callback function to run once the animation is over\n\t */\n\tfadeIn (time = 400, callback) {\n\t\tif (this.collection[0]) {\n\t\t\tconst element = this.collection[0];\n\t\t\telement.style.opacity = 0;\n\n\t\t\tlet last = +new Date();\n\n\t\t\tconst tick = () => {\n\t\t\t\telement.style.opacity = +element.style.opacity + (new Date() - last) / time;\n\t\t\t\tlast = +new Date();\n\n\t\t\t\tif (+element.style.opacity < 1) {\n\t\t\t\t\t(window.requestAnimationFrame && requestAnimationFrame(tick)) || setTimeout(tick, 16);\n\t\t\t\t} else {\n\t\t\t\t\tif (typeof callback === 'function') {\n\t\t\t\t\t\tcallback();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\ttick();\n\t\t}\n\t}\n\n\t/**\n\t * Use a fade out animation i the first element matching the selector\n\t *\n\t * @param {type} [time=400] - Time duration for the animation\n\t * @param {type} callback - Callback function to run once the animation is over\n\t */\n\tfadeOut (time = 400, callback) {\n\t\tif (this.collection[0]) {\n\t\t\tlet last = +new Date ();\n\t\t\tconst element = this.collection[0];\n\t\t\tconst tick = () => {\n\t\t\t\telement.style.opacity = +element.style.opacity - (new Date() - last) / time;\n\t\t\t\tlast = +new Date ();\n\n\t\t\t\tif (+element.style.opacity > 0) {\n\t\t\t\t\t(window.requestAnimationFrame && requestAnimationFrame (tick)) || setTimeout(tick, 16);\n\t\t\t\t} else {\n\t\t\t\t\tif (typeof callback === 'function') {\n\t\t\t\t\t\tcallback ();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t\ttick ();\n\t\t}\n\t}\n\n\t/**\tCheck if the first element in the collection matches a given selector\n\t *\n\t * @param {string} selector - Selector to match\n\t * @return {boolean} - Whether the element matches the selector or not\n\t */\n\tmatches (selector) {\n\t\tconst check = Element.prototype;\n\t\tconst polyfill = check.matches || check.webkitMatchesSelector || check.mozMatchesSelector || check.msMatchesSelector || function () {\n\t\t\treturn [].indexOf.call (document.querySelectorAll (selector), this) !== -1;\n\t\t};\n\t\treturn polyfill.call (this.collection[0], selector);\n\t}\n\n\t/**\n\t * Remove all elements in the collection\n\t */\n\tremove () {\n\t\tfor (const element of this.collection) {\n\t\t\telement.parentNode.removeChild (element);\n\t\t}\n\t}\n\n\t/**\n\t * Replace the first element in the collection with a new one\n\t */\n\treplaceWith (newElement) {\n\t\tlet replaceElement = newElement;\n\n\t\tif (typeof newElement === 'string') {\n\t\t\tconst div = document.createElement ('div');\n\t\t\tdiv.innerHTML = newElement;\n\t\t\treplaceElement = div.firstChild;\n\t\t}\n\n\t\tfor (const element of this.collection) {\n\t\t\telement.parentElement.replaceChild (replaceElement, element);\n\t\t}\n\t}\n\n\t/**\n\t * Reset every element in the collection\n\t */\n\treset () {\n\t\tfor (const element of this.collection) {\n\t\t\telement.reset ();\n\t\t}\n\t}\n\n\t/**\n\t * Get or set a property for the first element in the collection\n\t *\n\t * @param {string} property - Property name to set or get\n\t * @param {string|Number} [value] - Value to set the property to\n\t * @return {string|Number} - If no value is provided, this function will return the\n\t * current value of the indicated property\n\t */\n\tproperty (property, value) {\n\t\tif (typeof value !== 'undefined') {\n\t\t\tfor (const element of this.collection) {\n\t\t\t\telement[property] = value;\n\t\t\t}\n\t\t} else {\n\t\t\tif (this.collection[0]) {\n\t\t\t\treturn this.collection[0][property];\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Simple wrapper function to use the DOM library\n *\n * @param {string|Object|array} selector - Selector or DOM element to use\n * @return {DOM} - DOM instance or class if no selector is used\n */\nexport function $_ (selector) {\n\tif (typeof selector !== 'undefined') {\n\t\treturn new DOM (selector);\n\t} else {\n\t\treturn DOM;\n\t}\n}\n\n/**\n * Utility function to attach the 'load' listener to the window\n *\n * @param {function} callback - Callback function to run when the window is ready\n */\nexport function $_ready (callback) {\n\twindow.addEventListener ('load', callback);\n}","/**\n* ==============================\n* Request\n* ==============================\n*/\n\n/**\n * Simple Wrapper for the fetch API, providing simple functions to handle requests\n *\n * @class\n */\nexport class Request {\n\n\t/**\n\t * @static serialize - Serialize an object of data into a URI encoded format\n\t *\n\t * @param {Object} data - Key-value object of data to serialize\n\t * @return {string} - Serialized Data\n\t */\n\tstatic serialize (data) {\n\t\treturn Object.keys (data).map ((key) => {\n\t\t\treturn encodeURIComponent (key) + '=' + encodeURIComponent (data[key]);\n\t\t}).join ('&');\n\t}\n\n\t/**\n\t * @static get - Make a GET request to a given URL with the provided data\n\t * parameters and an optional configuration object for the request.\n\t *\n\t * @param {string} url - URL to make the request to\n\t * @param {Object} [data = {}] - Parameters to send in the URL, represented\n\t * as a JSON object. These parameters will be sent as a query in the URL\n\t * @param {Object} [options = {}] - Options object for configurations you want\n\t * to use in the fetch () request made.\n\t * @return {Promise<Response>} - Resolves to the response of the request\n\t */\n\tstatic get (url, data = {}, options = {}) {\n\t\tconst query = Request.serialize (data);\n\n\t\t// Check if there is actually any data parameters and join them to the\n\t\t// url as query parameters\n\t\tif (query !== '') {\n\t\t\turl = `${url}?${query}`;\n\t\t}\n\n\t\treturn fetch (url, options);\n\t}\n\n\t/**\n\t * @static post - Make a POST request to a given URL with the provided data\n\t * and an optional configuration object for the request.\n\t *\n\t * @param {string} url - URL to make the request\n\t * @param {Object} [data = {}] - Set of data to send in the URL, represented\n\t * as a JSON object\n \t * @param {Object} [options = {}] - Options object for configurations you want\n\t * to use in the fetch () request made. The Content-Type header is used to\n\t * serialize data in the correct format and defaults to application/x-www-form-urlencoded\n\t * @return {Promise<Response>} - Resolves to the response of the request\n\t */\n\tstatic post (url, data, options = {}) {\n\t\tlet formData;\n\n\t\tif (typeof options.headers !== 'undefined') {\n\t\t\tconst contentType = options.headers['Content-Type'];\n\t\t\tif (typeof contentType !== 'undefined') {\n\t\t\t\tif (contentType == 'multipart/form-data') {\n\t\t\t\t\tformData = new FormData ();\n\t\t\t\t\tfor (const value in data) {\n\t\t\t\t\t\tformData.append (value, data[value]);\n\t\t\t\t\t}\n\t\t\t\t} else if (contentType == 'application/json') {\n\t\t\t\t\tformData = JSON.stringify (data);\n\t\t\t\t} else {\n\t\t\t\t\tformData = Request.serialize (data);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tformData = Request.serialize (data);\n\t\t}\n\n\t\tconst props = Object.assign ({}, {\n\t\t\tmethod: 'POST',\n\t\t\theaders: {\n\t\t\t\t'Content-Type': 'application/x-www-form-urlencoded'\n\t\t\t},\n\t\t\tbody: formData\n\t\t}, options);\n\n\t\t// Delete the explicit multipart/form-data header to allow boundary automatic filling\n\t\tif (typeof props.headers !== 'undefined') {\n\t\t\tif (props.headers['Content-Type'] === 'multipart/form-data') {\n\t\t\t\tdelete props.headers['Content-Type'];\n\t\t\t}\n\t\t}\n\n\t\treturn fetch (url, props);\n\t}\n\n\t/**\n\t * @static put - Make a PUT request to a given URL with the provided data\n\t * and an optional configuration object for the request.\n\t *\n\t * @param {string} url - URL to make the request\n\t * @param {Object} [data = {}] - Set of data to send in the URL, represented\n\t * as a JSON object\n \t * @param {Object} [options = {}] - Options object for configurations you want\n\t * to use in the fetch () request made. The Content-Type header is used to\n\t * serialize data in the correct format and defaults to application/x-www-form-urlencoded\n\t * @return {Promise<Response>} - Resolves to the response of the request\n\t */\n\tstatic put (url, data, options = {}) {\n\t\treturn Request.post (url, data, Object.assign ({}, {method: 'PUT'}, options));\n\t}\n\n\t/**\n\t * @static delete - Make a DELETE request to a given URL with the provided data\n\t * and an optional configuration object for the request.\n\t *\n\t * @param {string} url - URL to make the request\n\t * @param {Object} [data = {}] - Parameters to send in the URL, represented\n\t * as a JSON object. These parameters will be sent as a query in the URL\n \t * @param {Object} [options = {}] - Options object for configurations you want\n\t * to use in the fetch () request made. The Content-Type header is used to\n\t * serialize data in the correct format and defaults to application/x-www-form-urlencoded\n\t * @return {Promise<Response>} - Resolves to the response of the request\n\t */\n\tstatic delete (url, data, options = {}) {\n\t\treturn Request.get (url, data, Object.assign ({}, {method: 'DELETE'}, options));\n\t}\n\n\t/**\n \t * @static json - Request a JSON object from a given URL through a GET request\n \t *\n \t * @param {string} url - URL to make the request to\n \t * @param {Object} [data = {}] - Parameters to send in the URL, represented\n \t * as a JSON object. These parameters will be sent as a query in the URL\n \t * @param {Object} [options = {}] - Options object for configurations you want\n \t * to use in the fetch () request made.\n \t * @return {Promise<Object>} - Resolves to the json object obtained from the request response\n \t */\n\tstatic json (url, data = {}, options = {}) {\n\t\treturn Request.get (url, data, options).then ((response) => {\n\t\t\treturn response.json ();\n\t\t});\n\t}\n\n\t/**\n \t * @static blob - Request a Blob from a given URL through a GET request\n \t *\n \t * @param {string} url - URL to make the request to\n \t * @param {Object} [data = {}] - Parameters to send in the URL, represented\n \t * as a JSON object. These parameters will be sent as a query in the URL\n \t * @param {Object} [options = {}] - Options object for configurations you want\n \t * to use in the fetch () request made.\n \t * @return {Promise<Blob>} - Resolves to the blob obtained from the request response\n \t */\n\tstatic blob (url, data = {}, options = {}) {\n\t\treturn Request.get (url, data, options).then ((response) => {\n\t\t\treturn response.blob ();\n\t\t});\n\t}\n}","/**\n * ==============================\n * File System\n * ==============================\n */\n\nimport { Request } from './Request';\n\n/**\n * A simple class wrapper for the File and FileReader web API, while this class\n * doesn't actually provide acces to the host file system, it does provide useful\n * utilities for form file inputs and remote content loading.\n *\n * @class\n */\nexport class FileSystem {\n\n\n\t/**\n\t * @static readRemote - Read a file from a remote location given a URL. This\n\t * function will fetch the file blob using the Request class and then use the\n\t * read () function to read the blob in the format required.\n\t *\n\t * @param {type} url - URL to fetch the file from\n\t * @param {type} [type = 'base64'] - Type of data to be read, values can be\n\t * 'text', 'base64' and 'buffer'. This parameter is used for the read () function.\n\t * @param {Object} [props = {}] - Props to send to the Request object\n\t * @return {Promise<ArrayBuffer|string>} - Content of the file. The format\n\t * depends on the type parameter used.\n\t */\n\tstatic readRemote (url, type = 'base64', props = {}) {\n\t\treturn Request.blob (url, {}, props).then ((file) => {\n\t\t\treturn FileSystem.read (file, type);\n\t\t});\n\t}\n\n\t/**\n\t * @static read - Read a given File or Blob object.\n\t *\n\t * @param {File|Blob} file - File to read\n\t * @param {string} [type = 'text'] - Type of data to be read, values can be\n\t * 'text', 'base64' and 'buffer'.\n\t * @return {Promise<Event, ArrayBuffer|string>} - Promise that resolves to\n\t * the Load event and content of the file. The format depends on the type\n\t * parameter used.\n\t */\n\tstatic read (file, type = 'text') {\n\t\treturn new Promise ((resolve, reject) => {\n\t\t\tconst reader = new FileReader ();\n\n\t\t\treader.onload = (event) => {\n\t\t\t\t// Pass down the event object and the content\n\t\t\t\tresolve (event, event.target.result);\n\t\t\t};\n\n\t\t\treader.onerror = (error) => {\n\t\t\t\treject (error);\n\t\t\t};\n\n\t\t\tif (type === 'base64') {\n\t\t\t\treader.readAsDataURL (file);\n\t\t\t} else if (type === 'buffer') {\n\t\t\t\treader.readAsArrayBuffer (file);\n\t\t\t} else {\n\t\t\t\treader.readAsText (file, 'UTF-8');\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * @static create - Create a new File, this uses the File API and will note\n\t * actually create a file in the user's file system, however using it with\n\t * other features, that may be possible\n\t *\n\t * @param {string} file - Name of the file (Including extension)\n\t * @param {ArrayBuffer|ArrayBufferView|Blob|string} content - Content to save in the file\n\t * @param {string} [type = 'text/plain'] - Mime Type for the file\n\t * @return {Promise<File>}\n\t */\n\tstatic create (name, content, type = 'text/plain') {\n\t\treturn Promise.resolve (new File ([content], name, {type}));\n\t}\n\n\t/**\n\t * @static extension - Returns the extension of a file given its file name.\n\t *\n\t * @param {string} name - Name or full path of the file\n\t * @return {string} - File extension without the leading dot (.)\n\t */\n\tstatic extension (name) {\n\t\treturn name.split ('.').pop ();\n\t}\n\n\t/**\n\t * @static isImage - Check if a file is an image by its extension.\n\t *\n\t * @param {string} name - Name or full path of the file\n\t * @return {boolean}\n\t */\n\tstatic isImage (name) {\n\t\tconst extensions = ['jpg', 'jpeg', 'png', 'gif', 'svg', 'webp', 'bmp'];\n\t\treturn extensions.indexOf (FileSystem.extension (name).toLowerCase ()) > -1;\n\t}\n\n}","/**\n* ==============================\n* Form\n* ==============================\n*/\n\nimport { $_ } from './DOM';\n\n/**\n * Utility class that provides simple function for filling and retrieving values\n * from froms. This class requires the use of the `data-form` attribute.\n *\n * @class\n */\nexport class Form {\n\n\t/**\n\t * @static fill - Fill a form's inputs with the given values. Each key in the\n\t * provided object must match the `name` attribute of the input to fill.\n\t *\n\t * @param {string} name - Form name. Must match the `data-form` attribute of the Form.\n\t * @param {Object} data - JSON object with key-value pairs to fill the inputs.\n\t */\n\tstatic fill (name, data) {\n\t\tfor (const field in data) {\n\t\t\tconst element = $_(`form[data-form='${name}'] [name='${field}']`).get (0);\n\t\t\tif (typeof element != 'undefined') {\n\t\t\t\tswitch (element.type) {\n\n\t\t\t\t\tcase 'file':\n\t\t\t\t\tcase 'file[]':\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\telement.value = data[field];\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t}\n\n\t/**\n\t * @static values - Get all the values from a form's input. The keys are mapped\n\t * using the `name` attribute of each input.\n\t *\n\t * @param {string} name - Form name. Must match the `data-form` attribute of the Form.\n\t * @return {Object} - Key-value JSON object\n\t */\n\tstatic values (name) {\n\t\tconst data = {};\n\t\t$_(`form[data-form='${name}'] [name]`).each ((element) => {\n\t\t\tlet value;\n\t\t\tswitch (element.type) {\n\t\t\t\tcase 'file[]':\n\t\t\t\t\tvalue = element.files;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'file':\n\t\t\t\t\tvalue = element.files[0];\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tvalue = element.value;\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (typeof value != 'undefined' && value !== null) {\n\t\t\t\tdata[element.name] = value;\n\t\t\t}\n\t\t});\n\n\t\treturn data;\n\t}\n}","/**\n* ==============================\n* Platform\n* ==============================\n*/\n\n/**\n * General checks for what kind of platform is the being used to run the app.\n * @class\n */\nexport class Platform {\n\n\t/**\n\t * Check if the screen has a retina pixel ratio\n\t * @returns {boolean}\n\t */\n\tstatic retina () {\n\t\treturn window.devicePixelRatio >= 2;\n\t}\n\n\t/**\n\t * Check if the device is on portrait orientation\n\t * @returns {boolean}\n\t */\n\tstatic portrait () {\n\t\treturn window.orientation === 0 || window.orientation === 180;\n\t}\n\n\t/**\n\t * Check if the device is on landscape orientation\n\t * @returns {boolean}\n\t */\n\tstatic landscape () {\n\t\treturn (window.orientation === 90 || window.orientation === -90);\n\t}\n\n\t/**\n\t * Get device Orientation\n\t * @returns {string} portrait | landscape\n\t */\n\tstatic orientation () {\n\t\treturn Platform.portrait () ? 'portrait' : 'landscape';\n\t}\n\n\t/**\n\t * Check if the app is running over Electron\n\t * @returns {boolean}\n\t */\n\tstatic electron () {\n\t\treturn window && window.process && window.process.type;\n\t}\n\n\t/**\n\t * Check if the app is running over Cordova\n\t * @returns {boolean}\n\t */\n\tstatic cordova () {\n\t\treturn !!window.cordova;\n\t}\n\n\t/**\n\t * Check if the app is running in a desktop platform\n\t * @returns {boolean}\n\t */\n\tstatic desktop (platform = 'Any') {\n\t\tlet match = false;\n\t\tswitch (platform) {\n\t\t\tcase 'Windows':\n\t\t\t\tmatch = navigator.platform.includes ('Win');\n\t\t\t\tbreak;\n\n\t\t\tcase 'macOS':\n\t\t\t\tmatch = navigator.platform.includes ('Mac');\n\t\t\t\tbreak;\n\n\t\t\tcase 'Linux':\n\t\t\t\tmatch = navigator.platform.includes ('Linux');\n\t\t\t\tbreak;\n\n\t\t\tcase 'FreeBSD':\n\t\t\t\tmatch = navigator.platform.includes ('FreeBSD');\n\t\t\t\tbreak;\n\n\t\t\tcase 'webOS':\n\t\t\t\tmatch = navigator.platform.includes ('WebTV');\n\t\t\t\tbreak;\n\n\t\t\tcase 'Any':\n\t\t\tdefault:\n\t\t\t\tmatch = navigator.platform.includes ('Win')\n\t\t\t\t\t\t|| navigator.platform.includes ('Mac')\n\t\t\t\t\t\t|| navigator.platform.includes ('Linux')\n\t\t\t\t\t\t|| navigator.platform.includes ('FreeBSD')\n\t\t\t\t\t\t|| navigator.platform.includes ('WebTV');\n\t\t\t\tbreak;\n\t\t}\n\t\treturn match;\n\t}\n\n\t/**\n\t * Check if the app is running in a mobile platform\n\t * @param {string } [platform='Any'] - Check for a specific mobile platform [Android | iOS | Opera | Windows | BlackBerry | Any]\n\t * @returns {boolean}\n\t */\n\tstatic mobile (platform = 'Any') {\n\t\tlet match = false;\n\t\tswitch (platform) {\n\t\t\tcase 'Android':\n\t\t\t\tmatch = /Android/i.test (navigator.userAgent);\n\t\t\t\tbreak;\n\n\t\t\tcase 'iOS':\n\t\t\t\tmatch = /iPhone|iPad|iPod/i.test (navigator.userAgent);\n\t\t\t\tbreak;\n\n\t\t\tcase 'Opera':\n\t\t\t\tmatch = /Opera Mini/i.test (navigator.userAgent);\n\t\t\t\tbreak;\n\n\t\t\tcase 'Windows':\n\t\t\t\tmatch = /Windows Phone|IEMobile|WPDesktop/i.test (navigator.userAgent);\n\t\t\t\tbreak;\n\n\t\t\tcase 'BlackBerry':\n\t\t\t\tmatch = /BlackBerry|BB10/i.test (navigator.userAgent);\n\t\t\t\tbreak;\n\n\t\t\tcase 'Any':\n\t\t\tdefault:\n\t\t\t\tmatch = /Android|iPhone|iPad|iPod|Windows Phone|IEMobile|WPDesktop|BlackBerry|BB10/i.test (navigator.userAgent);\n\t\t\t\tbreak;\n\t\t}\n\t\treturn match;\n\t}\n\n\t/**\n\t * @static serviceWorkers - Check if the platform allows the use of service\n\t * workers\n\t *\n\t * @return {boolean} - Whether they're supported or not\n\t */\n\tstatic serviceWorkers () {\n\t\tif (typeof navigator !== 'undefined') {\n\t\t\tif ('serviceWorker' in navigator && location.protocol.indexOf ('http') > -1) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n}","/**\n * ==============================\n * Preload\n * ==============================\n */\n\nimport { Request } from './Request';\n\n/**\n * A simple class for asset preloading. This class assumes you have a service\n * worker set up that will be caching all requests.\n * @class\n */\nexport class Preload {\n\n\t/**\n\t * @static image - Preload an image file\n\t *\n\t * @param {string} route - Route to the image\n\t * @return {Promise} - Resolves to the image object or gets rejected with\n\t * the rejection event\n\t */\n\tstatic image (route) {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst image = new Image ();\n\n\t\t\timage.onload = () => {\n\t\t\t\tresolve (image);\n\t\t\t};\n\n\t\t\timage.onerror = (e) => {\n\t\t\t\treject (e);\n\t\t\t};\n\n\t\t\timage.src = route;\n\t\t});\n\t}\n\n\t/**\n\t * @static file - Preload any kind of file\n\t *\n\t * @param {string} route - Route to the file\n\t * @return {Promise} - Resolves or rejects depending on request success\n\t */\n\tstatic file (route) {\n\t\treturn Request.blob (route);\n\t}\n}","/**\n* ==============================\n* Local Storage Adapter\n* ==============================\n*/\n\n/**\n * The Local Storage Adapter provides the Space Class the ability to interact\n * with the localStorage api found in most modern browsers.\n *\n * @class\n */\nexport class LocalStorage {\n\n\t/**\n\t * Create a new LocalStorage. If no configuration is provided, the LocalStorage\n\t * global object is used. The LocalStorage Adapter can provide independency\n\t * by store name and space name.\n\t *\n\t * @constructor\n\t * @param {Object} [configuration={name = '', version = '', store = ''}] - Configuration Object for the Adapter\n\t * @param {string} configuration.name - Name of the Space\n\t * @param {string} configuration.version - Version of the Space in Semantic versioning syntax\n\t * @param {string} configuration.store - Name of the Object Store to use\n\t *\n\t */\n\tconstructor ({name = '', version = '', store = ''}) {\n\t\tthis.name = name;\n\t\tthis.version = version;\n\t\tthis.store = store;\n\n\t\tthis.upgrades = {};\n\n\t\tif (this.version === '') {\n\t\t\tthis.numericVersion = 0;\n\t\t} else {\n\t\t\tthis.numericVersion = parseInt (version.replace (/\\./g, ''));\n\t\t}\n\n\t\tif (name !== '' && version !== '' && store !== '') {\n\t\t\tthis.id = `${this.name}::${this.store}::${this.version}_`;\n\t\t} else if (name !== '' && version !== '') {\n\t\t\tthis.id = `${this.name}::${this.version}_`;\n\t\t} else if (name !== '') {\n\t\t\tthis.id = `${this.name}::_`;\n\t\t} else {\n\t\t\tthis.id = '';\n\t\t}\n\t}\n\n\t/**\n\t * Open the Storage Object\n\t *\n\t * @return {Promise}\n\t */\n\topen () {\n\t\tif (typeof this.storage === 'object' && !(this.storage instanceof Promise)) {\n\t\t\treturn Promise.resolve (this);\n\t\t} else if (this.storage instanceof Promise) {\n\t\t\treturn this.storage;\n\t\t} else {\n\t\t\tthis.storage = new Promise ((resolve) => {\n\t\t\t\tlet upgradesToApply = [];\n\n\t\t\t\t// Check if this space is versioned\n\t\t\t\tif (this.version !== '') {\n\t\t\t\t\t// Get the versionless part of the ID to check if an upgrade needs\n\t\t\t\t\t// to ocurr based on the version available on storage and the current\n\t\t\t\t\t// version.\n\t\t\t\t\tlet versionless = '';\n\t\t\t\t\tif (this.name !== '' && this.version !== '' && this.store !== '') {\n\t\t\t\t\t\tversionless = `${this.name}::${this.store}::`;\n\t\t\t\t\t} else if (this.name !== '' && this.version !== '') {\n\t\t\t\t\t\tversionless = `${this.name}::`;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Get all the currently stored keys that contain the versionless\n\t\t\t\t\t// ID, which means they belong to this space\n\t\t\t\t\tconst storedVersions = Object.keys (window.localStorage).filter ((key) => {\n\t\t\t\t\t\treturn key.indexOf (versionless) === 0;\n\t\t\t\t\t}).map ((key) => {\n\t\t\t\t\t\t// Remove the versionless part of the ID and keep only the\n\t\t\t\t\t\t// part of the key belonging to the ID\n\t\t\t\t\t\treturn key.replace (versionless, '').split ('_')[0];\n\t\t\t\t\t}). filter ((key) => {\n\t\t\t\t\t\t// Filter all that didn't match the versionless part fully\n\t\t\t\t\t\treturn key.indexOf ('::') === -1;\n\t\t\t\t\t}).sort ();\n\n\t\t\t\t\tif (storedVersions.length > 0) {\n\t\t\t\t\t\t// We'll only take the lowest one every time\n\t\t\t\t\t\tconst oldVersion = storedVersions[0];\n\t\t\t\t\t\tconst oldVersionNumeric = parseInt (oldVersion.replace (/\\./g, ''));\n\n\t\t\t\t\t\tif (oldVersionNumeric < this.numericVersion) {\n\t\t\t\t\t\t\t// Check what upgrade functions have been declared in their respective order\n\t\t\t\t\t\t\tconst availableUpgrades = Object.keys (this.upgrades).sort ();\n\n\t\t\t\t\t\t\t// Find the first update that needs to be applied to the database given\n\t\t\t\t\t\t\t// the old version it currently has.\n\t\t\t\t\t\t\tconst startFrom = availableUpgrades.findIndex (u => {\n\t\t\t\t\t\t\t\tconst [old, ] = u.split ('::');\n\t\t\t\t\t\t\t\treturn parseInt (old) === oldVersionNumeric;\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif (startFrom > -1) {\n\t\t\t\t\t\t\t\tupgradesToApply = availableUpgrades.slice (startFrom).filter ((u) => {\n\t\t\t\t\t\t\t\t\tconst [old, next] = u.split ('::');\n\t\t\t\t\t\t\t\t\treturn parseInt (old) < this.numericVersion && parseInt (next) <= this.numericVersion;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Get the previous ID using the old version\n\t\t\t\t\t\t\tlet previousId = `${this.name}::${oldVersion}_`;\n\n\t\t\t\t\t\t\tif (this.name !== '' && this.version !== '' && this.store !== '') {\n\t\t\t\t\t\t\t\tpreviousId = `${this.name}::${this.store}::${oldVersion}_`;\n\t\t\t\t\t\t\t} else if (this.name !== '' && this.version !== '') {\n\t\t\t\t\t\t\t\tpreviousId = `${this.name}::${oldVersion}_`;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Get all keys from the previous version\n\t\t\t\t\t\t\tconst keys = Object.keys (window.localStorage).filter ((key) => {\n\t\t\t\t\t\t\t\treturn key.indexOf (previousId) === 0;\n\t\t\t\t\t\t\t}).map ((key) => {\n\t\t\t\t\t\t\t\treturn key.replace (previousId, '');\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tfor (const key of keys) {\n\t\t\t\t\t\t\t\t// Get the value stored with the previous version\n\t\t\t\t\t\t\t\tconst previous = window.localStorage.getItem (`${previousId}${key}`);\n\n\t\t\t\t\t\t\t\t// Re-insert the value using the new ID as a key\n\t\t\t\t\t\t\t\twindow.localStorage.setItem (this.id + key, previous);\n\n\t\t\t\t\t\t\t\t// Delete the previous value.\n\t\t\t\t\t\t\t\twindow.localStorage.removeItem (`${previousId}${key}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tresolve ({ upgrades: upgradesToApply });\n\t\t\t}).then (({ upgrades }) => {\n\t\t\t\tthis.storage = window.localStorage;\n\t\t\t\treturn new Promise ((resolve) => {\n\t\t\t\t\tconst res = () => resolve (this);\n\t\t\t\t\tthis._upgrade (upgrades, res);\n\t\t\t\t});\n\t\t\t});\n\t\t\treturn this.storage;\n\t\t}\n\t}\n\n\t/**\n\t * Store a key-value pair\n\t *\n\t * @param {string} key - Key with which this value will be saved\n\t * @param {Object|string|Number} - Value to save\n\t * @return {Promise<{key, value}>}\n\t */\n\tset (key, value) {\n\t\treturn this.open ().then (() => {\n\n\t\t\tif (typeof value === 'object') {\n\t\t\t\tthis.storage.setItem (this.id + key, JSON.stringify (value));\n\t\t\t} else {\n\t\t\t\tthis.storage.setItem (this.id + key, value);\n\t\t\t}\n\n\t\t\treturn Promise.resolve ({key, value});\n\t\t});\n\t}\n\n\t/**\n\t * Update a key-value pair. In difference with the set () method, the update\n\t * method will use an Object.assign () in the case of objects so no value is\n\t * lost.\n\t *\n\t * @param {string} key - Key with which this value will be saved\n\t * @param {Object|string|Number} - Value to save\n\t * @return {Promise<{key, value}>}\n\t */\n\tupdate (key, value) {\n\t\treturn this.get (key).then ((currentValue) => {\n\t\t\tif (typeof currentValue === 'object') {\n\t\t\t\tif (typeof value === 'object') {\n\t\t\t\t\tvalue = Object.assign ({}, currentValue, value);\n\t\t\t\t}\n\t\t\t\tthis.storage.setItem (this.id + key, JSON.stringify (value));\n\t\t\t} else {\n\t\t\t\tthis.storage.setItem (this.id + key, value);\n\t\t\t}\n\t\t\treturn Promise.resolve ({key, value});\n\t\t}).catch (() => {\n\t\t\treturn this.set (key, value);\n\t\t});\n\t}\n\n\t/**\n\t * Retrieves a value from storage given it's key\n\t *\n\t * @param {string} - Key with which the value was saved\n\t * @return {Promise<Object>|Promise<string>|Promise<Number>} - Resolves to the retreived value\n\t * or its rejected if it doesn't exist\n\t */\n\tget (key) {\n\t\treturn this.open ().then (() => {\n\t\t\treturn new Promise ((resolve, reject) => {\n\t\t\t\tlet value = null;\n\t\t\t\tvalue = this.storage.getItem (this.id + key);\n\t\t\t\ttry {\n\t\t\t\t\tconst o = JSON.parse (value);\n\t\t\t\t\tif (o && typeof o === 'object') {\n\t\t\t\t\t\tvalue = o;\n\t\t\t\t\t}\n\t\t\t\t} catch (exception) {\n\t\t\t\t\t// Unable to parse to JSON\n\t\t\t\t}\n\n\t\t\t\tif (typeof value !== 'undefined' && value !== null) {\n\t\t\t\t\tresolve (value);\n\t\t\t\t} else {\n\t\t\t\t\treject ();\n\t\t\t\t}\n\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Retrieves all the values in the space in a key-value JSON object\n\t *\n\t * @return {Promise<Object>} - Resolves to the retreived values\n\t */\n\tgetAll () {\n\t\treturn this.keys ().then ((keys) => {\n\t\t\tconst values = {};\n\t\t\tconst promises = [];\n\t\t\tfor (const key of keys) {\n\t\t\t\tpromises.push (this.get (key).then ((value) => {\n\t\t\t\t\tvalues[key] = value;\n\t\t\t\t}));\n\t\t\t}\n\t\t\treturn Promise.all (promises).then (() => {\n\t\t\t\treturn values;\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Check if the space contains a given key.\n\t *\n\t * @param {string} key - Key to look for.\n\t * @return {Promise} Promise gets resolved if it exists and rejected if\n\t * doesn't\n\t */\n\tcontains (key) {\n\t\treturn this.keys ().then ((keys) => {\n\t\t\tif (keys.includes (key)) {\n\t\t\t\tPromise.resolve ();\n\t\t\t} else {\n\t\t\t\treturn Promise.reject ();\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Upgrade a Space Version\n\t *\n\t * @param oldVersion {string} - The version of the storage to be upgraded\n\t * @param newVersion {string} - The version to be upgraded to\n\t * @param callback {function} - Function to transform the old stored values to the new version's format\n\t * @returns {Promise}\n\t */\n\tupgrade (oldVersion, newVersion, callback) {\n\t\tthis.upgrades[`${parseInt (oldVersion.replace (/\\./g, ''))}::${parseInt (newVersion.replace (/\\./g, ''))}`] = callback;\n\t\treturn Promise.resolve ();\n\t}\n\n\t// This function acts as a helper for the upgrade progress by executing the\n\t// needed upgrade callbacks in the correct order and sychronously.\n\t_upgrade (upgradesToApply, resolve) {\n\t\t// Check if there are still upgrades to apply\n\t\tif (upgradesToApply.length > 0) {\n\t\t\tthis.upgrades[upgradesToApply[0]].call (this, this).then (() => {\n\t\t\t\tthis._upgrade (upgradesToApply.slice (1), resolve);\n\t\t\t}).catch ((e) => console.error (e));\n\t\t} else {\n\t\t\tresolve ();\n\t\t}\n\t}\n\n\t/**\n\t * Rename a Space\n\t *\n\t * @param {string} name - New name to be used.\n\t * @returns {Promise} - Result of the rename operation\n\t */\n\trename (name) {\n\t\t// Check if the name is different\n\t\tif (this.name !== name) {\n\t\t\treturn this.keys ().then ((keys) => {\n\t\t\t\t// Save the previous Space id\n\t\t\t\tconst oldId = this.id;\n\n\t\t\t\t// Set new object properties with the new name\n\t\t\t\tthis.name = name;\n\n\t\t\t\tif (this.name !== '' && this.version !== '' && this.store !== '') {\n\t\t\t\t\tthis.id = `${this.name}::${this.store}::${this.version}_`;\n\t\t\t\t} else if (this.name !== '' && this.version !== '') {\n\t\t\t\t\tthis.id = `${this.name}::${this.version}_`;\n\t\t\t\t} else if (this.name !== '') {\n\t\t\t\t\tthis.id = `${this.name}::_`;\n\t\t\t\t} else {\n\t\t\t\t\tthis.id = '';\n\t\t\t\t}\n\n\t\t\t\tconst promises = [];\n\t\t\t\tfor (const key of keys) {\n\t\t\t\t\tpromises.push (this.set (key, this.storage.getItem (`${oldId}${key}`)).then (() => {\n\t\t\t\t\t\tthis.storage.removeItem (`${oldId}${key}`);\n\t\t\t\t\t}));\n\t\t\t\t}\n\t\t\t\treturn Promise.all (promises);\n\t\t\t});\n\t\t} else {\n\t\t\treturn Promise.reject ();\n\t\t}\n\t}\n\n\t/**\n\t * Get the key that corresponds to a given index in the storage\n\t *\n\t * @param {Number} index - Index to get the key from\n\t * @param {boolean} [full=false] - Whether to return the full key name including space id or just the key name\n\t * @return {Promise<string>} - Resolves to the key's name\n\t */\n\tkey (index, full = false) {\n\t\treturn this.open ().then (() => {\n\t\t\tif (full === true) {\n\t\t\t\treturn Promise.resolve (this.storage.key (index));\n\t\t\t} else {\n\t\t\t\treturn Promise.resolve (this.storage.key (index).replace (this.id, ''));\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Return all keys stored in the space.\n\t *\n\t * @param {boolean} [full=false] - Whether to return the full key name including space id or just the key name\n\t * @return {Promise<string[]>} - Array of keys\n\t */\n\tkeys (full = false) {\n\t\treturn this.open ().then (() => {\n\t\t\treturn Promise.resolve (Object.keys (this.storage).filter ((key) => {\n\t\t\t\treturn key.indexOf (this.id) === 0;\n\t\t\t}).map ((key) => {\n\t\t\t\tif (full === true) {\n\t\t\t\t\treturn key;\n\t\t\t\t} else {\n\t\t\t\t\treturn key.replace (this.id, '');\n\t\t\t\t}\n\t\t\t}));\n\t\t});\n\t}\n\n\t/**\n\t * Delete a value from the space given its key\n\t *\n\t * @param {string} key - Key of the item to delete\n\t * @return {Promise<value>} - Resolves to the value of the deleted object\n\t */\n\tremove (key) {\n\t\treturn this.get (key).then ((value) => {\n\t\t\tthis.storage.removeItem (this.id + key);\n\t\t\treturn Promise.resolve (value);\n\t\t});\n\t}\n\n\t/**\n\t * Clear the entire space\n\t *\n\t * @return {Promise} - Result of the clear operation\n\t */\n\tclear () {\n\t\treturn this.keys ().then ((keys) => {\n\t\t\tfor (const key of keys) {\n\t\t\t\tthis.remove (key);\n\t\t\t}\n\t\t\treturn Promise.resolve ();\n\t\t});\n\t}\n}","/**\n* ==============================\n* Session Storage Adapter\n* ==============================\n*/\n\nimport { LocalStorage } from './LocalStorage';\n\n/**\n * The Session Storage Adapter provides the Space Class the ability to interact\n * with the sessionStorage api found in most modern browsers. Since this API\n * shares pretty much the same methods to the local storage one, this class\n * inherits from the LocalStorage adapter.\n *\n * @class\n */\nexport class SessionStorage extends LocalStorage {\n\n\t/**\n\t * Create a new SessionStorage. If no configuration is provided, the SessionStorage\n\t * global object is used.The SessionStorage Adapter can provide independency\n\t * by store name and space name.\n\t *\n\t * @constructor\n\t * @param {Object} [configuration={name = '', version = '', store = ''}] - Configuration Object for the Adapter\n\t * @param {string} configuration.name - Name of the Space\n\t * @param {string} configuration.version - Version of the Space in Semantic versioning syntax\n\t * @param {string} configuration.store - Name of the Object Store to use\n\t *\n\t */\n\tconstructor ({name = '', version = '', store = ''}) {\n\t\tsuper ({name, version, store});\n\t}\n\n\t/**\n\t * Open the Storage Object\n\n\t * @return {Promise<SessionStorage>}\n\t */\n\topen () {\n\t\tif (typeof this.storage === 'undefined') {\n\t\t\tthis.storage = window.sessionStorage;\n\t\t}\n\t\treturn Promise.resolve (this);\n\t}\n}","/**\n* ==============================\n* IndexedDB Adapter\n* ==============================\n*/\n\n/**\n * The IndexedDB Adapter provides the Space Class the ability to interact\n * with the IndexedDB API found in most modern browsers.\n *\n * @class\n */\nexport class IndexedDB {\n\n\t/**\n\t * Create a new IndexedDB. Differently from Local and Session Storages, the\n\t * IndexedDB Adapter requires a mandatory name, version and store name.\n\t *\n\t * @constructor\n\t * @param {Object} [configuration={name = '', version = '', store = '', props = {}, index = {}}] - Configuration Object for the Adapter\n\t * @param {string} configuration.name - Name of the Space\n\t * @param {string} configuration.version - Version of the Space in Semantic versioning syntax\n\t * @param {string} configuration.store - Name of the Object Store to use\n\t * @param {Object} configuration.props - Optional Parameters for the Object Store\n\t * @param {Object} configuration.index - Object of the indexes to declare for\n\t * the Object Store. Each index is a JSON object with the following properties:\n\t * @param {String} configuration.index[...].name - Name for the Index\n\t * @param {String} configuration.index[...].field - Field on the store to apply the index to\n\t * @param {Object} configuration.index[...].props - Index properties object\n\t */\n\tconstructor ({name = '', version = '', store = '', props = {}, index = {}}) {\n\t\tthis.name = name;\n\t\tthis.version = version;\n\t\tthis.store = store;\n\t\tthis.props = props;\n\t\tthis.index = index;\n\n\t\tthis.upgrades = {};\n\n\t\tif (this.version === '') {\n\t\t\tthis.numericVersion = 0;\n\t\t} else {\n\t\t\tthis.numericVersion = parseInt (version.replace (/\\./g, ''));\n\t\t}\n\t}\n\n\t/**\n\t * Open the Storage Object\n\t *\n\t * @return {Promise}\n\t */\n\topen () {\n\n\t\tif (this.name === '') {\n\t\t\tconsole.error ('No name has been defined for IndexedDB space.');\n\t\t\treturn Promise.reject ();\n\t\t}\n\n\t\tif (this.store === '') {\n\t\t\tconsole.error ('No store has been defined for IndexedDB space.');\n\t\t\treturn Promise.reject ();\n\t\t}\n\n\t\tif (this.storage instanceof IDBDatabase) {\n\t\t\treturn Promise.resolve (this);\n\t\t} else if (this.storage instanceof Promise) {\n\t\t\treturn this.storage;\n\t\t} else {\n\t\t\tthis.storage = new Promise ((resolve, reject) => {\n\t\t\t\tlet upgradesToApply = [];\n\t\t\t\tconst storage = window.indexedDB.open (this.name, this.numericVersion);\n\n\t\t\t\tstorage.onerror = (event) => {\n\t\t\t\t\treject (event);\n\t\t\t\t};\n\n\t\t\t\tstorage.onsuccess = (event) => {\n\t\t\t\t\tresolve ({ storage: event.target.result, upgrades: upgradesToApply });\n\t\t\t\t};\n\n\t\t\t\tstorage.onupgradeneeded = (event) => {\n\t\t\t\t\t// If the previous version is less than one, it means that\n\t\t\t\t\t// the database needs to be created first\n\t\t\t\t\tif (event.oldVersion < 1) {\n\t\t\t\t\t\t// Create all the needed Stores\n\t\t\t\t\t\tconst store = event.target.result.createObjectStore (this.store, this.props);\n\t\t\t\t\t\tfor (const index of Object.keys (this.index)) {\n\t\t\t\t\t\t\tstore.createIndex (this.index[index].name, this.index[index].field, this.index[index].props);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Check what upgrade functions have been declared in their respective order\n\t\t\t\t\t\tconst availableUpgrades = Object.keys (this.upgrades).sort ();\n\t\t\t\t\t\t\n\t\t\t\t\t\t// Find the first update that needs to be applied to the database given\n\t\t\t\t\t\t// the old version it currently has.\n\t\t\t\t\t\tconst startFrom = availableUpgrades.findIndex (u => {\n\t\t\t\t\t\t\tconst [old, ] = u.split ('::');\n\t\t\t\t\t\t\treturn parseInt (old) === event.oldVersion;\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (startFrom > -1) {\n\t\t\t\t\t\t\tupgradesToApply = availableUpgrades.slice (startFrom).filter ((u) => {\n\t\t\t\t\t\t\t\tconst [old, next] = u.split ('::');\n\t\t\t\t\t\t\t\treturn parseInt (old) < this.numericVersion && parseInt (next) <= this.numericVersion;\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Once the transaction is done, resolve the storage object\n\t\t\t\t\tconst transaction = event.target.transaction;\n\t\t\t\t\ttransaction.addEventListener ('success', () => {\n\t\t\t\t\t\tresolve ({ storage: event.target.result, upgrades: upgradesToApply });\n\t\t\t\t\t});\n\t\t\t\t};\n\t\t\t}).then (({ storage, upgrades }) => {\n\t\t\t\tthis.storage = storage;\n\t\t\t\treturn new Promise ((resolve) => {\n\t\t\t\t\tconst res = () => resolve (storage);\n\t\t\t\t\tthis._upgrade (upgrades, res, event);\n\t\t\t\t});\n\t\t\t});\n\t\t\treturn this.storage;\n\t\t}\n\t}\n\n\t/**\n\t * Store a key-value pair. Because of the nature of a IndexedDB Database, the\n\t * stored values must be JSON objects.\n\t *\n\t * @param {string} key - Key with which this value will be saved\n\t * @param {Object} - Value to save\n\t * @return {Promise<Object>} - When resolved, a {key, value} object is handed\n\t * down, when it's rejected, the event is handed down.\n\t */\n\tset (key = null, value) {\n\t\treturn this.open ().then (() => {\n\t\t\treturn new Promise ((resolve, reject) => {\n\t\t\t\tconst transaction = this.storage.transaction (this.store, 'readwrite').objectStore (this.store);\n\t\t\t\tlet op;\n\t\t\t\tif (key !== null) {\n\t\t\t\t\top = transaction.put (Object.assign ({}, {id: key}, value));\n\t\t\t\t} else {\n\t\t\t\t\top = transaction.add (value);\n\t\t\t\t}\n\t\t\t\top.addEventListener ('success', (event) => { resolve ({key: event.target.result, value: value});});\n\t\t\t\top.addEventListener ('error', (event) => {reject (event);});\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Update a key-value pair. In difference with the set () method, the update\n\t * method will use an Object.assign () in the case of objects so no value is\n\t * lost.\n\t *\n\t * @param {string} key - Key with which this value will be saved\n\t * @param {Object} - Value to save\n\t * @return {Promise<Object>} - When resolved, a {key, value} object is handed\n\t * down, when it's rejected, the event is handed down.\n\t */\n\tupdate (key, value) {\n\t\treturn this.get (key).then ((currentValue) => {\n\t\t\t// If this key did not exist on the storage, then create it using the\n\t\t\t// set method\n\t\t\tif (typeof currentValue === 'undefined') {\n\t\t\t\treturn this.set (key, value);\n\t\t\t}\n\t\t\treturn new Promise ((resolve, reject) => {\n\t\t\t\tconst transaction = this.storage.transaction (this.store, 'readwrite').objectStore (this.store);\n\t\t\t\tconst op = transaction.put (Object.assign ({}, currentValue, value));\n\t\t\t\top.addEventListener ('success', (event) => {resolve ({key: event.target.result, value: value});});\n\t\t\t\top.addEventListener ('error', (event) => {reject (event);});\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Retrieves a value from storage given it's key\n\t *\n\t * @param {string} - Key with which the value was saved\n\t * @return {Promise<Object>} - Resolves to the retreived value or its rejected\n\t * if it doesn't exist\n\t */\n\tget (key) {\n\t\treturn this.open ().then (() => {\n\t\t\treturn new Promise ((resolve, reject) => {\n\t\t\t\tconst transaction = this.storage.transaction (this.store).objectStore (this.store);\n\t\t\t\tconst op = transaction.get (key);\n\n\t\t\t\top.addEventListener ('success', (event) => {resolve (event.target.result);});\n\t\t\t\top.addEventListener ('error', (event) => {reject (event);});\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Retrieves all the values in the space in a key-value JSON object\n\t *\n\t * @return {Promise<Object>} - Resolves to the retreived values\n\t */\n\tgetAll () {\n\t\treturn this.open ().then (() => {\n\t\t\treturn new Promise ((resolve, reject) => {\n\t\t\t\tconst transaction = this.storage.transaction (this.store).objectStore (this.store);\n\t\t\t\tconst op = transaction.getAll ();\n\n\t\t\t\top.addEventListener ('success', (event) => {resolve (event.target.result);});\n\t\t\t\top.addEventListener ('error', (event) => {reject (event);});\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Check if the space contains a given key.\n\t *\n\t * @param {string} key - Key to look for.\n\t * @return {Promise} - Promise gets resolved if it exists and rejected if it\n\t * doesn't\n\t */\n\tcontains (key) {\n\t\treturn this.get (key).then ((keys) => {\n\t\t\tif (keys.includes (key)) {\n\t\t\t\tPromise.resolve ();\n\t\t\t} else {\n\t\t\t\treturn Promise.reject ();\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Upgrade a Space Version. Upgrades must be declared before the open ()\n\t * method is executed.\n\t *\n\t * @param {string} oldVersion - The version to be upgraded\n\t * @param {string} newVersion - The version to be upgraded to\n\t * @param {function} callback - Function to transform the old stored values to the new version's format\n\t * @returns {Promise}\n\t */\n\tupgrade (oldVersion, newVersion, callback) {\n\t\tthis.upgrades[`${parseInt (oldVersion.replace (/\\./g, ''))}::${parseInt (newVersion.replace (/\\./g, ''))}`] = callback;\n\t\treturn Promise.resolve ();\n\t}\n\n\t// This function acts as a helper for the upgrade progress by executing the\n\t// needed upgrade callbacks in the correct order and sychronously.\n\t_upgrade (upgradesToApply, resolve, event) {\n\t\t// Check if there are still upgrades to apply\n\t\tif (upgradesToApply.length > 0) {\n\t\t\tthis.upgrades[upgradesToApply[0]].call (this, this, event).then (() => {\n\t\t\t\tthis._upgrade (upgradesToApply.slice (1), resolve, event);\n\t\t\t}).catch ((e) => console.error (e));\n\t\t} else {\n\t\t\tresolve ();\n\t\t}\n\t}\n\n\t/**\n\t * Renaming the space is not possible with the IndexedDB adapter therefore\n\t * this function always gets a rejection.\n\t *\n\t * @returns {Promise} - Result of the rename operation\n\t */\n\trename () {\n\t\treturn Promise.reject ();\n\t}\n\n\t/**\n\t * Getting a key by its index is not possible in this adapter, therefore this\n\t * function always gets rejected.\n\t *\n\t * @return {Promise} - Promise Rejection\n\t */\n\tkey () {\n\t\treturn Promise.reject ();\n\t}\n\n\t/**\n\t * Return all keys stored in the space.\n\t *\n\t * @return {Promise<string[]>} - Array of keys\n\t */\n\tkeys () {\n\t\treturn this.open ().then (() => {\n\t\t\treturn new Promise ((resolve, reject) => {\n\t\t\t\tconst transaction = this.storage.transaction (this.store, 'readwrite').objectStore (this.store);\n\t\t\t\tconst op = transaction.getAllKeys ();\n\t\t\t\top.addEventListener ('success', (event) => {resolve (event.target.result);}, false);\n\t\t\t\top.addEventListener ('error', (event) => {reject (event);}, false);\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Delete a value from the space given its key\n\t *\n\t * @param {string} key - Key of the item to delete\n\t * @return {Promise<key, value>} - Resolves to the key and value of the deleted object\n\t */\n\tremove (key) {\n\t\treturn this.get (key).then ((value) => {\n\t\t\treturn new Promise ((resolve, reject) => {\n\t\t\t\tconst transaction = this.storage.transaction (this.store, 'readwrite').objectStore (this.store);\n\t\t\t\tconst op = transaction.delete (key);\n\t\t\t\top.addEventListener ('success', () => {resolve (value);}, false);\n\t\t\t\top.addEventListener ('error', (event) => {reject (event);}, false);\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Clear the entire space\n\t *\n\t * @return {Promise} - Result of the clear operation\n\t */\n\tclear () {\n\t\treturn this.open ().then (() => {\n\t\t\treturn new Promise ((resolve, reject) => {\n\t\t\t\tconst transaction = this.storage.transaction (this.store, 'readwrite').objectStore (this.store);\n\t\t\t\tconst op = transaction.clear ();\n\t\t\t\top.addEventListener ('success', () => {resolve ();}, false);\n\t\t\t\top.addEventListener ('error', (event) => {reject (event);}, false);\n\t\t\t});\n\t\t});\n\t}\n}","/**\n* ==============================\n* Remote Storage Adapter\n* ==============================\n*/\n\nimport { Request } from './../Request';\n\n/**\n * The Remote Storage Adapter provides the Space Class the ability to interact\n * with a server in order to handle data persistance. The server's implementation\n * is up to the developer but it will need to respond to this adapter's request\n * formatting. This adapter uses the Request class to perfom its tasks.\n *\n * @class\n */\nexport class RemoteStorage {\n\n\t/**\n\t * Create a new Remote Storage. This adapter requires an endpoint url where\n\t * it will make the requests. If a store is defined, the request will be made\n\t * using the store as an URL, for example, let's assume the following endpoint:\n\t *\n\t * https://example.com/api/v1/\n\t *\n\t * If no store is defined, then the requests will be made to that simple route,\n\t * with a store definition, requests will be made to:\n\t *\n\t * https://example.com/api/v1/{myStore}/\n\t *\n\t * The key of each item in this store represents another part of the request\n\t *\n\t * https://example.com/api/v1/{key}/\n\t *\n\t * Or:\n\t *\n\t * https://example.com/api/v1/{myStore}/{key}/\n\t *\n\t * This adapter just as the IndexedDB, works with JSON objects instead of string or\n\t * numeric values.\n\t *\n\t * @constructor\n\t * @param {object} [configuration={name = '', version = '', store = '', endpoint = '', props = {}] - Configuration Object for the Adapter\n\t * @param {string} configuration.name - Name of the Space\n\t * @param {string} configuration.version - Version of the Space in Semantic versioning syntax\n\t * @param {string} configuration.store - Name of the Object Store to use\n\t * @param {string} configuration.endpoint - Endpoint URL where the requests will be made\n\t * @param {string} configuration.props - Properties object to use for the fetch requests\n\t */\n\tconstructor ({name = '', version = '', store = '', endpoint = '', props = {}}) {\n\t\tthis.name = name;\n\t\tthis.version = version;\n\t\tthis.store = store;\n\t\tthis.endpoint = `${endpoint}${store}/`;\n\t\tthis.props = props;\n\t}\n\n\t/**\n\t * Open the Storage Object\n\t *\n\t * @return {Promise<RemoteStorage>}\n\t */\n\topen () {\n\t\tif (typeof this.storage === 'undefined') {\n\t\t\tthis.storage = Request;\n\t\t}\n\t\treturn Promise.resolve (this);\n\t}\n\n\t/**\n\t * Store a key-value pair. This function sends a POST request to the server\n\t *\n\t * @param {string} key - Key with which this value will be saved\n\t * @param {Object} value - Value to save\n\t * @return {Promise<Response>}\n\t */\n\tset (key, value) {\n\t\treturn this.open ().then (() => {\n\t\t\treturn this.storage.post (this.endpoint + key, value, this.props);\n\t\t});\n\t}\n\n\t/**\n\t * Update a key-value pair. In difference with the set () method, the update\n\t * method will use an Object.assign () in the case of objects so no value is\n\t * lost. This function sends a PUT request to the server.\n\t *\n\t * @param {string} key - Key with which this value will be saved\n\t * @param {Object} value - Value to save\n\t * @return {Promise<Object>}\n\t */\n\tupdate (key, value) {\n\t\treturn this.get (key).then ((currentValue) => {\n\t\t\treturn this.storage.put (this.endpoint + key, Object.assign ({}, currentValue, value), this.props).then ((response) => {\n\t\t\t\treturn response.json ();\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Retrieves a value from storage given it's key\n\t *\n\t * @param {string} - Key with which the value was saved\n\t * @return {Promise<Object>} - Resolves to the retreived value or its rejected\n\t * if it doesn't exist\n\t */\n\tget (key) {\n\t\treturn this.open ().then (() => {\n\t\t\treturn this.storage.json (this.endpoint + key, {}, this.props);\n\t\t});\n\t}\n\n\t/**\n\t * Retrieves all the values in the space in a key-value JSON object\n\t *\n\t * @return {Promise<Object>} - Resolves to the retreived values\n\t */\n\tgetAll () {\n\t\treturn this.open ().then (() => {\n\t\t\treturn this.storage.json (this.endpoint, {}, this.props);\n\t\t});\n\t}\n\n\t/**\n\t * Check if a space contains a given key.\n\t *\n\t * @param {string} key - Key to look for.\n\t * @return {Promise} Promise gets resolved if it exists and rejected if it\n\t * doesn't\n\t */\n\tcontains (key) {\n\t\treturn this.keys ().then ((keys) => {\n\t\t\tif (keys.includes (key)) {\n\t\t\t\tPromise.resolve ();\n\t\t\t} else {\n\t\t\t\treturn Promise.reject ();\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Upgrading the Storage must be done on the server side, therefore this function\n\t * always gets rejected.\n\t *\n\t * @returns {Promise}\n\t */\n\tupgrade () {\n\t\treturn Promise.reject ();\n\t}\n\n\t/**\n\t * Renaming the Storage must be done on the server side, therefore this function\n\t * always gets rejected.\n\t *\n\t * @returns {Promise}\n\t */\n\trename () {\n\t\treturn Promise.reject ();\n\t}\n\n\t/**\n\t * Getting a key by its index is not possible in this adapter, therefore this\n\t * function always gets rejected.\n\t *\n\t * @return {Promise} - Promise Rejection\n\t */\n\tkey () {\n\t\treturn Promise.reject ();\n\t}\n\n\t/**\n\t * Return all keys stored in the space. This makes a GET request to the full\n\t * endpoint (the URL of the endpoint and store name) with a keys query\n\t * parameter:\n\t *\n\t * https://example.com/api/v1/?keys=true\n \t *\n\t * Or:\n \t *\n \t * https://example.com/api/v1/{myStore}/?keys=true\n\t *\n\t * @return {Promise<string[]>} - Array of keys\n\t */\n\tkeys () {\n\t\treturn this.open ().then (() => {\n\t\t\treturn this.storage.json (this.endpoint, {keys: true}, this.props);\n\t\t});\n\t}\n\n\t/**\n\t * Delete a value from the space given it's key. This function sends a DELETE\n\t * request to the server.\n\t *\n\t * @param {string} key - Key of the item to delete\n\t * @return {Promise<key, value>} - Resolves to the key and value of the deleted object\n\t */\n\tremove (key) {\n\t\treturn this.open ().then (() => {\n\t\t\treturn this.storage.delete (this.endpoint + key, {}, this.props).then ((response) => {\n\t\t\t\treturn Promise.resolve (key, response.json ());\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Clear the entire space. This function sends a DELETE request to the server.\n\t * The difference between a clear () and remove () operation is that the clear\n\t * operation does not uses a key in the URL where the request is made.\n\t *\n\t * @return {Promise} - Result of the clear operation\n\t */\n\tclear () {\n\t\treturn this.open ().then (() => {\n\t\t\treturn this.storage.delete (this.endpoint, {}, this.props);\n\t\t});\n\t}\n}","/**\n* ==============================\n* Space\n* ==============================\n*/\n\nimport { LocalStorage } from './SpaceAdapter/LocalStorage';\nimport { SessionStorage } from './SpaceAdapter/SessionStorage';\nimport { IndexedDB } from './SpaceAdapter/IndexedDB';\nimport { RemoteStorage } from './SpaceAdapter/RemoteStorage';\n\n/**\n * List of Adapters Available\n */\nexport const SpaceAdapter = {\n\tLocalStorage,\n\tSessionStorage,\n\tIndexedDB,\n\tRemoteStorage\n};\n\n/**\n * Space provides a simple wrapper for different Storage APIs. It aims to\n * provide data independence through storage namespaces and versioning, allowing\n * transparent data formatting and content modifications through versions.\n *\n * While this class documentation provides some information, specific details may\n * be addressed on the documentation of each adapter.\n *\n * @class\n */\nexport class Space {\n\n\t/**\n\t * Create a new Space Object. If no name and version is defined, the global LocalSpace space is used.\n\t *\n\t * @constructor\n\t * @param {SpaceAdapter} [adapter = SpaceAdapter.LocalStorage] - Space Adapter\n\t * to use. Currently LocalStorage, SessionStorage, IndexedDB and Server are\n\t * available\n\t * @param {Object} [configuration = {}] - Configuration object for the space.\n\t * This configuration may change depending on the adapter used, however all\n\t * adapters have support for a name, version and store properties.\n\t * @param {string} configuration.name - Name of the Space\n\t * @param {string} configuration.version - Version of the Space in Semantic versioning syntax\n\t * @param {string} configuration.store - Name of the Object Store to use\n\t */\n\tconstructor (adapter = SpaceAdapter.LocalStorage, configuration = {}) {\n\t\t// Assign the provided configuration to the default one\n\t\tthis._configuration = Object.assign ({}, {name: '', version: '', store: ''}, configuration);\n\n\t\t// Set up the adapter instance to use\n\t\tthis.adapter = new adapter (this._configuration);\n\n\t\t// This object stores all the callbacks the user can define for the\n\t\t// space operations\n\t\tthis.callbacks = {\n\t\t\t'create': [],\n\t\t\t'update': [],\n\t\t\t'delete': []\n\t\t};\n\n\t\t// A transformation is an object that can contain a set and get functions\n\t\t// every transformation will be applied to the retrieved value or to the\n\t\t// value before storing it.\n\t\tthis.transformations = {\n\n\t\t};\n\t}\n\n\t/**\n\t * Modify the space configuration, it will also be passed down to the adapter\n\t * using its configuration () function.\n\t *\n\t * @param {object} - Configuration object to set up\n\t * @return {object} - Configuration object if no param was passed\n\t */\n\tconfiguration (object = null) {\n\t\tif (object !== null) {\n\t\t\tthis._configuration = Object.assign ({}, this._configuration, object);\n\t\t\tthis.adapter.configuration (object);\n\t\t} else {\n\t\t\treturn this._configuration;\n\t\t}\n\t}\n\n\t/**\n\t * Open the Storage Object to be used depending on the SpaceAdapter\n\t *\n\t * @return {Promise}\n\t */\n\topen () {\n\t\treturn this.adapter.open ().then (() => {\n\t\t\treturn Promise.resolve (this);\n\t\t});\n\t}\n\n\t/**\n\t * Store a key-value pair\n\t *\n\t * @param {string} key - Key with which this value will be saved\n\t * @param {Object|string|Number} - Value to save\n\t * @return {Promise<{key, value}>}\n\t */\n\tset (key, value) {\n\t\t// Apply all set transformations to the value\n\t\tfor (const id of Object.keys (this.transformations)) {\n\t\t\tif (typeof this.transformations[id].set === 'function') {\n\t\t\t\tvalue = this.transformations[id].set.call (null, key, value);\n\t\t\t}\n\t\t}\n\n\t\treturn this.adapter.set (key, value).then (({key, value}) => {\n\t\t\tfor (const callback of this.callbacks.create) {\n\t\t\t\tcallback.call (null, key, value);\n\t\t\t}\n\t\t\treturn Promise.resolve ({key, value});\n\t\t});\n\t}\n\n\t/**\n\t * Update a key-value pair. In difference with the set () method, the update\n\t * method will use an Object.assign () in the case of objects so no value is\n\t * lost.\n\t *\n\t * @param {string} key - Key with which this value will be saved\n\t * @param {Object|string|Number} - Value to save\n\t * @return {Promise<{key, value}>}\n\t */\n\tupdate (key, value) {\n\t\t// Apply all set transformations to the value\n\t\tfor (const id of Object.keys (this.transformations)) {\n\t\t\tif (typeof this.transformations[id].set === 'function') {\n\t\t\t\tvalue = this.transformations[id].set.call (null, key, value);\n\t\t\t}\n\t\t}\n\n\t\treturn this.adapter.update (key, value).then (({key, value}) => {\n\t\t\tfor (const callback of this.callbacks.update) {\n\t\t\t\tcallback.call (null, key, value);\n\t\t\t}\n\t\t\treturn Promise.resolve ({key, value});\n\t\t});\n\t}\n\n\t/**\n\t * Retrieves a value from storage given it's key\n\t *\n\t * @param {string} - Key with which the value was saved\n\t * @return {Promise<Object>|Promise<string>|Promise<Number>} - Resolves to the retreived value\n\t * or its rejected if it doesn't exist.\n\t */\n\tget (key) {\n\t\treturn this.adapter.get (key).then ((value) => {\n\t\t\t// Apply all get transformations to the value\n\t\t\tfor (const id of Object.keys (this.transformations)) {\n\t\t\t\tif (typeof this.transformations[id].get === 'function') {\n\t\t\t\t\tvalue = this.transformations[id].get.call (null, key, value);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn value;\n\t\t});\n\t}\n\n\t/**\n\t * Retrieves all the values in the space in a key-value JSON object\n\t *\n\t * @return {Promise<Object>} - Resolves to the retreived values\n\t */\n\tgetAll () {\n\t\treturn this.adapter.getAll ().then ((values) => {\n\t\t\t// Apply all get transformations to the value\n\t\t\tfor (const key of Object.keys (values)) {\n\t\t\t\tfor (const id of Object.keys (this.transformations)) {\n\t\t\t\t\tif (typeof this.transformations[id].get === 'function') {\n\t\t\t\t\t\tvalues[key] = this.transformations[id].get.call (null, key, values[key]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn values;\n\t\t});\n\t}\n\n\t/**\n\t * Iterate over every value in the space\n\t *\n\t * @param {function (key, value)} callback - A callback function receiving the\n\t * key and value of a value. Must return a callback\n\t * @return {Promise} - Resolves when all callbacks have been resolved.\n\t */\n\teach (callback) {\n\t\treturn this.getAll ().then ((values) => {\n\t\t\tconst promises = [];\n\t\t\tfor (const i of Object.keys (values)) {\n\t\t\t\tpromises.push (callback.call (this, i, values[i]));\n\t\t\t}\n\t\t\treturn Promise.all (promises);\n\t\t});\n\t}\n\n\t/**\n\t * Check if a space contains a given key. Not all adapters may give this information\n\t *\n\t * @param {string} key - Key to look for.\n\t * @return {Promise} - Promise gets resolved if it exists and rejected if\n\t * doesn't\n\t */\n\tcontains (key) {\n\t\treturn this.adapter.contains (key);\n\t}\n\n\t/**\n\t * Upgrade a Space Version. Not all adapters may provide this functionality\n\t *\n\t * @param oldVersion {string} - The version of the storage to be upgraded\n\t * @param newVersion {string} - The version to be upgraded to\n\t * @param callback {function} - Function to transform the old stored values to the new version's format\n\t *\n\t * @returns {Promise} - Result of the upgrade operation\n\t */\n\tupgrade (oldVersion, newVersion, callback) {\n\t\treturn this.adapter.upgrade (oldVersion, newVersion, callback).then (() => {\n\t\t\treturn Promise.resolve (this);\n\t\t});\n\t}\n\n\t/**\n\t * Rename a Space. Not all adapters may provide this functionality\n\t *\n\t * @param {string} name - New name to be used.\n\t * @returns {Promise} Result of the rename operation\n\t */\n\trename (name) {\n\t\treturn this.adapter.rename (name);\n\t}\n\n\t/**\n\t * Add a callback function to be run every time a value is created.\n\t *\n\t * @param {function (key, value)} callback - Callback Function. Key and Value pair will be sent as parameters when run.\n\t */\n\tonCreate (callback) {\n\t\tthis.callbacks.create.push (callback);\n\t}\n\n\t/**\n\t * Add a callback function to be run every time a value is updated.\n\t *\n\t * @param {function (key, value)} callback - Callback Function. Key and Value pair will be sent as parameters when run.\n\t */\n\tonUpdate (callback) {\n\t\tthis.callbacks.update.push (callback);\n\t}\n\n\t/**\n\t * Add a callback function to be run every time a value is deleted.\n\t *\n\t * @param {function (key, value)} callback - Callback Function. Key and Value pair will be sent as parameters when run.\n\t */\n\tonDelete (callback) {\n\t\tthis.callbacks.delete.push (callback);\n\t}\n\n\t/**\n\t * Add a transformation function to the space.\n\t *\n\t * @param {string} id - Unique transformation name or identifier\n\t * @param {function (key, value)|null} get - Transformation function to apply to the content before\n\t * returning the value when using the get () function .\n\t * @param {function (key, value)|null} set - Transformation function to apply to the content before\n\t * saving it when using the set () function befo.\n\t */\n\taddTransformation ({id, get, set}) {\n\t\tthis.transformations[id] = {\n\t\t\tid,\n\t\t\tget,\n\t\t\tset\n\t\t};\n\t}\n\n\t/**\n\t * Remove a transformation function given its id\n\t *\n\t * @param {string} id - Name or identifier of the transformation to remove\n\t */\n\tremoveTransformation (id) {\n\t\tdelete this.transformations[id];\n\t}\n\n\t/**\n\t * Get the key that corresponds to a given index in the storage. Not all adapters may provide this functionality\n\t *\n\t * @param {Number} index - Index to get the key from\n\t * @param {boolean} [full = false] - Whether to return the full key name including space id or just the key name\n\t * @return {Promise<string>} - Resolves to the key's name\n\t */\n\tkey (index, full = false) {\n\t\treturn this.adapter.key (index, full);\n\t}\n\n\t/**\n\t * Return all keys stored in the space. Not all adapters may provide this functionality\n\t *\n\t * @param {boolean} [full = false] - Whether to return the full key name including space id or just the key name\n\t * @return {Promise<string[]>} - Array of keys\n\t */\n\tkeys (full = false) {\n\t\treturn this.adapter.keys (full);\n\t}\n\n\t/**\n\t * Delete a value from the space given it's key\n\t *\n\t * @param {string} key - Key of the item to delete\n\t * @return {Promise<key, value>} - Resolves to the key and value of the deleted object\n\t */\n\tremove (key) {\n\t\treturn this.adapter.remove (key).then ((value) => {\n\t\t\t// Run the callback for deletions\n\t\t\tfor (const callback of this.callbacks.delete) {\n\t\t\t\tcallback.call (null, key, value);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Clear the entire space\n\t *\n\t * @return {Promise} - Result of the clear operation\n\t */\n\tclear () {\n\t\treturn this.adapter.clear ();\n\t}\n}","/**\n* ==============================\n* Text\n* ==============================\n*/\n\n/**\n * Provides utility functions for texts\n * @class\n */\nexport class Text {\n\n\t/**\n\t * @static capitalize - Capatalizes every word in a string\n\t *\n\t * @param {string} text - Text string to capitalize\n\t * @return {string} - Capitalized string\n\t */\n\tstatic capitalize (text) {\n\t\treturn text.replace (/\\w\\S*/g, (txt) => {\n\t\t\treturn txt.charAt (0).toUpperCase () + txt.substr (1).toLowerCase ();\n\t\t});\n\t}\n\n\t/**\n\t * @static suffix - Gets the suffix of a string given a key\n\t *\n\t * @param {string} key - Key part of the string\n\t * @param {string} text - Full string to extract the suffix from\n\t * @return {string} - Suffix\n\t */\n\tstatic suffix (key, text) {\n\t\tlet suffix = '';\n\t\tlet position = text.indexOf (key);\n\t\tif (position !== -1) {\n\t\t\tposition += key.length;\n\t\t\tsuffix = text.substr (position, text.length - position);\n\t\t}\n\t\treturn suffix;\n\t}\n\n\n\t/**\n\t * @static selection - Get the currently selected text\n\t *\n\t * @return {string} - Text selection\n\t */\n\tstatic selection () {\n\t\tif (window.getSelection) {\n\t\t\treturn window.getSelection ().toString ();\n\t\t} else if (document.selection && document.selection.type != 'Control') {\n\t\t\treturn document.selection.createRange ().text;\n\t\t}\n\t}\n\n\t/**\n\t * @static prefix - Gets the prefix of a string given a key\n\t *\n\t * @param {string} key - Key part of the string\n\t * @param {string} text - Full string to extract the prefix from\n\t * @return {string} - Prefix\n\t */\n\tstatic prefix (key, text) {\n\t\tlet prefix = '';\n\t\tconst position = text.indexOf (key);\n\t\tif (position != -1) {\n\t\t\tprefix = text.substr (0, position);\n\t\t}\n\t\treturn prefix;\n\t}\n\n\t/**\n\t * @static friendly - Transforms a given text into a friendly URL string replacing all special characters\n\t *\n\t * @param {string} text - The text to build the url from\n\t * @return {string} - Friendly URL\n\t */\n\tstatic friendly (text) {\n\t\tconst regex = [\n\t\t\t/[áàâãªä]/,\n\t\t\t/[ÁÀÂÃÄ]/,\n\t\t\t/[ÍÌÎÏ]/,\n\t\t\t/[íìîï]/,\n\t\t\t/[éèêë]/,\n\t\t\t/[ÉÈÊË]/,\n\t\t\t/[óòôõºö]/,\n\t\t\t/[ÓÒÔÕÖ]/,\n\t\t\t/[úùûü]/,\n\t\t\t/[ÚÙÛÜ]/,\n\t\t\t/ç/,\n\t\t\t/Ç/,\n\t\t\t/ñ/,\n\t\t\t/Ñ/,\n\t\t\t/_/,\n\t\t\t/[’‘‹›<>']/,\n\t\t\t/[“”«»„\"]/,\n\t\t\t/[(){}[\\]]/,\n\t\t\t/[?¿!¡#$%&^*´`~/°|]/,\n\t\t\t/[,.:;]/,\n\t\t\t/ /\n\t\t];\n\n\t\tconst replacements = [\n\t\t\t'a',\n\t\t\t'A',\n\t\t\t'I',\n\t\t\t'i',\n\t\t\t'e',\n\t\t\t'E',\n\t\t\t'o',\n\t\t\t'O',\n\t\t\t'u',\n\t\t\t'U',\n\t\t\t'c',\n\t\t\t'C',\n\t\t\t'n',\n\t\t\t'N',\n\t\t\t'-',\n\t\t\t'',\n\t\t\t'',\n\t\t\t'',\n\t\t\t'',\n\t\t\t'',\n\t\t\t'-'\n\t\t];\n\n\t\tfor (const index in regex) {\n\t\t\ttext = text.replace(new RegExp(regex[index], 'g'), replacements[index]);\n\t\t}\n\n\t\treturn text;\n\t}\n}","export * from './src/Component';\nexport * from './src/Debug';\nexport * from './src/DOM';\nexport * from './src/FileSystem';\nexport * from './src/Form';\nexport * from './src/Platform';\nexport * from './src/Preload';\nexport * from './src/Request';\nexport * from './src/Space';\nexport * from './src/Text';\nexport * from './src/Util';"]}
|