canada-api 1.0.0

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/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # canada-api
2
+
3
+ API for fetching public data from [canada.ca](https://www.canada.ca). Implements rate limiting to prevent being throttled.
4
+
5
+ ## Install
6
+
7
+ ### Browsers
8
+
9
+ <script src="https://cdn.jsdelivr.net/gh/bsoicher/canada-api/dist/ca.js"><script>
10
+
11
+ Support: Edge 15+, Firefox 54+, Chrome 51+, Safari 10+
12
+
13
+ ### Nodejs
14
+
15
+ Will be published to npm once stable
16
+
17
+ ## API
18
+
19
+ ### ca.children(node)
20
+
21
+ Fetches listing of child nodes
22
+
23
+ ### ca.content(node)
24
+
25
+ Fetches content of a node
26
+
27
+ ### ca.meta(node)
28
+
29
+ Fetches metadata of a node
30
+
31
+ Note: API also works for DAM assets
package/dist/ca.js ADDED
@@ -0,0 +1 @@
1
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("cross-fetch")):"function"==typeof define&&define.amd?define("ca",["cross-fetch"],t):"object"==typeof exports?exports.ca=t(require("cross-fetch")):e.ca=t(e.fetch)}("undefined"!=typeof self?self:this,(__WEBPACK_EXTERNAL_MODULE__268__=>(()=>{"use strict";var __webpack_modules__={578:(e,t,n)=>{var r,i,s;s=n(92),i=n(800),r=function(){class e{constructor(e={}){this.options=e,s.load(this.options,this.defaults,this),this.Events=new i(this),this._arr=[],this._resetPromise(),this._lastFlush=Date.now()}_resetPromise(){return this._promise=new this.Promise(((e,t)=>this._resolve=e))}_flush(){return clearTimeout(this._timeout),this._lastFlush=Date.now(),this._resolve(),this.Events.trigger("batch",this._arr),this._arr=[],this._resetPromise()}add(e){var t;return this._arr.push(e),t=this._promise,this._arr.length===this.maxSize?this._flush():null!=this.maxTime&&1===this._arr.length&&(this._timeout=setTimeout((()=>this._flush()),this.maxTime)),t}}return e.prototype.defaults={maxTime:null,maxSize:null,Promise},e}.call(void 0),e.exports=r},529:(e,t,n)=>{function r(e,t){return o(e)||function(e,t){var n=[],r=!0,i=!1,s=void 0;try{for(var o,a=e[Symbol.iterator]();!(r=(o=a.next()).done)&&(n.push(o.value),!t||n.length!==t);r=!0);}catch(e){i=!0,s=e}finally{try{r||null==a.return||a.return()}finally{if(i)throw s}}return n}(e,t)||s()}function i(e){return o(e)||function(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}(e)||s()}function s(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}function o(e){if(Array.isArray(e))return e}function a(e,t,n,r,i,s,o){try{var a=e[s](o),l=a.value}catch(e){return void n(e)}a.done?t(l):Promise.resolve(l).then(r,i)}function l(e){return function(){var t=this,n=arguments;return new Promise((function(r,i){var s=e.apply(t,n);function o(e){a(s,r,i,o,l,"next",e)}function l(e){a(s,r,i,o,l,"throw",e)}o(void 0)}))}}var c,u,h,_,d,p,v,m,y,g=[].splice;y=n(92),d=n(186),h=n(262),_=n(705),p=n(220),u=n(800),v=n(376),m=n(915),c=function(){class e{constructor(t={},...n){var r,i;this._addToQueue=this._addToQueue.bind(this),this._validateOptions(t,n),y.load(t,this.instanceDefaults,this),this._queues=new d(10),this._scheduled={},this._states=new v(["RECEIVED","QUEUED","RUNNING","EXECUTING"].concat(this.trackDoneStatus?["DONE"]:[])),this._limiter=null,this.Events=new u(this),this._submitLock=new m("submit",this.Promise),this._registerLock=new m("register",this.Promise),i=y.load(t,this.storeDefaults,{}),this._store=function(){if("redis"===this.datastore||"ioredis"===this.datastore||null!=this.connection)return r=y.load(t,this.redisStoreDefaults,{}),new p(this,i,r);if("local"===this.datastore)return r=y.load(t,this.localStoreDefaults,{}),new _(this,i,r);throw new e.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`)}.call(this),this._queues.on("leftzero",(()=>{var e;return null!=(e=this._store.heartbeat)&&"function"==typeof e.ref?e.ref():void 0})),this._queues.on("zero",(()=>{var e;return null!=(e=this._store.heartbeat)&&"function"==typeof e.unref?e.unref():void 0}))}_validateOptions(t,n){if(null==t||"object"!=typeof t||0!==n.length)throw new e.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1.")}ready(){return this._store.ready}clients(){return this._store.clients}channel(){return`b_${this.id}`}channel_client(){return`b_${this.id}_${this._store.clientId}`}publish(e){return this._store.__publish__(e)}disconnect(e=!0){return this._store.__disconnect__(e)}chain(e){return this._limiter=e,this}queued(e){return this._queues.queued(e)}clusterQueued(){return this._store.__queued__()}empty(){return 0===this.queued()&&this._submitLock.isEmpty()}running(){return this._store.__running__()}done(){return this._store.__done__()}jobStatus(e){return this._states.jobStatus(e)}jobs(e){return this._states.statusJobs(e)}counts(){return this._states.statusCounts()}_randomIndex(){return Math.random().toString(36).slice(2)}check(e=1){return this._store.__check__(e)}_clearGlobalState(e){return null!=this._scheduled[e]&&(clearTimeout(this._scheduled[e].expiration),delete this._scheduled[e],!0)}_free(e,t,n,r){var i=this;return l((function*(){var t,s;try{if(s=(yield i._store.__free__(e,n.weight)).running,i.Events.trigger("debug",`Freed ${n.id}`,r),0===s&&i.empty())return i.Events.trigger("idle")}catch(e){return t=e,i.Events.trigger("error",t)}}))()}_run(e,t,n){var r,i,s;return t.doRun(),r=this._clearGlobalState.bind(this,e),s=this._run.bind(this,e,t),i=this._free.bind(this,e,t),this._scheduled[e]={timeout:setTimeout((()=>t.doExecute(this._limiter,r,s,i)),n),expiration:null!=t.options.expiration?setTimeout((function(){return t.doExpire(r,s,i)}),n+t.options.expiration):void 0,job:t}}_drainOne(e){return this._registerLock.schedule((()=>{var t,n,r,i,s;if(0===this.queued())return this.Promise.resolve(null);s=this._queues.getFirst();var o=r=s.first();return i=o.options,t=o.args,null!=e&&i.weight>e?this.Promise.resolve(null):(this.Events.trigger("debug",`Draining ${i.id}`,{args:t,options:i}),n=this._randomIndex(),this._store.__register__(n,i.weight,i.expiration).then((({success:e,wait:o,reservoir:a})=>{var l;return this.Events.trigger("debug",`Drained ${i.id}`,{success:e,args:t,options:i}),e?(s.shift(),(l=this.empty())&&this.Events.trigger("empty"),0===a&&this.Events.trigger("depleted",l),this._run(n,r,o),this.Promise.resolve(i.weight)):this.Promise.resolve(null)})))}))}_drainAll(e,t=0){return this._drainOne(e).then((n=>{var r;return null!=n?(r=null!=e?e-n:e,this._drainAll(r,t+n)):this.Promise.resolve(t)})).catch((e=>this.Events.trigger("error",e)))}_dropAllQueued(e){return this._queues.shiftAll((function(t){return t.doDrop({message:e})}))}stop(t={}){var n,r;return t=y.load(t,this.stopDefaults),r=e=>{var t;return t=()=>{var t;return(t=this._states.counts)[0]+t[1]+t[2]+t[3]===e},new this.Promise(((e,n)=>t()?e():this.on("done",(()=>{if(t())return this.removeAllListeners("done"),e()}))))},n=t.dropWaitingJobs?(this._run=function(e,n){return n.doDrop({message:t.dropErrorMessage})},this._drainOne=()=>this.Promise.resolve(null),this._registerLock.schedule((()=>this._submitLock.schedule((()=>{var e,n,i;for(e in n=this._scheduled)i=n[e],"RUNNING"===this.jobStatus(i.job.options.id)&&(clearTimeout(i.timeout),clearTimeout(i.expiration),i.job.doDrop({message:t.dropErrorMessage}));return this._dropAllQueued(t.dropErrorMessage),r(0)}))))):this.schedule({priority:9,weight:0},(()=>r(1))),this._receive=function(n){return n._reject(new e.prototype.BottleneckError(t.enqueueErrorMessage))},this.stop=()=>this.Promise.reject(new e.prototype.BottleneckError("stop() has already been called")),n}_addToQueue(t){var n=this;return l((function*(){var r,i,s,o,a,l,c;r=t.args,o=t.options;try{var u=yield n._store.__submit__(n.queued(),o.weight);a=u.reachedHWM,i=u.blocked,c=u.strategy}catch(e){return s=e,n.Events.trigger("debug",`Could not queue ${o.id}`,{args:r,options:o,error:s}),t.doDrop({error:s}),!1}return i?(t.doDrop(),!0):a&&(null!=(l=c===e.prototype.strategy.LEAK?n._queues.shiftLastFrom(o.priority):c===e.prototype.strategy.OVERFLOW_PRIORITY?n._queues.shiftLastFrom(o.priority+1):c===e.prototype.strategy.OVERFLOW?t:void 0)&&l.doDrop(),null==l||c===e.prototype.strategy.OVERFLOW)?(null==l&&t.doDrop(),a):(t.doQueue(a,i),n._queues.push(t),yield n._drainAll(),a)}))()}_receive(t){return null!=this._states.jobStatus(t.options.id)?(t._reject(new e.prototype.BottleneckError(`A job with the same id already exists (id=${t.options.id})`)),!1):(t.doReceive(),this._submitLock.schedule(this._addToQueue,t))}submit(...e){var t,n,s,o,a,l,c,u,_;return"function"==typeof e[0]?(l=i(e),n=l[0],e=l.slice(1),c=r(g.call(e,-1),1),t=c[0],o=y.load({},this.jobDefaults)):(o=(u=i(e))[0],n=u[1],e=u.slice(2),_=r(g.call(e,-1),1),t=_[0],o=y.load(o,this.jobDefaults)),a=(...e)=>new this.Promise((function(t,r){return n(...e,(function(...e){return(null!=e[0]?r:t)(e)}))})),(s=new h(a,e,o,this.jobDefaults,this.rejectOnDrop,this.Events,this._states,this.Promise)).promise.then((function(e){return"function"==typeof t?t(...e):void 0})).catch((function(e){return Array.isArray(e)?"function"==typeof t?t(...e):void 0:"function"==typeof t?t(e):void 0})),this._receive(s)}schedule(...e){var t,n,r;if("function"==typeof e[0]){var s=i(e);r=s[0],e=s.slice(1),n={}}else{var o=i(e);n=o[0],r=o[1],e=o.slice(2)}return t=new h(r,e,n,this.jobDefaults,this.rejectOnDrop,this.Events,this._states,this.Promise),this._receive(t),t.promise}wrap(e){var t,n;return t=this.schedule.bind(this),(n=function(...n){return t(e.bind(this),...n)}).withOptions=function(n,...r){return t(n,e,...r)},n}updateSettings(e={}){var t=this;return l((function*(){return yield t._store.__updateSettings__(y.overwrite(e,t.storeDefaults)),y.overwrite(e,t.instanceDefaults,t),t}))()}currentReservoir(){return this._store.__currentReservoir__()}incrementReservoir(e=0){return this._store.__incrementReservoir__(e)}}return e.default=e,e.Events=u,e.version=e.prototype.version=n(636).i,e.strategy=e.prototype.strategy={LEAK:1,OVERFLOW:2,OVERFLOW_PRIORITY:4,BLOCK:3},e.BottleneckError=e.prototype.BottleneckError=n(6),e.Group=e.prototype.Group=n(613),e.RedisConnection=e.prototype.RedisConnection=n(427),e.IORedisConnection=e.prototype.IORedisConnection=n(442),e.Batcher=e.prototype.Batcher=n(578),e.prototype.jobDefaults={priority:5,weight:1,expiration:null,id:"<no-id>"},e.prototype.storeDefaults={maxConcurrent:null,minTime:0,highWater:null,strategy:e.prototype.strategy.LEAK,penalty:null,reservoir:null,reservoirRefreshInterval:null,reservoirRefreshAmount:null,reservoirIncreaseInterval:null,reservoirIncreaseAmount:null,reservoirIncreaseMaximum:null},e.prototype.localStoreDefaults={Promise,timeout:null,heartbeatInterval:250},e.prototype.redisStoreDefaults={Promise,timeout:null,heartbeatInterval:5e3,clientTimeout:1e4,Redis:null,clientOptions:{},clusterNodes:null,clearDatastore:!1,connection:null},e.prototype.instanceDefaults={datastore:"local",connection:null,id:"<no-id>",rejectOnDrop:!0,trackDoneStatus:!1,Promise},e.prototype.stopDefaults={enqueueErrorMessage:"This limiter has been stopped and cannot accept new jobs.",dropWaitingJobs:!0,dropErrorMessage:"This limiter has been stopped."},e}.call(void 0),e.exports=c},6:e=>{var t;t=class extends Error{},e.exports=t},938:e=>{var t;t=class{constructor(e,t){this.incr=e,this.decr=t,this._first=null,this._last=null,this.length=0}push(e){var t;this.length++,"function"==typeof this.incr&&this.incr(),t={value:e,prev:this._last,next:null},null!=this._last?(this._last.next=t,this._last=t):this._first=this._last=t}shift(){var e;if(null!=this._first)return this.length--,"function"==typeof this.decr&&this.decr(),e=this._first.value,null!=(this._first=this._first.next)?this._first.prev=null:this._last=null,e}first(){if(null!=this._first)return this._first.value}getArray(){var e,t,n;for(e=this._first,n=[];null!=e;)n.push((t=e,e=e.next,t.value));return n}forEachShift(e){var t;for(t=this.shift();null!=t;)e(t),t=this.shift()}debug(){var e,t,n,r,i;for(e=this._first,i=[];null!=e;)i.push((t=e,e=e.next,{value:t.value,prev:null!=(n=t.prev)?n.value:void 0,next:null!=(r=t.next)?r.value:void 0}));return i}},e.exports=t},800:e=>{function t(e,t,n,r,i,s,o){try{var a=e[s](o),l=a.value}catch(e){return void n(e)}a.done?t(l):Promise.resolve(l).then(r,i)}function n(e){return function(){var n=this,r=arguments;return new Promise((function(i,s){var o=e.apply(n,r);function a(e){t(o,i,s,a,l,"next",e)}function l(e){t(o,i,s,a,l,"throw",e)}a(void 0)}))}}var r;r=class{constructor(e){if(this.instance=e,this._events={},null!=this.instance.on||null!=this.instance.once||null!=this.instance.removeAllListeners)throw new Error("An Emitter already exists for this object");this.instance.on=(e,t)=>this._addListener(e,"many",t),this.instance.once=(e,t)=>this._addListener(e,"once",t),this.instance.removeAllListeners=(e=null)=>null!=e?delete this._events[e]:this._events={}}_addListener(e,t,n){var r;return null==(r=this._events)[e]&&(r[e]=[]),this._events[e].push({cb:n,status:t}),this.instance}listenerCount(e){return null!=this._events[e]?this._events[e].length:0}trigger(e,...t){var r=this;return n((function*(){var i,s;try{if("debug"!==e&&r.trigger("debug",`Event triggered: ${e}`,t),null==r._events[e])return;return r._events[e]=r._events[e].filter((function(e){return"none"!==e.status})),s=r._events[e].map(function(){var e=n((function*(e){var n,i;if("none"!==e.status){"once"===e.status&&(e.status="none");try{return"function"==typeof(null!=(i="function"==typeof e.cb?e.cb(...t):void 0)?i.then:void 0)?yield i:i}catch(e){return n=e,r.trigger("error",n),null}}}));return function(t){return e.apply(this,arguments)}}()),(yield Promise.all(s)).find((function(e){return null!=e}))}catch(e){return i=e,r.trigger("error",i),null}}))()}},e.exports=r},613:(e,t,n)=>{function r(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=[],r=!0,i=!1,s=void 0;try{for(var o,a=e[Symbol.iterator]();!(r=(o=a.next()).done)&&(n.push(o.value),!t||n.length!==t);r=!0);}catch(e){i=!0,s=e}finally{try{r||null==a.return||a.return()}finally{if(i)throw s}}return n}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function i(e,t,n,r,i,s,o){try{var a=e[s](o),l=a.value}catch(e){return void n(e)}a.done?t(l):Promise.resolve(l).then(r,i)}function s(e){return function(){var t=this,n=arguments;return new Promise((function(r,s){var o=e.apply(t,n);function a(e){i(o,r,s,a,l,"next",e)}function l(e){i(o,r,s,a,l,"throw",e)}a(void 0)}))}}var o,a,l,c,u,h;h=n(92),o=n(800),c=n(427),l=n(442),u=n(812),a=function(){class e{constructor(e={}){this.deleteKey=this.deleteKey.bind(this),this.limiterOptions=e,h.load(this.limiterOptions,this.defaults,this),this.Events=new o(this),this.instances={},this.Bottleneck=n(529),this._startAutoCleanup(),this.sharedConnection=null!=this.connection,null==this.connection&&("redis"===this.limiterOptions.datastore?this.connection=new c(Object.assign({},this.limiterOptions,{Events:this.Events})):"ioredis"===this.limiterOptions.datastore&&(this.connection=new l(Object.assign({},this.limiterOptions,{Events:this.Events}))))}key(e=""){var t;return null!=(t=this.instances[e])?t:(()=>{var t;return t=this.instances[e]=new this.Bottleneck(Object.assign(this.limiterOptions,{id:`${this.id}-${e}`,timeout:this.timeout,connection:this.connection})),this.Events.trigger("created",t,e),t})()}deleteKey(e=""){var t=this;return s((function*(){var n,r;return r=t.instances[e],t.connection&&(n=yield t.connection.__runCommand__(["del",...u.allKeys(`${t.id}-${e}`)])),null!=r&&(delete t.instances[e],yield r.disconnect()),null!=r||n>0}))()}limiters(){var e,t,n,r;for(e in n=[],t=this.instances)r=t[e],n.push({key:e,limiter:r});return n}keys(){return Object.keys(this.instances)}clusterKeys(){var e=this;return s((function*(){var t,n,i,s,o,a,l,c;if(null==e.connection)return e.Promise.resolve(e.keys());for(a=[],t=null,c=`b_${e.id}-`.length,n="_settings".length;0!==t;){var u=r(yield e.connection.__runCommand__(["scan",null!=t?t:0,"match",`b_${e.id}-*_settings`,"count",1e4]),2);for(t=~~u[0],s=0,l=(i=u[1]).length;s<l;s++)o=i[s],a.push(o.slice(c,-n))}return a}))()}_startAutoCleanup(){var e,t=this;return clearInterval(this.interval),"function"==typeof(e=this.interval=setInterval(s((function*(){var e,n,r,i,s,o;for(n in s=Date.now(),i=[],r=t.instances){o=r[n];try{(yield o._store.__groupCheck__(s))?i.push(t.deleteKey(n)):i.push(void 0)}catch(t){e=t,i.push(o.Events.trigger("error",e))}}return i})),this.timeout/2)).unref?e.unref():void 0}updateSettings(e={}){if(h.overwrite(e,this.defaults,this),h.overwrite(e,e,this.limiterOptions),null!=e.timeout)return this._startAutoCleanup()}disconnect(e=!0){var t;if(!this.sharedConnection)return null!=(t=this.connection)?t.disconnect(e):void 0}}return e.prototype.defaults={timeout:3e5,connection:null,Promise,id:"group-key"},e}.call(void 0),e.exports=a},442:(module,__unused_webpack_exports,__webpack_require__)=>{function _slicedToArray(e,t){return _arrayWithHoles(e)||_iterableToArrayLimit(e,t)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}function _iterableToArrayLimit(e,t){var n=[],r=!0,i=!1,s=void 0;try{for(var o,a=e[Symbol.iterator]();!(r=(o=a.next()).done)&&(n.push(o.value),!t||n.length!==t);r=!0);}catch(e){i=!0,s=e}finally{try{r||null==a.return||a.return()}finally{if(i)throw s}}return n}function _arrayWithHoles(e){if(Array.isArray(e))return e}function asyncGeneratorStep(e,t,n,r,i,s,o){try{var a=e[s](o),l=a.value}catch(e){return void n(e)}a.done?t(l):Promise.resolve(l).then(r,i)}function _asyncToGenerator(e){return function(){var t=this,n=arguments;return new Promise((function(r,i){var s=e.apply(t,n);function o(e){asyncGeneratorStep(s,r,i,o,a,"next",e)}function a(e){asyncGeneratorStep(s,r,i,o,a,"throw",e)}o(void 0)}))}}var Events,IORedisConnection,Scripts,parser;parser=__webpack_require__(92),Events=__webpack_require__(800),Scripts=__webpack_require__(812),IORedisConnection=function(){class IORedisConnection{constructor(options={}){parser.load(options,this.defaults,this),null==this.Redis&&(this.Redis=eval("require")("ioredis")),null==this.Events&&(this.Events=new Events(this)),this.terminated=!1,null!=this.clusterNodes?(this.client=new this.Redis.Cluster(this.clusterNodes,this.clientOptions),this.subscriber=new this.Redis.Cluster(this.clusterNodes,this.clientOptions)):null!=this.client&&null==this.client.duplicate?this.subscriber=new this.Redis.Cluster(this.client.startupNodes,this.client.options):(null==this.client&&(this.client=new this.Redis(this.clientOptions)),this.subscriber=this.client.duplicate()),this.limiters={},this.ready=this.Promise.all([this._setup(this.client,!1),this._setup(this.subscriber,!0)]).then((()=>(this._loadScripts(),{client:this.client,subscriber:this.subscriber})))}_setup(e,t){return e.setMaxListeners(0),new this.Promise(((n,r)=>(e.on("error",(e=>this.Events.trigger("error",e))),t&&e.on("message",((e,t)=>{var n;return null!=(n=this.limiters[e])?n._store.onMessage(e,t):void 0})),"ready"===e.status?n():e.once("ready",n))))}_loadScripts(){return Scripts.names.forEach((e=>this.client.defineCommand(e,{lua:Scripts.payload(e)})))}__runCommand__(e){var t=this;return _asyncToGenerator((function*(){yield t.ready;var n=_slicedToArray(yield t.client.pipeline([e]).exec(),1),r=_slicedToArray(n[0],2);return r[0],r[1]}))()}__addLimiter__(e){return this.Promise.all([e.channel(),e.channel_client()].map((t=>new this.Promise(((n,r)=>this.subscriber.subscribe(t,(()=>(this.limiters[t]=e,n()))))))))}__removeLimiter__(e){var t=this;return[e.channel(),e.channel_client()].forEach(function(){var e=_asyncToGenerator((function*(e){return t.terminated||(yield t.subscriber.unsubscribe(e)),delete t.limiters[e]}));return function(t){return e.apply(this,arguments)}}())}__scriptArgs__(e,t,n,r){var i;return[(i=Scripts.keys(e,t)).length].concat(i,n,r)}__scriptFn__(e){return this.client[e].bind(this.client)}disconnect(e=!0){var t,n,r,i;for(t=0,r=(i=Object.keys(this.limiters)).length;t<r;t++)n=i[t],clearInterval(this.limiters[n]._store.heartbeat);return this.limiters={},this.terminated=!0,e?this.Promise.all([this.client.quit(),this.subscriber.quit()]):(this.client.disconnect(),this.subscriber.disconnect(),this.Promise.resolve())}}return IORedisConnection.prototype.datastore="ioredis",IORedisConnection.prototype.defaults={Redis:null,clientOptions:{},clusterNodes:null,client:null,Promise,Events:null},IORedisConnection}.call(void 0),module.exports=IORedisConnection},262:(e,t,n)=>{function r(e,t,n,r,i,s,o){try{var a=e[s](o),l=a.value}catch(e){return void n(e)}a.done?t(l):Promise.resolve(l).then(r,i)}function i(e){return function(){var t=this,n=arguments;return new Promise((function(i,s){var o=e.apply(t,n);function a(e){r(o,i,s,a,l,"next",e)}function l(e){r(o,i,s,a,l,"throw",e)}a(void 0)}))}}var s,o,a;a=n(92),s=n(6),o=class{constructor(e,t,n,r,i,s,o,l){this.task=e,this.args=t,this.rejectOnDrop=i,this.Events=s,this._states=o,this.Promise=l,this.options=a.load(n,r),this.options.priority=this._sanitizePriority(this.options.priority),this.options.id===r.id&&(this.options.id=`${this.options.id}-${this._randomIndex()}`),this.promise=new this.Promise(((e,t)=>{this._resolve=e,this._reject=t})),this.retryCount=0}_sanitizePriority(e){var t;return(t=~~e!==e?5:e)<0?0:t>9?9:t}_randomIndex(){return Math.random().toString(36).slice(2)}doDrop({error:e,message:t="This job has been dropped by Bottleneck"}={}){return!!this._states.remove(this.options.id)&&(this.rejectOnDrop&&this._reject(null!=e?e:new s(t)),this.Events.trigger("dropped",{args:this.args,options:this.options,task:this.task,promise:this.promise}),!0)}_assertStatus(e){var t;if((t=this._states.jobStatus(this.options.id))!==e&&("DONE"!==e||null!==t))throw new s(`Invalid job status ${t}, expected ${e}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`)}doReceive(){return this._states.start(this.options.id),this.Events.trigger("received",{args:this.args,options:this.options})}doQueue(e,t){return this._assertStatus("RECEIVED"),this._states.next(this.options.id),this.Events.trigger("queued",{args:this.args,options:this.options,reachedHWM:e,blocked:t})}doRun(){return 0===this.retryCount?(this._assertStatus("QUEUED"),this._states.next(this.options.id)):this._assertStatus("EXECUTING"),this.Events.trigger("scheduled",{args:this.args,options:this.options})}doExecute(e,t,n,r){var s=this;return i((function*(){var i,o,a;0===s.retryCount?(s._assertStatus("RUNNING"),s._states.next(s.options.id)):s._assertStatus("EXECUTING"),o={args:s.args,options:s.options,retryCount:s.retryCount},s.Events.trigger("executing",o);try{if(a=yield null!=e?e.schedule(s.options,s.task,...s.args):s.task(...s.args),t())return s.doDone(o),yield r(s.options,o),s._assertStatus("DONE"),s._resolve(a)}catch(e){return i=e,s._onFailure(i,o,t,n,r)}}))()}doExpire(e,t,n){var r,i;return this._states.jobStatus("RUNNING"===this.options.id)&&this._states.next(this.options.id),this._assertStatus("EXECUTING"),i={args:this.args,options:this.options,retryCount:this.retryCount},r=new s(`This job timed out after ${this.options.expiration} ms.`),this._onFailure(r,i,e,t,n)}_onFailure(e,t,n,r,s){var o=this;return i((function*(){var i,a;if(n())return null!=(i=yield o.Events.trigger("failed",e,t))?(a=~~i,o.Events.trigger("retry",`Retrying ${o.options.id} after ${a} ms`,t),o.retryCount++,r(a)):(o.doDone(t),yield s(o.options,t),o._assertStatus("DONE"),o._reject(e))}))()}doDone(e){return this._assertStatus("EXECUTING"),this._states.next(this.options.id),this.Events.trigger("done",e)}},e.exports=o},705:(e,t,n)=>{function r(e,t,n,r,i,s,o){try{var a=e[s](o),l=a.value}catch(e){return void n(e)}a.done?t(l):Promise.resolve(l).then(r,i)}function i(e){return function(){var t=this,n=arguments;return new Promise((function(i,s){var o=e.apply(t,n);function a(e){r(o,i,s,a,l,"next",e)}function l(e){r(o,i,s,a,l,"throw",e)}a(void 0)}))}}var s,o,a;a=n(92),s=n(6),o=class{constructor(e,t,n){this.instance=e,this.storeOptions=t,this.clientId=this.instance._randomIndex(),a.load(n,n,this),this._nextRequest=this._lastReservoirRefresh=this._lastReservoirIncrease=Date.now(),this._running=0,this._done=0,this._unblockTime=0,this.ready=this.Promise.resolve(),this.clients={},this._startHeartbeat()}_startHeartbeat(){var e;return null==this.heartbeat&&(null!=this.storeOptions.reservoirRefreshInterval&&null!=this.storeOptions.reservoirRefreshAmount||null!=this.storeOptions.reservoirIncreaseInterval&&null!=this.storeOptions.reservoirIncreaseAmount)?"function"==typeof(e=this.heartbeat=setInterval((()=>{var e,t,n,r,i;if(r=Date.now(),null!=this.storeOptions.reservoirRefreshInterval&&r>=this._lastReservoirRefresh+this.storeOptions.reservoirRefreshInterval&&(this._lastReservoirRefresh=r,this.storeOptions.reservoir=this.storeOptions.reservoirRefreshAmount,this.instance._drainAll(this.computeCapacity())),null!=this.storeOptions.reservoirIncreaseInterval&&r>=this._lastReservoirIncrease+this.storeOptions.reservoirIncreaseInterval){var s=this.storeOptions;if(e=s.reservoirIncreaseAmount,n=s.reservoirIncreaseMaximum,i=s.reservoir,this._lastReservoirIncrease=r,(t=null!=n?Math.min(e,n-i):e)>0)return this.storeOptions.reservoir+=t,this.instance._drainAll(this.computeCapacity())}}),this.heartbeatInterval)).unref?e.unref():void 0:clearInterval(this.heartbeat)}__publish__(e){var t=this;return i((function*(){return yield t.yieldLoop(),t.instance.Events.trigger("message",e.toString())}))()}__disconnect__(e){var t=this;return i((function*(){return yield t.yieldLoop(),clearInterval(t.heartbeat),t.Promise.resolve()}))()}yieldLoop(e=0){return new this.Promise((function(t,n){return setTimeout(t,e)}))}computePenalty(){var e;return null!=(e=this.storeOptions.penalty)?e:15*this.storeOptions.minTime||5e3}__updateSettings__(e){var t=this;return i((function*(){return yield t.yieldLoop(),a.overwrite(e,e,t.storeOptions),t._startHeartbeat(),t.instance._drainAll(t.computeCapacity()),!0}))()}__running__(){var e=this;return i((function*(){return yield e.yieldLoop(),e._running}))()}__queued__(){var e=this;return i((function*(){return yield e.yieldLoop(),e.instance.queued()}))()}__done__(){var e=this;return i((function*(){return yield e.yieldLoop(),e._done}))()}__groupCheck__(e){var t=this;return i((function*(){return yield t.yieldLoop(),t._nextRequest+t.timeout<e}))()}computeCapacity(){var e,t,n=this.storeOptions;return e=n.maxConcurrent,t=n.reservoir,null!=e&&null!=t?Math.min(e-this._running,t):null!=e?e-this._running:null!=t?t:null}conditionsCheck(e){var t;return null==(t=this.computeCapacity())||e<=t}__incrementReservoir__(e){var t=this;return i((function*(){var n;return yield t.yieldLoop(),n=t.storeOptions.reservoir+=e,t.instance._drainAll(t.computeCapacity()),n}))()}__currentReservoir__(){var e=this;return i((function*(){return yield e.yieldLoop(),e.storeOptions.reservoir}))()}isBlocked(e){return this._unblockTime>=e}check(e,t){return this.conditionsCheck(e)&&this._nextRequest-t<=0}__check__(e){var t=this;return i((function*(){var n;return yield t.yieldLoop(),n=Date.now(),t.check(e,n)}))()}__register__(e,t,n){var r=this;return i((function*(){var e,n;return yield r.yieldLoop(),e=Date.now(),r.conditionsCheck(t)?(r._running+=t,null!=r.storeOptions.reservoir&&(r.storeOptions.reservoir-=t),n=Math.max(r._nextRequest-e,0),r._nextRequest=e+n+r.storeOptions.minTime,{success:!0,wait:n,reservoir:r.storeOptions.reservoir}):{success:!1}}))()}strategyIsBlock(){return 3===this.storeOptions.strategy}__submit__(e,t){var n=this;return i((function*(){var r,i,o;if(yield n.yieldLoop(),null!=n.storeOptions.maxConcurrent&&t>n.storeOptions.maxConcurrent)throw new s(`Impossible to add a job having a weight of ${t} to a limiter having a maxConcurrent setting of ${n.storeOptions.maxConcurrent}`);return i=Date.now(),o=null!=n.storeOptions.highWater&&e===n.storeOptions.highWater&&!n.check(t,i),(r=n.strategyIsBlock()&&(o||n.isBlocked(i)))&&(n._unblockTime=i+n.computePenalty(),n._nextRequest=n._unblockTime+n.storeOptions.minTime,n.instance._dropAllQueued()),{reachedHWM:o,blocked:r,strategy:n.storeOptions.strategy}}))()}__free__(e,t){var n=this;return i((function*(){return yield n.yieldLoop(),n._running-=t,n._done+=t,n.instance._drainAll(n.computeCapacity()),{running:n._running}}))()}},e.exports=o},186:(e,t,n)=>{var r,i,s;r=n(938),i=n(800),s=class{constructor(e){this.Events=new i(this),this._length=0,this._lists=function(){var t,n,i;for(i=[],t=1,n=e;1<=n?t<=n:t>=n;1<=n?++t:--t)i.push(new r((()=>this.incr()),(()=>this.decr())));return i}.call(this)}incr(){if(0==this._length++)return this.Events.trigger("leftzero")}decr(){if(0==--this._length)return this.Events.trigger("zero")}push(e){return this._lists[e.options.priority].push(e)}queued(e){return null!=e?this._lists[e].length:this._length}shiftAll(e){return this._lists.forEach((function(t){return t.forEachShift(e)}))}getFirst(e=this._lists){var t,n,r;for(t=0,n=e.length;t<n;t++)if((r=e[t]).length>0)return r;return[]}shiftLastFrom(e){return this.getFirst(this._lists.slice(e).reverse()).shift()}},e.exports=s},427:(module,__unused_webpack_exports,__webpack_require__)=>{function asyncGeneratorStep(e,t,n,r,i,s,o){try{var a=e[s](o),l=a.value}catch(e){return void n(e)}a.done?t(l):Promise.resolve(l).then(r,i)}function _asyncToGenerator(e){return function(){var t=this,n=arguments;return new Promise((function(r,i){var s=e.apply(t,n);function o(e){asyncGeneratorStep(s,r,i,o,a,"next",e)}function a(e){asyncGeneratorStep(s,r,i,o,a,"throw",e)}o(void 0)}))}}var Events,RedisConnection,Scripts,parser;parser=__webpack_require__(92),Events=__webpack_require__(800),Scripts=__webpack_require__(812),RedisConnection=function(){class RedisConnection{constructor(options={}){parser.load(options,this.defaults,this),null==this.Redis&&(this.Redis=eval("require")("redis")),null==this.Events&&(this.Events=new Events(this)),this.terminated=!1,null==this.client&&(this.client=this.Redis.createClient(this.clientOptions)),this.subscriber=this.client.duplicate(),this.limiters={},this.shas={},this.ready=this.Promise.all([this._setup(this.client,!1),this._setup(this.subscriber,!0)]).then((()=>this._loadScripts())).then((()=>({client:this.client,subscriber:this.subscriber})))}_setup(e,t){return e.setMaxListeners(0),new this.Promise(((n,r)=>(e.on("error",(e=>this.Events.trigger("error",e))),t&&e.on("message",((e,t)=>{var n;return null!=(n=this.limiters[e])?n._store.onMessage(e,t):void 0})),e.ready?n():e.once("ready",n))))}_loadScript(e){return new this.Promise(((t,n)=>{var r;return r=Scripts.payload(e),this.client.multi([["script","load",r]]).exec(((r,i)=>null!=r?n(r):(this.shas[e]=i[0],t(i[0]))))}))}_loadScripts(){return this.Promise.all(Scripts.names.map((e=>this._loadScript(e))))}__runCommand__(e){var t=this;return _asyncToGenerator((function*(){return yield t.ready,new t.Promise(((n,r)=>t.client.multi([e]).exec_atomic((function(e,t){return null!=e?r(e):n(t[0])}))))}))()}__addLimiter__(e){return this.Promise.all([e.channel(),e.channel_client()].map((t=>new this.Promise(((n,r)=>{var i;return i=r=>{if(r===t)return this.subscriber.removeListener("subscribe",i),this.limiters[t]=e,n()},this.subscriber.on("subscribe",i),this.subscriber.subscribe(t)})))))}__removeLimiter__(e){var t=this;return this.Promise.all([e.channel(),e.channel_client()].map(function(){var e=_asyncToGenerator((function*(e){return t.terminated||(yield new t.Promise(((n,r)=>t.subscriber.unsubscribe(e,(function(t,i){return null!=t?r(t):i===e?n():void 0}))))),delete t.limiters[e]}));return function(t){return e.apply(this,arguments)}}()))}__scriptArgs__(e,t,n,r){var i;return i=Scripts.keys(e,t),[this.shas[e],i.length].concat(i,n,r)}__scriptFn__(e){return this.client.evalsha.bind(this.client)}disconnect(e=!0){var t,n,r,i;for(t=0,r=(i=Object.keys(this.limiters)).length;t<r;t++)n=i[t],clearInterval(this.limiters[n]._store.heartbeat);return this.limiters={},this.terminated=!0,this.client.end(e),this.subscriber.end(e),this.Promise.resolve()}}return RedisConnection.prototype.datastore="redis",RedisConnection.prototype.defaults={Redis:null,clientOptions:{},client:null,Promise,Events:null},RedisConnection}.call(void 0),module.exports=RedisConnection},220:(e,t,n)=>{function r(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=[],r=!0,i=!1,s=void 0;try{for(var o,a=e[Symbol.iterator]();!(r=(o=a.next()).done)&&(n.push(o.value),!t||n.length!==t);r=!0);}catch(e){i=!0,s=e}finally{try{r||null==a.return||a.return()}finally{if(i)throw s}}return n}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function i(e,t,n,r,i,s,o){try{var a=e[s](o),l=a.value}catch(e){return void n(e)}a.done?t(l):Promise.resolve(l).then(r,i)}function s(e){return function(){var t=this,n=arguments;return new Promise((function(r,s){var o=e.apply(t,n);function a(e){i(o,r,s,a,l,"next",e)}function l(e){i(o,r,s,a,l,"throw",e)}a(void 0)}))}}var o,a,l,c,u;u=n(92),o=n(6),l=n(427),a=n(442),c=class{constructor(e,t,n){this.instance=e,this.storeOptions=t,this.originalId=this.instance.id,this.clientId=this.instance._randomIndex(),u.load(n,n,this),this.clients={},this.capacityPriorityCounters={},this.sharedConnection=null!=this.connection,null==this.connection&&(this.connection="redis"===this.instance.datastore?new l({Redis:this.Redis,clientOptions:this.clientOptions,Promise:this.Promise,Events:this.instance.Events}):"ioredis"===this.instance.datastore?new a({Redis:this.Redis,clientOptions:this.clientOptions,clusterNodes:this.clusterNodes,Promise:this.Promise,Events:this.instance.Events}):void 0),this.instance.connection=this.connection,this.instance.datastore=this.connection.datastore,this.ready=this.connection.ready.then((e=>(this.clients=e,this.runScript("init",this.prepareInitSettings(this.clearDatastore))))).then((()=>this.connection.__addLimiter__(this.instance))).then((()=>this.runScript("register_client",[this.instance.queued()]))).then((()=>{var e;return"function"==typeof(e=this.heartbeat=setInterval((()=>this.runScript("heartbeat",[]).catch((e=>this.instance.Events.trigger("error",e)))),this.heartbeatInterval)).unref&&e.unref(),this.clients}))}__publish__(e){var t=this;return s((function*(){return(yield t.ready).client.publish(t.instance.channel(),`message:${e.toString()}`)}))()}onMessage(e,t){var n=this;return s((function*(){var e,i,o,a,l,c,u,h,_,d;try{u=t.indexOf(":");var p=[t.slice(0,u),t.slice(u+1)];if(o=p[1],"capacity"===(d=p[0]))return yield n.instance._drainAll(o.length>0?~~o:void 0);if("capacity-priority"===d){var v=r(o.split(":"),3);return _=v[0],h=v[1],i=v[2],e=_.length>0?~~_:void 0,h===n.clientId?(a=yield n.instance._drainAll(e),c=null!=e?e-(a||0):"",yield n.clients.client.publish(n.instance.channel(),`capacity-priority:${c}::${i}`)):""===h?(clearTimeout(n.capacityPriorityCounters[i]),delete n.capacityPriorityCounters[i],n.instance._drainAll(e)):n.capacityPriorityCounters[i]=setTimeout(s((function*(){var t;try{return delete n.capacityPriorityCounters[i],yield n.runScript("blacklist_client",[h]),yield n.instance._drainAll(e)}catch(e){return t=e,n.instance.Events.trigger("error",t)}})),1e3)}if("message"===d)return n.instance.Events.trigger("message",o);if("blocked"===d)return yield n.instance._dropAllQueued()}catch(e){return l=e,n.instance.Events.trigger("error",l)}}))()}__disconnect__(e){return clearInterval(this.heartbeat),this.sharedConnection?this.connection.__removeLimiter__(this.instance):this.connection.disconnect(e)}runScript(e,t){var n=this;return s((function*(){return"init"!==e&&"register_client"!==e&&(yield n.ready),new n.Promise(((r,i)=>{var s,o;return s=[Date.now(),n.clientId].concat(t),n.instance.Events.trigger("debug",`Calling Redis script: ${e}.lua`,s),o=n.connection.__scriptArgs__(e,n.originalId,s,(function(e,t){return null!=e?i(e):r(t)})),n.connection.__scriptFn__(e)(...o)})).catch((r=>"SETTINGS_KEY_NOT_FOUND"===r.message?"heartbeat"===e?n.Promise.resolve():n.runScript("init",n.prepareInitSettings(!1)).then((()=>n.runScript(e,t))):"UNKNOWN_CLIENT"===r.message?n.runScript("register_client",[n.instance.queued()]).then((()=>n.runScript(e,t))):n.Promise.reject(r)))}))()}prepareArray(e){var t,n,r,i;for(r=[],t=0,n=e.length;t<n;t++)i=e[t],r.push(null!=i?i.toString():"");return r}prepareObject(e){var t,n,r;for(n in t=[],e)r=e[n],t.push(n,null!=r?r.toString():"");return t}prepareInitSettings(e){var t;return(t=this.prepareObject(Object.assign({},this.storeOptions,{id:this.originalId,version:this.instance.version,groupTimeout:this.timeout,clientTimeout:this.clientTimeout}))).unshift(e?1:0,this.instance.version),t}convertBool(e){return!!e}__updateSettings__(e){var t=this;return s((function*(){return yield t.runScript("update_settings",t.prepareObject(e)),u.overwrite(e,e,t.storeOptions)}))()}__running__(){return this.runScript("running",[])}__queued__(){return this.runScript("queued",[])}__done__(){return this.runScript("done",[])}__groupCheck__(){var e=this;return s((function*(){return e.convertBool(yield e.runScript("group_check",[]))}))()}__incrementReservoir__(e){return this.runScript("increment_reservoir",[e])}__currentReservoir__(){return this.runScript("current_reservoir",[])}__check__(e){var t=this;return s((function*(){return t.convertBool(yield t.runScript("check",t.prepareArray([e])))}))()}__register__(e,t,n){var i=this;return s((function*(){var s,o,a,l=r(yield i.runScript("register",i.prepareArray([e,t,n])),3);return o=l[0],a=l[1],s=l[2],{success:i.convertBool(o),wait:a,reservoir:s}}))()}__submit__(e,t){var n=this;return s((function*(){var i,s,a,l,c;try{var u=r(yield n.runScript("submit",n.prepareArray([e,t])),3);return l=u[0],i=u[1],c=u[2],{reachedHWM:n.convertBool(l),blocked:n.convertBool(i),strategy:c}}catch(e){if(0===(s=e).message.indexOf("OVERWEIGHT")){var h=r(s.message.split(":"),3);throw h[0],t=h[1],a=h[2],new o(`Impossible to add a job having a weight of ${t} to a limiter having a maxConcurrent setting of ${a}`)}throw s}}))()}__free__(e,t){var n=this;return s((function*(){return{running:yield n.runScript("free",n.prepareArray([e]))}}))()}},e.exports=c},812:(e,t,n)=>{var r,i,s;i=n(936),r={refs:i["refs.lua"],validate_keys:i["validate_keys.lua"],validate_client:i["validate_client.lua"],refresh_expiration:i["refresh_expiration.lua"],process_tick:i["process_tick.lua"],conditions_check:i["conditions_check.lua"],get_time:i["get_time.lua"]},t.allKeys=function(e){return[`b_${e}_settings`,`b_${e}_job_weights`,`b_${e}_job_expirations`,`b_${e}_job_clients`,`b_${e}_client_running`,`b_${e}_client_num_queued`,`b_${e}_client_last_registered`,`b_${e}_client_last_seen`]},s={init:{keys:t.allKeys,headers:["process_tick"],refresh_expiration:!0,code:i["init.lua"]},group_check:{keys:t.allKeys,headers:[],refresh_expiration:!1,code:i["group_check.lua"]},register_client:{keys:t.allKeys,headers:["validate_keys"],refresh_expiration:!1,code:i["register_client.lua"]},blacklist_client:{keys:t.allKeys,headers:["validate_keys","validate_client"],refresh_expiration:!1,code:i["blacklist_client.lua"]},heartbeat:{keys:t.allKeys,headers:["validate_keys","validate_client","process_tick"],refresh_expiration:!1,code:i["heartbeat.lua"]},update_settings:{keys:t.allKeys,headers:["validate_keys","validate_client","process_tick"],refresh_expiration:!0,code:i["update_settings.lua"]},running:{keys:t.allKeys,headers:["validate_keys","validate_client","process_tick"],refresh_expiration:!1,code:i["running.lua"]},queued:{keys:t.allKeys,headers:["validate_keys","validate_client"],refresh_expiration:!1,code:i["queued.lua"]},done:{keys:t.allKeys,headers:["validate_keys","validate_client","process_tick"],refresh_expiration:!1,code:i["done.lua"]},check:{keys:t.allKeys,headers:["validate_keys","validate_client","process_tick","conditions_check"],refresh_expiration:!1,code:i["check.lua"]},submit:{keys:t.allKeys,headers:["validate_keys","validate_client","process_tick","conditions_check"],refresh_expiration:!0,code:i["submit.lua"]},register:{keys:t.allKeys,headers:["validate_keys","validate_client","process_tick","conditions_check"],refresh_expiration:!0,code:i["register.lua"]},free:{keys:t.allKeys,headers:["validate_keys","validate_client","process_tick"],refresh_expiration:!0,code:i["free.lua"]},current_reservoir:{keys:t.allKeys,headers:["validate_keys","validate_client","process_tick"],refresh_expiration:!1,code:i["current_reservoir.lua"]},increment_reservoir:{keys:t.allKeys,headers:["validate_keys","validate_client","process_tick"],refresh_expiration:!0,code:i["increment_reservoir.lua"]}},t.names=Object.keys(s),t.keys=function(e,t){return s[e].keys(t)},t.payload=function(e){var t;return t=s[e],Array.prototype.concat(r.refs,t.headers.map((function(e){return r[e]})),t.refresh_expiration?r.refresh_expiration:"",t.code).join("\n")}},376:(e,t,n)=>{var r,i;r=n(6),i=class{constructor(e){this.status=e,this._jobs={},this.counts=this.status.map((function(){return 0}))}next(e){var t,n;return n=(t=this._jobs[e])+1,null!=t&&n<this.status.length?(this.counts[t]--,this.counts[n]++,this._jobs[e]++):null!=t?(this.counts[t]--,delete this._jobs[e]):void 0}start(e){return this._jobs[e]=0,this.counts[0]++}remove(e){var t;return null!=(t=this._jobs[e])&&(this.counts[t]--,delete this._jobs[e]),null!=t}jobStatus(e){var t;return null!=(t=this.status[this._jobs[e]])?t:null}statusJobs(e){var t,n,i,s;if(null!=e){if((n=this.status.indexOf(e))<0)throw new r(`status must be one of ${this.status.join(", ")}`);for(t in s=[],i=this._jobs)i[t]===n&&s.push(t);return s}return Object.keys(this._jobs)}statusCounts(){return this.counts.reduce(((e,t,n)=>(e[this.status[n]]=t,e)),{})}},e.exports=i},915:(e,t,n)=>{function r(e,t,n,r,i,s,o){try{var a=e[s](o),l=a.value}catch(e){return void n(e)}a.done?t(l):Promise.resolve(l).then(r,i)}function i(e){return function(){var t=this,n=arguments;return new Promise((function(i,s){var o=e.apply(t,n);function a(e){r(o,i,s,a,l,"next",e)}function l(e){r(o,i,s,a,l,"throw",e)}a(void 0)}))}}var s,o;s=n(938),o=class{constructor(e,t){this.schedule=this.schedule.bind(this),this.name=e,this.Promise=t,this._running=0,this._queue=new s}isEmpty(){return 0===this._queue.length}_tryToRun(){var e=this;return i((function*(){var t,n,r,s,o,a,l;if(e._running<1&&e._queue.length>0){e._running++;var c=e._queue.shift();return l=c.task,t=c.args,o=c.resolve,s=c.reject,n=yield i((function*(){try{return a=yield l(...t),function(){return o(a)}}catch(e){return r=e,function(){return s(r)}}}))(),e._running--,e._tryToRun(),n()}}))()}schedule(e,...t){var n,r,i;return i=r=null,n=new this.Promise((function(e,t){return i=e,r=t})),this._queue.push({task:e,args:t,resolve:i,reject:r}),this._tryToRun(),n}},e.exports=o},861:(e,t,n)=>{e.exports=n(529)},92:(e,t)=>{t.load=function(e,t,n={}){var r,i,s;for(r in t)s=t[r],n[r]=null!=(i=e[r])?i:s;return n},t.overwrite=function(e,t,n={}){var r,i;for(r in e)i=e[r],void 0!==t[r]&&(n[r]=i);return n}},268:e=>{e.exports=__WEBPACK_EXTERNAL_MODULE__268__},936:e=>{e.exports=JSON.parse("{\"blacklist_client.lua\":\"local blacklist = ARGV[num_static_argv + 1]\\n\\nif redis.call('zscore', client_last_seen_key, blacklist) then\\n redis.call('zadd', client_last_seen_key, 0, blacklist)\\nend\\n\\n\\nreturn {}\\n\",\"check.lua\":\"local weight = tonumber(ARGV[num_static_argv + 1])\\n\\nlocal capacity = process_tick(now, false)['capacity']\\nlocal nextRequest = tonumber(redis.call('hget', settings_key, 'nextRequest'))\\n\\nreturn conditions_check(capacity, weight) and nextRequest - now <= 0\\n\",\"conditions_check.lua\":\"local conditions_check = function (capacity, weight)\\n return capacity == nil or weight <= capacity\\nend\\n\",\"current_reservoir.lua\":\"return process_tick(now, false)['reservoir']\\n\",\"done.lua\":\"process_tick(now, false)\\n\\nreturn tonumber(redis.call('hget', settings_key, 'done'))\\n\",\"free.lua\":\"local index = ARGV[num_static_argv + 1]\\n\\nredis.call('zadd', job_expirations_key, 0, index)\\n\\nreturn process_tick(now, false)['running']\\n\",\"get_time.lua\":\"redis.replicate_commands()\\n\\nlocal get_time = function ()\\n local time = redis.call('time')\\n\\n return tonumber(time[1]..string.sub(time[2], 1, 3))\\nend\\n\",\"group_check.lua\":\"return not (redis.call('exists', settings_key) == 1)\\n\",\"heartbeat.lua\":\"process_tick(now, true)\\n\",\"increment_reservoir.lua\":\"local incr = tonumber(ARGV[num_static_argv + 1])\\n\\nredis.call('hincrby', settings_key, 'reservoir', incr)\\n\\nlocal reservoir = process_tick(now, true)['reservoir']\\n\\nlocal groupTimeout = tonumber(redis.call('hget', settings_key, 'groupTimeout'))\\nrefresh_expiration(0, 0, groupTimeout)\\n\\nreturn reservoir\\n\",\"init.lua\":\"local clear = tonumber(ARGV[num_static_argv + 1])\\nlocal limiter_version = ARGV[num_static_argv + 2]\\nlocal num_local_argv = num_static_argv + 2\\n\\nif clear == 1 then\\n redis.call('del', unpack(KEYS))\\nend\\n\\nif redis.call('exists', settings_key) == 0 then\\n -- Create\\n local args = {'hmset', settings_key}\\n\\n for i = num_local_argv + 1, #ARGV do\\n table.insert(args, ARGV[i])\\n end\\n\\n redis.call(unpack(args))\\n redis.call('hmset', settings_key,\\n 'nextRequest', now,\\n 'lastReservoirRefresh', now,\\n 'lastReservoirIncrease', now,\\n 'running', 0,\\n 'done', 0,\\n 'unblockTime', 0,\\n 'capacityPriorityCounter', 0\\n )\\n\\nelse\\n -- Apply migrations\\n local settings = redis.call('hmget', settings_key,\\n 'id',\\n 'version'\\n )\\n local id = settings[1]\\n local current_version = settings[2]\\n\\n if current_version ~= limiter_version then\\n local version_digits = {}\\n for k, v in string.gmatch(current_version, \\\"([^.]+)\\\") do\\n table.insert(version_digits, tonumber(k))\\n end\\n\\n -- 2.10.0\\n if version_digits[2] < 10 then\\n redis.call('hsetnx', settings_key, 'reservoirRefreshInterval', '')\\n redis.call('hsetnx', settings_key, 'reservoirRefreshAmount', '')\\n redis.call('hsetnx', settings_key, 'lastReservoirRefresh', '')\\n redis.call('hsetnx', settings_key, 'done', 0)\\n redis.call('hset', settings_key, 'version', '2.10.0')\\n end\\n\\n -- 2.11.1\\n if version_digits[2] < 11 or (version_digits[2] == 11 and version_digits[3] < 1) then\\n if redis.call('hstrlen', settings_key, 'lastReservoirRefresh') == 0 then\\n redis.call('hmset', settings_key,\\n 'lastReservoirRefresh', now,\\n 'version', '2.11.1'\\n )\\n end\\n end\\n\\n -- 2.14.0\\n if version_digits[2] < 14 then\\n local old_running_key = 'b_'..id..'_running'\\n local old_executing_key = 'b_'..id..'_executing'\\n\\n if redis.call('exists', old_running_key) == 1 then\\n redis.call('rename', old_running_key, job_weights_key)\\n end\\n if redis.call('exists', old_executing_key) == 1 then\\n redis.call('rename', old_executing_key, job_expirations_key)\\n end\\n redis.call('hset', settings_key, 'version', '2.14.0')\\n end\\n\\n -- 2.15.2\\n if version_digits[2] < 15 or (version_digits[2] == 15 and version_digits[3] < 2) then\\n redis.call('hsetnx', settings_key, 'capacityPriorityCounter', 0)\\n redis.call('hset', settings_key, 'version', '2.15.2')\\n end\\n\\n -- 2.17.0\\n if version_digits[2] < 17 then\\n redis.call('hsetnx', settings_key, 'clientTimeout', 10000)\\n redis.call('hset', settings_key, 'version', '2.17.0')\\n end\\n\\n -- 2.18.0\\n if version_digits[2] < 18 then\\n redis.call('hsetnx', settings_key, 'reservoirIncreaseInterval', '')\\n redis.call('hsetnx', settings_key, 'reservoirIncreaseAmount', '')\\n redis.call('hsetnx', settings_key, 'reservoirIncreaseMaximum', '')\\n redis.call('hsetnx', settings_key, 'lastReservoirIncrease', now)\\n redis.call('hset', settings_key, 'version', '2.18.0')\\n end\\n\\n end\\n\\n process_tick(now, false)\\nend\\n\\nlocal groupTimeout = tonumber(redis.call('hget', settings_key, 'groupTimeout'))\\nrefresh_expiration(0, 0, groupTimeout)\\n\\nreturn {}\\n\",\"process_tick.lua\":\"local process_tick = function (now, always_publish)\\n\\n local compute_capacity = function (maxConcurrent, running, reservoir)\\n if maxConcurrent ~= nil and reservoir ~= nil then\\n return math.min((maxConcurrent - running), reservoir)\\n elseif maxConcurrent ~= nil then\\n return maxConcurrent - running\\n elseif reservoir ~= nil then\\n return reservoir\\n else\\n return nil\\n end\\n end\\n\\n local settings = redis.call('hmget', settings_key,\\n 'id',\\n 'maxConcurrent',\\n 'running',\\n 'reservoir',\\n 'reservoirRefreshInterval',\\n 'reservoirRefreshAmount',\\n 'lastReservoirRefresh',\\n 'reservoirIncreaseInterval',\\n 'reservoirIncreaseAmount',\\n 'reservoirIncreaseMaximum',\\n 'lastReservoirIncrease',\\n 'capacityPriorityCounter',\\n 'clientTimeout'\\n )\\n local id = settings[1]\\n local maxConcurrent = tonumber(settings[2])\\n local running = tonumber(settings[3])\\n local reservoir = tonumber(settings[4])\\n local reservoirRefreshInterval = tonumber(settings[5])\\n local reservoirRefreshAmount = tonumber(settings[6])\\n local lastReservoirRefresh = tonumber(settings[7])\\n local reservoirIncreaseInterval = tonumber(settings[8])\\n local reservoirIncreaseAmount = tonumber(settings[9])\\n local reservoirIncreaseMaximum = tonumber(settings[10])\\n local lastReservoirIncrease = tonumber(settings[11])\\n local capacityPriorityCounter = tonumber(settings[12])\\n local clientTimeout = tonumber(settings[13])\\n\\n local initial_capacity = compute_capacity(maxConcurrent, running, reservoir)\\n\\n --\\n -- Process 'running' changes\\n --\\n local expired = redis.call('zrangebyscore', job_expirations_key, '-inf', '('..now)\\n\\n if #expired > 0 then\\n redis.call('zremrangebyscore', job_expirations_key, '-inf', '('..now)\\n\\n local flush_batch = function (batch, acc)\\n local weights = redis.call('hmget', job_weights_key, unpack(batch))\\n redis.call('hdel', job_weights_key, unpack(batch))\\n local clients = redis.call('hmget', job_clients_key, unpack(batch))\\n redis.call('hdel', job_clients_key, unpack(batch))\\n\\n -- Calculate sum of removed weights\\n for i = 1, #weights do\\n acc['total'] = acc['total'] + (tonumber(weights[i]) or 0)\\n end\\n\\n -- Calculate sum of removed weights by client\\n local client_weights = {}\\n for i = 1, #clients do\\n local removed = tonumber(weights[i]) or 0\\n if removed > 0 then\\n acc['client_weights'][clients[i]] = (acc['client_weights'][clients[i]] or 0) + removed\\n end\\n end\\n end\\n\\n local acc = {\\n ['total'] = 0,\\n ['client_weights'] = {}\\n }\\n local batch_size = 1000\\n\\n -- Compute changes to Zsets and apply changes to Hashes\\n for i = 1, #expired, batch_size do\\n local batch = {}\\n for j = i, math.min(i + batch_size - 1, #expired) do\\n table.insert(batch, expired[j])\\n end\\n\\n flush_batch(batch, acc)\\n end\\n\\n -- Apply changes to Zsets\\n if acc['total'] > 0 then\\n redis.call('hincrby', settings_key, 'done', acc['total'])\\n running = tonumber(redis.call('hincrby', settings_key, 'running', -acc['total']))\\n end\\n\\n for client, weight in pairs(acc['client_weights']) do\\n redis.call('zincrby', client_running_key, -weight, client)\\n end\\n end\\n\\n --\\n -- Process 'reservoir' changes\\n --\\n local reservoirRefreshActive = reservoirRefreshInterval ~= nil and reservoirRefreshAmount ~= nil\\n if reservoirRefreshActive and now >= lastReservoirRefresh + reservoirRefreshInterval then\\n reservoir = reservoirRefreshAmount\\n redis.call('hmset', settings_key,\\n 'reservoir', reservoir,\\n 'lastReservoirRefresh', now\\n )\\n end\\n\\n local reservoirIncreaseActive = reservoirIncreaseInterval ~= nil and reservoirIncreaseAmount ~= nil\\n if reservoirIncreaseActive and now >= lastReservoirIncrease + reservoirIncreaseInterval then\\n local num_intervals = math.floor((now - lastReservoirIncrease) / reservoirIncreaseInterval)\\n local incr = reservoirIncreaseAmount * num_intervals\\n if reservoirIncreaseMaximum ~= nil then\\n incr = math.min(incr, reservoirIncreaseMaximum - (reservoir or 0))\\n end\\n if incr > 0 then\\n reservoir = (reservoir or 0) + incr\\n end\\n redis.call('hmset', settings_key,\\n 'reservoir', reservoir,\\n 'lastReservoirIncrease', lastReservoirIncrease + (num_intervals * reservoirIncreaseInterval)\\n )\\n end\\n\\n --\\n -- Clear unresponsive clients\\n --\\n local unresponsive = redis.call('zrangebyscore', client_last_seen_key, '-inf', (now - clientTimeout))\\n local unresponsive_lookup = {}\\n local terminated_clients = {}\\n for i = 1, #unresponsive do\\n unresponsive_lookup[unresponsive[i]] = true\\n if tonumber(redis.call('zscore', client_running_key, unresponsive[i])) == 0 then\\n table.insert(terminated_clients, unresponsive[i])\\n end\\n end\\n if #terminated_clients > 0 then\\n redis.call('zrem', client_running_key, unpack(terminated_clients))\\n redis.call('hdel', client_num_queued_key, unpack(terminated_clients))\\n redis.call('zrem', client_last_registered_key, unpack(terminated_clients))\\n redis.call('zrem', client_last_seen_key, unpack(terminated_clients))\\n end\\n\\n --\\n -- Broadcast capacity changes\\n --\\n local final_capacity = compute_capacity(maxConcurrent, running, reservoir)\\n\\n if always_publish or (initial_capacity ~= nil and final_capacity == nil) then\\n -- always_publish or was not unlimited, now unlimited\\n redis.call('publish', 'b_'..id, 'capacity:'..(final_capacity or ''))\\n\\n elseif initial_capacity ~= nil and final_capacity ~= nil and final_capacity > initial_capacity then\\n -- capacity was increased\\n -- send the capacity message to the limiter having the lowest number of running jobs\\n -- the tiebreaker is the limiter having not registered a job in the longest time\\n\\n local lowest_concurrency_value = nil\\n local lowest_concurrency_clients = {}\\n local lowest_concurrency_last_registered = {}\\n local client_concurrencies = redis.call('zrange', client_running_key, 0, -1, 'withscores')\\n\\n for i = 1, #client_concurrencies, 2 do\\n local client = client_concurrencies[i]\\n local concurrency = tonumber(client_concurrencies[i+1])\\n\\n if (\\n lowest_concurrency_value == nil or lowest_concurrency_value == concurrency\\n ) and (\\n not unresponsive_lookup[client]\\n ) and (\\n tonumber(redis.call('hget', client_num_queued_key, client)) > 0\\n ) then\\n lowest_concurrency_value = concurrency\\n table.insert(lowest_concurrency_clients, client)\\n local last_registered = tonumber(redis.call('zscore', client_last_registered_key, client))\\n table.insert(lowest_concurrency_last_registered, last_registered)\\n end\\n end\\n\\n if #lowest_concurrency_clients > 0 then\\n local position = 1\\n local earliest = lowest_concurrency_last_registered[1]\\n\\n for i,v in ipairs(lowest_concurrency_last_registered) do\\n if v < earliest then\\n position = i\\n earliest = v\\n end\\n end\\n\\n local next_client = lowest_concurrency_clients[position]\\n redis.call('publish', 'b_'..id,\\n 'capacity-priority:'..(final_capacity or '')..\\n ':'..next_client..\\n ':'..capacityPriorityCounter\\n )\\n redis.call('hincrby', settings_key, 'capacityPriorityCounter', '1')\\n else\\n redis.call('publish', 'b_'..id, 'capacity:'..(final_capacity or ''))\\n end\\n end\\n\\n return {\\n ['capacity'] = final_capacity,\\n ['running'] = running,\\n ['reservoir'] = reservoir\\n }\\nend\\n\",\"queued.lua\":\"local clientTimeout = tonumber(redis.call('hget', settings_key, 'clientTimeout'))\\nlocal valid_clients = redis.call('zrangebyscore', client_last_seen_key, (now - clientTimeout), 'inf')\\nlocal client_queued = redis.call('hmget', client_num_queued_key, unpack(valid_clients))\\n\\nlocal sum = 0\\nfor i = 1, #client_queued do\\n sum = sum + tonumber(client_queued[i])\\nend\\n\\nreturn sum\\n\",\"refresh_expiration.lua\":\"local refresh_expiration = function (now, nextRequest, groupTimeout)\\n\\n if groupTimeout ~= nil then\\n local ttl = (nextRequest + groupTimeout) - now\\n\\n for i = 1, #KEYS do\\n redis.call('pexpire', KEYS[i], ttl)\\n end\\n end\\n\\nend\\n\",\"refs.lua\":\"local settings_key = KEYS[1]\\nlocal job_weights_key = KEYS[2]\\nlocal job_expirations_key = KEYS[3]\\nlocal job_clients_key = KEYS[4]\\nlocal client_running_key = KEYS[5]\\nlocal client_num_queued_key = KEYS[6]\\nlocal client_last_registered_key = KEYS[7]\\nlocal client_last_seen_key = KEYS[8]\\n\\nlocal now = tonumber(ARGV[1])\\nlocal client = ARGV[2]\\n\\nlocal num_static_argv = 2\\n\",\"register.lua\":\"local index = ARGV[num_static_argv + 1]\\nlocal weight = tonumber(ARGV[num_static_argv + 2])\\nlocal expiration = tonumber(ARGV[num_static_argv + 3])\\n\\nlocal state = process_tick(now, false)\\nlocal capacity = state['capacity']\\nlocal reservoir = state['reservoir']\\n\\nlocal settings = redis.call('hmget', settings_key,\\n 'nextRequest',\\n 'minTime',\\n 'groupTimeout'\\n)\\nlocal nextRequest = tonumber(settings[1])\\nlocal minTime = tonumber(settings[2])\\nlocal groupTimeout = tonumber(settings[3])\\n\\nif conditions_check(capacity, weight) then\\n\\n redis.call('hincrby', settings_key, 'running', weight)\\n redis.call('hset', job_weights_key, index, weight)\\n if expiration ~= nil then\\n redis.call('zadd', job_expirations_key, now + expiration, index)\\n end\\n redis.call('hset', job_clients_key, index, client)\\n redis.call('zincrby', client_running_key, weight, client)\\n redis.call('hincrby', client_num_queued_key, client, -1)\\n redis.call('zadd', client_last_registered_key, now, client)\\n\\n local wait = math.max(nextRequest - now, 0)\\n local newNextRequest = now + wait + minTime\\n\\n if reservoir == nil then\\n redis.call('hset', settings_key,\\n 'nextRequest', newNextRequest\\n )\\n else\\n reservoir = reservoir - weight\\n redis.call('hmset', settings_key,\\n 'reservoir', reservoir,\\n 'nextRequest', newNextRequest\\n )\\n end\\n\\n refresh_expiration(now, newNextRequest, groupTimeout)\\n\\n return {true, wait, reservoir}\\n\\nelse\\n return {false}\\nend\\n\",\"register_client.lua\":\"local queued = tonumber(ARGV[num_static_argv + 1])\\n\\n-- Could have been re-registered concurrently\\nif not redis.call('zscore', client_last_seen_key, client) then\\n redis.call('zadd', client_running_key, 0, client)\\n redis.call('hset', client_num_queued_key, client, queued)\\n redis.call('zadd', client_last_registered_key, 0, client)\\nend\\n\\nredis.call('zadd', client_last_seen_key, now, client)\\n\\nreturn {}\\n\",\"running.lua\":\"return process_tick(now, false)['running']\\n\",\"submit.lua\":\"local queueLength = tonumber(ARGV[num_static_argv + 1])\\nlocal weight = tonumber(ARGV[num_static_argv + 2])\\n\\nlocal capacity = process_tick(now, false)['capacity']\\n\\nlocal settings = redis.call('hmget', settings_key,\\n 'id',\\n 'maxConcurrent',\\n 'highWater',\\n 'nextRequest',\\n 'strategy',\\n 'unblockTime',\\n 'penalty',\\n 'minTime',\\n 'groupTimeout'\\n)\\nlocal id = settings[1]\\nlocal maxConcurrent = tonumber(settings[2])\\nlocal highWater = tonumber(settings[3])\\nlocal nextRequest = tonumber(settings[4])\\nlocal strategy = tonumber(settings[5])\\nlocal unblockTime = tonumber(settings[6])\\nlocal penalty = tonumber(settings[7])\\nlocal minTime = tonumber(settings[8])\\nlocal groupTimeout = tonumber(settings[9])\\n\\nif maxConcurrent ~= nil and weight > maxConcurrent then\\n return redis.error_reply('OVERWEIGHT:'..weight..':'..maxConcurrent)\\nend\\n\\nlocal reachedHWM = (highWater ~= nil and queueLength == highWater\\n and not (\\n conditions_check(capacity, weight)\\n and nextRequest - now <= 0\\n )\\n)\\n\\nlocal blocked = strategy == 3 and (reachedHWM or unblockTime >= now)\\n\\nif blocked then\\n local computedPenalty = penalty\\n if computedPenalty == nil then\\n if minTime == 0 then\\n computedPenalty = 5000\\n else\\n computedPenalty = 15 * minTime\\n end\\n end\\n\\n local newNextRequest = now + computedPenalty + minTime\\n\\n redis.call('hmset', settings_key,\\n 'unblockTime', now + computedPenalty,\\n 'nextRequest', newNextRequest\\n )\\n\\n local clients_queued_reset = redis.call('hkeys', client_num_queued_key)\\n local queued_reset = {}\\n for i = 1, #clients_queued_reset do\\n table.insert(queued_reset, clients_queued_reset[i])\\n table.insert(queued_reset, 0)\\n end\\n redis.call('hmset', client_num_queued_key, unpack(queued_reset))\\n\\n redis.call('publish', 'b_'..id, 'blocked:')\\n\\n refresh_expiration(now, newNextRequest, groupTimeout)\\nend\\n\\nif not blocked and not reachedHWM then\\n redis.call('hincrby', client_num_queued_key, client, 1)\\nend\\n\\nreturn {reachedHWM, blocked, strategy}\\n\",\"update_settings.lua\":\"local args = {'hmset', settings_key}\\n\\nfor i = num_static_argv + 1, #ARGV do\\n table.insert(args, ARGV[i])\\nend\\n\\nredis.call(unpack(args))\\n\\nprocess_tick(now, true)\\n\\nlocal groupTimeout = tonumber(redis.call('hget', settings_key, 'groupTimeout'))\\nrefresh_expiration(0, 0, groupTimeout)\\n\\nreturn {}\\n\",\"validate_client.lua\":\"if not redis.call('zscore', client_last_seen_key, client) then\\n return redis.error_reply('UNKNOWN_CLIENT')\\nend\\n\\nredis.call('zadd', client_last_seen_key, now, client)\\n\",\"validate_keys.lua\":\"if not (redis.call('exists', settings_key) == 1) then\\n return redis.error_reply('SETTINGS_KEY_NOT_FOUND')\\nend\\n\"}")},636:e=>{e.exports={i:"2.19.5"}}},__webpack_module_cache__={};function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;var n=__webpack_module_cache__[e]={exports:{}};return __webpack_modules__[e](n,n.exports,__webpack_require__),n.exports}__webpack_require__.d=(e,t)=>{for(var n in t)__webpack_require__.o(t,n)&&!__webpack_require__.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var __webpack_exports__={};return(()=>{__webpack_require__.r(__webpack_exports__),__webpack_require__.d(__webpack_exports__,{children:()=>u,content:()=>_,limiter:()=>s,meta:()=>h});var e=__webpack_require__(268),t=__webpack_require__(861);const n="www.canada.ca",r={Jan:"01",Feb:"02",Mar:"03",Apr:"04",May:"05",Jun:"06",Jul:"07",Aug:"08",Sep:"09",Oct:"10",Nov:"11",Dec:"12"};function i(e){let t=/^\w{3} (\w{3}) (\d{2}) (\d{4}) ([\d:]{8}) GMT([\-+]\d{4})$/.exec(e);return t?new Date(t[3]+"-"+r[t[1]]+"-"+t[2]+"T"+t[4]+t[5]).getTime():e}const s=new t({reservoir:120,reservoirRefreshAmount:120,reservoirRefreshInterval:6e4,maxConcurrent:10});function o(e,t){return"https://"+n+e+t+"?_="+Date.now()}function a(e){if((e=new URL(e,"https://"+n)).hostname!==n)throw new Error("Invalid hostname "+e.hostname);if(e.pathname.startsWith("/content/dam/"))return e.pathname;if(e.pathname.startsWith("/content/canadasite/")&&(e.pathname=e.pathname.substr(19)),/^\/(en|fr)(\/|$)/.test(e.pathname))return e.pathname.replace(/\.[^\.]+$/,"").replace(/\/$/,"");throw new Error("Invalid path "+e)}function l(e){if("string"==typeof e)return{path:a(e)};if("object"==typeof e&&"string"==typeof e.path)return e.path=a(e.path),e;throw new Error("Invalid node")}function c(e){if(!e.ok)throw new Error(e.statusText);if(!e.url.includes(n))throw new Error("Redirect");if(e.url.includes("/errors/404.html"))throw new Error("Not Found");return e}function u(t){return t=l(t),s.schedule((()=>e(o(t.path,".sitemap.xml")))).then(c).then((e=>e.text())).then((e=>{let t=e.match(/(?<=<loc>)[^<]+(?=<\/loc>)/g),n=e.match(/(?<=<lastmod>)[^<]+(?=<\/lastmod>)/g);return t.map(((e,t)=>({path:a(e),lastmod:new Date(n[t]).getTime()})))})).catch((e=>e))}function h(t){return t=l(t),s.schedule((()=>e(o(t.path,"/jcr:content.json")))).then(c).then((e=>e.json())).then((e=>{for(var n in e)"true"===e[n]?e[n]=!0:"false"===e[n]?e[n]=!1:n.endsWith("@TypeHint")?delete e[n]:"string"==typeof e[n]&&33===e[n].length&&(e[n]=i(e[n]));return t.meta=e,t})).catch((e=>(t.meta=e,t)))}function _(t){let n=(t=l(t)).path.startsWith("/content/dam/")?"":".html";return s.schedule((()=>e(o(t.path,n)))).then(c).then((e=>e.headers.get("Content-Type").includes("application/json")?e.json():e.text())).then((e=>(t.content=e,t))).catch((e=>(t.content=e,t)))}})(),__webpack_exports__})()));
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "canada-api",
3
+ "version": "1.0.0",
4
+ "description": "API for fetching data from canada.ca",
5
+ "scripts": {
6
+ "test": "echo \"Error: no test specified\" && exit 1",
7
+ "build": "webpack",
8
+ "dev": "webpack --mode development"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/bsoicher/canada-api.git"
13
+ },
14
+ "author": "Ben Soicher",
15
+ "license": "MIT",
16
+ "bugs": {
17
+ "url": "https://github.com/bsoicher/canada-api/issues"
18
+ },
19
+ "homepage": "https://github.com/bsoicher/canada-api#readme",
20
+ "devDependencies": {
21
+ "webpack": "^5.70.0",
22
+ "webpack-cli": "^4.9.2"
23
+ },
24
+ "dependencies": {
25
+ "bottleneck": "^2.19.5",
26
+ "cross-fetch": "^3.1.5"
27
+ }
28
+ }
package/src/index.mjs ADDED
@@ -0,0 +1,205 @@
1
+ import fetch from 'cross-fetch'
2
+ import Bottleneck from 'bottleneck'
3
+
4
+ const domain = 'www.canada.ca'
5
+
6
+ /**
7
+ * Map month name to index
8
+ */
9
+ const months = {
10
+ 'Jan': '01',
11
+ 'Feb': '02',
12
+ 'Mar': '03',
13
+ 'Apr': '04',
14
+ 'May': '05',
15
+ 'Jun': '06',
16
+ 'Jul': '07',
17
+ 'Aug': '08',
18
+ 'Sep': '09',
19
+ 'Oct': '10',
20
+ 'Nov': '11',
21
+ 'Dec': '12'
22
+ }
23
+
24
+ /**
25
+ * Parse date in RFC1123 format
26
+ * @param {string} date
27
+ * @returns {Date}
28
+ */
29
+ function parseDate(date) {
30
+ let m = /^\w{3} (\w{3}) (\d{2}) (\d{4}) ([\d:]{8}) GMT([\-+]\d{4})$/.exec(date)
31
+ return m ? new Date(m[3] + '-' + months[m[1]] + '-' + m[2] + 'T' + m[4] + m[5]).getTime() : date
32
+ }
33
+
34
+ /**
35
+ * Throttles requests to prevent being throttled by the server
36
+ */
37
+ export const limiter = new Bottleneck({
38
+ reservoir: 120,
39
+ reservoirRefreshAmount: 120,
40
+ reservoirRefreshInterval: 60000,
41
+ maxConcurrent: 10,
42
+ })
43
+
44
+ /**
45
+ * Format fetch URL
46
+ * @param {string} path Node path
47
+ * @param {string} suffix
48
+ * @returns {string}
49
+ */
50
+ function formatURL(path, suffix) {
51
+ return 'https://' + domain + path + suffix + '?_=' + Date.now()
52
+ }
53
+
54
+ /**
55
+ * Normalize AEM path from URL
56
+ * @param {string} url
57
+ * @throws {Error} Invalid path
58
+ * @returns {string}
59
+ */
60
+ function normalizePath(url) {
61
+ url = new URL(url, 'https://' + domain)
62
+
63
+ if (url.hostname !== domain) {
64
+ throw new Error('Invalid hostname ' + url.hostname)
65
+ }
66
+
67
+ if (url.pathname.startsWith('/content/dam/')) {
68
+ return url.pathname
69
+ } else if (url.pathname.startsWith('/content/canadasite/')) {
70
+ url.pathname = url.pathname.substr(19)
71
+ }
72
+
73
+ if (/^\/(en|fr)(\/|$)/.test(url.pathname)) {
74
+ return url.pathname.replace(/\.[^\.]+$/, '').replace(/\/$/, '')
75
+ }
76
+
77
+ throw new Error('Invalid path ' + url)
78
+ }
79
+
80
+ /**
81
+ * Normalize node object (Modifies existing node if provided)
82
+ * @param {string|Object} node
83
+ * @throws {Error} Invalid node
84
+ * @returns {Object}
85
+ */
86
+ function normalizeNode(node) {
87
+ if (typeof node === 'string') {
88
+ return { path: normalizePath(node) }
89
+ } else if (typeof node === 'object' && typeof node.path === 'string') {
90
+ node.path = normalizePath(node.path)
91
+ return node
92
+ }
93
+
94
+ throw new Error('Invalid node')
95
+ }
96
+
97
+ /**
98
+ * Verify if fetch succeeded
99
+ * @param {Response} response
100
+ * @throws {Error} Fetch failed to load as expected
101
+ * @returns {Response}
102
+ */
103
+ function verifyResponse(response) {
104
+ if (!response.ok) {
105
+ // Bad http response
106
+ throw new Error(response.statusText)
107
+ } else if (!response.url.includes(domain)) {
108
+ // Redirected outside of domain
109
+ throw new Error('Redirect')
110
+ } else if (response.url.includes('/errors/404.html')) {
111
+ // 404 document was loaded
112
+ throw new Error('Not Found')
113
+ }
114
+
115
+ return response
116
+ }
117
+
118
+ /**
119
+ * Get node children
120
+ * @param {string|Object} node
121
+ * @param {array} list Node list to extend
122
+ * @returns {Object}
123
+ */
124
+ export function children(node) {
125
+ node = normalizeNode(node)
126
+
127
+ return limiter.schedule(() => fetch(formatURL(node.path, '.sitemap.xml')))
128
+ .then(verifyResponse)
129
+ .then(response => response.text())
130
+ .then(xml => {
131
+ // Extract XML data
132
+ let locs = xml.match(/(?<=<loc>)[^<]+(?=<\/loc>)/g)
133
+ let mods = xml.match(/(?<=<lastmod>)[^<]+(?=<\/lastmod>)/g)
134
+ return locs.map((loc, index) => {
135
+ return {
136
+ path: normalizePath(loc),
137
+ lastmod: new Date(mods[index]).getTime()
138
+ }
139
+ })
140
+ })
141
+ .catch(err => {
142
+ return err
143
+ })
144
+ }
145
+
146
+ /**
147
+ * Get node metadata
148
+ * @param {string|Object} node
149
+ * @returns {Object}
150
+ */
151
+ export function meta(node) {
152
+ node = normalizeNode(node)
153
+
154
+ return limiter.schedule(() => fetch(formatURL(node.path, '/jcr:content.json')))
155
+ .then(verifyResponse)
156
+ .then(response => response.json())
157
+ .then(meta => {
158
+ // Format properties
159
+ for (var key in meta) {
160
+ if (meta[key] === 'true') {
161
+ meta[key] = true
162
+ } else if (meta[key] === 'false') {
163
+ meta[key] = false
164
+ } else if (key.endsWith('@TypeHint')) {
165
+ delete meta[key]
166
+ } else if (typeof meta[key] === 'string' && meta[key].length === 33) {
167
+ meta[key] = parseDate(meta[key])
168
+ }
169
+ }
170
+
171
+ node.meta = meta
172
+ return node
173
+ })
174
+ .catch(err => {
175
+ node.meta = err
176
+ return node
177
+ })
178
+ }
179
+
180
+ /**
181
+ * Get node content
182
+ * @param {string|Object} node
183
+ * @returns {Object}
184
+ */
185
+ export function content(node) {
186
+ node = normalizeNode(node)
187
+ let suffix = node.path.startsWith('/content/dam/') ? '' : '.html'
188
+
189
+ return limiter.schedule(() => fetch(formatURL(node.path, suffix)))
190
+ .then(verifyResponse)
191
+ .then(response => {
192
+ if (response.headers.get('Content-Type').includes('application/json')) {
193
+ return response.json()
194
+ }
195
+ return response.text()
196
+ })
197
+ .then(content => {
198
+ node.content = content
199
+ return node
200
+ })
201
+ .catch(err => {
202
+ node.content = err
203
+ return node
204
+ })
205
+ }
@@ -0,0 +1,25 @@
1
+ const path = require('path');
2
+
3
+ module.exports = {
4
+ mode: 'production',
5
+ entry: './src/index.mjs',
6
+ output: {
7
+ path: path.resolve(__dirname, './dist/'),
8
+ filename: 'ca.js',
9
+ library: {
10
+ name: 'ca',
11
+ type: 'umd',
12
+ umdNamedDefine: true
13
+ },
14
+ globalObject: 'typeof self !== \'undefined\' ? self : this',
15
+ clean: true
16
+ },
17
+ externals: {
18
+ 'cross-fetch': {
19
+ amd: 'cross-fetch',
20
+ commonjs: 'cross-fetch',
21
+ commonjs2: 'cross-fetch',
22
+ root: 'fetch'
23
+ }
24
+ },
25
+ }