Skip to content

Instantly share code, notes, and snippets.

@nolanlawson
Created February 7, 2015 18:01
Show Gist options
  • Save nolanlawson/6f69f4a573c1da862e92 to your computer and use it in GitHub Desktop.
Save nolanlawson/6f69f4a573c1da862e92 to your computer and use it in GitHub Desktop.
IndexedDB+Dexie+Lunr MTG full-text search demo
(function(n,t,i,r){"use strict";function h(n,t){return typeof t!="object"&&(t=t()),Object.keys(t).forEach(function(i){n[i]=t[i]}),n}function y(n){return{from:function(t){return n.prototype=Object.create(t.prototype),n.prototype.constructor=n,{extend:function(i){h(n.prototype,typeof i!="object"?i(t.prototype):i)}}}}}function p(n,t){return t(n)}function f(t){function or(){if(i)w.on("versionchange",function(t){w.close();t.newVersion&&n.location.reload(!0)})}function ki(n){this._cfg={version:n,storesSource:null,dbschema:{},tables:{},contentUpgrade:null};this.stores({})}function sr(n,t,i,r){var e,f,o,h,l,c;if(n==0)Object.keys(pt).forEach(function(n){di(t,n,pt[n].primKey,pt[n].indexes)}),e=w._createTransaction(kt,ri,pt),e.idbtrans=t,e.idbtrans.onerror=s(i,["populating database"]),e.on("error").subscribe(i),u.newPSD(function(){u.PSD.trans=e;try{w.on("populate").fire(e)}catch(n){r.onerror=t.onerror=function(n){n.preventDefault()};try{t.abort()}catch(f){}t.db.close();i(n)}});else{if(f=[],o=ii.filter(function(t){return t._cfg.version===n})[0],!o)throw new et("Dexie specification of currently installed DB version is missing");pt=w._dbSchema=o._cfg.dbschema;h=!1;l=ii.filter(function(t){return t._cfg.version>n});l.forEach(function(n){var e=pt,r=n._cfg.dbschema,u;ur(e,t);ur(r,t);pt=w._dbSchema=r;u=hr(e,r);u.add.forEach(function(n){f.push(function(t,i){di(t,n[0],n[1].primKey,n[1].indexes);i()})});u.change.forEach(function(n){if(n.recreate)throw new et("Not yet support for changing primary key");else f.push(function(t,i){var r=t.objectStore(n.name);n.add.forEach(function(n){gi(r,n)});n.change.forEach(function(n){r.deleteIndex(n.name);gi(r,n)});n.del.forEach(function(n){r.deleteIndex(n)});i()})});n._cfg.contentUpgrade&&f.push(function(t,u){var f,e;h=!0;f=w._createTransaction(kt,[].slice.call(t.db.objectStoreNames,0),r);f.idbtrans=t;e=0;f._promise=p(f._promise,function(n){return function(t,i,r){function f(n){return function(){n.apply(this,arguments);--e==0&&u()}}return++e,n.call(this,t,function(n,t){arguments[0]=f(n);arguments[1]=f(t);i.apply(this,arguments)},r)}});t.onerror=s(i,["running upgrader function for version",n._cfg.version]);f.on("error").subscribe(i);n._cfg.contentUpgrade(f);e===0&&u()});h&&wr()||f.push(function(n,t){lr(r,n);t()})});c=function(){try{f.length?f.shift()(t,c):cr(pt,t)}catch(n){r.onerror=t.onerror=function(n){n.preventDefault()};t.abort();t.db.close();i(n)}};c()}}function hr(n,t){var f={del:[],add:[],change:[]},r,e,o,i,c,s,u,l,h;for(r in n)t[r]||f.del.push(r);for(r in t)if(e=n[r],o=t[r],e)if(i={name:r,def:t[r],recreate:!1,del:[],add:[],change:[]},e.primKey.src!=o.primKey.src)i.recreate=!0,f.change.push(i);else{c=e.indexes.reduce(function(n,t){return n[t.name]=t,n},{});s=o.indexes.reduce(function(n,t){return n[t.name]=t,n},{});for(u in c)s[u]||i.del.push(u);for(u in s)l=c[u],h=s[u],l?l.src!=h.src&&i.change.push(h):i.add.push(h);(i.recreate||i.del.length>0||i.add.length>0||i.change.length>0)&&f.change.push(i)}else f.add.push([r,o]);return f}function di(n,t,i,r){var u=n.db.createObjectStore(t,i.keyPath?{keyPath:i.keyPath,autoIncrement:i.auto}:{autoIncrement:i.auto});return r.forEach(function(n){gi(u,n)}),u}function cr(n,t){Object.keys(n).forEach(function(i){t.db.objectStoreNames.contains(i)||di(t,i,n[i].primKey,n[i].indexes)})}function lr(n,t){for(var u,i=0;i<t.db.objectStoreNames.length;++i)u=t.db.objectStoreNames[i],(n[u]===null||n[u]===r)&&t.db.deleteObjectStore(u)}function gi(n,t){n.createIndex(t.name,t.keyPath,{unique:t.unique,multiEntry:t.multi})}function ar(n,t){throw new et("Table "+t[0]+" not part of transaction. Original Scope Function Source: "+f.Promise.PSD.trans.scopeFunc.toString());}function fi(n,t,i,r){this.name=n;this.schema=i;this.hook=gt[n]?gt[n].hook:b(null,{creating:[ht,e],reading:[st,nt],updating:[ct,e],deleting:[vt,e]});this._tpf=t;this._collClass=r||hi}function nr(n,t,i,r){fi.call(this,n,t,i,r||ir)}function tr(n,t,i,r){function o(n,t,i,r){return s._promise(n,i,r)}var s=this,f,u,e;for(this.db=w,this.mode=n,this.storeNames=t,this.idbtrans=null,this.on=b(this,["complete","error"],"abort"),this._reculock=0,this._blockedFuncs=[],this._psd=null,this.active=!0,this._dbschema=i,r&&(this.parent=r),this._tpf=o,this.tables=Object.create(bi),f=t.length-1;f!==-1;--f)u=t[f],e=w._tableFactory(n,i[u],o),this.tables[u]=e,this[u]||(this[u]=e)}function si(n,t,i){this._ctx={table:n,index:t===":id"?null:t,collClass:n._collClass,or:i}}function hi(n,t){var i=n._ctx;this._ctx={table:i.table,index:i.index,isPrimKey:!i.index||i.table.schema.primKey.keyPath&&i.index===i.table.schema.primKey.name,range:t,op:"openCursor",dir:"next",unique:"",algorithm:null,filter:null,isMatch:null,offset:0,limit:Infinity,error:null,or:i.or}}function ir(){hi.apply(this,arguments)}function vr(n,t){return n._cfg.version-t._cfg.version}function rr(n,t,i,r,f,e){i.forEach(function(i){var o=w._tableFactory(r,f[i],t);n.forEach(function(n){n[i]||(e?Object.defineProperty(n,i,{configurable:!0,enumerable:!0,get:function(){return u.PSD&&u.PSD.trans?u.PSD.trans.tables[i]:o}}):n[i]=o)})})}function yr(n){n.forEach(function(n){for(var t in n)n[t]instanceof fi&&delete n[t]})}function yi(n,t,i,r,f,e){var o=u.PSD;e=e||nt;n.onerror||(n.onerror=s(f));n.onsuccess=t?d(function(){var u=n.result,o;u?(o=function(){u.continue()},t(u,function(n){o=n},r,f)&&i(e(u.value),u,function(n){o=n}),o()):r()},f,o):d(function(){var t=n.result,u;t?(u=function(){t.continue()},i(e(t.value),t,function(n){u=n}),u()):r()},f,o)}function pr(n){var t=[];return n.split(",").forEach(function(n){n=n.trim();var i=n.replace("&","").replace("++","").replace("*",""),r=i.indexOf("[")!==0?i:n.substring(n.indexOf("[")+1,n.indexOf("]")).split("+");t.push(new v(i,r||null,n.indexOf("&")!=-1,n.indexOf("*")!=-1,n.indexOf("++")!=-1,Array.isArray(r),r.indexOf(".")!=-1))}),t}function pi(n,t){return n<t?-1:n>t?1:0}function fr(n,t){return n<t?1:n>t?-1:0}function er(n){return function(t,i){for(var r=0,u;;){if(u=n(t[r],i[r]),u!==0)return u;if(++r,r===t.length||r===i.length)return n(t.length,i.length)}}}function wi(n,t){return n?t?function(){return n.apply(this,arguments)&&t.apply(this,arguments)}:n:t}function wr(){return navigator.userAgent.indexOf("Trident")>=0||navigator.userAgent.indexOf("MSIE")>=0}function br(){if(w.verno=lt.version/10,w._dbSchema=pt={},ri=[].slice.call(lt.objectStoreNames,0),ri.length!=0){var n=lt.transaction(ri,"readonly");ri.forEach(function(t){for(var u,s,r=n.objectStore(t),i=r.keyPath,f=i&&typeof i=="string"&&i.indexOf(".")!=-1,h=new v(i,i||"",!1,!1,!!r.autoIncrement,i&&typeof i!="string",f),o=[],e=0;e<r.indexNames.length;++e)u=r.index(r.indexNames[e]),i=u.keyPath,f=i&&typeof i=="string"&&i.indexOf(".")!=-1,s=new v(u.name,i,!!u.unique,!!u.multiEntry,!1,i&&typeof i!="string",f),o.push(s);pt[t]=new ut(t,h,o,{})});rr([gt],w._transPromiseFactory,Object.keys(pt),kt,pt)}}function ur(n,t){for(var i,r,u,o,s=t.db.objectStoreNames,f=0;f<s.length;++f)for(i=s[f],r=t.objectStore(i),u=0;u<r.indexNames.length;++u){var h=r.indexNames[u],e=r.index(h).keyPath,c=typeof e=="string"?e:"["+[].slice.call(e).join("+")+"]";n[i]&&(o=n[i].idxByName[c],o&&(o.name=h))}}var ei=f.dependencies,ci=ei.indexedDB,dt=ei.IDBKeyRange,kr=ei.IDBTransaction,dr=ei.DOMError,vi=ei.TypeError,et=ei.Error,pt=this._dbSchema={},ii=[],ri=[],gt={},bi={},lt=null,oi=!0,ui=null,li=!1,ni="readonly",kt="readwrite",w=this,ti=[],ai=!1;this.version=function(n){if(lt)throw new et("Cannot add version when database is open");this.verno=Math.max(this.verno,n);var t=ii.filter(function(t){return t._cfg.version==n})[0];return t?t:(t=new ki(n),ii.push(t),ii.sort(vr),t)};h(ki.prototype,{stores:function(n){var i,t;return this._cfg.storesSource=this._cfg.storesSource?h(this._cfg.storesSource,n):n,i={},ii.forEach(function(n){h(i,n._cfg.storesSource)}),t=this._cfg.dbschema={},this._parseStoresSpec(i,t),pt=w._dbSchema=t,yr([gt,w,bi]),rr([bi],ar,Object.keys(t),kt,t),rr([gt,w,this._cfg.tables],w._transPromiseFactory,Object.keys(t),kt,t,!0),ri=Object.keys(t),this},upgrade:function(n){var t=this;return o(function(){n(w._createTransaction(kt,Object.keys(t._cfg.dbschema),t._cfg.dbschema))}),this._cfg.contentUpgrade=n,this},_parseStoresSpec:function(n,t){Object.keys(n).forEach(function(i){if(n[i]!==null){var u={},f=pr(n[i]),r=f.shift();if(r.multi)throw new et("Primary key cannot be multi-valued");r.keyPath&&r.auto&&c(u,r.keyPath,0);f.forEach(function(n){if(n.auto)throw new et("Only primary key can be marked as autoIncrement (++)");if(!n.keyPath)throw new et("Index must have a name and cannot be an empty string");c(u,n.keyPath,n.compound?n.keyPath.map(function(){return""}):"")});t[i]=new ut(i,r,f,u)}})}});this._allTables=gt;this._tableFactory=function(n,t,i){return n===ni?new fi(t.name,i,t,hi):new nr(t.name,i,t)};this._createTransaction=function(n,t,i,r){return new tr(n,t,i,r)};this._transPromiseFactory=function(n,t,i){var f,r;return!oi||u.PSD&&u.PSD.letThrough?(r=w._createTransaction(n,t,pt),r._promise(n,function(n,t){r.error(function(n){w.on("error").fire(n)});i(function(t){r.complete(function(){n(t)})},t,r)})):f=new u(function(r,u){ti.push({resume:function(){var e=w._transPromiseFactory(n,t,i);f.onuncatched=e.onuncatched;e.then(r,u)}})})};this._whenReady=function(n){return oi&&(!u.PSD||!u.PSD.letThrough)?new u(function(t,i){o(function(){new u(function(){n(t,i)})});ti.push({resume:function(){n(t,i)}})}):new u(n)};this.verno=0;this.open=function(){return new u(function(n,i){function f(n){li=!1;ui=n;oi=!1;i(ui);ti.forEach(function(n){n.resume()});ti=[]}if(lt||li)throw new et("Database already opened or being opened");try{if(ui=null,li=!0,ii.length==0&&(ai=!0),!ci)throw new et("indexedDB API not found. If using IE10+, make sure to run your code on a server URL (not locally). If using Safari, make sure to include indexedDB polyfill.");var e=!1,r=ai?ci.open(t):ci.open(t,Math.round(w.verno*10));r.onerror=s(f,["opening database",t]);r.onblocked=function(n){w.on("blocked").fire(n)};r.onupgradeneeded=d(function(n){var i,u;ai&&!w._allowEmptyDB?(r.onerror=function(n){n.preventDefault()},r.transaction.abort(),r.result.close(),i=ci.deleteDatabase(t),i.onsuccess=i.onerror=function(){f(new et("Database '"+t+"' doesnt exist"))}):(n.oldVersion==0&&(e=!0),r.transaction.onerror=s(f),u=n.oldVersion>Math.pow(2,62)?0:n.oldVersion,sr(u/10,r.transaction,f,r))},f);r.onsuccess=d(function(){li=!1;lt=r.result;ai?br():lt.objectStoreNames.length>0&&ur(pt,lt.transaction(lt.objectStoreNames,ni));lt.onversionchange=w.on("versionchange").fire;rt(function(n){if(n.indexOf(t)===-1)return n.push(t)});u.newPSD(function(){function i(){oi=!1;ti.forEach(function(n){n.resume()});ti=[];n()}u.PSD.letThrough=!0;try{var t=w.on.ready.fire();t&&typeof t.then=="function"?t.then(i,function(n){lt.close();lt=null;f(n)}):k(i)}catch(r){f(r)}})},f)}catch(o){f(o)}})};this.close=function(){lt&&(lt.close(),lt=null,oi=!0,ui=null)};this.delete=function(){var n=arguments;return new u(function(i,r){function u(){w.close();var n=ci.deleteDatabase(t);n.onsuccess=function(){rt(function(n){var i=n.indexOf(t);if(i>=0)return n.splice(i,1)});i()};n.onerror=s(r,["deleting",t]);n.onblocked=function(){w.on("blocked").fire()}}if(n.length>0)throw new et("Arguments not allowed in db.delete()");li?ti.push({resume:u}):u()})};this.backendDB=function(){return lt};this.isOpen=function(){return lt!==null};this.hasFailed=function(){return ui!==null};this.name=t;Object.defineProperty(this,"tables",{get:function(){return Object.keys(gt).map(function(n){return gt[n]})}});this.on=b(this,"error","populate","blocked",{ready:[yt,e],versionchange:[at,e]});this.on.ready.subscribe=p(this.on.ready.subscribe,function(n){return function(t,i){function r(){return i||w.on.ready.unsubscribe(r),t.apply(this,arguments)}n.call(this,r);w.isOpen()&&(oi?ti.push({resume:r}):r())}});o(function(){w.on("populate").fire(w._createTransaction(kt,ri,pt));w.on("error").fire(new et)});this.transaction=function(n,t,i){function s(t,e){var s=null,c,a,h;try{if(f)throw f;s=w._createTransaction(n,o,pt,r);c=o.map(function(n){return s.tables[n]});c.push(s);h=0;u.newPSD(function(){u.PSD.trans=s;s.scopeFunc=i;r&&(s.idbtrans=r.idbtrans,s._promise=p(s._promise,function(n){return function(t,i,r){function u(n){return function(t){var i=n(t);return--h==0&&s.active&&(s.active=!1,s.on.complete.fire()),i}}return++h,n.call(this,t,function(n,t,r){return i(u(n),u(t),r)},r)}}));s.complete(function(){t(a)});s.error(function(n){s.idbtrans.onerror=ot;s.abort();r&&(r.active=!1,r.on.error.fire(n));var t=e(n);r||t||w.on.error.fire(n)});a=i.apply(s,c)});(!s.idbtrans||r&&h===0)&&s._nop()}catch(l){s&&s.idbtrans&&(s.idbtrans.onerror=ot);s&&s.abort();r&&r.on.error.fire(l);k(function(){e(l)||w.on("error").fire(l)})}}var r,e;t=[].slice.call(arguments,1,arguments.length-1);i=arguments[arguments.length-1];r=u.PSD&&u.PSD.trans;n.indexOf("!")!==-1&&(r=null);e=n.indexOf("?")!==-1;n=n.replace("!","").replace("?","");var h=Array.isArray(t[0])?t.reduce(function(n,t){return n.concat(t)}):t,f=null,o=h.map(function(n){return typeof n=="string"?n:(n instanceof fi||(f=f||new vi("Invalid type. Arguments following mode must be instances of Table or String")),n.name)});return n=="r"||n==ni?n=ni:n=="rw"||n==kt?n=kt:f=new et("Invalid transaction mode: "+n),r&&(f||(r.db!=w&&(e?r=null:f=new et("Current transaction bound to different database instance")),r&&r.mode===ni&&n===kt&&(e?r=null:f=f||new et("Cannot enter a sub-transaction with READWRITE mode when parent transaction is READONLY")),r&&o.forEach(function(n){r.tables.hasOwnProperty(n)||(e?r=null:f=f||new et("Table "+n+" not included in parent transaction. Parent Transaction function: "+r.scopeFunc.toString()))}))),r?r._promise(n,s,"lock"):w._whenReady(s)};this.table=function(n){if(!ai&&!gt.hasOwnProperty(n))throw new et("Table does not exist");return gt[n]};h(fi.prototype,function(){function n(){throw new et("Current Transaction is READONLY");}return{_trans:function(n,t,i){return this._tpf(n,[this.name],t,i)},_idbstore:function(n,t,i){var r=this;return this._tpf(n,[this.name],function(n,i,u){t(n,i,u.idbtrans.objectStore(r.name),u)},i)},get:function(n,t){var i=this;return o(function(){t(i.schema.instanceTemplate)}),this._idbstore(ni,function(t,r,u){var f=u.get(n);f.onerror=s(r,["getting",n,"from",i.name]);f.onsuccess=function(){t(i.hook.reading.fire(f.result))}}).then(t)},where:function(n){return new si(this,n)},count:function(n){return this.toCollection().count(n)},offset:function(n){return this.toCollection().offset(n)},limit:function(n){return this.toCollection().limit(n)},reverse:function(){return this.toCollection().reverse()},filter:function(n){return this.toCollection().and(n)},each:function(n){var t=this;return o(function(){n(t.schema.instanceTemplate)}),this._idbstore(ni,function(i,r,u){var f=u.openCursor();f.onerror=s(r,["calling","Table.each()","on",t.name]);yi(f,null,n,i,r,t.hook.reading.fire)})},toArray:function(n){var t=this;return o(function(){n([t.schema.instanceTemplate])}),this._idbstore(ni,function(n,i,r){var u=[],f=r.openCursor();f.onerror=s(i,["calling","Table.toArray()","on",t.name]);yi(f,null,function(n){u.push(n)},function(){n(u)},i,t.hook.reading.fire)}).then(n)},orderBy:function(n){return new this._collClass(new si(this,n))},toCollection:function(){return new this._collClass(new si(this))},mapToClass:function(n,t){var i,r;return this.schema.mappedClass=n,i=Object.create(n.prototype),this.schema.primKey.keyPath&&(c(i,this.schema.primKey.keyPath,this.schema.primKey.auto?0:""),ft(n.prototype,this.schema.primKey.keyPath)),t&&it(i,t),this.schema.instanceTemplate=i,r=Object.setPrototypeOf?function(t){return t?(Object.setPrototypeOf(t,n.prototype),t):t}:function(t){var r,i;if(!t)return t;r=Object.create(n.prototype);for(i in t)t.hasOwnProperty(i)&&(r[i]=t[i]);return r},this.schema.readHook&&this.hook.reading.unsubscribe(this.schema.readHook),this.schema.readHook=r,this.hook("reading",r),n},defineClass:function(n){return this.mapToClass(f.defineClass(n),n)},add:n,put:n,"delete":n,clear:n,update:n}});y(nr).from(fi).extend(function(){return{add:function(n,t){var u=this,i=this.hook.creating.fire;return this._idbstore(kt,function(f,o,h,a){var v={},w,y,p;i!==e&&(w=t||(h.keyPath?l(n,h.keyPath):r),y=i.call(v,w,n,a),w===r&&y!==r&&(h.keyPath?c(n,h.keyPath,y):t=y));p=t?h.add(n,t):h.add(n);p.onerror=s(function(n){if(v.onerror)v.onerror(n);return o(n)},["adding",n,"into",u.name]);p.onsuccess=function(t){var i=h.keyPath;if(i&&c(n,i,t.target.result),v.onsuccess)v.onsuccess(t.target.result);f(p.result)}})},put:function(n,t){var i=this,u=this.hook.creating.fire,f=this.hook.updating.fire;return u!==e||f!==e?this._trans(kt,function(u,f,e){var o=t||i.schema.primKey.keyPath&&l(n,i.schema.primKey.keyPath);o===r?e.tables[i.name].add(n).then(u,f):(e._lock(),n=a(n),e.tables[i.name].where(":id").equals(o).modify(function(){this.value=n}).then(function(r){return r===0?e.tables[i.name].add(n,t):o}).finally(function(){e._unlock()}).then(u,f))}):this._idbstore(kt,function(r,u,f){var e=t?f.put(n,t):f.put(n);e.onerror=s(u,["putting",n,"into",i.name]);e.onsuccess=function(t){var i=f.keyPath;i&&c(n,i,t.target.result);r(e.result)}})},"delete":function(n){return this.hook.deleting.subscribers.length?this.where(":id").equals(n).delete():this._idbstore(kt,function(t,i,r){var u=r.delete(n);u.onerror=s(i,["deleting",n,"from",r.name]);u.onsuccess=function(){t(u.result)}})},clear:function(){return this.hook.deleting.subscribers.length?this.toCollection().delete():this._idbstore(kt,function(n,t,i){var r=i.clear();r.onerror=s(t,["clearing",i.name]);r.onsuccess=function(){n(r.result)}})},update:function(n,t){if(typeof t!="object"||Array.isArray(t))throw new et("db.update(keyOrObject, modifications). modifications must be an object.");if(typeof n!="object"||Array.isArray(n))return this.where(":id").equals(n).modify(t);Object.keys(t).forEach(function(i){c(n,i,t[i])});var i=l(n,this.schema.primKey.keyPath);return i===r&&u.reject(new et("Object does not contain its primary key")),this.where(":id").equals(i).modify(t)}}});h(tr.prototype,{_lock:function(){return++this._reculock,this._reculock===1&&u.PSD&&(u.PSD.lockOwnerFor=this),this},_unlock:function(){if(--this._reculock==0)for(u.PSD&&(u.PSD.lockOwnerFor=null);this._blockedFuncs.length>0&&!this._locked();){var n=this._blockedFuncs.shift();try{n()}catch(t){}}return this},_locked:function(){return this._reculock&&(!u.PSD||u.PSD.lockOwnerFor!==this)},_nop:function(n){this.tables[this.storeNames[0]].get(0).then(n)},_promise:function(n,t,i){var r=this;return u.newPSD(function(){var e;return r._locked()?e=new u(function(u,f){r._blockedFuncs.push(function(){r._promise(n,t,i).then(u,f)})}):(e=r.active?new u(function(u,e){if(!r.idbtrans&&n){if(!lt)throw ui?new et("Database not open. Following error in populate, ready or upgrade function made Dexie.open() fail: "+ui):new et("Database not open");var o=r.idbtrans=lt.transaction(r.storeNames,r.mode);o.onerror=function(n){r.on("error").fire(n&&n.target.error);n.preventDefault();r.abort()};o.onabort=function(n){r.active=!1;r.on("abort").fire(n)};o.oncomplete=function(n){r.active=!1;r.on("complete").fire(n)}}i&&r._lock();try{t(u,e,r)}catch(s){f.spawn(function(){r.on("error").fire(s)});r.abort();e(s)}}):u.reject(bt(new et("Transaction is inactive. Original Scope Function Source: "+r.scopeFunc.toString()))),r.active&&i&&e.finally(function(){r._unlock()})),e.onuncatched=function(n){f.spawn(function(){r.on("error").fire(n)});r.abort()},e})},complete:function(n){return this.on("complete",n)},error:function(n){return this.on("error",n)},abort:function(){if(this.idbtrans&&this.active)try{this.active=!1;this.idbtrans.abort();this.on.error.fire(new et("Transaction Aborted"))}catch(n){}},table:function(n){if(!this.tables.hasOwnProperty(n))throw new et("Table "+n+" not in transaction");return this.tables[n]}});h(si.prototype,function(){function n(n,t){try{throw t;}catch(i){n._ctx.error=i}return n}function i(n){return Array.prototype.slice.call(n.length===1&&Array.isArray(n[0])?n[0]:n)}function r(n){return n==="next"?function(n){return n.toUpperCase()}:function(n){return n.toLowerCase()}}function u(n){return n==="next"?function(n){return n.toLowerCase()}:function(n){return n.toUpperCase()}}function f(n,t,i,r,u,f){for(var h,s=Math.min(n.length,r.length),o=-1,e=0;e<s;++e){if(h=t[e],h!==r[e])return u(n[e],i[e])<0?n.substr(0,e)+i[e]+i.substr(e+1):u(n[e],r[e])<0?n.substr(0,e)+r[e]+i.substr(e+1):o>=0?n.substr(0,o)+t[o]+i.substr(o+1):null;u(n[e],h)<0&&(o=e)}return s<r.length&&f==="next"?n+i.substr(n.length):s<n.length&&f==="prev"?n.substr(0,i.length):o<0?null:n.substr(0,o)+r[o]+i.substr(o+1)}function t(n,t,i){function a(n){s=r(n);e=u(n);h=n==="next"?pi:fr;c=s(i);o=e(i);l=n}var s,e,h,c,o,l;a("next");n._ondirectionchange=function(n){a(n)};n._addAlgorithm(function(n,i,r){var u=n.key,s,a;return typeof u!="string"?!1:(s=e(u),t(s,o)?(i(function(){n.continue()}),!0):(a=f(u,s,c,o,h,l),a?i(function(){n.continue(a)}):i(r),!1))})}return{between:function(n,t,i,r){return(i=i!==!1,r=r===!0,n>t||n==t&&(i||r)&&!(i&&r))?new this._ctx.collClass(this,dt.only(n)).limit(0):new this._ctx.collClass(this,dt.bound(n,t,!i,!r))},equals:function(n){return new this._ctx.collClass(this,dt.only(n))},above:function(n){return new this._ctx.collClass(this,dt.lowerBound(n,!0))},aboveOrEqual:function(n){return new this._ctx.collClass(this,dt.lowerBound(n))},below:function(n){return new this._ctx.collClass(this,dt.upperBound(n,!0))},belowOrEqual:function(n){return new this._ctx.collClass(this,dt.upperBound(n))},startsWith:function(t){return typeof t!="string"?n(new this._ctx.collClass(this),new vi("String expected")):this.between(t,t+String.fromCharCode(65535),!0,!0)},startsWithIgnoreCase:function(i){if(typeof i!="string")return n(new this._ctx.collClass(this),new vi("String expected"));if(i==="")return this.startsWith(i);var r=new this._ctx.collClass(this,dt.bound(i.toUpperCase(),i.toLowerCase()+String.fromCharCode(65535)));return t(r,function(n,t){return n.indexOf(t)===0},i),r._ondirectionchange=function(){n(r,new et("reverse() not supported with WhereClause.startsWithIgnoreCase()"))},r},equalsIgnoreCase:function(i){if(typeof i!="string")return n(new this._ctx.collClass(this),new vi("String expected"));var r=new this._ctx.collClass(this,dt.bound(i.toUpperCase(),i.toLowerCase()));return t(r,function(n,t){return n===t},i),r},anyOf:function(){var f=this._ctx,e=f.table.schema,o=f.index?e.idxByName[f.index]:e.primKey,s=o&&o.compound,n=i(arguments),t=s?er(pi):pi,u,r;return(n.sort(t),n.length===0)?new this._ctx.collClass(this,dt.only("")).limit(0):(u=new this._ctx.collClass(this,dt.bound(n[0],n[n.length-1])),u._ondirectionchange=function(i){t=i==="next"?pi:fr;s&&(t=er(t));n.sort(t)},r=0,u._addAlgorithm(function(i,u,f){for(var e=i.key;t(e,n[r])>0;)if(++r,r===n.length)return u(f),!1;return t(e,n[r])===0?(u(function(){i.continue()}),!0):(u(function(){i.continue(n[r])}),!1)}),u)}}});h(hi.prototype,function(){function t(n,t){n.filter=wi(n.filter,t)}function f(n,t){n.isMatch=wi(n.isMatch,t)}function r(n,t){if(n.isPrimKey)return t;var i=n.table.schema.idxByName[n.index];if(!i)throw new et("KeyPath "+n.index+" on object store "+t.name+" is not indexed");return n.isPrimKey?t:t.index(i.name)}function u(n,t){return r(n,t)[n.op](n.range||null,n.dir+n.unique)}function i(n,t,i,r,f){n.or?function(){function e(){++c==2&&i()}function h(n,i,u){if(!o||o(i,u,e,r)){var f=i.primaryKey.toString();s.hasOwnProperty(f)||(s[f]=!0,t(n,i,u))}}var o=n.filter,s={},l=n.table.schema.primKey.keyPath,c=0;n.or._iterate(h,e,r,f);yi(u(n,f),n.algorithm,h,e,r,n.table.hook.reading.fire)}():yi(u(n,f),wi(n.algorithm,n.filter),t,i,r,n.table.hook.reading.fire)}function n(n){return n.table.schema.instanceTemplate}return{_read:function(n,t){var i=this._ctx;return i.error?i.table._trans(null,function(n,t){t(i.error)}):i.table._idbstore(ni,n).then(t)},_write:function(n){var t=this._ctx;return t.error?t.table._trans(null,function(n,i){i(t.error)}):t.table._idbstore(kt,n,"locked")},_addAlgorithm:function(n){var t=this._ctx;t.algorithm=wi(t.algorithm,n)},_iterate:function(n,t,r,u){return i(this._ctx,n,t,r,u)},each:function(t){var r=this._ctx;return o(function(){t(n(r))}),this._read(function(n,u,f){i(r,t,n,u,f)})},count:function(n){var f,t,u;return o(function(){n(0)}),f=this,t=this._ctx,t.filter||t.algorithm||t.or?(u=0,this._read(function(n,r,f){i(t,function(){return++u,!1},function(){n(u)},r,f)},n)):this._read(function(n,i,u){var e=r(t,u),o=t.range?e.count(t.range):e.count();o.onerror=s(i,["calling","count()","on",f.name]);o.onsuccess=function(i){n(Math.min(i.target.result,Math.max(0,t.limit-t.offset)))}},n)},sortBy:function(t,i){function u(n,t){return t?u(n[r[t]],t-1):n[h]}function c(n,t){var i=u(n,e),r=u(t,e);return i<r?-f:i>r?f:0}var s=this._ctx,f;o(function(){i([n(s)])});var r=t.split(".").reverse(),h=r[0],e=r.length-1;return f=this._ctx.dir==="next"?1:-1,this.toArray(function(n){return n.sort(c)}).then(i)},toArray:function(t){var r=this._ctx;return o(function(){t([n(r)])}),this._read(function(n,t,u){var f=[];i(r,function(n){f.push(n)},function(){n(f)},t,u)},t)},offset:function(n){var i=this._ctx;return n<=0?this:(i.offset+=n,i.or||i.algorithm||i.filter?t(i,function(){return--n<0}):t(i,function(t,i){return n===0?!0:n===1?(--n,!1):(i(function(){t.advance(n);n=0}),!1)}),this)},limit:function(n){return this._ctx.limit=Math.min(this._ctx.limit,n),t(this._ctx,function(t,i,r){return--n<=0&&i(r),n>=0}),this},until:function(i,r){var u=this._ctx;return o(function(){i(n(u))}),t(this._ctx,function(n,t,u){return i(n.value)?(t(u),r):!0}),this},first:function(t){var i=this;return o(function(){t(n(i._ctx))}),this.limit(1).toArray(function(n){return n[0]}).then(t)},last:function(n){return this.reverse().first(n)},and:function(i){var r=this;return o(function(){i(n(r._ctx))}),t(this._ctx,function(n){return i(n.value)}),f(this._ctx,i),this},or:function(n){return new si(this._ctx.table,n,this)},reverse:function(){return this._ctx.dir=this._ctx.dir=="prev"?"next":"prev",this._ondirectionchange&&this._ondirectionchange(this._ctx.dir),this},desc:function(){return this.reverse()},eachKey:function(t){var i=this,r=this._ctx;return o(function(){t(n(i._ctx)[i._ctx.index])}),r.isPrimKey||(r.op="openKeyCursor"),this.each(function(n,i){t(i.key,i)})},eachUniqueKey:function(n){return this._ctx.unique="unique",this.eachKey(n)},keys:function(t){var u,i,r;return o(function(){t([n(i)[u._ctx.index]])}),u=this,i=this._ctx,i.isPrimKey||(i.op="openKeyCursor"),r=[],this.each(function(n,t){r.push(t.key)}).then(function(){return r}).then(t)},uniqueKeys:function(n){return this._ctx.unique="unique",this.keys(n)},firstKey:function(n){var t=this;return this.limit(1).keys(function(n){return n[0]}).then(n)},lastKey:function(n){return this.reverse().firstKey(n)},distinct:function(){var n={};return t(this._ctx,function(t){var i=t.primaryKey.toString(),r=n.hasOwnProperty(i);return n[i]=!0,!r}),this}}});y(ir).from(hi).extend({modify:function(n){var f=this,t=this._ctx,r=t.table.hook,i=r.updating.fire,u=r.deleting.fire;return o(function(){typeof n=="function"&&n.call({value:t.table.schema.instanceTemplate},t.table.schema.instanceTemplate)}),this._write(function(r,o,v,y){function st(n,i){var r,u,f;ft=i.primaryKey;r={primKey:i.primaryKey,value:n};w.call(r,n)!==!1&&(u=!r.hasOwnProperty("value"),f=u?i.delete():i.update(r.value),++rt,f.onerror=s(function(n){if(p.push(n),nt.push(r.primKey),r.onerror)r.onerror(n);return!0},u?["deleting",n,"from",t.table.name]:["modifying",n,"on",t.table.name]),f.onsuccess=function(){if(r.onsuccess)r.onsuccess(r.value);++b;ot()})}function et(n){return n&&(p.push(n),nt.push(ft)),o(new g("Error modifying one or more objects",p,b,nt))}function ot(){ut&&b+p.length===rt&&(p.length>0?et():r(b))}var w,k,it,d;typeof n=="function"?w=i===e&&u===e?n:function(t){var f=a(t),e,r;if(n.call(this,t)===!1)return!1;this.hasOwnProperty("value")?(e=wt(f,this.value),r=i.call(this,e,this.primKey,f,y),r&&(t=this.value,Object.keys(r).forEach(function(n){c(t,n,r[n])}))):u.call(this,this.primKey,t,y)}:i===e?(k=Object.keys(n),it=k.length,w=function(t){for(var i,u,f=!1,r=0;r<it;++r)i=k[r],u=n[i],l(t,i)!==u&&(c(t,i,u),f=!0);return f}):(d=n,n=tt(d),w=function(t){var u=!1,r=i.call(this,n,this.primKey,a(t),y);return r&&h(n,r),Object.keys(n).forEach(function(i){var r=n[i];l(t,i)!==r&&(c(t,i,n[i]),u=!0)}),r&&(n=tt(d)),u});var rt=0,b=0,ut=!1,p=[],nt=[],ft=null;f._iterate(st,function(){ut=!0;ot()},et,v)})},"delete":function(){return this.modify(function(){delete this.value})}});h(this,{Collection:hi,Table:fi,Transaction:tr,Version:ki,WhereClause:si,WriteableCollection:ir,WriteableTable:nr});or();f.addons.forEach(function(n){n(w)})}function e(){}function nt(n){return n}function st(n,t){return n===nt?t:function(i){return t(n(i))}}function w(n,t){return function(){n.apply(this,arguments);t.apply(this,arguments)}}function ht(n,t){return n===e?t:function(){var f=n.apply(this,arguments),i,u,e;return f!==r&&(arguments[0]=f),i=this.onsuccess,u=this.onerror,delete this.onsuccess,delete this.onerror,e=t.apply(this,arguments),i&&(this.onsuccess=this.onsuccess?w(i,this.onsuccess):i),u&&(this.onerror=this.onerror?w(u,this.onerror):u),e!==r?e:f}}function ct(n,t){return n===e?t:function(){var i=n.apply(this,arguments),f,e,u;return i!==r&&h(arguments[0],i),f=this.onsuccess,e=this.onerror,delete this.onsuccess,delete this.onerror,u=t.apply(this,arguments),f&&(this.onsuccess=this.onsuccess?w(f,this.onsuccess):f),e&&(this.onerror=this.onerror?w(e,this.onerror):e),i===r?u===r?r:u:u===r?i:h(i,u)}}function lt(n,t){return n===e?t:function(){return n.apply(this,arguments)===!1?!1:t.apply(this,arguments)}}function at(n,t){return n===e?t:function(){return t.apply(this,arguments)===!1?!1:n.apply(this,arguments)}}function vt(n,t){return n===e?t:function(){n.apply(this,arguments);t.apply(this,arguments)}}function yt(n,t){return n===e?t:function(){var i=n.apply(this,arguments),r,u;return i&&typeof i.then=="function"?(r=this,u=arguments,i.then(function(){return t.apply(r,u)})):t.apply(this,arguments)}}function b(t){function i(n,t,i){if(Array.isArray(n))return c(n);if(typeof n=="object")return h(n);t||(t=lt);i||(i=e);var r={subscribers:[],fire:i,subscribe:function(n){r.subscribers.push(n);r.fire=t(r.fire,n)},unsubscribe:function(n){r.subscribers=r.subscribers.filter(function(t){return t!==n});r.fire=r.subscribers.reduce(t,i)}};return u[n]=f[n]=r,r}function h(t){Object.keys(t).forEach(function(r){var f=t[r],u;if(Array.isArray(f))i(r,t[r][0],t[r][1]);else if(f==="asap")u=i(r,null,function(){var t=arguments;u.subscribers.forEach(function(i){k(function(){i.apply(n,t)})})}),u.subscribe=function(n){u.subscribers.indexOf(n)===-1&&u.subscribers.push(n)},u.unsubscribe=function(n){var t=u.subscribers.indexOf(n);t!==-1&&u.subscribers.splice(t,1)};else throw new Error("Invalid event config");})}function c(n){function r(){if(t)return!1;t=!0}var t=!1;n.forEach(function(n){i(n).subscribe(r)})}var o=arguments,u={},f=function(n,i){if(i){var f=[].slice.call(arguments,1),r=u[n];return r.subscribe.apply(r,f),t}if(typeof n=="string")return u[n]},r,s;for(f.addEventType=i,r=1,s=o.length;r<s;++r)i(o[r]);return f}function pt(n){if(!n)throw new Error("Assertion failed");}function k(t){n.setImmediate?setImmediate(t):setTimeout(t,0)}function o(n){var t=setTimeout(n,1e3);clearTimeout(t)}function d(n,t,i){return function(){var r=u.PSD;u.PSD=i;try{n.apply(this,arguments)}catch(f){t(f)}finally{u.PSD=r}}}function l(n,t){var f,i,o,s,u,e;if(n.hasOwnProperty(t))return n[t];if(!t)return n;if(typeof t!="string"){for(f=[],i=0,o=t.length;i<o;++i)s=l(n,t[i]),f.push(s);return f}return(u=t.indexOf("."),u!==-1)?(e=n[t.substr(0,u)],e===r?r:l(e,t.substr(u+1))):r}function c(n,t,i){var u,h,e,f,s,o;if(n&&t!==r)if(typeof t!="string"&&"length"in t)for(pt(typeof i!="string"&&"length"in i),u=0,h=t.length;u<h;++u)c(n,t[u],i[u]);else e=t.indexOf("."),e!==-1?(f=t.substr(0,e),s=t.substr(e+1),s===""?i===r?delete n[f]:n[f]=i:(o=n[f],o||(o=n[f]={}),c(o,s,i))):i===r?delete n[t]:n[t]=i}function ft(n,t){c(n,t,r)}function tt(n){var i={};for(var t in n)n.hasOwnProperty(t)&&(i[t]=n[t]);return i}function a(n){var t,i,u,r;if(!n||typeof n!="object")return n;if(Array.isArray(n))for(t=[],i=0,u=n.length;i<u;++i)t.push(a(n[i]));else if(n instanceof Date)t=new Date,t.setTime(n.getTime());else{t=n.constructor?Object.create(n.constructor.prototype):{};for(r in n)n.hasOwnProperty(r)&&(t[r]=a(n[r]))}return t}function wt(n,t){var u={};for(var i in n)n.hasOwnProperty(i)&&(t.hasOwnProperty(i)?n[i]!==t[i]&&JSON.stringify(n[i])!=JSON.stringify(t[i])&&(u[i]=t[i]):u[i]=r);for(i in t)t.hasOwnProperty(i)&&!n.hasOwnProperty(i)&&(u[i]=t[i]);return u}function et(n){if(typeof n=="function")return new n;if(Array.isArray(n))return[et(n[0])];if(n&&typeof n=="object"){var t={};return it(t,n),t}return n}function it(n,t){Object.keys(t).forEach(function(i){var r=et(t[i]);n[i]=r})}function s(n,t){return function(i){var r=i&&i.target.error||new Error,u;return t&&(u=" occured when "+t.map(function(n){switch(typeof n){case"function":return n();case"string":return n;default:return JSON.stringify(n)}}).join(" "),r.name?r.toString=function(){return r.name+u+(r.message?". "+r.message:"")}:r=r+u),n(r),i.stopPropagation(),i.preventDefault(),!1}}function bt(n){try{throw n;}catch(t){return t}}function ot(n){n.preventDefault()}function rt(n){var t;try{t=JSON.parse(localStorage.getItem("Dexie.DatabaseNames")||"[]")}catch(i){t=[]}n(t)&&localStorage.setItem("Dexie.DatabaseNames",JSON.stringify(t))}function v(n,t,i,r,u,f,e){this.name=n;this.keyPath=t;this.unique=i;this.multi=r;this.auto=u;this.compound=f;this.dotted=e;var o=typeof t=="string"?t:t&&"["+[].join.call(t,"+")+"]";this.src=(i?"&":"")+(r?"*":"")+(u?"++":"")+o}function ut(n,t,i,r){this.name=n;this.primKey=t||new v;this.indexes=i||[new v];this.instanceTemplate=r;this.mappedClass=null;this.idxByName=i.reduce(function(n,t){return n[t.name]=t,n},{})}function g(n,t,i,r){this.name="ModifyError";this.failures=t;this.failedKeys=r;this.successCount=i;this.message=t.join("\n")}var u=function(){function y(n){r.push([n,s.call(arguments,1)])}function p(){var u=r,t,f,i;for(r=[],t=0,f=u.length;t<f;++t)i=u[t],i[0].apply(n,i[1])}function t(n){if(typeof this!="object")throw new TypeError("Promises must be constructed via new");if(typeof n!="function")throw new TypeError("not a function");this._state=null;this._value=null;this._deferreds=[];this._catched=!1;var r=this,f=!0;this._PSD=t.PSD;try{v(this,n,function(n){f?i(o,r,n):o(r,n)},function(n){return f?(i(u,r,n),!1):u(r,n)})}finally{f=!1}}function e(n,t){var e,u,o,l;if(n._state===null){n._deferreds.push(t);return}if(e=n._state?t.onFulfilled:t.onRejected,e===null)return(n._state?t.resolve:t.reject)(n._value);o=f;f=!1;i=y;try{u=e(n._value);n._state||u&&typeof u.then=="function"&&u._state===!1||c(n)}catch(s){if(l=t.reject(s),!l&&n.onuncatched)try{n.onuncatched(s)}catch(s){}return}if(t.resolve(u),o){while(r.length>0)p();i=h;f=!0}}function c(n){n._catched=!0;n._parent&&c(n._parent)}function o(n,i){var r=t.PSD;t.PSD=n._PSD;try{if(i===n)throw new TypeError("A promise cannot be resolved with itself.");if(i&&(typeof i=="object"||typeof i=="function")&&typeof i.then=="function"){v(n,function(n,t){i.then(n,t)},function(t){o(n,t)},function(t){u(n,t)});return}n._state=!0;n._value=i;l.call(n)}catch(f){u(f)}finally{t.PSD=r}}function u(n,i){var r=t.PSD;if(t.PSD=n._PSD,n._state=!1,n._value=i,l.call(n),!n._catched&&n.onuncatched)try{n.onuncatched(n._value)}catch(u){}return t.PSD=r,n._catched}function l(){for(var n=0,t=this._deferreds.length;n<t;n++)e(this,this._deferreds[n]);this._deferreds=[]}function a(n,t,i,r){this.onFulfilled=typeof n=="function"?n:null;this.onRejected=typeof t=="function"?t:null;this.resolve=i;this.reject=r}function v(n,t,i,r){var u=!1;try{t(function(n){u||(u=!0,i(n))},function(t){return u?n._catched:(u=!0,r(t))})}catch(f){return u?void 0:r(f)}}var s=[].slice,h=typeof setImmediate=="undefined"?function(t){var i=arguments;setTimeout(function(){t.apply(n,s.call(i,1))},0)}:setImmediate,i=h,f=!0,r=[];return t.all=function(){var n=Array.prototype.slice.call(arguments.length===1&&Array.isArray(arguments[0])?arguments[0]:arguments);return new t(function(t,i){function f(r,e){try{if(e&&(typeof e=="object"||typeof e=="function")){var o=e.then;if(typeof o=="function"){o.call(e,function(n){f(r,n)},i);return}}n[r]=e;--u==0&&t(n)}catch(s){i(s)}}var u,r;if(n.length===0)return t([]);for(u=n.length,r=0;r<n.length;r++)f(r,n[r])})},t.prototype.then=function(n,r){var f=this,u=new t(function(t,u){f._state===null?e(f,new a(n,r,t,u)):i(e,f,new a(n,r,t,u))});return u._PSD=this._PSD,u.onuncatched=this.onuncatched,u._parent=this,u},t.prototype["catch"]=function(n){if(arguments.length===1)return this.then(null,n);var i=arguments[0],r=arguments[1];return typeof i=="function"?this.then(null,function(n){return n instanceof i?r(n):t.reject(n)}):this.then(null,function(n){return n&&n.name===i?r(n):t.reject(n)})},t.prototype["finally"]=function(n){return this.then(function(t){return n(),t},function(i){return n(),t.reject(i)})},t.prototype.onuncatched=null,t.resolve=function(n){var i=new t(function(){});return i._state=!0,i._value=n,i},t.reject=function(n){var i=new t(function(){});return i._state=!1,i._value=n,i},t.race=function(n){return new t(function(t,i){n.map(function(n){n.then(t,i)})})},t.PSD=null,t.newPSD=function(n){var i=t.PSD;t.PSD=i?Object.create(i):{};try{return n()}finally{t.PSD=i}},t}();y(g).from(Error);f.delete=function(n){var t=new f(n),i=t.delete();return i.onblocked=function(n){t.on("blocked",n);return this},i};f.getDatabaseNames=function(n){return new u(function(n,t){if("webkitGetDatabaseNames"in indexedDB||"getDatabaseNames"in indexedDB){var i="getDatabaseNames"in indexedDB?indexedDB.getDatabaseNames():indexedDB.webkitGetDatabaseNames();i.onsuccess=function(t){n([].slice.call(t.target.result,0))};i.onerror=s(t)}else rt(function(t){return n(t),!1})}).then(n)};f.defineClass=function(n){function t(n){n&&h(this,n)}return it(t.prototype,n),t};f.spawn=function(n){return u.newPSD(function(){return u.PSD.trans=null,n()})};f.vip=function(n){return u.newPSD(function(){return u.PSD.letThrough=!0,n()})};Object.defineProperty(f,"currentTransaction",{get:function(){return u.PSD&&u.PSD.trans||null}});f.Promise=u;f.derive=y;f.extend=h;f.override=p;f.events=b;f.getByKeyPath=l;f.setByKeyPath=c;f.delByKeyPath=ft;f.shallowClone=tt;f.deepClone=a;f.addons=[];f.fakeAutoComplete=o;f.asap=k;f.ModifyError=g;f.MultiModifyError=g;f.IndexSpec=v;f.TableSchema=ut;f.dependencies={indexedDB:n.indexedDB||n.mozIndexedDB||n.webkitIndexedDB||n.msIndexedDB,IDBKeyRange:n.IDBKeyRange||n.webkitIDBKeyRange,IDBTransaction:n.IDBTransaction||n.webkitIDBTransaction,Error:n.Error||String,SyntaxError:n.SyntaxError||String,TypeError:n.TypeError||String,DOMError:n.DOMError||String};f.version=1.02;t("Dexie",f)}).apply(this,typeof module=="undefined"||typeof window!="undefined"&&this==window?[window,function(n,t){window[n]=t},!0]:[global,function(n,t){module.exports=t},!1]);
//# sourceMappingURL=Dexie.min.js.map
<html>
<body>
<h1>IndexedDB MTG full-text search demo</h1>
<p>Run this in Firefox or Chrome. Look in the console.</p>
<script src="lunr.min.js"></script>
<script src="Dexie.min.js"></script>
<script src="index.js"></script>
</body>
</html>
var attempt = Date.now(), reminder = {};
var db;
var log = console.log.bind(console);
var index = lunr();
function getTokenStream(text) {
return index.pipeline.run(lunr.tokenizer(text));
}
function search(query) {
var docs = [];
return db.transaction('r', db.cards, function () {
db.cards.where("tokens").equals(query).each(function (doc) {
docs.push(doc);
});
}).then(function () {
return docs;
});
}
Promise.resolve()
.then(start('Attempt ' + attempt, 'group'))
.then(start('Destroying database'))
.then(function() {
return new Promise(function (resolve, reject) {
var req = indexedDB.deleteDatabase('test');
req.onsuccess = resolve;
req.onerror = resolve;
});
})
.then(stop())
.then(start('Creating database'))
.then(function() {
return new Promise(function (resolve, reject) {
db = new Dexie("test");
db.version(1).stores({cards: "&name,text,*tokens"});
db.open();
resolve();
});
})
.then(stop())
.then(start('Downloading cards'))
.then(function(db) {
return new Promise(function(resolve, reject) {
window.mtgjsoncallback = function(cards) {
resolve({ db: db, cards: cards });
};
var script = document.createElement('script');
script.src = 'http://mtgjson.com/json/AllCards.jsonp';
script.onload = function() {
script.parentNode.removeChild(script);
};
document.body.appendChild(script);
});
})
.then(stop())
.then(start('Transforming object to array'))
.then(function(result) {
result.cards = Object.keys(result.cards).map(function(name) {
return result.cards[name];
});
return result;
})
.then(stop())
.then(start('Inserting data'))
.then(function(result) {
return db.transaction("rw", db.cards, function () {
result.cards.forEach(function (card) {
var tokenStream = getTokenStream(card.text);
var cardToInsert = {
name: card.name,
text: card.text,
tokens: tokenStream
};
db.cards.add(cardToInsert);
});
});
})
.then(stop())
.then(start('Searching for "jeskai"'))
.then(function() {
return search('jeskai').then(log);
})
.then(stop())
.then(start('Searching for "counter"'))
.then(function() {
return search('counter').then(log);
})
.then(stop())
.then(start('Searching for "target"'))
.then(function() {
return search('target').then(log);
})
.then(stop())
.catch(console.error.bind(console))
.then(console.log.bind(console, 'Done!'))
.then(stop('group'), stop('group'));
// Helpers
function start(label, type) {
return function(result) {
reminder[type] = label;
if(type !== 'group') console.log(label);
console[type || 'time'](label);
return result;
};
}
function stop(type) {
return function(result) {
console[(type || 'time') + 'End'](reminder[type]);
return result;
};
}
/**
* lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.5.7
* Copyright (C) 2014 Oliver Nightingale
* MIT Licensed
* @license
*/
!function(){var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.5.7",t.utils={},t.utils.warn=function(t){return function(e){t.console&&console.warn&&console.warn(e)}}(this),t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var t=Array.prototype.slice.call(arguments),e=t.pop(),n=t;if("function"!=typeof e)throw new TypeError("last argument must be a function");n.forEach(function(t){this.hasHandler(t)||(this.events[t]=[]),this.events[t].push(e)},this)},t.EventEmitter.prototype.removeListener=function(t,e){if(this.hasHandler(t)){var n=this.events[t].indexOf(e);this.events[t].splice(n,1),this.events[t].length||delete this.events[t]}},t.EventEmitter.prototype.emit=function(t){if(this.hasHandler(t)){var e=Array.prototype.slice.call(arguments,1);this.events[t].forEach(function(t){t.apply(void 0,e)})}},t.EventEmitter.prototype.hasHandler=function(t){return t in this.events},t.tokenizer=function(t){if(!arguments.length||null==t||void 0==t)return[];if(Array.isArray(t))return t.map(function(t){return t.toLowerCase()});for(var e=t.toString().replace(/^\s+/,""),n=e.length-1;n>=0;n--)if(/\S/.test(e.charAt(n))){e=e.substring(0,n+1);break}return e.split(/(?:\s+|\-)/).filter(function(t){return!!t}).map(function(t){return t.toLowerCase()})},t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.registeredFunctions[e];if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e)+1;this._stack.splice(i,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);this._stack.splice(i,0,n)},t.Pipeline.prototype.remove=function(t){var e=this._stack.indexOf(t);this._stack.splice(e,1)},t.Pipeline.prototype.run=function(t){for(var e=[],n=t.length,i=this._stack.length,o=0;n>o;o++){for(var r=t[o],s=0;i>s&&(r=this._stack[s](r,o,t),void 0!==r);s++);void 0!==r&&e.push(r)}return e},t.Pipeline.prototype.reset=function(){this._stack=[]},t.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Vector=function(){this._magnitude=null,this.list=void 0,this.length=0},t.Vector.Node=function(t,e,n){this.idx=t,this.val=e,this.next=n},t.Vector.prototype.insert=function(e,n){var i=this.list;if(!i)return this.list=new t.Vector.Node(e,n,i),this.length++;for(var o=i,r=i.next;void 0!=r;){if(e<r.idx)return o.next=new t.Vector.Node(e,n,r),this.length++;o=r,r=r.next}return o.next=new t.Vector.Node(e,n,r),this.length++},t.Vector.prototype.magnitude=function(){if(this._magniture)return this._magnitude;for(var t,e=this.list,n=0;e;)t=e.val,n+=t*t,e=e.next;return this._magnitude=Math.sqrt(n)},t.Vector.prototype.dot=function(t){for(var e=this.list,n=t.list,i=0;e&&n;)e.idx<n.idx?e=e.next:e.idx>n.idx?n=n.next:(i+=e.val*n.val,e=e.next,n=n.next);return i},t.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},t.SortedSet=function(){this.length=0,this.elements=[]},t.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},t.SortedSet.prototype.add=function(){Array.prototype.slice.call(arguments).forEach(function(t){~this.indexOf(t)||this.elements.splice(this.locationFor(t),0,t)},this),this.length=this.elements.length},t.SortedSet.prototype.toArray=function(){return this.elements.slice()},t.SortedSet.prototype.map=function(t,e){return this.elements.map(t,e)},t.SortedSet.prototype.forEach=function(t,e){return this.elements.forEach(t,e)},t.SortedSet.prototype.indexOf=function(t,e,n){var e=e||0,n=n||this.elements.length,i=n-e,o=e+Math.floor(i/2),r=this.elements[o];return 1>=i?r===t?o:-1:t>r?this.indexOf(t,o,n):r>t?this.indexOf(t,e,o):r===t?o:void 0},t.SortedSet.prototype.locationFor=function(t,e,n){var e=e||0,n=n||this.elements.length,i=n-e,o=e+Math.floor(i/2),r=this.elements[o];if(1>=i){if(r>t)return o;if(t>r)return o+1}return t>r?this.locationFor(t,o,n):r>t?this.locationFor(t,e,o):void 0},t.SortedSet.prototype.intersect=function(e){for(var n=new t.SortedSet,i=0,o=0,r=this.length,s=e.length,a=this.elements,h=e.elements;;){if(i>r-1||o>s-1)break;a[i]!==h[o]?a[i]<h[o]?i++:a[i]>h[o]&&o++:(n.add(a[i]),i++,o++)}return n},t.SortedSet.prototype.clone=function(){var e=new t.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},t.SortedSet.prototype.union=function(t){var e,n,i;return this.length>=t.length?(e=this,n=t):(e=t,n=this),i=e.clone(),i.add.apply(i,n.toArray()),i},t.SortedSet.prototype.toJSON=function(){return this.toArray()},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.Store,this.tokenStore=new t.TokenStore,this.corpusTokens=new t.SortedSet,this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var t=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,t)},t.Index.prototype.off=function(t,e){return this.eventEmitter.removeListener(t,e)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;return n._fields=e.fields,n._ref=e.ref,n.documentStore=t.Store.load(e.documentStore),n.tokenStore=t.TokenStore.load(e.tokenStore),n.corpusTokens=t.SortedSet.load(e.corpusTokens),n.pipeline=t.Pipeline.load(e.pipeline),n},t.Index.prototype.field=function(t,e){var e=e||{},n={name:t,boost:e.boost||1};return this._fields.push(n),this},t.Index.prototype.ref=function(t){return this._ref=t,this},t.Index.prototype.add=function(e,n){var i={},o=new t.SortedSet,r=e[this._ref],n=void 0===n?!0:n;this._fields.forEach(function(n){var r=this.pipeline.run(t.tokenizer(e[n.name]));i[n.name]=r,t.SortedSet.prototype.add.apply(o,r)},this),this.documentStore.set(r,o),t.SortedSet.prototype.add.apply(this.corpusTokens,o.toArray());for(var s=0;s<o.length;s++){var a=o.elements[s],h=this._fields.reduce(function(t,e){var n=i[e.name].length;if(!n)return t;var o=i[e.name].filter(function(t){return t===a}).length;return t+o/n*e.boost},0);this.tokenStore.add(a,{ref:r,tf:h})}n&&this.eventEmitter.emit("add",e,this)},t.Index.prototype.remove=function(t,e){var n=t[this._ref],e=void 0===e?!0:e;if(this.documentStore.has(n)){var i=this.documentStore.get(n);this.documentStore.remove(n),i.forEach(function(t){this.tokenStore.remove(t,n)},this),e&&this.eventEmitter.emit("remove",t,this)}},t.Index.prototype.update=function(t,e){var e=void 0===e?!0:e;this.remove(t,!1),this.add(t,!1),e&&this.eventEmitter.emit("update",t,this)},t.Index.prototype.idf=function(t){var e="@"+t;if(Object.prototype.hasOwnProperty.call(this._idfCache,e))return this._idfCache[e];var n=this.tokenStore.count(t),i=1;return n>0&&(i=1+Math.log(this.tokenStore.length/n)),this._idfCache[e]=i},t.Index.prototype.search=function(e){var n=this.pipeline.run(t.tokenizer(e)),i=new t.Vector,o=[],r=this._fields.reduce(function(t,e){return t+e.boost},0),s=n.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];n.forEach(function(e,n,s){var a=1/s.length*this._fields.length*r,h=this,u=this.tokenStore.expand(e).reduce(function(n,o){var r=h.corpusTokens.indexOf(o),s=h.idf(o),u=1,l=new t.SortedSet;if(o!==e){var c=Math.max(3,o.length-e.length);u=1/Math.log(c)}return r>-1&&i.insert(r,a*s*u),Object.keys(h.tokenStore.get(o)).forEach(function(t){l.add(t)}),n.union(l)},new t.SortedSet);o.push(u)},this);var a=o.reduce(function(t,e){return t.intersect(e)});return a.map(function(t){return{ref:t,score:i.similarity(this.documentVector(t))}},this).sort(function(t,e){return e.score-t.score})},t.Index.prototype.documentVector=function(e){for(var n=this.documentStore.get(e),i=n.length,o=new t.Vector,r=0;i>r;r++){var s=n.elements[r],a=this.tokenStore.get(s)[e].tf,h=this.idf(s);o.insert(this.corpusTokens.indexOf(s),a*h)}return o},t.Index.prototype.toJSON=function(){return{version:t.version,fields:this._fields,ref:this._ref,documentStore:this.documentStore.toJSON(),tokenStore:this.tokenStore.toJSON(),corpusTokens:this.corpusTokens.toJSON(),pipeline:this.pipeline.toJSON()}},t.Index.prototype.use=function(t){var e=Array.prototype.slice.call(arguments,1);e.unshift(this),t.apply(this,e)},t.Store=function(){this.store={},this.length=0},t.Store.load=function(e){var n=new this;return n.length=e.length,n.store=Object.keys(e.store).reduce(function(n,i){return n[i]=t.SortedSet.load(e.store[i]),n},{}),n},t.Store.prototype.set=function(t,e){this.has(t)||this.length++,this.store[t]=e},t.Store.prototype.get=function(t){return this.store[t]},t.Store.prototype.has=function(t){return t in this.store},t.Store.prototype.remove=function(t){this.has(t)&&(delete this.store[t],this.length--)},t.Store.prototype.toJSON=function(){return{store:this.store,length:this.length}},t.stemmer=function(){var t={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},e={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},n="[^aeiou]",i="[aeiouy]",o=n+"[^aeiouy]*",r=i+"[aeiou]*",s="^("+o+")?"+r+o,a="^("+o+")?"+r+o+"("+r+")?$",h="^("+o+")?"+r+o+r+o,u="^("+o+")?"+i,l=new RegExp(s),c=new RegExp(h),p=new RegExp(a),f=new RegExp(u),d=/^(.+?)(ss|i)es$/,v=/^(.+?)([^s])s$/,m=/^(.+?)eed$/,g=/^(.+?)(ed|ing)$/,y=/.$/,S=/(at|bl|iz)$/,w=new RegExp("([^aeiouylsz])\\1$"),x=new RegExp("^"+o+i+"[^aeiouwxy]$"),k=/^(.+?[^aeiou])y$/,b=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,E=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,_=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,O=/^(.+?)(s|t)(ion)$/,F=/^(.+?)e$/,P=/ll$/,T=new RegExp("^"+o+i+"[^aeiouwxy]$"),$=function(n){var i,o,r,s,a,h,u;if(n.length<3)return n;if(r=n.substr(0,1),"y"==r&&(n=r.toUpperCase()+n.substr(1)),s=d,a=v,s.test(n)?n=n.replace(s,"$1$2"):a.test(n)&&(n=n.replace(a,"$1$2")),s=m,a=g,s.test(n)){var $=s.exec(n);s=l,s.test($[1])&&(s=y,n=n.replace(s,""))}else if(a.test(n)){var $=a.exec(n);i=$[1],a=f,a.test(i)&&(n=i,a=S,h=w,u=x,a.test(n)?n+="e":h.test(n)?(s=y,n=n.replace(s,"")):u.test(n)&&(n+="e"))}if(s=k,s.test(n)){var $=s.exec(n);i=$[1],n=i+"i"}if(s=b,s.test(n)){var $=s.exec(n);i=$[1],o=$[2],s=l,s.test(i)&&(n=i+t[o])}if(s=E,s.test(n)){var $=s.exec(n);i=$[1],o=$[2],s=l,s.test(i)&&(n=i+e[o])}if(s=_,a=O,s.test(n)){var $=s.exec(n);i=$[1],s=c,s.test(i)&&(n=i)}else if(a.test(n)){var $=a.exec(n);i=$[1]+$[2],a=c,a.test(i)&&(n=i)}if(s=F,s.test(n)){var $=s.exec(n);i=$[1],s=c,a=p,h=T,(s.test(i)||a.test(i)&&!h.test(i))&&(n=i)}return s=P,a=c,s.test(n)&&a.test(n)&&(s=y,n=n.replace(s,"")),"y"==r&&(n=r.toLowerCase()+n.substr(1)),n};return $}(),t.Pipeline.registerFunction(t.stemmer,"stemmer"),t.stopWordFilter=function(e){return-1===t.stopWordFilter.stopWords.indexOf(e)?e:void 0},t.stopWordFilter.stopWords=new t.SortedSet,t.stopWordFilter.stopWords.length=119,t.stopWordFilter.stopWords.elements=["","a","able","about","across","after","all","almost","also","am","among","an","and","any","are","as","at","be","because","been","but","by","can","cannot","could","dear","did","do","does","either","else","ever","every","for","from","get","got","had","has","have","he","her","hers","him","his","how","however","i","if","in","into","is","it","its","just","least","let","like","likely","may","me","might","most","must","my","neither","no","nor","not","of","off","often","on","only","or","other","our","own","rather","said","say","says","she","should","since","so","some","than","that","the","their","them","then","there","these","they","this","tis","to","too","twas","us","wants","was","we","were","what","when","where","which","while","who","whom","why","will","with","would","yet","you","your"],t.Pipeline.registerFunction(t.stopWordFilter,"stopWordFilter"),t.trimmer=function(t){return t.replace(/^\W+/,"").replace(/\W+$/,"")},t.Pipeline.registerFunction(t.trimmer,"trimmer"),t.TokenStore=function(){this.root={docs:{}},this.length=0},t.TokenStore.load=function(t){var e=new this;return e.root=t.root,e.length=t.length,e},t.TokenStore.prototype.add=function(t,e,n){var n=n||this.root,i=t[0],o=t.slice(1);return i in n||(n[i]={docs:{}}),0===o.length?(n[i].docs[e.ref]=e,void(this.length+=1)):this.add(o,e,n[i])},t.TokenStore.prototype.has=function(t){if(!t)return!1;for(var e=this.root,n=0;n<t.length;n++){if(!e[t[n]])return!1;e=e[t[n]]}return!0},t.TokenStore.prototype.getNode=function(t){if(!t)return{};for(var e=this.root,n=0;n<t.length;n++){if(!e[t[n]])return{};e=e[t[n]]}return e},t.TokenStore.prototype.get=function(t,e){return this.getNode(t,e).docs||{}},t.TokenStore.prototype.count=function(t,e){return Object.keys(this.get(t,e)).length},t.TokenStore.prototype.remove=function(t,e){if(t){for(var n=this.root,i=0;i<t.length;i++){if(!(t[i]in n))return;n=n[t[i]]}delete n.docs[e]}},t.TokenStore.prototype.expand=function(t,e){var n=this.getNode(t),i=n.docs||{},e=e||[];return Object.keys(i).length&&e.push(t),Object.keys(n).forEach(function(n){"docs"!==n&&e.concat(this.expand(t+n,e))},this),e},t.TokenStore.prototype.toJSON=function(){return{root:this.root,length:this.length}},function(t,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():t.lunr=e()}(this,function(){return t})}();
@EloB
Copy link

EloB commented Dec 30, 2017

How fast is this compared to WebSQL? Can’t try it right now because I don’t have a computer atm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment