diff --git a/.github/workflows/node.yml b/.github/workflows/node.yml new file mode 100644 index 00000000..1b9d8ddf --- /dev/null +++ b/.github/workflows/node.yml @@ -0,0 +1,43 @@ +name: Unit tests + +on: + push: + branches: + - master + - develop + pull_request: + branches: + - master + - develop + release: + types: + - created + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [10.x, 14.x] + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - name: Cache Node.js modules + uses: actions/cache@v2 + with: + # npm cache files are stored in `~/.npm` on Linux/macOS + path: ~/.npm + key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.OS }}-node- + ${{ runner.OS }}- + - name: Build and test package + run: | + npm ci + npm run build + npm run test + env: + CI: true diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 188a0d95..00000000 --- a/.travis.yml +++ /dev/null @@ -1,22 +0,0 @@ -language: node_js -node_js: - - "lts/erbium" - - "lts/dubnium" -cache: - yarn: true - directories: - - node_modules -before_script: - - npm install -script: - - eslint . - - npm test -branches: - only: - - master - - develop -notifications: - email: - - abought@umich.edu - slack: - secure: z9tSuzj4LCeJ8SWA0mnOkXPzbufXGlbDOGXSihPAahFVoiTWgL2biA7ZOlZrF3lUBKurJnbP/vOJRAdcA/p+4gymvUXjNJY1uUAxRPo0TVApzhlJAVlYGD/KRoALhbCKMj8Y949esbY1IEKb1/IbfFSCL51wFo2E3G6woSAL3MlH+nDP8WI0LjqjqckrrFgKq8PI5v1b0eSVVK5Guog8+UZYWZhP8A3dvpwBB1cteggby7kmEedQQu4VZ6fh2GbdkZJ4w2IZVFdgTx+nEQuElcnTFvLGiK1U9eR44aLOzJRvnvNxswgiQj2DkEf1Qf2+XvCi9Z4ckozfpqt0fgUIgIOM/7Gi2xmEQVjxTzlQhvhnokX2aT6IRokCS2e0ooHZwtF3bK37OKKrseCxIxYDihJa/Sqh5CkPQAd3J2HnVbGMH/WAaD5zivh213WjhQcZbk6F6UGwAsNO4VP06E1zSzS8E2+hWnKTWbgDHKuFAZvck1P08hQD97gBxA0H2M8PtbSMDuKABemletyvYt/V1yHU1fDSXGQl1gn43OpQPnV4Hc/Potsqc8GKYmqtVJZkmcmjgYHlFzRAhwwS7kjGsWFp8b6ValufvJqmSMVko2aXFiJXw6g+SKqIFUTw5LN8m3vdsofyMLCzXf7HX/sFJbm/IKXS7Kwqc7rPZUN6VR8= diff --git a/README.md b/README.md index dd0e5931..60a3d961 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ LocusZoom is a Javascript/d3 embeddable plugin for interactively visualizing statistical genetic data from customizable sources. -[![Build Status](https://api.travis-ci.org/statgen/locuszoom.svg?branch=master)](https://api.travis-ci.org/statgen/locuszoom) +![Build Status](https://github.com/statgen/locuszoom/workflows/Unit%20tests/badge.svg?branch=develop) See [github.com/statgen/locuszoom/wiki](https://github.com/statgen/locuszoom/wiki) for full documentation and API reference. diff --git a/assets/docs/layout_tutorial.md b/assets/docs/layout_tutorial.md index 3edf7bb3..99d4f244 100644 --- a/assets/docs/layout_tutorial.md +++ b/assets/docs/layout_tutorial.md @@ -364,7 +364,6 @@ existing_datasources .add("assoc_study3", ["AssociationLZ", {url: "/api/association/", params: { source: 3 }}]); const new_panel = existing_plot.addPanel(extra_panel_layout); // Adds the panel and redraws plot -new_panel.addBasicLoader(); // Add a nice "loading" indicator for UI ``` ### Common issues diff --git a/css/locuszoom.scss b/css/locuszoom.scss index f5d9650e..7bd4217e 100644 --- a/css/locuszoom.scss +++ b/css/locuszoom.scss @@ -220,10 +220,16 @@ svg.#{$namespace}-locuszoom { stroke-width: 1px; } - rect.#{$namespace}-data_layer-intervals.#{$namespace}-interval_rect { + g.#{$namespace}-data_layer-intervals { stroke-width: 0px; } + rect.#{$namespace}-data_layer-intervals-highlighted, rect.#{$namespace}-data_layer-intervals-selected { + stroke: #{$default_black}; + stroke-opacity: #{$default_black_opacity}; + stroke-width: 1px; + } + path.#{$namespace}-data_layer-forest { stroke: #{$default_black_shadow}; stroke-opacity: #{$default_black_shadow_opacity}; diff --git a/dist/ext/lz-aggregation-tests.min.js b/dist/ext/lz-aggregation-tests.min.js index 7c0f1983..fca6840d 100644 --- a/dist/ext/lz-aggregation-tests.min.js +++ b/dist/ext/lz-aggregation-tests.min.js @@ -1,3 +1,3 @@ -/*! Locuszoom 0.13.0-beta.2 */ -var LzAggregationTests=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=11)}({11:function(e,t,n){"use strict";n.r(t);var r=n(4),o=n(2);function a(e){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,t,n){return(i="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(e,t,n){var r=function(e,t){for(;!Object.prototype.hasOwnProperty.call(e,t)&&null!==(e=d(e)););return e}(e,t);if(r){var o=Object.getOwnPropertyDescriptor(r,t);return o.get?o.get.call(n):o.value}})(e,t,n||e)}function u(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function c(e,t){for(var n=0;nt?1:0}))}}]),n}(t),l=function(e){f(n,e);var t=h(n);function n(){return u(this,n),t.apply(this,arguments)}return s(n,[{key:"_getRequiredSources",value:function(){return["gene_ns","aggregation_ns"]}},{key:"combineChainBody",value:function(e,t){var n=this._source_name_mapping.aggregation_ns,r=this._source_name_mapping.gene_ns,o=t.discrete[n],a=t.discrete[r],i={};return o.groups.forEach((function(e){Object.prototype.hasOwnProperty.call(i,e.group)||(i[e.group]=[]),i[e.group].push(e.pvalue)})),a.forEach((function(e){var t=e.gene_name,n=i[t];n&&(e.aggregation_best_pvalue=Math.min.apply(null,n))})),a}}]),n}(n);e.Adapters.add("AggregationTestSourceLZ",a),e.Adapters.add("AssocFromAggregationLZ",c),e.Adapters.add("GeneAggregationConnectorLZ",l)}"undefined"!=typeof LocusZoom&&LocusZoom.use(y),t.default=y},2:function(e,t,n){"use strict";function r(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(e)))return;var n=[],r=!0,o=!1,a=void 0;try{for(var i,u=e[Symbol.iterator]();!(r=(i=u.next()).done)&&(n.push(i.value),!t||n.length!==t);r=!0);}catch(e){o=!0,a=e}finally{try{r||null==u.return||u.return()}finally{if(o)throw a}}return n}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return o(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return o(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function o(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n1&&(2!==t.length||!t.includes("isrefvar")))throw new Error("LD does not know how to get all fields: ".concat(t.join(", ")))}},{key:"findMergeFields",value:function(e){var t,n={id:this.params.id_field,position:this.params.position_field,pvalue:this.params.pvalue_field,_names_:null};if(e&&e.body&&e.body.length>0){var r=Object.keys(e.body[0]),o=(t=r,function(){for(var e=arguments,n=function(n){var r=e[n],o=t.filter((function(e){return e.match(r)}));if(o.length)return{v:o[0]}},r=0;rt}:function(e,t){return et.log_pvalue))for(var u=0;u{if(!e.ok)throw new Error(e.statusText);return e.text()}).then((function(e){const t="string"==typeof e?JSON.parse(e):e;if(t.error)throw new Error(t.error);return t}))}annotateData(e,t){if(!e.groups)return{groups:[],variants:[]};e.groups=e.groups.filter((function(e){return"GENE"===e.groupType}));const r=n.helpers.parsePortalJSON(e);let o=r[0];const s=r[1];o=o.byMask(t.header.aggregation_mask_ids);const i=t.header.aggregation_calcs;if(!i||0===Object.keys(i).length)return{variants:[],groups:[],results:[]};return new n.helpers.PortalTestRunner(o,s,i).toJSON().then((function(e){const r=t.header.aggregation_masks.reduce((function(e,t){return e[t.name]=t.description,e}),{});return e.data.groups.forEach((function(e){e.mask_name=r[e.mask]})),e.data})).catch((function(e){throw console.error(e),new Error("Failed to calculate aggregation test results")}))}normalizeResponse(e){return e}combineChainBody(e,t){return t.body}}e.Adapters.add("AggregationTestSourceLZ",s),e.Adapters.add("AssocFromAggregationLZ",class extends t{constructor(e){if(!e||!e.from)throw"Must specify the name of the source that contains association data";super(...arguments)}parseInit(e){super.parseInit(e),this._from=e.from}getRequest(e,t,r){if(t.discrete&&!t.discrete[this._from])throw`${this.constructor.SOURCE_NAME} cannot be used before loading required data for: ${this._from}`;return Promise.resolve(JSON.parse(JSON.stringify(t.discrete[this._from].variants)))}normalizeResponse(e){const t=new RegExp("(?:chr)?(.+):(\\d+)_?(\\w+)?/?([^_]+)?_?(.*)?");return e.map(e=>{const r=e.variant.match(t);return{variant:e.variant,chromosome:r[1],position:+r[2],ref_allele:r[3],ref_allele_freq:1-e.altFreq,log_pvalue:-Math.log10(e.pvalue)}}).sort((e,t)=>(e=e.variant)<(t=t.variant)?-1:e>t?1:0)}}),e.Adapters.add("GeneAggregationConnectorLZ",class extends r{_getRequiredSources(){return["gene_ns","aggregation_ns"]}combineChainBody(e,t){const r=this._source_name_mapping.aggregation_ns,n=this._source_name_mapping.gene_ns,o=t.discrete[r],s=t.discrete[n],i={};return o.groups.forEach((function(e){Object.prototype.hasOwnProperty.call(i,e.group)||(i[e.group]=[]),i[e.group].push(e.pvalue)})),s.forEach((function(e){const t=e.gene_name,r=i[t];r&&(e.aggregation_best_pvalue=Math.min.apply(null,r))})),s}})}"undefined"!=typeof LocusZoom&&LocusZoom.use(s),t.default=s},2:function(e,t,r){"use strict";function n(e,t,r){if(t&&r||!t&&!r)throw new Error(e+' must provide a parameter specifying either "build" or "source". It should not specify both.');if(t&&!["GRCh37","GRCh38"].includes(t))throw new Error(e+" must specify a valid genome build number")}r.r(t),r.d(t,"BaseAdapter",(function(){return o})),r.d(t,"BaseApiAdapter",(function(){return s})),r.d(t,"AssociationLZ",(function(){return i})),r.d(t,"ConnectorSource",(function(){return f})),r.d(t,"GeneConstraintLZ",(function(){return d})),r.d(t,"GeneLZ",(function(){return c})),r.d(t,"GwasCatalogLZ",(function(){return u})),r.d(t,"LDServer",(function(){return a})),r.d(t,"PheWASLZ",(function(){return p})),r.d(t,"RecombLZ",(function(){return l})),r.d(t,"StaticSource",(function(){return h}));class o{constructor(e){this._enableCache=!0,this._cachedKey=null,this.__dependentSource=!1,this.parseInit(e)}parseInit(e){this.params=e.params||{}}getCacheKey(e,t,r){return this.getURL(e,t,r)}getURL(e,t,r){return this.url}fetchRequest(e,t,r){const n=this.getURL(e,t,r);return fetch(n).then(e=>{if(!e.ok)throw new Error(e.statusText);return e.text()})}getRequest(e,t,r){let n;const o=this.getCacheKey(e,t,r);return this._enableCache&&void 0!==o&&o===this._cachedKey?n=Promise.resolve(this._cachedResponse):(n=this.fetchRequest(e,t,r),this._enableCache&&(this._cachedKey=o,this._cachedResponse=n)),n}normalizeResponse(e){if(Array.isArray(e))return e;const t=Object.keys(e),r=e[t[0]].length;if(!t.every((function(t){return e[t].length===r})))throw new Error(this.constructor.name+" expects a response in which all arrays of data are the same length");const n=[],o=Object.keys(e);for(let t=0;tPromise.resolve(this.annotateData(e,t))).then(e=>Promise.resolve(this.extractFields(e,r,n,o))).then(e=>(t.discrete[s]=e,Promise.resolve(this.combineChainBody(e,t,r,n,o)))).then(e=>({header:t.header||{},discrete:t.discrete,body:e}))}getData(e,t,r,n){if(this.preGetData){const o=this.preGetData(e,t,r,n);this.pre&&(e=o.state||e,t=o.fields||t,r=o.outnames||r,n=o.trans||n)}return o=>this.__dependentSource&&o&&o.body&&!o.body.length?Promise.resolve(o):this.getRequest(e,o,t).then(e=>this.parseResponse(e,o,t,r,n))}}class s extends o{parseInit(e){if(super.parseInit(e),this.url=e.url,!this.url)throw new Error("Source not initialized with required URL")}}class i extends s{preGetData(e,t,r,n){return[this.params.id_field||"id","position"].forEach((function(e){t.includes(e)||(t.unshift(e),r.unshift(e),n.unshift(null))})),{fields:t,outnames:r,trans:n}}getURL(e,t,r){const n=t.header.analysis||this.params.source||this.params.analysis;if(void 0===n)throw new Error("Association source must specify an analysis ID to plot");return`${this.url}results/?filter=analysis in ${n} and chromosome in '${e.chr}' and position ge ${e.start} and position le ${e.end}`}normalizeResponse(e){return e=super.normalizeResponse(e),this.params&&this.params.sort&&e.length&&e[0].position&&e.sort((function(e,t){return e.position-t.position})),e}}class a extends s{constructor(e){super(e),this.__dependentSource=!0}preGetData(e,t){if(t.length>1&&(2!==t.length||!t.includes("isrefvar")))throw new Error("LD does not know how to get all fields: "+t.join(", "))}findMergeFields(e){let t={id:this.params.id_field,position:this.params.position_field,pvalue:this.params.pvalue_field,_names_:null};if(e&&e.body&&e.body.length>0){const n=Object.keys(e.body[0]),o=(r=n,function(){const e=arguments;for(let t=0;tt}:function(e,t){return e{if(!e.ok)throw new Error(e.statusText);return e.text()}).then((function(e){return e=JSON.parse(e),Object.keys(e.data).forEach((function(t){o.data[t]=(o.data[t]||[]).concat(e.data[t])})),e.next?s(e.next):o}))};return s(n)}}class u extends s{constructor(e){super(e),this.__dependentSource=!0}getURL(e,t,r){const o=e.genome_build||this.params.build;n(this.constructor.name,o,null);const s="GRCh38"===o?5:6,i=this.params.source||s;return`${this.url}?format=objects&sort=pos&filter=id eq ${i} and chrom eq '${e.chr}' and pos ge ${e.start} and pos le ${e.end}`}findMergeFields(e){const t=Object.keys(e).find((function(e){return e.match(/\b(position|pos)\b/i)}));if(!t)throw new Error("Could not find data to align with GWAS catalog results");return{pos:t}}extractFields(e,t,r,n){return e}combineChainBody(e,t,r,n,o){if(!e.length)return t.body;const s=n[r.indexOf("log_pvalue")];function i(e,t,r,n,o){const i=e.n_catalog_matches||0;if(e.n_catalog_matches=i+1,!(e[s]&&e[s]>t.log_pvalue))for(let s=0;se.ok?e.text():[]).catch(e=>[])}combineChainBody(e,t,r,n,o){return e?(t.body.forEach((function(t){const r="_"+t.gene_name.replace(/[^A-Za-z0-9_]/g,"_"),n=e[r]&&e[r].gnomad_constraint;n&&Object.keys(n).forEach((function(e){let r=n[e];void 0===t[e]&&("number"==typeof r&&r.toString().includes(".")&&(r=parseFloat(r.toFixed(2))),t[e]=r)}))})),t.body):t}}class l extends s{getURL(e,t,r){const o=e.genome_build||this.params.build;let s=this.params.source;return n(this.constructor.SOURCE_NAME,o,s),o&&(s="GRCh38"===o?16:15),`${this.url}?filter=id in ${s} and chromosome eq '${e.chr}' and position le ${e.end} and position ge ${e.start}`}}class h extends o{parseInit(e){this._data=e}getRequest(e,t,r){return Promise.resolve(this._data)}}class p extends s{getURL(e,t,r){const n=(e.genome_build?[e.genome_build]:null)||this.params.build;if(!n||!Array.isArray(n)||!n.length)throw new Error(["Data source",this.constructor.SOURCE_NAME,"requires that you specify array of one or more desired genome build names"].join(" "));return[this.url,"?filter=variant eq '",encodeURIComponent(e.variant),"'&format=objects&",n.map((function(e){return"build="+encodeURIComponent(e)})).join("&")].join("")}}class f extends o{constructor(e){if(super(e),!e||!e.sources)throw new Error("Connectors must specify the data they require as init.sources = {internal_name: chain_source_id}} pairs");this._source_name_mapping=e.sources;const t=Object.keys(e.sources);this._getRequiredSources().forEach(e=>{if(!t.includes(e))throw new Error(`Configuration for ${this.constructor.name} must specify a source ID corresponding to ${e}`)})}parseInit(){}getRequest(e,t,r){return Object.keys(this._source_name_mapping).forEach(e=>{const r=this._source_name_mapping[e];if(t.discrete&&!t.discrete[r])throw new Error(`${this.constructor.name} cannot be used before loading required data for: ${r}`)}),Promise.resolve(t.body||[])}parseResponse(e,t,r,n,o){return Promise.resolve(this.combineChainBody(e,t,r,n,o)).then((function(e){return{header:t.header||{},discrete:t.discrete||{},body:e}}))}combineChainBody(e,t){throw new Error("This method must be implemented in a subclass")}_getRequiredSources(){throw new Error("Must specify an array that identifes the kind of data required by this source")}}},4:function(e,t){e.exports=raremetal}}).default; //# sourceMappingURL=lz-aggregation-tests.min.js.map \ No newline at end of file diff --git a/dist/ext/lz-aggregation-tests.min.js.map b/dist/ext/lz-aggregation-tests.min.js.map index 805999e5..fb155f3c 100644 --- a/dist/ext/lz-aggregation-tests.min.js.map +++ b/dist/ext/lz-aggregation-tests.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack://[name]/webpack/bootstrap","webpack://[name]/./esm/ext/lz-aggregation-tests.js","webpack://[name]/./esm/data/adapters.js","webpack://[name]/external \"raremetal\""],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","install","LocusZoom","BaseAdapter","Adapters","ConnectorSource","AggregationTestSource","state","chain","fields","required_info","aggregation_tests","header","aggregation_genoset_id","genoset_id","aggregation_genoset_build","genoset_build","aggregation_phenoset_id","phenoset_id","aggregation_pheno","pheno","aggregation_calcs","calcs","mask_data","masks","aggregation_masks","aggregation_mask_ids","map","item","this","url","getURL","JSON","stringify","chrom","chr","start","stop","end","genotypeDataset","phenotypeDataset","phenotype","samples","genomeBuild","body","getCacheKey","fetch","method","headers","then","response","ok","Error","statusText","text","resp","json","parse","error","records","groups","variants","filter","groupType","parsed","helpers","parsePortalJSON","byMask","keys","length","PortalTestRunner","toJSON","res","mask_id_to_desc","reduce","acc","val","description","data","forEach","group","mask_name","mask","e","console","results","BaseApiAdapter","AssocFromAggregationLZ","config","from","arguments","_from","discrete","constructor","SOURCE_NAME","Promise","resolve","REGEX_EPACTS","RegExp","one_variant","match","variant","chromosome","position","ref_allele","ref_allele_freq","altFreq","log_pvalue","Math","log10","pvalue","sort","a","b","GeneAggregationConnectorLZ","aggregation_source_id","_source_name_mapping","gene_source_id","aggregationData","genesData","groupedAggregation","result","push","gene","gene_id","gene_name","tests","aggregation_best_pvalue","min","apply","add","use","validateBuildSource","class_name","build","source","includes","_enableCache","_cachedKey","__dependentSource","parseInit","params","req","cacheKey","_cachedResponse","fetchRequest","Array","isArray","N","every","record","j","outnames","trans","fieldFound","k","output_record","v","source_id","normalizeResponse","standardized","annotateData","extractFields","one_source_body","combineChainBody","new_body","preGetData","pre","getRequest","parseResponse","AssociationLZ","id_field","x","unshift","analysis","LDServer","join","arr","dataFields","id","position_field","pvalue_field","_names_","names","nameMatch","regexes","regex","id_match","obj","isrefvarin","isrefvarout","ldin","ldout","refVar","findRequestedFields","ldrefvar","findMergeFields","columns","pval_field","cmp","test","extremeVal","extremeIdx","findExtremeValue","genome_build","ld_source","population","ld_pop","getRefvar","original","pos","ref","alt","encodeURIComponent","reqFields","corrField","rsquare","left","right","lfield","rfield","position2","leftJoin","refvar","idfield","outrefname","outldname","tagRefVariant","combined","chainRequests","payload","concat","next","GwasCatalogLZ","build_option","default_source","posMatch","find","decider_out","indexOf","n_matches","fn","outn","chainNames","catNames","GeneLZ","GeneConstraintLZ","unique_gene_names","query","alias","replace","err","constraint","toString","parseFloat","toFixed","RecombLZ","StaticSource","_data","PheWASLZ","sources","specified_ids","_getRequiredSources","chain_source_id","raremetal"],"mappings":";mCACE,IAAIA,EAAmB,GAGvB,SAASC,EAAoBC,GAG5B,GAAGF,EAAiBE,GACnB,OAAOF,EAAiBE,GAAUC,QAGnC,IAAIC,EAASJ,EAAiBE,GAAY,CACzCG,EAAGH,EACHI,GAAG,EACHH,QAAS,IAUV,OANAI,EAAQL,GAAUM,KAAKJ,EAAOD,QAASC,EAAQA,EAAOD,QAASF,GAG/DG,EAAOE,GAAI,EAGJF,EAAOD,QA0Df,OArDAF,EAAoBQ,EAAIF,EAGxBN,EAAoBS,EAAIV,EAGxBC,EAAoBU,EAAI,SAASR,EAASS,EAAMC,GAC3CZ,EAAoBa,EAAEX,EAASS,IAClCG,OAAOC,eAAeb,EAASS,EAAM,CAAEK,YAAY,EAAMC,IAAKL,KAKhEZ,EAAoBkB,EAAI,SAAShB,GACX,oBAAXiB,QAA0BA,OAAOC,aAC1CN,OAAOC,eAAeb,EAASiB,OAAOC,YAAa,CAAEC,MAAO,WAE7DP,OAAOC,eAAeb,EAAS,aAAc,CAAEmB,OAAO,KAQvDrB,EAAoBsB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQrB,EAAoBqB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,iBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKX,OAAOY,OAAO,MAGvB,GAFA1B,EAAoBkB,EAAEO,GACtBX,OAAOC,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOrB,EAAoBU,EAAEe,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIRzB,EAAoB6B,EAAI,SAAS1B,GAChC,IAAIS,EAAST,GAAUA,EAAOqB,WAC7B,WAAwB,OAAOrB,EAAgB,SAC/C,WAA8B,OAAOA,GAEtC,OADAH,EAAoBU,EAAEE,EAAQ,IAAKA,GAC5BA,GAIRZ,EAAoBa,EAAI,SAASiB,EAAQC,GAAY,OAAOjB,OAAOkB,UAAUC,eAAe1B,KAAKuB,EAAQC,IAGzG/B,EAAoBkC,EAAI,GAIjBlC,EAAoBA,EAAoBmC,EAAI,I,s6DChErD,SAASC,EAASC,GAQd,IAAMC,EAAcD,EAAUE,SAAStB,IAAI,eACrCuB,EAAkBH,EAAUE,SAAStB,IAAI,mBAEzCwB,EAXmB,6HAYdC,EAAOC,EAAOC,GAIjB,IAAMC,EAAgBH,EAAMI,mBAAqB,GAE5CH,EAAMI,SACPJ,EAAMI,OAAS,IAGnBJ,EAAMI,OAAOC,uBAAyBH,EAAcI,YAAc,KAClEN,EAAMI,OAAOG,0BAA4BL,EAAcM,eAAiB,KACxER,EAAMI,OAAOK,wBAA0BP,EAAcQ,aAAe,KACpEV,EAAMI,OAAOO,kBAAoBT,EAAcU,OAAS,KACxDZ,EAAMI,OAAOS,kBAAoBX,EAAcY,OAAS,GACxD,IAAMC,EAAYb,EAAcc,OAAS,GAKzC,OAJAhB,EAAMI,OAAOa,kBAAoBF,EACjCf,EAAMI,OAAOc,qBAAuBH,EAAUI,KAAI,SAAUC,GACxD,OAAOA,EAAKpD,QAETqD,KAAKC,MAhCK,kCAmCTvB,EAAOC,EAAOC,GAEtB,OADAoB,KAAKE,OAAOxB,EAAOC,EAAOC,GACnBuB,KAAKC,UAAU,CAClBC,MAAO3B,EAAM4B,IACbC,MAAO7B,EAAM6B,MACbC,KAAM9B,EAAM+B,IACZC,gBAAiB/B,EAAMI,OAAOC,uBAC9B2B,iBAAkBhC,EAAMI,OAAOK,wBAC/BwB,UAAWjC,EAAMI,OAAOO,kBACxBuB,QAAS,MACTC,YAAanC,EAAMI,OAAOG,0BAC1BS,MAAOhB,EAAMI,OAAOc,yBA9CP,mCAkDRnB,EAAOC,EAAOC,GACvB,IAAMqB,EAAMD,KAAKE,OAAOxB,EAAOC,EAAOC,GAChCmC,EAAOf,KAAKgB,YAAYtC,EAAOC,EAAOC,GAK5C,OAAOqC,MAAMhB,EAAK,CAACiB,OAAQ,OAAQH,KAAMA,EAAMI,QAJ/B,CACZ,eAAgB,sBAG8CC,MAAK,SAACC,GACpE,IAAKA,EAASC,GACV,MAAM,IAAIC,MAAMF,EAASG,YAE7B,OAAOH,EAASI,UACjBL,MAAK,SAAUM,GACd,IAAMC,EAAsB,iBAARD,EAAmBvB,KAAKyB,MAAMF,GAAQA,EAC1D,GAAIC,EAAKE,MAIL,MAAM,IAAIN,MAAMI,EAAKE,OAEzB,OAAOF,OAtEM,mCA0ERG,EAASnD,GASlB,IAAKmD,EAAQC,OACT,MAAO,CAAEA,OAAQ,GAAIC,SAAU,IAGnCF,EAAQC,OAASD,EAAQC,OAAOE,QAAO,SAAUlC,GAC7C,MAA0B,SAAnBA,EAAKmC,aAGhB,IAAMC,EAASC,UAAQC,gBAAgBP,GACnCC,EAASI,EAAO,GACdH,EAAWG,EAAO,GAGxBJ,EAASA,EAAOO,OAAO3D,EAAMI,OAAOc,sBAGpC,IAAMJ,EAAQd,EAAMI,OAAOS,kBAC3B,OAAKC,GAAuC,IAA9B3C,OAAOyF,KAAK9C,GAAO+C,OAIlB,IAAIJ,UAAQK,iBAAiBV,EAAQC,EAAUvC,GAEhDiD,SACTtB,MAAK,SAAUuB,GAGZ,IAAMC,EAAkBjE,EAAMI,OAAOa,kBAAkBiD,QAAO,SAAUC,EAAKC,GAEzE,OADAD,EAAIC,EAAIpG,MAAQoG,EAAIC,YACbF,IACR,IAIH,OAHAH,EAAIM,KAAKlB,OAAOmB,SAAQ,SAAUC,GAC9BA,EAAMC,UAAYR,EAAgBO,EAAME,SAErCV,EAAIM,QAXZ,OAaI,SAAUK,GAEb,MADAC,QAAQ1B,MAAMyB,GACR,IAAI/B,MAAM,mDAnBb,CAAES,SAAU,GAAID,OAAQ,GAAIyB,QAAS,MAtG/B,wCA6HHP,GACd,OAAOA,IA9HU,uCAiIJnB,EAASnD,GAItB,OAAOA,EAAMoC,SArII,GAWW0C,kBA+H9BC,EA1ImB,8BA2IrB,WAAYC,GACR,GADgB,WACXA,IAAWA,EAAOC,KACnB,KAAM,qEAFM,oBAIPC,WA/IQ,4CAiJXF,GACN,6CAAgBA,GAChB3D,KAAK8D,MAAQH,EAAOC,OAnJH,iCAsJVlF,EAAOC,EAAOC,GAErB,GAAID,EAAMoF,WAAapF,EAAMoF,SAAS/D,KAAK8D,OACvC,eAAS9D,KAAKgE,YAAYC,YAA1B,6DAA0FjE,KAAK8D,OAGnG,OAAOI,QAAQC,QAAQhE,KAAKyB,MAAMzB,KAAKC,UAAUzB,EAAMoF,SAAS/D,KAAK8D,OAApB,cA5JhC,wCA+JHb,GAGd,IAAMmB,EAAe,IAAIC,OAAO,iDAChC,OAAOpB,EAAKnD,KAAI,SAACwE,GACb,IAAMC,EAAQD,EAAYE,QAAQD,MAAMH,GACxC,MAAO,CACHI,QAASF,EAAYE,QACrBC,WAAYF,EAAM,GAClBG,UAAWH,EAAM,GACjBI,WAAYJ,EAAM,GAClBK,gBAAiB,EAAIN,EAAYO,QACjCC,YAAaC,KAAKC,MAAMV,EAAYW,YAEzCC,MAAK,SAACC,EAAGC,GAGR,OAFAD,EAAIA,EAAEX,UACNY,EAAIA,EAAEZ,UAEM,EACDW,EAAIC,EACJ,EAGA,SAtLE,GA0IY9G,GA0D/B+G,EApMmB,4IAsMjB,MAAO,CAAC,UAAW,oBAtMF,uCAyMJpC,EAAMtE,GAInB,IAAM2G,EAAwBtF,KAAKuF,qBAAL,eACxBC,EAAiBxF,KAAKuF,qBAAL,QAGjBE,EAAkB9G,EAAMoF,SAASuB,GACjCI,EAAY/G,EAAMoF,SAASyB,GAE3BG,EAAqB,GAiB3B,OAfAF,EAAgB1D,OAAOmB,SAAQ,SAAU0C,GAChC9I,OAAOkB,UAAUC,eAAe1B,KAAKoJ,EAAoBC,EAAOzC,SACjEwC,EAAmBC,EAAOzC,OAAS,IAEvCwC,EAAmBC,EAAOzC,OAAO0C,KAAKD,EAAOX,WAIjDS,EAAUxC,SAAQ,SAAU4C,GACxB,IAAMC,EAAUD,EAAKE,UACfC,EAAQN,EAAmBI,GAC7BE,IACAH,EAAKI,wBAA0BnB,KAAKoB,IAAIC,MAAM,KAAMH,OAGrDP,MArOU,GAoMgBlH,GAsCzCH,EAAUE,SAAS8H,IAAI,0BAA2B5H,GAClDJ,EAAUE,SAAS8H,IAAI,yBAA0B3C,GACjDrF,EAAUE,SAAS8H,IAAI,6BAA8BhB,GAIhC,oBAAdhH,WAGPA,UAAUiI,IAAIlI,GAIHA,a,i1FCpQf,SAASmI,EAAoBC,EAAYC,EAAOC,GAE5C,GAAKD,GAASC,IAAaD,IAASC,EAChC,MAAM,IAAInF,MAAJ,UAAaiF,EAAb,iGAGV,GAAIC,IAAU,CAAC,SAAU,UAAUE,SAASF,GACxC,MAAM,IAAIlF,MAAJ,UAAaiF,EAAb,8C,kfASRlI,E,WACF,WAAYqF,GAAQ,UAKhB3D,KAAK4G,cAAe,EACpB5G,KAAK6G,WAAa,KAOlB7G,KAAK8G,mBAAoB,EAGzB9G,KAAK+G,UAAUpD,G,4CAWTA,GAEN3D,KAAKgH,OAASrD,EAAOqD,QAAU,K,kCAavBtI,EAAOC,EAAOC,GACtB,OAAOoB,KAAKE,OAAOxB,EAAOC,EAAOC,K,6BAO9BF,EAAOC,EAAOC,GACjB,OAAOoB,KAAKC,M,mCAYHvB,EAAOC,EAAOC,GACvB,IAAMqB,EAAMD,KAAKE,OAAOxB,EAAOC,EAAOC,GACtC,OAAOqC,MAAMhB,GAAKmB,MAAK,SAACC,GACpB,IAAKA,EAASC,GACV,MAAM,IAAIC,MAAMF,EAASG,YAE7B,OAAOH,EAASI,Y,iCAWb/C,EAAOC,EAAOC,GACrB,IAAIqI,EACEC,EAAWlH,KAAKgB,YAAYtC,EAAOC,EAAOC,GAUhD,OATIoB,KAAK4G,mBAAqC,IAAdM,GAA6BA,IAAalH,KAAK6G,WAC3EI,EAAM/C,QAAQC,QAAQnE,KAAKmH,kBAE3BF,EAAMjH,KAAKoH,aAAa1I,EAAOC,EAAOC,GAClCoB,KAAK4G,eACL5G,KAAK6G,WAAaK,EAClBlH,KAAKmH,gBAAkBF,IAGxBA,I,wCAcOhE,GACd,GAAIoE,MAAMC,QAAQrE,GAEd,OAAOA,EAIX,IAAMV,EAAOzF,OAAOyF,KAAKU,GACnBsE,EAAItE,EAAKV,EAAK,IAAIC,OAKxB,IAJmBD,EAAKiF,OAAM,SAAU7J,GAEpC,OADasF,EAAKtF,GACN6E,SAAW+E,KAGvB,MAAM,IAAIhG,MAAJ,UAAavB,KAAKgE,YAAYrH,KAA9B,wEAMV,IAFA,IAAMmF,EAAU,GACVlD,EAAS9B,OAAOyF,KAAKU,GAClB7G,EAAI,EAAGA,EAAImL,EAAGnL,IAAK,CAExB,IADA,IAAMqL,EAAS,GACNC,EAAI,EAAGA,EAAI9I,EAAO4D,OAAQkF,IAC/BD,EAAO7I,EAAO8I,IAAMzE,EAAKrE,EAAO8I,IAAItL,GAExC0F,EAAQ+D,KAAK4B,GAEjB,OAAO3F,I,mCAYEA,EAASnD,GAElB,OAAOmD,I,oCAkBImB,EAAMrE,EAAQ+I,EAAUC,GAInC,IAAKP,MAAMC,QAAQrE,GACf,OAAOA,EAGX,IAAKA,EAAKT,OAEN,OAAOS,EAIX,IADA,IAAM4E,EAAa,GACVC,EAAI,EAAGA,EAAIlJ,EAAO4D,OAAQsF,IAC/BD,EAAWC,GAAK,EAGpB,IAAMhG,EAAUmB,EAAKnD,KAAI,SAAUC,GAE/B,IADA,IAAMgI,EAAgB,GACbL,EAAI,EAAGA,EAAI9I,EAAO4D,OAAQkF,IAAK,CACpC,IAAI3E,EAAMhD,EAAKnB,EAAO8I,SACJ,IAAP3E,IACP8E,EAAWH,GAAK,GAEhBE,GAASA,EAAMF,KACf3E,EAAM6E,EAAMF,GAAG3E,IAEnBgF,EAAcJ,EAASD,IAAM3E,EAEjC,OAAOgF,KAOX,OALAF,EAAW3E,SAAQ,SAAS8E,EAAG5L,GAC3B,IAAK4L,EACD,MAAM,IAAIzG,MAAJ,gBAAmB3C,EAAOxC,GAA1B,sCAA0DuL,EAASvL,QAG1E0F,I,uCAeMmB,EAAMtE,EAAOC,EAAQ+I,EAAUC,GAC5C,OAAO3E,I,oCAoBIvB,EAAM/C,EAAOC,EAAQ+I,EAAUC,GAAO,WAC3CK,EAAYjI,KAAKiI,WAAajI,KAAKgE,YAAYrH,KAChDgC,EAAMoF,WACPpF,EAAMoF,SAAW,IAGrB,IAAMpC,EAAsB,iBAARD,EAAmBvB,KAAKyB,MAAMF,GAAQA,EAG1D,OAAOwC,QAAQC,QAAQnE,KAAKkI,kBAAkBvG,EAAKsB,MAAQtB,IACtDP,MAAK,SAAC+G,GAEH,OAAOjE,QAAQC,QAAQ,EAAKiE,aAAaD,EAAcxJ,OACxDyC,MAAK,SAAC6B,GACL,OAAOiB,QAAQC,QAAQ,EAAKkE,cAAcpF,EAAMrE,EAAQ+I,EAAUC,OACnExG,MAAK,SAACkH,GAIL,OADA3J,EAAMoF,SAASkE,GAAaK,EACrBpE,QAAQC,QAAQ,EAAKoE,iBAAiBD,EAAiB3J,EAAOC,EAAQ+I,EAAUC,OACxFxG,MAAK,SAACoH,GACL,MAAO,CAAEzJ,OAAQJ,EAAMI,QAAU,GAAIgF,SAAUpF,EAAMoF,SAAUhD,KAAMyH,Q,8BAmBzE9J,EAAOE,EAAQ+I,EAAUC,GAAO,WACpC,GAAI5H,KAAKyI,WAAY,CACjB,IAAMC,EAAM1I,KAAKyI,WAAW/J,EAAOE,EAAQ+I,EAAUC,GACjD5H,KAAK0I,MACLhK,EAAQgK,EAAIhK,OAASA,EACrBE,EAAS8J,EAAI9J,QAAUA,EACvB+I,EAAWe,EAAIf,UAAYA,EAC3BC,EAAQc,EAAId,OAASA,GAI7B,OAAO,SAACjJ,GACJ,OAAI,EAAKmI,mBAAqBnI,GAASA,EAAMoC,OAASpC,EAAMoC,KAAKyB,OAGtD0B,QAAQC,QAAQxF,GAGpB,EAAKgK,WAAWjK,EAAOC,EAAOC,GAAQwC,MAAK,SAACM,GAC/C,OAAO,EAAKkH,cAAclH,EAAM/C,EAAOC,EAAQ+I,EAAUC,W,KAUnEnE,E,gIACQE,GAKN,GAJA,6CAAgBA,GAGhB3D,KAAKC,IAAM0D,EAAO1D,KACbD,KAAKC,IACN,MAAM,IAAIsB,MAAM,gD,GAPCjD,GAgBvBuK,E,iIACUnK,EAAOE,EAAQ+I,EAAUC,GAUjC,MAPA,CADiB5H,KAAKgH,OAAO8B,UAAY,KAC9B,YAAY5F,SAAQ,SAAS6F,GAC/BnK,EAAO+H,SAASoC,KACjBnK,EAAOoK,QAAQD,GACfpB,EAASqB,QAAQD,GACjBnB,EAAMoB,QAAQ,UAGf,CAACpK,OAAQA,EAAQ+I,SAASA,EAAUC,MAAMA,K,6BAG7ClJ,EAAOC,EAAOC,GAClB,IAAMqK,EAAWtK,EAAMI,OAAOkK,UAAYjJ,KAAKgH,OAAON,QAAU1G,KAAKgH,OAAOiC,SAC5E,QAAuB,IAAZA,EACP,MAAM,IAAI1H,MAAM,0DAEpB,gBAAUvB,KAAKC,IAAf,uCAAiDgJ,EAAjD,gCAAiFvK,EAAM4B,IAAvF,6BAA+G5B,EAAM6B,MAArH,4BAA8I7B,EAAM+B,O,wCAGrIwC,GAWf,OANAA,EAAO,EAAH,mDAA2BA,GAC3BjD,KAAKgH,QAAUhH,KAAKgH,OAAO9B,MAAQjC,EAAKT,QAAUS,EAAK,GAAL,UAClDA,EAAKiC,MAAK,SAAUC,EAAGC,GACnB,OAAOD,EAAC,SAAeC,EAAC,YAGzBnC,M,GAjCaQ,GA6CtByF,E,8BACF,WAAYvF,GAAQ,wBAChB,cAAMA,IACDmD,mBAAoB,EAFT,E,6CAKTpI,EAAOE,GACd,GAAIA,EAAO4D,OAAS,IACM,IAAlB5D,EAAO4D,SAAiB5D,EAAO+H,SAAS,aACxC,MAAM,IAAIpF,MAAJ,kDAAqD3C,EAAOuK,KAAK,U,sCAKnExK,GAMZ,IAA6ByK,EAezBC,EAAa,CACbC,GAAItJ,KAAKgH,OAAO8B,SAChBpE,SAAU1E,KAAKgH,OAAOuC,eACtBtE,OAAQjF,KAAKgH,OAAOwC,aACpBC,QAAQ,MAEZ,GAAI9K,GAASA,EAAMoC,MAAQpC,EAAMoC,KAAKyB,OAAS,EAAG,CAC9C,IAAMkH,EAAQ5M,OAAOyF,KAAK5D,EAAMoC,KAAK,IAC/B4I,GAvBmBP,EAuBIM,EAtBtB,WAEH,IADA,IAAME,EAAU/F,UADD,WAENzH,GACL,IAAMyN,EAAQD,EAAQxN,GAChBI,EAAI4M,EAAInH,QAAO,SAAU8G,GAC3B,OAAOA,EAAExE,MAAMsF,MAEnB,GAAIrN,EAAEgG,OACF,SAAOhG,EAAE,KANRJ,EAAI,EAAGA,EAAIwN,EAAQpH,OAAQpG,IAAK,SAAhCA,GAAgC,8BASzC,OAAO,OAgBL0N,EAAWT,EAAWC,IAAMK,EAAU,IAAItF,OAAJ,UAAcgF,EAAWC,GAAzB,SAC5CD,EAAWC,GAAKQ,GAAYH,EAAU,gBAAkBA,EAAU,UAClEN,EAAW3E,SAAW2E,EAAW3E,UAAYiF,EAAU,gBAAiB,YACxEN,EAAWpE,OAASoE,EAAWpE,QAAU0E,EAAU,cAAe,mBAClEN,EAAWI,QAAUC,EAEzB,OAAOL,I,0CAGUzK,EAAQ+I,GAGzB,IADA,IAAIoC,EAAM,GACD3N,EAAI,EAAGA,EAAIwC,EAAO4D,OAAQpG,IACb,aAAdwC,EAAOxC,IACP2N,EAAIC,WAAapL,EAAOxC,GACxB2N,EAAIE,YAActC,GAAYA,EAASvL,KAEvC2N,EAAIG,KAAOtL,EAAOxC,GAClB2N,EAAII,MAAQxC,GAAYA,EAASvL,IAGzC,OAAO2N,I,wCAGQ9G,GAEf,OAAOA,I,gCAQDvE,EAAOC,EAAOC,GACpB,IAyBIwL,EADYpK,KAAKqK,oBAAoBzL,GAClBsL,KAIvB,GAHe,UAAXE,IACAA,EAAS1L,EAAM4L,UAAY3L,EAAMI,OAAOuL,UAAY,QAEzC,SAAXF,EAAmB,CACnB,IAAKzL,EAAMoC,KACP,MAAM,IAAIQ,MAAM,iDAEpB,IAAIgB,EAAOvC,KAAKuK,gBAAgB5L,GAChC,IAAK4D,EAAK0C,SAAW1C,EAAK+G,GAAI,CAC1B,IAAIkB,EAAU,GAOd,MANKjI,EAAK+G,KACNkB,GAAW,GAAJ,OAAOA,EAAQhI,OAAS,KAAO,GAA/B,OAEND,EAAK0C,SACNuF,GAAW,GAAJ,OAAOA,EAAQhI,OAAS,KAAO,GAA/B,WAEL,IAAIjB,MAAJ,wDAA2DiJ,EAA3D,wBAAkFjI,EAAKkH,QAAvF,MAEVW,EAASzL,EAAMoC,KA5CI,SAASe,EAAS2I,GAGrC,IACIC,EAEAA,EAHW,MAAMC,KADrBF,EAAaA,GAAc,cAIjB,SAAStF,EAAGC,GACd,OAAOD,EAAIC,GAGT,SAASD,EAAGC,GACd,OAAOD,EAAIC,GAInB,IADA,IAAIwF,EAAa9I,EAAQ,GAAG2I,GAAaI,EAAa,EAC7CzO,EAAI,EAAGA,EAAI0F,EAAQU,OAAQpG,IAC5BsO,EAAI5I,EAAQ1F,GAAGqO,GAAaG,KAC5BA,EAAa9I,EAAQ1F,GAAGqO,GACxBI,EAAazO,GAGrB,OAAOyO,EAuBaC,CAAiBnM,EAAMoC,KAAMwB,EAAK0C,SAAS1C,EAAK+G,IAExE,OAAOc,I,6BAGJ1L,EAAOC,EAAOC,GAOjB,IAAM6H,EAAQ/H,EAAMqM,cAAgB/K,KAAKgH,OAAOP,OAAS,SACrDC,EAAShI,EAAMsM,WAAahL,KAAKgH,OAAON,QAAU,QAChDuE,EAAavM,EAAMwM,QAAUlL,KAAKgH,OAAOiE,YAAc,MACvD/J,EAASlB,KAAKgH,OAAO9F,QAAU,UAEtB,UAAXwF,GAAgC,WAAVD,IAEtBC,EAAS,eAGbH,EAAoBvG,KAAKgE,YAAYrH,KAAM8J,EAAO,MAElD,IAAI2D,EAASpK,KAAKmL,UAAUzM,EAAOC,EAAOC,GAIpC2F,EAAQ6F,GAAUA,EAAO7F,MADV,0EAGrB,IAAKA,EACD,MAAM,IAAIhD,MAAM,kEA1BK,QA4BgBgD,EA5BhB,GA4BlB6G,EA5BkB,KA4BR/K,EA5BQ,KA4BDgL,EA5BC,KA4BIC,EA5BJ,KA4BSC,EA5BT,KAsCzB,OAPAnB,EAAS,GAAH,OAAM/J,EAAN,YAAegL,GACjBC,GAAOC,IACPnB,GAAU,IAAJ,OAAQkB,EAAR,YAAeC,IAGzB5M,EAAMI,OAAOuL,SAAWc,EAEhB,CACJpL,KAAKC,IAAK,iBAAkBwG,EAAO,eAAgBC,EAAQ,gBAAiBuE,EAAY,YACxF,gBAAiB/J,EACjB,YAAasK,mBAAmBpB,GAChC,UAAWoB,mBAAmB9M,EAAM4B,KACpC,UAAWkL,mBAAmB9M,EAAM6B,OACpC,SAAUiL,mBAAmB9M,EAAM+B,MACrC0I,KAAK,M,uCAGMlG,EAAMtE,EAAOC,EAAQ+I,EAAUC,GAC5C,IAAIrF,EAAOvC,KAAKuK,gBAAgB5L,GAC5B8M,EAAYzL,KAAKqK,oBAAoBzL,EAAQ+I,GACjD,IAAKpF,EAAKmC,SACN,MAAM,IAAInD,MAAJ,mDAAsDgB,EAAKkH,UAErE,IA0BIiC,EAAYzI,EAAK0I,QAAU,UAAY,cAK3C,OA/BiB,SAAUC,EAAMC,EAAOC,EAAQC,GAE5C,IADA,IAAI3P,EAAI,EAAGsL,EAAI,EACRtL,EAAIwP,EAAKpJ,QAAUkF,EAAImE,EAAMG,UAAUxJ,QACtCoJ,EAAKxP,GAAGmG,EAAKmC,YAAcmH,EAAMG,UAAUtE,IAC3CkE,EAAKxP,GAAG0P,GAAUD,EAAME,GAAQrE,GAChCtL,IACAsL,KACOkE,EAAKxP,GAAGmG,EAAKmC,UAAYmH,EAAMG,UAAUtE,GAChDtL,IAEAsL,IAiBZuE,CAAStN,EAAMoC,KAAMkC,EAAMwI,EAAUtB,MAAOuB,GACxCD,EAAUzB,YAAcrL,EAAMI,OAAOuL,UAdnB,SAAUrH,EAAMiJ,EAAQC,EAASC,EAAYC,GAC/D,IAAK,IAAIjQ,EAAI,EAAGA,EAAI6G,EAAKT,OAAQpG,IACzB6G,EAAK7G,GAAG+P,IAAYlJ,EAAK7G,GAAG+P,KAAaD,GACzCjJ,EAAK7G,GAAGgQ,GAAc,EACtBnJ,EAAK7G,GAAGiQ,GAAa,GAErBpJ,EAAK7G,GAAGgQ,GAAc,EAS9BE,CAAc3N,EAAMoC,KAAMpC,EAAMI,OAAOuL,SAAU/H,EAAK+G,GAAImC,EAAUxB,YAAawB,EAAUtB,OAExFxL,EAAMoC,O,mCAGJrC,EAAOC,EAAOC,GAEvB,IAAIqB,EAAMD,KAAKE,OAAOxB,EAAOC,EAAOC,GAChC2N,EAAW,CAAEtJ,KAAM,IAkBvB,OAjBoB,SAAhBuJ,EAA0BvM,GAC1B,OAAOgB,MAAMhB,GAAKmB,OAAOA,MAAK,SAACC,GAC3B,IAAKA,EAASC,GACV,MAAM,IAAIC,MAAMF,EAASG,YAE7B,OAAOH,EAASI,UACjBL,MAAK,SAASqL,GAKb,OAJAA,EAAUtM,KAAKyB,MAAM6K,GACrB3P,OAAOyF,KAAKkK,EAAQxJ,MAAMC,SAAQ,SAAUvF,GACxC4O,EAAStJ,KAAKtF,IAAQ4O,EAAStJ,KAAKtF,IAAQ,IAAI+O,OAAOD,EAAQxJ,KAAKtF,OAEpE8O,EAAQE,KACDH,EAAcC,EAAQE,MAE1BJ,KAGRC,CAAcvM,O,GAjPNwD,GA8PjBmJ,E,8BACF,WAAYjJ,GAAQ,wBAChB,cAAMA,IACDmD,mBAAoB,EAFT,E,yCAKbpI,EAAOC,EAAOC,GAGjB,IAAMiO,EAAenO,EAAMqM,cAAgB/K,KAAKgH,OAAOP,MACvDF,EAAoBvG,KAAKgE,YAAYrH,KAAMkQ,EAAc,MAOzD,IAAMC,EAAmC,WAAjBD,EAA6B,EAAI,EACnDnG,EAAS1G,KAAKgH,OAAON,QAAUoG,EACrC,gBAAU9M,KAAKC,IAAf,iDAA6DyG,EAA7D,0BAAqFhI,EAAM4B,IAA3F,wBAA8G5B,EAAM6B,MAApH,uBAAwI7B,EAAM+B,O,sCAGlIqB,GAEZ,IAEMiL,EAFcjQ,OAAOyF,KAAKT,GAEHkL,MAAK,SAAUjN,GACxC,OAAOA,EAAKwE,MAAM,0BAGtB,IAAKwI,EACD,MAAM,IAAIxL,MAAM,0DAEpB,MAAO,CAAE,IAAOwL,K,oCAGL9J,EAAMrE,EAAQ+I,EAAUC,GAEnC,OAAO3E,I,uCAGMA,EAAMtE,EAAOC,EAAQ+I,EAAUC,GAC5C,IAAK3E,EAAKT,OACN,OAAO7D,EAAMoC,KAKjB,IACMkM,EAActF,EAAS/I,EAAOsO,QADpB,eAGhB,SAASjB,EAASL,EAAMC,EAAOjN,EAAQ+I,EAAUC,GAE7C,IAAMuF,EAAYvB,EAAI,mBAAyB,EAE/C,GADAA,EAAI,kBAAwBuB,EAAY,IACzBvB,EAAKqB,IAAgBrB,EAAKqB,GAAepB,EAAK,YAM7D,IAAK,IAAInE,EAAI,EAAGA,EAAI9I,EAAO4D,OAAQkF,IAAK,CACpC,IAAM0F,EAAKxO,EAAO8I,GACZ2F,EAAO1F,EAASD,GAElB3E,EAAM8I,EAAMuB,GACZxF,GAASA,EAAMF,KACf3E,EAAM6E,EAAMF,GAAG3E,IAEnB6I,EAAKyB,GAAQtK,GAQrB,IAJA,IAAMuK,EAAatN,KAAKuK,gBAAgB5L,EAAMoC,KAAK,IAC7CwM,EAAWvN,KAAKuK,gBAAgBtH,EAAK,IAEvC7G,EAAI,EAAGsL,EAAI,EACRtL,EAAIuC,EAAMoC,KAAKyB,QAAUkF,EAAIzE,EAAKT,QAAQ,CAC7C,IAAIoJ,EAAOjN,EAAMoC,KAAK3E,GAClByP,EAAQ5I,EAAKyE,GAEbkE,EAAK0B,EAAWjC,OAASQ,EAAM0B,EAASlC,MAExCY,EAASL,EAAMC,EAAOjN,EAAQ+I,EAAUC,GACxCF,GAAK,GACEkE,EAAK0B,EAAWjC,KAAOQ,EAAM0B,EAASlC,KAC7CjP,GAAK,EAELsL,GAAK,EAGb,OAAO/I,EAAMoC,S,GA3FO0C,GAmGtB+J,E,6HACK9O,EAAOC,EAAOC,GACjB,IAAM6H,EAAQ/H,EAAMqM,cAAgB/K,KAAKgH,OAAOP,MAC5CC,EAAS1G,KAAKgH,OAAON,OASzB,OARAH,EAAoBvG,KAAKgE,YAAYrH,KAAM8J,EAAOC,GAE9CD,IAIAC,EAAoB,WAAVD,EAAsB,EAAI,GAExC,UAAUzG,KAAKC,IAAf,6BAAuCyG,EAAvC,0BAA+DhI,EAAM4B,IAArE,0BAA0F5B,EAAM+B,IAAhG,uBAAkH/B,EAAM6B,S,wCAG1G0C,GAGd,OAAOA,I,oCAGGA,EAAMrE,EAAQ+I,EAAUC,GAClC,OAAO3E,M,GAtBMQ,GAkCfgK,E,8BACF,WAAY9J,GAAQ,wBAChB,cAAMA,IACDmD,mBAAoB,EAFT,E,2CAMhB,OAAO9G,KAAKC,M,kCAEJvB,EAAOC,EAAOC,GACtB,IAAM6H,EAAQ/H,EAAMqM,cAAgB/K,KAAKgH,OAAOP,MAGhD,gBAAUzG,KAAKC,IAAf,YAAsBvB,EAAM4B,IAA5B,YAAmC5B,EAAM6B,MAAzC,YAAkD7B,EAAM+B,IAAxD,YAA+DgG,K,wCAGjDxD,GACd,OAAOA,I,mCAGEvE,EAAOC,EAAOC,GACvB,IAAM6H,EAAQ/H,EAAMqM,cAAgB/K,KAAKgH,OAAOP,MAChD,IAAKA,EACD,MAAM,IAAIlF,MAAJ,sBAAyBvB,KAAKgE,YAAYrH,KAA1C,0CAGV,IAAM+Q,EAAoB/O,EAAMoC,KAAK8B,QAGjC,SAAUC,EAAKgD,GAEX,OADAhD,EAAIgD,EAAKE,WAAa,KACflD,IAEX,IAEA6K,EAAQ7Q,OAAOyF,KAAKmL,GAAmB5N,KAAI,SAAUkG,GAErD,IAAM4H,EAAQ,IAAH,OAAO5H,EAAU6H,QAAQ,iBAAkB,MAEtD,gBAAUD,EAAV,gCAAuC5H,EAAvC,gCAAwES,EAAxE,sMAGJ,IAAKkH,EAAMnL,OAEP,OAAO0B,QAAQC,QAAQ,CAAElB,KAAM,OAGnC0K,EAAQ,IAAH,OAAOA,EAAMxE,KAAK,KAAlB,MACL,IAAMlJ,EAAMD,KAAKE,OAAOxB,EAAOC,EAAOC,GAEhCmC,EAAOZ,KAAKC,UAAU,CAAEuN,MAAOA,IAKrC,OAAO1M,MAAMhB,EAAK,CAAEiB,OAAQ,OAAQH,OAAMI,QAJ1B,CAAE,eAAgB,sBAImBC,MAAK,SAACC,GACvD,OAAKA,EAASC,GAGPD,EAASI,OAFL,MAFR,OAKE,SAACqM,GAAD,MAAS,Q,uCAGL7K,EAAMtE,EAAOC,EAAQ+I,EAAUC,GAC5C,OAAK3E,GAILtE,EAAMoC,KAAKmC,SAAQ,SAAS4C,GAExB,IAAM8H,EAAQ,IAAH,OAAO9H,EAAKE,UAAU6H,QAAQ,iBAAkB,MACrDE,EAAa9K,EAAK2K,IAAU3K,EAAK2K,GAAL,kBAC9BG,GAEAjR,OAAOyF,KAAKwL,GAAY7K,SAAQ,SAAUvF,GACtC,IAAIoF,EAAMgL,EAAWpQ,QACI,IAAdmI,EAAKnI,KACM,iBAAPoF,GAAmBA,EAAIiL,WAAWrH,SAAS,OAClD5D,EAAMkL,WAAWlL,EAAImL,QAAQ,KAEjCpI,EAAKnI,GAAOoF,SAKrBpE,EAAMoC,MApBFpC,M,GAjEY8E,GA6FzB0K,E,6HACKzP,EAAOC,EAAOC,GACjB,IAAM6H,EAAQ/H,EAAMqM,cAAgB/K,KAAKgH,OAAOP,MAC5CC,EAAS1G,KAAKgH,OAAON,OAMzB,OALAH,EAAoBvG,KAAKgE,YAAYC,YAAawC,EAAOC,GAErDD,IACAC,EAAoB,WAAVD,EAAsB,GAAK,IAEzC,UAAUzG,KAAKC,IAAf,yBAAmCyG,EAAnC,+BAAgEhI,EAAM4B,IAAtE,6BAA8F5B,EAAM+B,IAApG,4BAA2H/B,EAAM6B,W,GATlHkD,GAsBjB2K,E,gIACQnL,GAENjD,KAAKqO,MAAQpL,I,iCAENvE,EAAOC,EAAOC,GACrB,OAAOsF,QAAQC,QAAQnE,KAAKqO,W,GANT/P,GAiBrBgQ,E,6HACK5P,EAAOC,EAAOC,GACjB,IAAM6H,GAAS/H,EAAMqM,aAAe,CAACrM,EAAMqM,cAAgB,OAAS/K,KAAKgH,OAAOP,MAChF,IAAKA,IAAUY,MAAMC,QAAQb,KAAWA,EAAMjE,OAC1C,MAAM,IAAIjB,MAAM,CAAC,cAAevB,KAAKgE,YAAYC,YAAa,6EAA6EkF,KAAK,MASpJ,MAPY,CACRnJ,KAAKC,IACL,uBAAwBuL,mBAAmB9M,EAAM8F,SAAU,oBAC3DiC,EAAM3G,KAAI,SAAUC,GAChB,sBAAgByL,mBAAmBzL,OACpCoJ,KAAK,MAEDA,KAAK,Q,GAbD1F,GAkCjBjF,E,8BACF,WAAYmF,GAAQ,MAGhB,GAHgB,UAChB,cAAMA,IAEDA,IAAWA,EAAO4K,QACnB,MAAM,IAAIhN,MAAM,2GAWpB,EAAKgE,qBAAuB5B,EAAO4K,QAGnC,IAAMC,EAAgB1R,OAAOyF,KAAKoB,EAAO4K,SAlBzB,OAqBhB,EAAKE,sBAAsBvL,SAAQ,SAAC4E,GAChC,IAAK0G,EAAc7H,SAASmB,GAExB,MAAM,IAAIvG,MAAJ,4BAA+B,EAAKyC,YAAYrH,KAAhD,sDAAkGmL,OAxBhG,E,kFAgCTpJ,EAAOC,EAAOC,GAAQ,WAS7B,OANA9B,OAAOyF,KAAKvC,KAAKuF,sBAAsBrC,SAAQ,SAACzF,GAC5C,IAAMiR,EAAkB,EAAKnJ,qBAAqB9H,GAClD,GAAIkB,EAAMoF,WAAapF,EAAMoF,SAAS2K,GAClC,MAAM,IAAInN,MAAJ,UAAa,EAAKyC,YAAYrH,KAA9B,6DAAuF+R,OAG9FxK,QAAQC,QAAQxF,EAAMoC,MAAQ,M,oCAG3BkC,EAAMtE,EAAOC,EAAQ+I,EAAUC,GAMzC,OAAO1D,QAAQC,QAAQnE,KAAKuI,iBAAiBtF,EAAMtE,EAAOC,EAAQ+I,EAAUC,IACvExG,MAAK,SAASoH,GACX,MAAO,CAACzJ,OAAQJ,EAAMI,QAAU,GAAIgF,SAAUpF,EAAMoF,UAAY,GAAIhD,KAAMyH,Q,uCAIrE1G,EAASnD,GAEtB,MAAM,IAAI4C,MAAM,mD,4CAQhB,MAAM,IAAIA,MAAM,qF,GAnEMjD,I,gBC/6B9BnC,EAAOD,QAAUyS,a","file":"ext/lz-aggregation-tests.min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 11);\n","/** @module */\n/*\n * LocusZoom extensions used to calculate and render aggregation test results. Because these calculations depend on an\n * external library, the special data sources are defined here, rather than in LocusZoom core code.\n *\n * The page must incorporate and load all libraries before this file can be used, including:\n * - Vendor assets\n * - LocusZoom\n * - raremetal.js (available via NPM or a related CDN)\n */\n// This is defined as a UMD module, to work with multiple different module systems / bundlers\n// Arcane build note: everything defined here gets registered globally. This is not a \"pure\" module, and some build\n// systems may require being told that this file has side effects.\n\nimport {helpers} from 'raremetal.js';\nimport {BaseApiAdapter} from '../data/adapters';\n\n\nfunction install (LocusZoom) {\n /**\n * Data Source that calculates gene or region-based tests based on provided data\n * It will rarely be used by itself, but rather using a connector that attaches the results to data from\n * another source (like genes). Using a separate connector allows us to add caching and run this front-end\n * calculation only once, while using it in many different places\n * @public\n */\n const BaseAdapter = LocusZoom.Adapters.get('BaseAdapter');\n const ConnectorSource = LocusZoom.Adapters.get('ConnectorSource');\n\n class AggregationTestSource extends BaseApiAdapter {\n getURL(state, chain, fields) {\n // Unlike most sources, calculations may require access to plot state data even after the initial request\n // This example source REQUIRES that the external UI widget would store the needed test definitions in a plot state\n // field called `aggregation_tests` (an object {masks: [], calcs: {})\n const required_info = state.aggregation_tests || {};\n\n if (!chain.header) {\n chain.header = {};\n }\n // All of these fields are required in order to use this datasource. TODO: Add validation?\n chain.header.aggregation_genoset_id = required_info.genoset_id || null; // Number\n chain.header.aggregation_genoset_build = required_info.genoset_build || null; // String\n chain.header.aggregation_phenoset_id = required_info.phenoset_id || null; // Number\n chain.header.aggregation_pheno = required_info.pheno || null; // String\n chain.header.aggregation_calcs = required_info.calcs || {}; // String[]\n const mask_data = required_info.masks || [];\n chain.header.aggregation_masks = mask_data; // {name:desc}[]\n chain.header.aggregation_mask_ids = mask_data.map(function (item) {\n return item.name;\n }); // Number[]\n return this.url;\n }\n\n getCacheKey(state, chain, fields) {\n this.getURL(state, chain, fields); // TODO: This just sets the chain.header fields\n return JSON.stringify({\n chrom: state.chr,\n start: state.start,\n stop: state.end,\n genotypeDataset: chain.header.aggregation_genoset_id,\n phenotypeDataset: chain.header.aggregation_phenoset_id,\n phenotype: chain.header.aggregation_pheno,\n samples: 'ALL',\n genomeBuild: chain.header.aggregation_genoset_build,\n masks: chain.header.aggregation_mask_ids,\n });\n }\n\n fetchRequest(state, chain, fields) {\n const url = this.getURL(state, chain, fields);\n const body = this.getCacheKey(state, chain, fields);\n const headers = {\n 'Content-Type': 'application/json',\n };\n\n return fetch(url, {method: 'POST', body: body, headers: headers}).then((response) => {\n if (!response.ok) {\n throw new Error(response.statusText);\n }\n return response.text();\n }).then(function (resp) {\n const json = typeof resp == 'string' ? JSON.parse(resp) : resp;\n if (json.error) {\n // RAREMETAL-server quirk: The API sometimes returns a 200 status code for failed requests,\n // with a human-readable error description as a key\n // For now, this should be treated strictly as an error\n throw new Error(json.error);\n }\n return json;\n });\n }\n\n annotateData(records, chain) {\n // Operate on the calculated results. The result of this method will be added to chain.discrete\n\n // In a page using live API data, the UI would only request the masks it needs from the API.\n // But in our demos, sometimes boilerplate JSON has more masks than the UI asked for. Limit what calcs we run (by\n // type, and to the set of groups requested by the user)\n\n // The Raremetal-server API has a quirk: it returns a different payload structure if no groups are defined\n // for the request region. Detect when that happens and end the calculation immediately in that case\n if (!records.groups) {\n return { groups: [], variants: [] };\n }\n\n records.groups = records.groups.filter(function (item) {\n return item.groupType === 'GENE';\n });\n\n const parsed = helpers.parsePortalJSON(records);\n let groups = parsed[0];\n const variants = parsed[1];\n // Some APIs may return more data than we want (eg simple sites that are just serving up premade scorecov json files).\n // Filter the response to just what the user has chosen to analyze.\n groups = groups.byMask(chain.header.aggregation_mask_ids);\n\n // Determine what calculations to run\n const calcs = chain.header.aggregation_calcs;\n if (!calcs || Object.keys(calcs).length === 0) {\n // If no calcs have been requested, then return a dummy placeholder immediately\n return { variants: [], groups: [], results: [] };\n }\n const runner = new helpers.PortalTestRunner(groups, variants, calcs);\n\n return runner.toJSON()\n .then(function (res) {\n // Internally, raremetal helpers track how the calculation is done, but not any display-friendly values\n // We will annotate each mask name (id) with a human-friendly description for later use\n const mask_id_to_desc = chain.header.aggregation_masks.reduce(function (acc, val) {\n acc[val.name] = val.description;\n return acc;\n }, {});\n res.data.groups.forEach(function (group) {\n group.mask_name = mask_id_to_desc[group.mask];\n });\n return res.data;\n })\n .catch(function (e) {\n console.error(e);\n throw new Error('Failed to calculate aggregation test results');\n });\n }\n\n normalizeResponse(data) {\n return data;\n }\n\n combineChainBody(records, chain) {\n // aggregation tests are a bit unique, in that the data is rarely used directly- instead it is used to annotate many\n // other layers in different ways. The calculated result has been added to `chain.discrete`, but will not be returned\n // as part of the response body built up by the chain\n return chain.body;\n }\n\n }\n\n class AssocFromAggregationLZ extends BaseAdapter {\n constructor(config) {\n if (!config || !config.from) {\n throw 'Must specify the name of the source that contains association data';\n }\n super(...arguments);\n }\n parseInit(config) {\n super.parseInit(config);\n this._from = config.from;\n }\n\n getRequest(state, chain, fields) {\n // Does not actually make a request. Just pick off the specific bundle of data from a known payload structure.\n if (chain.discrete && !chain.discrete[this._from]) {\n throw `${this.constructor.SOURCE_NAME} cannot be used before loading required data for: ${this._from}`;\n }\n // Copy the data so that mutations (like sorting) don't affect the original\n return Promise.resolve(JSON.parse(JSON.stringify(chain.discrete[this._from]['variants'])));\n }\n\n normalizeResponse(data) {\n // The payload structure of the association source is slightly different than the one required by association\n // plots. For example, we need to parse variant names and convert to log_pvalue\n const REGEX_EPACTS = new RegExp('(?:chr)?(.+):(\\\\d+)_?(\\\\w+)?/?([^_]+)?_?(.*)?'); // match API variant strings\n return data.map((one_variant) => {\n const match = one_variant.variant.match(REGEX_EPACTS);\n return {\n variant: one_variant.variant,\n chromosome: match[1],\n position: +match[2],\n ref_allele: match[3],\n ref_allele_freq: 1 - one_variant.altFreq,\n log_pvalue: -Math.log10(one_variant.pvalue),\n };\n }).sort((a, b) => {\n a = a.variant;\n b = b.variant;\n if (a < b) {\n return -1;\n } else if (a > b) {\n return 1;\n } else {\n // names must be equal\n return 0;\n }\n });\n }\n }\n\n /**\n * A sample connector that aligns calculated aggregation test data with corresponding gene information. Returns a body\n * suitable for use with the genes datalayer.\n *\n * To use this source, one must specify a fields array that calls first the genes source, then a dummy field from\n * this source. The output will be to transparently add several new fields to the genes data.\n * @public\n */\n class GeneAggregationConnectorLZ extends ConnectorSource {\n _getRequiredSources() {\n return ['gene_ns', 'aggregation_ns'];\n }\n\n combineChainBody(data, chain) {\n // The genes layer receives all results, and displays only the best pvalue for each gene\n\n // Tie the calculated group-test results to genes with a matching name\n const aggregation_source_id = this._source_name_mapping['aggregation_ns'];\n const gene_source_id = this._source_name_mapping['gene_ns'];\n // This connector assumes that genes are the main body of records from the chain, and that aggregation tests are\n // a standalone source that has not acted on genes data yet\n const aggregationData = chain.discrete[aggregation_source_id];\n const genesData = chain.discrete[gene_source_id];\n\n const groupedAggregation = {}; // Group together all tests done on that gene- any mask, any test\n\n aggregationData.groups.forEach(function (result) {\n if (!Object.prototype.hasOwnProperty.call(groupedAggregation, result.group)) {\n groupedAggregation[result.group] = [];\n }\n groupedAggregation[result.group].push(result.pvalue);\n });\n\n // Annotate any genes that have test results\n genesData.forEach(function (gene) {\n const gene_id = gene.gene_name;\n const tests = groupedAggregation[gene_id];\n if (tests) {\n gene.aggregation_best_pvalue = Math.min.apply(null, tests);\n }\n });\n return genesData;\n }\n }\n\n\n LocusZoom.Adapters.add('AggregationTestSourceLZ', AggregationTestSource);\n LocusZoom.Adapters.add('AssocFromAggregationLZ', AssocFromAggregationLZ);\n LocusZoom.Adapters.add('GeneAggregationConnectorLZ', GeneAggregationConnectorLZ);\n}\n\n\nif (typeof LocusZoom !== 'undefined') {\n // Auto-register the plugin when included as a script tag. ES6 module users must register via LocusZoom.use()\n // eslint-disable-next-line no-undef\n LocusZoom.use(install);\n}\n\n\nexport default install;\n","/**\n * Define standard data adapters used to retrieve data (usually from REST APIs)\n * @module\n */\n\nfunction validateBuildSource(class_name, build, source) {\n // Build OR Source, not both\n if ((build && source) || !(build || source)) {\n throw new Error(`${class_name} must provide a parameter specifying either \"build\" or \"source\". It should not specify both.`);\n }\n // If the build isn't recognized, our APIs can't transparently select a source to match\n if (build && !['GRCh37', 'GRCh38'].includes(build)) {\n throw new Error(`${class_name} must specify a valid genome build number`);\n }\n}\n\n\n/**\n * Base class for LocusZoom data sources (any). See also: BaseApiAdapter\n * @public\n */\nclass BaseAdapter {\n constructor(config) {\n /**\n * Whether this source should enable caching\n * @member {Boolean}\n */\n this._enableCache = true;\n this._cachedKey = null;\n\n /**\n * Whether this data source type is dependent on previous requests- for example, the LD source cannot annotate\n * association data if no data was found for that region.\n * @member {boolean}\n */\n this.__dependentSource = false;\n\n // Parse configuration options\n this.parseInit(config);\n }\n\n /**\n * Parse configuration used to create the data source. Many custom sources will override this method to suit their\n * needs (eg specific config options, or for sources that do not retrieve data from a URL)\n * @protected\n * @param {String|Object} config Basic configuration- either a url, or a config object\n * @param {String} [config.url] The datasource URL\n * @param {String} [config.params] Initial config params for the datasource\n */\n parseInit(config) {\n /** @member {Object} */\n this.params = config.params || {};\n }\n\n /**\n * A unique identifier that indicates whether cached data is valid for this request. For most sources using GET\n * requests to a REST API, this is usually the URL.\n * @protected\n * @param {Object} state Information available in plot.state (chr, start, end). Sometimes used to inject globally\n * available information that influences the request being made.\n * @param {Object} chain The data chain from previous requests made in a sequence.\n * @param fields\n * @returns {String|undefined}\n */\n getCacheKey(state, chain, fields) {\n return this.getURL(state, chain, fields);\n }\n\n /**\n * Stub: build the URL for any requests made by this source.\n * @protected\n */\n getURL(state, chain, fields) {\n return this.url;\n }\n\n /**\n * Perform a network request to fetch data for this source. This is usually the method that is used to override\n * when defining how to retrieve data.\n * @protected\n * @param {Object} state The state of the parent plot\n * @param chain\n * @param fields\n * @returns {Promise}\n */\n fetchRequest(state, chain, fields) {\n const url = this.getURL(state, chain, fields);\n return fetch(url).then((response) => {\n if (!response.ok) {\n throw new Error(response.statusText);\n }\n return response.text();\n });\n }\n\n /**\n * Gets the data for just this source, typically via a network request (but using cache where possible)\n *\n * For most use cases, it is better to override `fetchRequest` instead, to avoid bypassing the cache mechanism\n * by accident.\n * @protected\n */\n getRequest(state, chain, fields) {\n let req;\n const cacheKey = this.getCacheKey(state, chain, fields);\n if (this._enableCache && typeof(cacheKey) !== 'undefined' && cacheKey === this._cachedKey) {\n req = Promise.resolve(this._cachedResponse); // Resolve to the value of the current promise\n } else {\n req = this.fetchRequest(state, chain, fields);\n if (this._enableCache) {\n this._cachedKey = cacheKey;\n this._cachedResponse = req;\n }\n }\n return req;\n }\n\n /**\n * Ensure the server response is in a canonical form, an array of one object per record. [ {field: oneval} ].\n * If the server response contains columns, reformats the response from {column1: [], column2: []} to the above.\n *\n * Does not apply namespacing, transformations, or field extraction.\n *\n * May be overridden by data sources that inherently return more complex payloads, or that exist to annotate other\n * sources (eg, if the payload provides extra data rather than a series of records).\n * @protected\n * @param {Object[]|Object} data The original parsed server response\n */\n normalizeResponse(data) {\n if (Array.isArray(data)) {\n // Already in the desired form\n return data;\n }\n // Otherwise, assume the server response is an object representing columns of data.\n // Each array should have the same length (verify), and a given array index corresponds to a single row.\n const keys = Object.keys(data);\n const N = data[keys[0]].length;\n const sameLength = keys.every(function (key) {\n const item = data[key];\n return item.length === N;\n });\n if (!sameLength) {\n throw new Error(`${this.constructor.name} expects a response in which all arrays of data are the same length`);\n }\n\n // Go down the rows, and create an object for each record\n const records = [];\n const fields = Object.keys(data);\n for (let i = 0; i < N; i++) {\n const record = {};\n for (let j = 0; j < fields.length; j++) {\n record[fields[j]] = data[fields[j]][i];\n }\n records.push(record);\n }\n return records;\n }\n\n /**\n * Hook to post-process the data returned by this source with new, additional behavior.\n * (eg cleaning up API values or performing complex calculations on the returned data)\n *\n * @protected\n * @param {Object[]} records The parsed data from the source (eg standardized api response)\n * @param {Object} chain The data chain object. For example, chain.headers may provide useful annotation metadata\n * @returns {Object[]|Promise} The modified set of records\n */\n annotateData(records, chain) {\n // Default behavior: no transformations\n return records;\n }\n\n /**\n * Clean up the server records for use by datalayers: extract only certain fields, with the specified names.\n * Apply per-field transformations as appropriate.\n *\n * This hook can be overridden, eg to create a source that always returns all records and ignores the \"fields\" array.\n * This is particularly common for sources at the end of a chain- many \"dependent\" sources do not allow\n * cherry-picking individual fields, in which case by **convention** the fields array specifies \"last_source_name:all\"\n *\n * @protected\n * @param {Object[]} data One record object per element\n * @param {String[]} fields The names of fields to extract (as named in the source data). Eg \"afield\"\n * @param {String[]} outnames How to represent the source fields in the output. Eg \"namespace:afield|atransform\"\n * @param {function[]} trans An array of transformation functions (if any). One function per data element, or null.\n * @protected\n */\n extractFields (data, fields, outnames, trans) {\n //intended for an array of objects\n // [ {\"id\":1, \"val\":5}, {\"id\":2, \"val\":10}]\n // Since a number of sources exist that do not obey this format, we will provide a convenient pass-through\n if (!Array.isArray(data)) {\n return data;\n }\n\n if (!data.length) {\n // Sometimes there are regions that just don't have data- this should not trigger a missing field error message!\n return data;\n }\n\n const fieldFound = [];\n for (let k = 0; k < fields.length; k++) {\n fieldFound[k] = 0;\n }\n\n const records = data.map(function (item) {\n const output_record = {};\n for (let j = 0; j < fields.length; j++) {\n let val = item[fields[j]];\n if (typeof val != 'undefined') {\n fieldFound[j] = 1;\n }\n if (trans && trans[j]) {\n val = trans[j](val);\n }\n output_record[outnames[j]] = val;\n }\n return output_record;\n });\n fieldFound.forEach(function(v, i) {\n if (!v) {\n throw new Error(`field ${fields[i]} not found in response for ${outnames[i]}`);\n }\n });\n return records;\n }\n\n /**\n * Combine records from this source with others in the chain to yield final chain body.\n * Handles merging this data with other sources (if applicable).\n *\n * @protected\n * @param {Object[]} data The data That would be returned from this source alone\n * @param {Object} chain The data chain built up during previous requests\n * @param {String[]} fields\n * @param {String[]} outnames\n * @param {String[]} trans\n * @return {Promise|Object[]} The new chain body\n */\n combineChainBody(data, chain, fields, outnames, trans) {\n return data;\n }\n\n /**\n * Coordinates the work of parsing a response and returning records. This is broken into 4 steps, which may be\n * overridden separately for fine-grained control. Each step can return either raw data or a promise.\n *\n * @protected\n *\n * @param {String|Object} resp The raw data associated with the response\n * @param {Object} chain The combined parsed response data from this and all other requests made in the chain\n * @param {String[]} fields Array of requested field names (as they would appear in the response payload)\n * @param {String[]} outnames Array of field names as they will be represented in the data returned by this source,\n * including the namespace. This must be an array with the same length as `fields`\n * @param {Function[]} trans The collection of transformation functions to be run on selected fields.\n * This must be an array with the same length as `fields`\n * @returns {Promise} A promise that resolves to an object containing\n * request metadata (`headers: {}`), the consolidated data for plotting (`body: []`), and the individual responses that would be\n * returned by each source in the chain in isolation (`discrete: {}`)\n */\n parseResponse (resp, chain, fields, outnames, trans) {\n const source_id = this.source_id || this.constructor.name;\n if (!chain.discrete) {\n chain.discrete = {};\n }\n\n const json = typeof resp == 'string' ? JSON.parse(resp) : resp;\n\n // Perform the 4 steps of parsing the payload and return a combined chain object\n return Promise.resolve(this.normalizeResponse(json.data || json))\n .then((standardized) => {\n // Perform calculations on the data from just this source\n return Promise.resolve(this.annotateData(standardized, chain));\n }).then((data) => {\n return Promise.resolve(this.extractFields(data, fields, outnames, trans));\n }).then((one_source_body) => {\n // Store a copy of the data that would be returned by parsing this source in isolation (and taking the\n // fields array into account). This is useful when we want to re-use the source output in many ways.\n chain.discrete[source_id] = one_source_body;\n return Promise.resolve(this.combineChainBody(one_source_body, chain, fields, outnames, trans));\n }).then((new_body) => {\n return { header: chain.header || {}, discrete: chain.discrete, body: new_body };\n });\n }\n\n /**\n * Fetch the data from the specified data source, and apply transformations requested by an external consumer.\n * This is the public-facing datasource method that will most be called by the plot, but custom data sources will\n * almost never want to override this method directly- more specific hooks are provided to control individual pieces\n * of the request lifecycle.\n *\n * @private\n * @param {Object} state The current \"state\" of the plot, such as chromosome and start/end positions\n * @param {String[]} fields Array of field names that the plot has requested from this data source. (without the \"namespace\" prefix)\n * @param {String[]} outnames Array describing how the output data should refer to this field. This represents the\n * originally requested field name, including the namespace. This must be an array with the same length as `fields`\n * @param {Function[]} trans The collection of transformation functions to be run on selected fields.\n * This must be an array with the same length as `fields`\n * @returns {function} A callable operation that can be used as part of the data chain\n */\n getData(state, fields, outnames, trans) {\n if (this.preGetData) { // TODO try to remove this method if at all possible\n const pre = this.preGetData(state, fields, outnames, trans);\n if (this.pre) {\n state = pre.state || state;\n fields = pre.fields || fields;\n outnames = pre.outnames || outnames;\n trans = pre.trans || trans;\n }\n }\n\n return (chain) => {\n if (this.__dependentSource && chain && chain.body && !chain.body.length) {\n // A \"dependent\" source should not attempt to fire a request if there is no data for it to act on.\n // Therefore, it should simply return the previous data chain.\n return Promise.resolve(chain);\n }\n\n return this.getRequest(state, chain, fields).then((resp) => {\n return this.parseResponse(resp, chain, fields, outnames, trans);\n });\n };\n }\n}\n\n/**\n * Base source for LocusZoom data sources that receive their data over the web. Adds default config parameters\n * (and potentially other behavior) that are relevant to URL-based requests.\n */\nclass BaseApiAdapter extends BaseAdapter {\n parseInit(config) {\n super.parseInit(config);\n\n /** @member {String} */\n this.url = config.url;\n if (!this.url) {\n throw new Error('Source not initialized with required URL');\n }\n }\n}\n\n/**\n * Data Source for Association Data from the LocusZoom/ Portaldev API (or compatible). Defines how to make a requesr\n * @public\n */\nclass AssociationLZ extends BaseApiAdapter {\n preGetData (state, fields, outnames, trans) {\n // TODO: Modify internals to see if we can go without this method\n const id_field = this.params.id_field || 'id';\n [id_field, 'position'].forEach(function(x) {\n if (!fields.includes(x)) {\n fields.unshift(x);\n outnames.unshift(x);\n trans.unshift(null);\n }\n });\n return {fields: fields, outnames:outnames, trans:trans};\n }\n\n getURL (state, chain, fields) {\n const analysis = chain.header.analysis || this.params.source || this.params.analysis; // Old usages called this param \"analysis\"\n if (typeof analysis == 'undefined') {\n throw new Error('Association source must specify an analysis ID to plot');\n }\n return `${this.url}results/?filter=analysis in ${analysis} and chromosome in '${state.chr}' and position ge ${state.start} and position le ${state.end}`;\n }\n\n normalizeResponse (data) {\n // Some association sources do not sort their data in a predictable order, which makes it hard to reliably\n // align with other sources (such as LD). For performance reasons, sorting is an opt-in argument.\n // TODO: Consider more fine grained sorting control in the future. This was added as a very specific\n // workaround for the original T2D portal.\n data = super.normalizeResponse(data);\n if (this.params && this.params.sort && data.length && data[0]['position']) {\n data.sort(function (a, b) {\n return a['position'] - b['position'];\n });\n }\n return data;\n }\n}\n\n/**\n * Fetch linkage disequilibrium information from a UMich LDServer-compatible API\n *\n * This source is designed to connect its results to association data, and therefore depends on association data having\n * been loaded by a previous request in the data chain.\n *\n * In older versions of LocusZoom, this was known as \"LDServer\". A prior source (targeted at older APIs) has been removed.\n */\nclass LDServer extends BaseApiAdapter {\n constructor(config) {\n super(config);\n this.__dependentSource = true;\n }\n\n preGetData(state, fields) {\n if (fields.length > 1) {\n if (fields.length !== 2 || !fields.includes('isrefvar')) {\n throw new Error(`LD does not know how to get all fields: ${fields.join(', ')}`);\n }\n }\n }\n\n findMergeFields(chain) {\n // Find the fields (as provided by a previous step in the chain, like an association source) that will be needed to\n // combine LD data with existing information\n\n // Since LD information may be shared across multiple assoc sources with different namespaces,\n // we use regex to find columns to join on, rather than requiring exact matches\n const exactMatch = function (arr) {\n return function () {\n const regexes = arguments;\n for (let i = 0; i < regexes.length; i++) {\n const regex = regexes[i];\n const m = arr.filter(function (x) {\n return x.match(regex);\n });\n if (m.length) {\n return m[0];\n }\n }\n return null;\n };\n };\n let dataFields = {\n id: this.params.id_field,\n position: this.params.position_field,\n pvalue: this.params.pvalue_field,\n _names_:null,\n };\n if (chain && chain.body && chain.body.length > 0) {\n const names = Object.keys(chain.body[0]);\n const nameMatch = exactMatch(names);\n // Internally, fields are generally prefixed with the name of the source they come from.\n // If the user provides an id_field (like `variant`), it should work across data sources( `assoc1:variant`,\n // assoc2:variant), but not match fragments of other field names (assoc1:variant_thing)\n // Note: these lookups hard-code a couple of common fields that will work based on known APIs in the wild\n const id_match = dataFields.id && nameMatch(new RegExp(`${dataFields.id}\\\\b`));\n dataFields.id = id_match || nameMatch(/\\bvariant\\b/) || nameMatch(/\\bid\\b/);\n dataFields.position = dataFields.position || nameMatch(/\\bposition\\b/i, /\\bpos\\b/i);\n dataFields.pvalue = dataFields.pvalue || nameMatch(/\\bpvalue\\b/i, /\\blog_pvalue\\b/i);\n dataFields._names_ = names;\n }\n return dataFields;\n }\n\n findRequestedFields (fields, outnames) {\n // Assumption: all usages of this source will only ever ask for \"isrefvar\" or \"state\". This maps to output names.\n let obj = {};\n for (let i = 0; i < fields.length; i++) {\n if (fields[i] === 'isrefvar') {\n obj.isrefvarin = fields[i];\n obj.isrefvarout = outnames && outnames[i];\n } else {\n obj.ldin = fields[i];\n obj.ldout = outnames && outnames[i];\n }\n }\n return obj;\n }\n\n normalizeResponse (data) {\n // The LD API payload does not obey standard format conventions; do not try to transform it.\n return data;\n }\n\n /**\n * Get the LD reference variant, which by default will be the most significant hit in the assoc results\n * This will be used in making the original query to the LD server for pairwise LD information\n * @returns {*|string} The marker id (expected to be in `chr:pos_ref/alt` format) of the reference variant\n */\n getRefvar(state, chain, fields) {\n let findExtremeValue = function(records, pval_field) {\n // Finds the most significant hit (smallest pvalue, or largest -log10p). Will try to auto-detect the appropriate comparison.\n pval_field = pval_field || 'log_pvalue'; // The official LZ API returns log_pvalue\n const is_log = /log/.test(pval_field);\n let cmp;\n if (is_log) {\n cmp = function(a, b) {\n return a > b;\n };\n } else {\n cmp = function(a, b) {\n return a < b;\n };\n }\n let extremeVal = records[0][pval_field], extremeIdx = 0;\n for (let i = 1; i < records.length; i++) {\n if (cmp(records[i][pval_field], extremeVal)) {\n extremeVal = records[i][pval_field];\n extremeIdx = i;\n }\n }\n return extremeIdx;\n };\n\n let reqFields = this.findRequestedFields(fields);\n let refVar = reqFields.ldin;\n if (refVar === 'state') {\n refVar = state.ldrefvar || chain.header.ldrefvar || 'best';\n }\n if (refVar === 'best') {\n if (!chain.body) {\n throw new Error('No association data found to find best pvalue');\n }\n let keys = this.findMergeFields(chain);\n if (!keys.pvalue || !keys.id) {\n let columns = '';\n if (!keys.id) {\n columns += `${columns.length ? ', ' : ''}id`;\n }\n if (!keys.pvalue) {\n columns += `${columns.length ? ', ' : ''}pvalue`;\n }\n throw new Error(`Unable to find necessary column(s) for merge: ${columns} (available: ${keys._names_})`);\n }\n refVar = chain.body[findExtremeValue(chain.body, keys.pvalue)][keys.id];\n }\n return refVar;\n }\n\n getURL(state, chain, fields) {\n // Accept the following params in this.params:\n // - method (r, rsquare, cov)\n // - source (aka panel)\n // - population (ALL, AFR, EUR, etc)\n // - build\n // The LD source/pop can be overridden from plot.state for dynamic layouts\n const build = state.genome_build || this.params.build || 'GRCh37';\n let source = state.ld_source || this.params.source || '1000G';\n const population = state.ld_pop || this.params.population || 'ALL'; // LDServer panels will always have an ALL\n const method = this.params.method || 'rsquare';\n\n if (source === '1000G' && build === 'GRCh38') {\n // For build 38 (only), there is a newer/improved 1000G LD panel available that uses WGS data. Auto upgrade by default.\n source = '1000G-FRZ09';\n }\n\n validateBuildSource(this.constructor.name, build, null); // LD doesn't need to validate `source` option\n\n let refVar = this.getRefvar(state, chain, fields);\n // Some datasets, notably the Portal, use a different marker format.\n // Coerce it into one that will work with the LDServer API. (CHROM:POS_REF/ALT)\n const REGEX_MARKER = /^(?:chr)?([a-zA-Z0-9]+?)[_:-](\\d+)[_:|-]?(\\w+)?[/_:|-]?([^_]+)?_?(.*)?/;\n const match = refVar && refVar.match(REGEX_MARKER);\n\n if (!match) {\n throw new Error('Could not request LD for a missing or incomplete marker format');\n }\n const [original, chrom, pos, ref, alt] = match;\n // Currently, the LD server only accepts full variant specs; it won't return LD w/o ref+alt. Allowing\n // a partial match at most leaves room for potential future features.\n refVar = `${chrom}:${pos}`;\n if (ref && alt) {\n refVar += `_${ref}/${alt}`;\n }\n // Preserve the user-provided variant spec for use when matching to assoc data\n chain.header.ldrefvar = original;\n\n return [\n this.url, 'genome_builds/', build, '/references/', source, '/populations/', population, '/variants',\n '?correlation=', method,\n '&variant=', encodeURIComponent(refVar),\n '&chrom=', encodeURIComponent(state.chr),\n '&start=', encodeURIComponent(state.start),\n '&stop=', encodeURIComponent(state.end),\n ].join('');\n }\n\n combineChainBody(data, chain, fields, outnames, trans) {\n let keys = this.findMergeFields(chain);\n let reqFields = this.findRequestedFields(fields, outnames);\n if (!keys.position) {\n throw new Error(`Unable to find position field for merge: ${keys._names_}`);\n }\n const leftJoin = function (left, right, lfield, rfield) {\n let i = 0, j = 0;\n while (i < left.length && j < right.position2.length) {\n if (left[i][keys.position] === right.position2[j]) {\n left[i][lfield] = right[rfield][j];\n i++;\n j++;\n } else if (left[i][keys.position] < right.position2[j]) {\n i++;\n } else {\n j++;\n }\n }\n };\n const tagRefVariant = function (data, refvar, idfield, outrefname, outldname) {\n for (let i = 0; i < data.length; i++) {\n if (data[i][idfield] && data[i][idfield] === refvar) {\n data[i][outrefname] = 1;\n data[i][outldname] = 1; // For label/filter purposes, implicitly mark the ref var as LD=1 to itself\n } else {\n data[i][outrefname] = 0;\n }\n }\n };\n\n // LD servers vary slightly. Some report corr as \"rsquare\", others as \"correlation\"\n let corrField = data.rsquare ? 'rsquare' : 'correlation';\n leftJoin(chain.body, data, reqFields.ldout, corrField);\n if (reqFields.isrefvarin && chain.header.ldrefvar) {\n tagRefVariant(chain.body, chain.header.ldrefvar, keys.id, reqFields.isrefvarout, reqFields.ldout);\n }\n return chain.body;\n }\n\n fetchRequest(state, chain, fields) {\n // The API is paginated, but we need all of the data to render a plot. Depaginate and combine where appropriate.\n let url = this.getURL(state, chain, fields);\n let combined = { data: {} };\n let chainRequests = function (url) {\n return fetch(url).then().then((response) => {\n if (!response.ok) {\n throw new Error(response.statusText);\n }\n return response.text();\n }).then(function(payload) {\n payload = JSON.parse(payload);\n Object.keys(payload.data).forEach(function (key) {\n combined.data[key] = (combined.data[key] || []).concat(payload.data[key]);\n });\n if (payload.next) {\n return chainRequests(payload.next);\n }\n return combined;\n });\n };\n return chainRequests(url);\n }\n}\n\n/**\n * Data source for GWAS catalogs of known variants\n * @public\n * @class\n * @param {Object|String} init Configuration (URL or object)\n * @param {Object} [init.params] Optional configuration parameters\n * @param {Number} [init.params.source=2] The ID of the chosen catalog. Defaults to EBI GWAS catalog, GRCh37\n * @param {('strict'|'loose')} [init.params.match_type='strict'] Whether to match on exact variant, or just position.\n */\nclass GwasCatalogLZ extends BaseApiAdapter {\n constructor(config) {\n super(config);\n this.__dependentSource = true;\n }\n\n getURL(state, chain, fields) {\n // This is intended to be aligned with another source- we will assume they are always ordered by position, asc\n // (regardless of the actual match field)\n const build_option = state.genome_build || this.params.build;\n validateBuildSource(this.constructor.name, build_option, null); // Source can override build- not mutually exclusive\n\n // Most of our annotations will respect genome build before any other option.\n // But there can be more than one GWAS catalog version available in the same API, for the same build- an\n // explicit config option will always take\n // precedence.\n // See: http://portaldev.sph.umich.edu/api/v1/annotation/gwascatalog/?format=objects\n const default_source = (build_option === 'GRCh38') ? 5 : 6; // EBI GWAS catalog\n const source = this.params.source || default_source;\n return `${this.url }?format=objects&sort=pos&filter=id eq ${source} and chrom eq '${state.chr}' and pos ge ${state.start} and pos le ${state.end}`;\n }\n\n findMergeFields(records) {\n // Data from previous sources is already namespaced. Find the alignment field by matching.\n const knownFields = Object.keys(records);\n // Note: All API endoints involved only give results for 1 chromosome at a time; match is implied\n const posMatch = knownFields.find(function (item) {\n return item.match(/\\b(position|pos)\\b/i);\n });\n\n if (!posMatch) {\n throw new Error('Could not find data to align with GWAS catalog results');\n }\n return { 'pos': posMatch };\n }\n\n extractFields (data, fields, outnames, trans) {\n // Skip the \"individual field extraction\" step; extraction will be handled when building chain body instead\n return data;\n }\n\n combineChainBody(data, chain, fields, outnames, trans) {\n if (!data.length) {\n return chain.body;\n }\n\n // TODO: Better reuse options in the future. This source is very specifically tied to the PortalDev API, where\n // the field name is always \"log_pvalue\". Relatively few sites will write their own gwas-catalog endpoint.\n const decider = 'log_pvalue';\n const decider_out = outnames[fields.indexOf(decider)];\n\n function leftJoin(left, right, fields, outnames, trans) { // Add `fields` from `right` to `left`\n // Add a synthetic, un-namespaced field to all matching records\n const n_matches = left['n_catalog_matches'] || 0;\n left['n_catalog_matches'] = n_matches + 1;\n if (decider && left[decider_out] && left[decider_out] > right[decider]) {\n // There may be more than one GWAS catalog entry for the same SNP. This source is intended for a 1:1\n // annotation scenario, so for now it only joins the catalog entry that has the best -log10 pvalue\n return;\n }\n\n for (let j = 0; j < fields.length; j++) {\n const fn = fields[j];\n const outn = outnames[j];\n\n let val = right[fn];\n if (trans && trans[j]) {\n val = trans[j](val);\n }\n left[outn] = val;\n }\n }\n\n const chainNames = this.findMergeFields(chain.body[0]);\n const catNames = this.findMergeFields(data[0]);\n\n var i = 0, j = 0;\n while (i < chain.body.length && j < data.length) {\n var left = chain.body[i];\n var right = data[j];\n\n if (left[chainNames.pos] === right[catNames.pos]) {\n // There may be multiple catalog entries for each matching SNP; evaluate match one at a time\n leftJoin(left, right, fields, outnames, trans);\n j += 1;\n } else if (left[chainNames.pos] < right[catNames.pos]) {\n i += 1;\n } else {\n j += 1;\n }\n }\n return chain.body;\n }\n}\n\n/**\n * Data Source for Gene Data, as fetched from the LocusZoom/Portaldev API server (or compatible format)\n * @public\n */\nclass GeneLZ extends BaseApiAdapter {\n getURL(state, chain, fields) {\n const build = state.genome_build || this.params.build;\n let source = this.params.source;\n validateBuildSource(this.constructor.name, build, source);\n\n if (build) {\n // If build specified, we auto-select the best current portaldev API dataset for that build\n // If build is not specified, we use the exact source ID provided by the user.\n // See: https://portaldev.sph.umich.edu/api/v1/annotation/genes/sources/?format=objects\n source = (build === 'GRCh38') ? 4 : 5;\n }\n return `${this.url}?filter=source in ${source} and chrom eq '${state.chr}' and start le ${state.end} and end ge ${state.start}`;\n }\n\n normalizeResponse(data) {\n // Genes have a very complex internal data format. Bypass any record parsing, and provide the data layer with\n // the exact information returned by the API. (ignoring the fields array in the layout)\n return data;\n }\n\n extractFields(data, fields, outnames, trans) {\n return data;\n }\n}\n\n/**\n * Data Source for Gene Constraint Data, as fetched from the gnomAD server (or compatible)\n *\n * This is intended to be the second request in a chain, with special logic that connects it to Genes data\n * already fetched.\n *\n * @public\n*/\nclass GeneConstraintLZ extends BaseApiAdapter {\n constructor(config) {\n super(config);\n this.__dependentSource = true;\n }\n getURL() {\n // GraphQL API: request details are encoded in the body, not the URL\n return this.url;\n }\n getCacheKey(state, chain, fields) {\n const build = state.genome_build || this.params.build;\n // GraphQL API: request not defined solely by the URL\n // Gather the state params that govern constraint query for a given region.\n return `${this.url} ${state.chr} ${state.start} ${state.end} ${build}`;\n }\n\n normalizeResponse(data) {\n return data;\n }\n\n fetchRequest(state, chain, fields) {\n const build = state.genome_build || this.params.build;\n if (!build) {\n throw new Error(`Data source ${this.constructor.name} must specify a 'genome_build' option`);\n }\n\n const unique_gene_names = chain.body.reduce(\n // In rare cases, the same gene symbol may appear at multiple positions. (issue #179) We de-duplicate the\n // gene names to avoid issuing a malformed GraphQL query.\n function (acc, gene) {\n acc[gene.gene_name] = null;\n return acc;\n },\n {}\n );\n let query = Object.keys(unique_gene_names).map(function (gene_name) {\n // GraphQL alias names must match a specific set of allowed characters: https://stackoverflow.com/a/45757065/1422268\n const alias = `_${gene_name.replace(/[^A-Za-z0-9_]/g, '_')}`;\n // Each gene symbol is a separate graphQL query, grouped into one request using aliases\n return `${alias}: gene(gene_symbol: \"${gene_name}\", reference_genome: ${build}) { gnomad_constraint { exp_syn obs_syn syn_z oe_syn oe_syn_lower oe_syn_upper exp_mis obs_mis mis_z oe_mis oe_mis_lower oe_mis_upper exp_lof obs_lof pLI oe_lof oe_lof_lower oe_lof_upper } } `;\n });\n\n if (!query.length) {\n // If there are no genes, skip the network request\n return Promise.resolve({ data: null });\n }\n\n query = `{${query.join(' ')} }`; // GraphQL isn't quite JSON; items are separated by spaces but not commas\n const url = this.getURL(state, chain, fields);\n // See: https://graphql.org/learn/serving-over-http/\n const body = JSON.stringify({ query: query });\n const headers = { 'Content-Type': 'application/json' };\n\n // FIXME: The gnomAD API sometimes has temporary CORS changes that temporarily break the genes track\n // If request blocked, return a fake \"no data\" signal so the genes track can still render w/o constraint info\n return fetch(url, { method: 'POST', body, headers }).then((response) => {\n if (!response.ok) {\n return [];\n }\n return response.text();\n }).catch((err) => []);\n }\n\n combineChainBody(data, chain, fields, outnames, trans) {\n if (!data) {\n return chain;\n }\n\n chain.body.forEach(function(gene) {\n // Find payload keys that match gene names in this response\n const alias = `_${gene.gene_name.replace(/[^A-Za-z0-9_]/g, '_')}`; // aliases are modified gene names\n const constraint = data[alias] && data[alias]['gnomad_constraint']; // gnomad API has two ways of specifying missing data for a requested gene\n if (constraint) {\n // Add all fields from constraint data- do not override fields present in the gene source\n Object.keys(constraint).forEach(function (key) {\n let val = constraint[key];\n if (typeof gene[key] === 'undefined') {\n if (typeof val == 'number' && val.toString().includes('.')) {\n val = parseFloat(val.toFixed(2));\n }\n gene[key] = val; // These two sources are both designed to bypass namespacing\n }\n });\n }\n });\n return chain.body;\n }\n}\n\n/**\n * Data Source for Recombination Rate Data, as fetched from the LocusZoom API server (or compatible)\n * @public\n */\nclass RecombLZ extends BaseApiAdapter {\n getURL(state, chain, fields) {\n const build = state.genome_build || this.params.build;\n let source = this.params.source;\n validateBuildSource(this.constructor.SOURCE_NAME, build, source);\n\n if (build) { // If build specified, choose a known Portal API dataset IDs (build 37/38)\n source = (build === 'GRCh38') ? 16 : 15;\n }\n return `${this.url}?filter=id in ${source} and chromosome eq '${state.chr}' and position le ${state.end} and position ge ${state.start}`;\n }\n}\n\n/**\n * Data Source for static blobs of data as raw JS objects. This does not perform additional parsing, and it bypasses\n * namespaces. Therefore it is the responsibility of the user to pass information in a format that can be read and\n * understood by the chosen plot- a StaticJSON source is rarely a drop-in replacement.\n *\n * This source is largely here for legacy reasons. More often, a convenient way to serve static data is as separate\n * JSON files to an existing source (with the JSON url in place of an API).\n * @public\n */\nclass StaticSource extends BaseAdapter {\n parseInit(data) {\n // Does not receive any config; the only argument is the raw data, embedded when source is created\n this._data = data;\n }\n getRequest(state, chain, fields) {\n return Promise.resolve(this._data);\n }\n}\n\n\n/**\n * Data source for PheWAS data retrieved from a LocusZoom/PortalDev compatible API\n * @public\n * @param {String[]} init.params.build This datasource expects to be provided the name of the genome build that will\n * be used to provide pheWAS results for this position. Note positions may not translate between builds.\n */\nclass PheWASLZ extends BaseApiAdapter {\n getURL(state, chain, fields) {\n const build = (state.genome_build ? [state.genome_build] : null) || this.params.build;\n if (!build || !Array.isArray(build) || !build.length) {\n throw new Error(['Data source', this.constructor.SOURCE_NAME, 'requires that you specify array of one or more desired genome build names'].join(' '));\n }\n const url = [\n this.url,\n \"?filter=variant eq '\", encodeURIComponent(state.variant), \"'&format=objects&\",\n build.map(function (item) {\n return `build=${encodeURIComponent(item)}`;\n }).join('&'),\n ];\n return url.join('');\n }\n}\n\n\n/**\n * Base class for \"connectors\"- this is meant to be subclassed, rather than used directly.\n *\n * A connector is a source that makes no server requests and caches no data of its own. Instead, it decides how to\n * combine data from other sources in the chain. Connectors are useful when we want to request (or calculate) some\n * useful piece of information once, but apply it to many different kinds of record types.\n *\n * Typically, a subclass will implement the field merging logic in `combineChainBody`.\n *\n * @public\n * @param {Object} init Configuration for this source\n * @param {Object} init.sources Specify how the hard-coded logic should find the data it relies on in the chain,\n * as {internal_name: chain_source_id} pairs. This allows writing a reusable connector that does not need to make\n * assumptions about what namespaces a source is using.\n * @type {*|Function}\n */\nclass ConnectorSource extends BaseAdapter {\n constructor(config) {\n super(config);\n\n if (!config || !config.sources) {\n throw new Error('Connectors must specify the data they require as init.sources = {internal_name: chain_source_id}} pairs');\n }\n\n /**\n * Tells the connector how to find the data it relies on\n *\n * For example, a connector that applies burden test information to the genes layer might specify:\n * {gene_ns: \"gene\", aggregation_ns: \"aggregation\"}\n *\n * @member {Object}\n */\n this._source_name_mapping = config.sources;\n\n // Validate that this source has been told how to find the required information\n const specified_ids = Object.keys(config.sources);\n /** @property {String[]} Specifies the sources that must be provided in the original config object */\n\n this._getRequiredSources().forEach((k) => {\n if (!specified_ids.includes(k)) {\n // TODO: Fix constructor.name usage in minified bundles\n throw new Error(`Configuration for ${this.constructor.name} must specify a source ID corresponding to ${k}`);\n }\n });\n }\n\n // Stub- connectors don't have their own url or data, so the defaults don't make sense\n parseInit() {}\n\n getRequest(state, chain, fields) {\n // Connectors do not request their own data by definition, but they *do* depend on other sources having been loaded\n // first. This method performs basic validation, and preserves the accumulated body from the chain so far.\n Object.keys(this._source_name_mapping).forEach((ns) => {\n const chain_source_id = this._source_name_mapping[ns];\n if (chain.discrete && !chain.discrete[chain_source_id]) {\n throw new Error(`${this.constructor.name} cannot be used before loading required data for: ${chain_source_id}`);\n }\n });\n return Promise.resolve(chain.body || []);\n }\n\n parseResponse(data, chain, fields, outnames, trans) {\n // A connector source does not update chain.discrete, but it may use it. It bypasses data formatting\n // and field selection (both are assumed to have been done already, by the previous sources this draws from)\n\n // Because of how the chain works, connectors are not very good at applying new transformations or namespacing.\n // Typically connectors are called with `connector_name:all` in the fields array.\n return Promise.resolve(this.combineChainBody(data, chain, fields, outnames, trans))\n .then(function(new_body) {\n return {header: chain.header || {}, discrete: chain.discrete || {}, body: new_body};\n });\n }\n\n combineChainBody(records, chain) {\n // Stub method: specifies how to combine the data\n throw new Error('This method must be implemented in a subclass');\n }\n\n /**\n * Helper method since ES6 doesn't support class fields\n * @private\n */\n _getRequiredSources() {\n throw new Error('Must specify an array that identifes the kind of data required by this source');\n }\n}\n\nexport { BaseAdapter, BaseApiAdapter };\n\nexport {\n AssociationLZ,\n ConnectorSource,\n GeneConstraintLZ,\n GeneLZ,\n GwasCatalogLZ,\n LDServer,\n PheWASLZ,\n RecombLZ,\n StaticSource,\n};\n","module.exports = raremetal;"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack://[name]/webpack/bootstrap","webpack://[name]/./esm/ext/lz-aggregation-tests.js","webpack://[name]/./esm/data/adapters.js","webpack://[name]/external \"raremetal\""],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","install","LocusZoom","BaseAdapter","Adapters","ConnectorSource","AggregationTestSource","state","chain","fields","required_info","aggregation_tests","header","aggregation_genoset_id","genoset_id","aggregation_genoset_build","genoset_build","aggregation_phenoset_id","phenoset_id","aggregation_pheno","pheno","aggregation_calcs","calcs","mask_data","masks","aggregation_masks","aggregation_mask_ids","map","item","this","url","getURL","JSON","stringify","chrom","chr","start","stop","end","genotypeDataset","phenotypeDataset","phenotype","samples","genomeBuild","body","getCacheKey","fetch","method","headers","then","response","ok","Error","statusText","text","resp","json","parse","error","records","groups","variants","filter","groupType","parsed","parsePortalJSON","byMask","keys","length","results","PortalTestRunner","toJSON","res","mask_id_to_desc","reduce","acc","val","description","data","forEach","group","mask_name","mask","catch","e","console","add","config","from","super","arguments","parseInit","_from","discrete","constructor","SOURCE_NAME","Promise","resolve","REGEX_EPACTS","RegExp","one_variant","match","variant","chromosome","position","ref_allele","ref_allele_freq","altFreq","log_pvalue","Math","log10","pvalue","sort","a","b","aggregation_source_id","_source_name_mapping","gene_source_id","aggregationData","genesData","groupedAggregation","result","push","gene","gene_id","gene_name","tests","aggregation_best_pvalue","min","apply","use","validateBuildSource","class_name","build","source","includes","_enableCache","_cachedKey","__dependentSource","params","req","cacheKey","_cachedResponse","fetchRequest","Array","isArray","N","every","record","j","outnames","trans","fieldFound","k","output_record","v","source_id","normalizeResponse","standardized","annotateData","extractFields","one_source_body","combineChainBody","new_body","preGetData","pre","getRequest","parseResponse","BaseApiAdapter","AssociationLZ","id_field","x","unshift","analysis","LDServer","join","dataFields","id","position_field","pvalue_field","_names_","names","nameMatch","arr","regexes","regex","id_match","obj","isrefvarin","isrefvarout","ldin","ldout","refVar","findRequestedFields","ldrefvar","findMergeFields","columns","pval_field","cmp","test","extremeVal","extremeIdx","findExtremeValue","genome_build","ld_source","population","ld_pop","getRefvar","original","pos","ref","alt","encodeURIComponent","reqFields","corrField","rsquare","left","right","lfield","rfield","position2","leftJoin","refvar","idfield","outrefname","outldname","tagRefVariant","combined","chainRequests","payload","concat","next","GwasCatalogLZ","build_option","default_source","posMatch","find","decider_out","indexOf","n_matches","fn","outn","chainNames","catNames","GeneLZ","GeneConstraintLZ","unique_gene_names","query","replace","err","alias","constraint","toString","parseFloat","toFixed","RecombLZ","StaticSource","_data","PheWASLZ","sources","specified_ids","_getRequiredSources","chain_source_id","raremetal"],"mappings":"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","file":"ext/lz-aggregation-tests.min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 12);\n","/** @module */\n/*\n * LocusZoom extensions used to calculate and render aggregation test results. Because these calculations depend on an\n * external library, the special data sources are defined here, rather than in LocusZoom core code.\n *\n * The page must incorporate and load all libraries before this file can be used, including:\n * - Vendor assets\n * - LocusZoom\n * - raremetal.js (available via NPM or a related CDN)\n */\n// This is defined as a UMD module, to work with multiple different module systems / bundlers\n// Arcane build note: everything defined here gets registered globally. This is not a \"pure\" module, and some build\n// systems may require being told that this file has side effects.\n\nimport {helpers} from 'raremetal.js';\nimport {BaseApiAdapter} from '../data/adapters';\n\n\nfunction install (LocusZoom) {\n /**\n * Data Source that calculates gene or region-based tests based on provided data\n * It will rarely be used by itself, but rather using a connector that attaches the results to data from\n * another source (like genes). Using a separate connector allows us to add caching and run this front-end\n * calculation only once, while using it in many different places\n * @public\n */\n const BaseAdapter = LocusZoom.Adapters.get('BaseAdapter');\n const ConnectorSource = LocusZoom.Adapters.get('ConnectorSource');\n\n class AggregationTestSource extends BaseApiAdapter {\n getURL(state, chain, fields) {\n // Unlike most sources, calculations may require access to plot state data even after the initial request\n // This example source REQUIRES that the external UI widget would store the needed test definitions in a plot state\n // field called `aggregation_tests` (an object {masks: [], calcs: {})\n const required_info = state.aggregation_tests || {};\n\n if (!chain.header) {\n chain.header = {};\n }\n // All of these fields are required in order to use this datasource. TODO: Add validation?\n chain.header.aggregation_genoset_id = required_info.genoset_id || null; // Number\n chain.header.aggregation_genoset_build = required_info.genoset_build || null; // String\n chain.header.aggregation_phenoset_id = required_info.phenoset_id || null; // Number\n chain.header.aggregation_pheno = required_info.pheno || null; // String\n chain.header.aggregation_calcs = required_info.calcs || {}; // String[]\n const mask_data = required_info.masks || [];\n chain.header.aggregation_masks = mask_data; // {name:desc}[]\n chain.header.aggregation_mask_ids = mask_data.map(function (item) {\n return item.name;\n }); // Number[]\n return this.url;\n }\n\n getCacheKey(state, chain, fields) {\n this.getURL(state, chain, fields); // TODO: This just sets the chain.header fields\n return JSON.stringify({\n chrom: state.chr,\n start: state.start,\n stop: state.end,\n genotypeDataset: chain.header.aggregation_genoset_id,\n phenotypeDataset: chain.header.aggregation_phenoset_id,\n phenotype: chain.header.aggregation_pheno,\n samples: 'ALL',\n genomeBuild: chain.header.aggregation_genoset_build,\n masks: chain.header.aggregation_mask_ids,\n });\n }\n\n fetchRequest(state, chain, fields) {\n const url = this.getURL(state, chain, fields);\n const body = this.getCacheKey(state, chain, fields);\n const headers = {\n 'Content-Type': 'application/json',\n };\n\n return fetch(url, {method: 'POST', body: body, headers: headers}).then((response) => {\n if (!response.ok) {\n throw new Error(response.statusText);\n }\n return response.text();\n }).then(function (resp) {\n const json = typeof resp == 'string' ? JSON.parse(resp) : resp;\n if (json.error) {\n // RAREMETAL-server quirk: The API sometimes returns a 200 status code for failed requests,\n // with a human-readable error description as a key\n // For now, this should be treated strictly as an error\n throw new Error(json.error);\n }\n return json;\n });\n }\n\n annotateData(records, chain) {\n // Operate on the calculated results. The result of this method will be added to chain.discrete\n\n // In a page using live API data, the UI would only request the masks it needs from the API.\n // But in our demos, sometimes boilerplate JSON has more masks than the UI asked for. Limit what calcs we run (by\n // type, and to the set of groups requested by the user)\n\n // The Raremetal-server API has a quirk: it returns a different payload structure if no groups are defined\n // for the request region. Detect when that happens and end the calculation immediately in that case\n if (!records.groups) {\n return { groups: [], variants: [] };\n }\n\n records.groups = records.groups.filter(function (item) {\n return item.groupType === 'GENE';\n });\n\n const parsed = helpers.parsePortalJSON(records);\n let groups = parsed[0];\n const variants = parsed[1];\n // Some APIs may return more data than we want (eg simple sites that are just serving up premade scorecov json files).\n // Filter the response to just what the user has chosen to analyze.\n groups = groups.byMask(chain.header.aggregation_mask_ids);\n\n // Determine what calculations to run\n const calcs = chain.header.aggregation_calcs;\n if (!calcs || Object.keys(calcs).length === 0) {\n // If no calcs have been requested, then return a dummy placeholder immediately\n return { variants: [], groups: [], results: [] };\n }\n const runner = new helpers.PortalTestRunner(groups, variants, calcs);\n\n return runner.toJSON()\n .then(function (res) {\n // Internally, raremetal helpers track how the calculation is done, but not any display-friendly values\n // We will annotate each mask name (id) with a human-friendly description for later use\n const mask_id_to_desc = chain.header.aggregation_masks.reduce(function (acc, val) {\n acc[val.name] = val.description;\n return acc;\n }, {});\n res.data.groups.forEach(function (group) {\n group.mask_name = mask_id_to_desc[group.mask];\n });\n return res.data;\n })\n .catch(function (e) {\n console.error(e);\n throw new Error('Failed to calculate aggregation test results');\n });\n }\n\n normalizeResponse(data) {\n return data;\n }\n\n combineChainBody(records, chain) {\n // aggregation tests are a bit unique, in that the data is rarely used directly- instead it is used to annotate many\n // other layers in different ways. The calculated result has been added to `chain.discrete`, but will not be returned\n // as part of the response body built up by the chain\n return chain.body;\n }\n\n }\n\n class AssocFromAggregationLZ extends BaseAdapter {\n constructor(config) {\n if (!config || !config.from) {\n throw 'Must specify the name of the source that contains association data';\n }\n super(...arguments);\n }\n parseInit(config) {\n super.parseInit(config);\n this._from = config.from;\n }\n\n getRequest(state, chain, fields) {\n // Does not actually make a request. Just pick off the specific bundle of data from a known payload structure.\n if (chain.discrete && !chain.discrete[this._from]) {\n throw `${this.constructor.SOURCE_NAME} cannot be used before loading required data for: ${this._from}`;\n }\n // Copy the data so that mutations (like sorting) don't affect the original\n return Promise.resolve(JSON.parse(JSON.stringify(chain.discrete[this._from]['variants'])));\n }\n\n normalizeResponse(data) {\n // The payload structure of the association source is slightly different than the one required by association\n // plots. For example, we need to parse variant names and convert to log_pvalue\n const REGEX_EPACTS = new RegExp('(?:chr)?(.+):(\\\\d+)_?(\\\\w+)?/?([^_]+)?_?(.*)?'); // match API variant strings\n return data.map((one_variant) => {\n const match = one_variant.variant.match(REGEX_EPACTS);\n return {\n variant: one_variant.variant,\n chromosome: match[1],\n position: +match[2],\n ref_allele: match[3],\n ref_allele_freq: 1 - one_variant.altFreq,\n log_pvalue: -Math.log10(one_variant.pvalue),\n };\n }).sort((a, b) => {\n a = a.variant;\n b = b.variant;\n if (a < b) {\n return -1;\n } else if (a > b) {\n return 1;\n } else {\n // names must be equal\n return 0;\n }\n });\n }\n }\n\n /**\n * A sample connector that aligns calculated aggregation test data with corresponding gene information. Returns a body\n * suitable for use with the genes datalayer.\n *\n * To use this source, one must specify a fields array that calls first the genes source, then a dummy field from\n * this source. The output will be to transparently add several new fields to the genes data.\n * @public\n */\n class GeneAggregationConnectorLZ extends ConnectorSource {\n _getRequiredSources() {\n return ['gene_ns', 'aggregation_ns'];\n }\n\n combineChainBody(data, chain) {\n // The genes layer receives all results, and displays only the best pvalue for each gene\n\n // Tie the calculated group-test results to genes with a matching name\n const aggregation_source_id = this._source_name_mapping['aggregation_ns'];\n const gene_source_id = this._source_name_mapping['gene_ns'];\n // This connector assumes that genes are the main body of records from the chain, and that aggregation tests are\n // a standalone source that has not acted on genes data yet\n const aggregationData = chain.discrete[aggregation_source_id];\n const genesData = chain.discrete[gene_source_id];\n\n const groupedAggregation = {}; // Group together all tests done on that gene- any mask, any test\n\n aggregationData.groups.forEach(function (result) {\n if (!Object.prototype.hasOwnProperty.call(groupedAggregation, result.group)) {\n groupedAggregation[result.group] = [];\n }\n groupedAggregation[result.group].push(result.pvalue);\n });\n\n // Annotate any genes that have test results\n genesData.forEach(function (gene) {\n const gene_id = gene.gene_name;\n const tests = groupedAggregation[gene_id];\n if (tests) {\n gene.aggregation_best_pvalue = Math.min.apply(null, tests);\n }\n });\n return genesData;\n }\n }\n\n\n LocusZoom.Adapters.add('AggregationTestSourceLZ', AggregationTestSource);\n LocusZoom.Adapters.add('AssocFromAggregationLZ', AssocFromAggregationLZ);\n LocusZoom.Adapters.add('GeneAggregationConnectorLZ', GeneAggregationConnectorLZ);\n}\n\n\nif (typeof LocusZoom !== 'undefined') {\n // Auto-register the plugin when included as a script tag. ES6 module users must register via LocusZoom.use()\n // eslint-disable-next-line no-undef\n LocusZoom.use(install);\n}\n\n\nexport default install;\n","/**\n * Define standard data adapters used to retrieve data (usually from REST APIs)\n * @module\n */\n\nfunction validateBuildSource(class_name, build, source) {\n // Build OR Source, not both\n if ((build && source) || !(build || source)) {\n throw new Error(`${class_name} must provide a parameter specifying either \"build\" or \"source\". It should not specify both.`);\n }\n // If the build isn't recognized, our APIs can't transparently select a source to match\n if (build && !['GRCh37', 'GRCh38'].includes(build)) {\n throw new Error(`${class_name} must specify a valid genome build number`);\n }\n}\n\n\n/**\n * Base class for LocusZoom data sources (any). See also: BaseApiAdapter\n * @public\n */\nclass BaseAdapter {\n constructor(config) {\n /**\n * Whether this source should enable caching\n * @member {Boolean}\n */\n this._enableCache = true;\n this._cachedKey = null;\n\n /**\n * Whether this data source type is dependent on previous requests- for example, the LD source cannot annotate\n * association data if no data was found for that region.\n * @member {boolean}\n */\n this.__dependentSource = false;\n\n // Parse configuration options\n this.parseInit(config);\n }\n\n /**\n * Parse configuration used to create the data source. Many custom sources will override this method to suit their\n * needs (eg specific config options, or for sources that do not retrieve data from a URL)\n * @protected\n * @param {String|Object} config Basic configuration- either a url, or a config object\n * @param {String} [config.url] The datasource URL\n * @param {String} [config.params] Initial config params for the datasource\n */\n parseInit(config) {\n /** @member {Object} */\n this.params = config.params || {};\n }\n\n /**\n * A unique identifier that indicates whether cached data is valid for this request. For most sources using GET\n * requests to a REST API, this is usually the URL.\n * @protected\n * @param {Object} state Information available in plot.state (chr, start, end). Sometimes used to inject globally\n * available information that influences the request being made.\n * @param {Object} chain The data chain from previous requests made in a sequence.\n * @param fields\n * @returns {String|undefined}\n */\n getCacheKey(state, chain, fields) {\n return this.getURL(state, chain, fields);\n }\n\n /**\n * Stub: build the URL for any requests made by this source.\n * @protected\n */\n getURL(state, chain, fields) {\n return this.url;\n }\n\n /**\n * Perform a network request to fetch data for this source. This is usually the method that is used to override\n * when defining how to retrieve data.\n * @protected\n * @param {Object} state The state of the parent plot\n * @param chain\n * @param fields\n * @returns {Promise}\n */\n fetchRequest(state, chain, fields) {\n const url = this.getURL(state, chain, fields);\n return fetch(url).then((response) => {\n if (!response.ok) {\n throw new Error(response.statusText);\n }\n return response.text();\n });\n }\n\n /**\n * Gets the data for just this source, typically via a network request (but using cache where possible)\n *\n * For most use cases, it is better to override `fetchRequest` instead, to avoid bypassing the cache mechanism\n * by accident.\n * @protected\n */\n getRequest(state, chain, fields) {\n let req;\n const cacheKey = this.getCacheKey(state, chain, fields);\n if (this._enableCache && typeof(cacheKey) !== 'undefined' && cacheKey === this._cachedKey) {\n req = Promise.resolve(this._cachedResponse); // Resolve to the value of the current promise\n } else {\n req = this.fetchRequest(state, chain, fields);\n if (this._enableCache) {\n this._cachedKey = cacheKey;\n this._cachedResponse = req;\n }\n }\n return req;\n }\n\n /**\n * Ensure the server response is in a canonical form, an array of one object per record. [ {field: oneval} ].\n * If the server response contains columns, reformats the response from {column1: [], column2: []} to the above.\n *\n * Does not apply namespacing, transformations, or field extraction.\n *\n * May be overridden by data sources that inherently return more complex payloads, or that exist to annotate other\n * sources (eg, if the payload provides extra data rather than a series of records).\n * @protected\n * @param {Object[]|Object} data The original parsed server response\n */\n normalizeResponse(data) {\n if (Array.isArray(data)) {\n // Already in the desired form\n return data;\n }\n // Otherwise, assume the server response is an object representing columns of data.\n // Each array should have the same length (verify), and a given array index corresponds to a single row.\n const keys = Object.keys(data);\n const N = data[keys[0]].length;\n const sameLength = keys.every(function (key) {\n const item = data[key];\n return item.length === N;\n });\n if (!sameLength) {\n throw new Error(`${this.constructor.name} expects a response in which all arrays of data are the same length`);\n }\n\n // Go down the rows, and create an object for each record\n const records = [];\n const fields = Object.keys(data);\n for (let i = 0; i < N; i++) {\n const record = {};\n for (let j = 0; j < fields.length; j++) {\n record[fields[j]] = data[fields[j]][i];\n }\n records.push(record);\n }\n return records;\n }\n\n /**\n * Hook to post-process the data returned by this source with new, additional behavior.\n * (eg cleaning up API values or performing complex calculations on the returned data)\n *\n * @protected\n * @param {Object[]} records The parsed data from the source (eg standardized api response)\n * @param {Object} chain The data chain object. For example, chain.headers may provide useful annotation metadata\n * @returns {Object[]|Promise} The modified set of records\n */\n annotateData(records, chain) {\n // Default behavior: no transformations\n return records;\n }\n\n /**\n * Clean up the server records for use by datalayers: extract only certain fields, with the specified names.\n * Apply per-field transformations as appropriate.\n *\n * This hook can be overridden, eg to create a source that always returns all records and ignores the \"fields\" array.\n * This is particularly common for sources at the end of a chain- many \"dependent\" sources do not allow\n * cherry-picking individual fields, in which case by **convention** the fields array specifies \"last_source_name:all\"\n *\n * @protected\n * @param {Object[]} data One record object per element\n * @param {String[]} fields The names of fields to extract (as named in the source data). Eg \"afield\"\n * @param {String[]} outnames How to represent the source fields in the output. Eg \"namespace:afield|atransform\"\n * @param {function[]} trans An array of transformation functions (if any). One function per data element, or null.\n * @protected\n */\n extractFields (data, fields, outnames, trans) {\n //intended for an array of objects\n // [ {\"id\":1, \"val\":5}, {\"id\":2, \"val\":10}]\n // Since a number of sources exist that do not obey this format, we will provide a convenient pass-through\n if (!Array.isArray(data)) {\n return data;\n }\n\n if (!data.length) {\n // Sometimes there are regions that just don't have data- this should not trigger a missing field error message!\n return data;\n }\n\n const fieldFound = [];\n for (let k = 0; k < fields.length; k++) {\n fieldFound[k] = 0;\n }\n\n const records = data.map(function (item) {\n const output_record = {};\n for (let j = 0; j < fields.length; j++) {\n let val = item[fields[j]];\n if (typeof val != 'undefined') {\n fieldFound[j] = 1;\n }\n if (trans && trans[j]) {\n val = trans[j](val);\n }\n output_record[outnames[j]] = val;\n }\n return output_record;\n });\n fieldFound.forEach(function(v, i) {\n if (!v) {\n throw new Error(`field ${fields[i]} not found in response for ${outnames[i]}`);\n }\n });\n return records;\n }\n\n /**\n * Combine records from this source with others in the chain to yield final chain body.\n * Handles merging this data with other sources (if applicable).\n *\n * @protected\n * @param {Object[]} data The data That would be returned from this source alone\n * @param {Object} chain The data chain built up during previous requests\n * @param {String[]} fields\n * @param {String[]} outnames\n * @param {String[]} trans\n * @return {Promise|Object[]} The new chain body\n */\n combineChainBody(data, chain, fields, outnames, trans) {\n return data;\n }\n\n /**\n * Coordinates the work of parsing a response and returning records. This is broken into 4 steps, which may be\n * overridden separately for fine-grained control. Each step can return either raw data or a promise.\n *\n * @protected\n *\n * @param {String|Object} resp The raw data associated with the response\n * @param {Object} chain The combined parsed response data from this and all other requests made in the chain\n * @param {String[]} fields Array of requested field names (as they would appear in the response payload)\n * @param {String[]} outnames Array of field names as they will be represented in the data returned by this source,\n * including the namespace. This must be an array with the same length as `fields`\n * @param {Function[]} trans The collection of transformation functions to be run on selected fields.\n * This must be an array with the same length as `fields`\n * @returns {Promise} A promise that resolves to an object containing\n * request metadata (`headers: {}`), the consolidated data for plotting (`body: []`), and the individual responses that would be\n * returned by each source in the chain in isolation (`discrete: {}`)\n */\n parseResponse (resp, chain, fields, outnames, trans) {\n const source_id = this.source_id || this.constructor.name;\n if (!chain.discrete) {\n chain.discrete = {};\n }\n\n const json = typeof resp == 'string' ? JSON.parse(resp) : resp;\n\n // Perform the 4 steps of parsing the payload and return a combined chain object\n return Promise.resolve(this.normalizeResponse(json.data || json))\n .then((standardized) => {\n // Perform calculations on the data from just this source\n return Promise.resolve(this.annotateData(standardized, chain));\n }).then((data) => {\n return Promise.resolve(this.extractFields(data, fields, outnames, trans));\n }).then((one_source_body) => {\n // Store a copy of the data that would be returned by parsing this source in isolation (and taking the\n // fields array into account). This is useful when we want to re-use the source output in many ways.\n chain.discrete[source_id] = one_source_body;\n return Promise.resolve(this.combineChainBody(one_source_body, chain, fields, outnames, trans));\n }).then((new_body) => {\n return { header: chain.header || {}, discrete: chain.discrete, body: new_body };\n });\n }\n\n /**\n * Fetch the data from the specified data source, and apply transformations requested by an external consumer.\n * This is the public-facing datasource method that will most be called by the plot, but custom data sources will\n * almost never want to override this method directly- more specific hooks are provided to control individual pieces\n * of the request lifecycle.\n *\n * @private\n * @param {Object} state The current \"state\" of the plot, such as chromosome and start/end positions\n * @param {String[]} fields Array of field names that the plot has requested from this data source. (without the \"namespace\" prefix)\n * @param {String[]} outnames Array describing how the output data should refer to this field. This represents the\n * originally requested field name, including the namespace. This must be an array with the same length as `fields`\n * @param {Function[]} trans The collection of transformation functions to be run on selected fields.\n * This must be an array with the same length as `fields`\n * @returns {function} A callable operation that can be used as part of the data chain\n */\n getData(state, fields, outnames, trans) {\n if (this.preGetData) { // TODO try to remove this method if at all possible\n const pre = this.preGetData(state, fields, outnames, trans);\n if (this.pre) {\n state = pre.state || state;\n fields = pre.fields || fields;\n outnames = pre.outnames || outnames;\n trans = pre.trans || trans;\n }\n }\n\n return (chain) => {\n if (this.__dependentSource && chain && chain.body && !chain.body.length) {\n // A \"dependent\" source should not attempt to fire a request if there is no data for it to act on.\n // Therefore, it should simply return the previous data chain.\n return Promise.resolve(chain);\n }\n\n return this.getRequest(state, chain, fields).then((resp) => {\n return this.parseResponse(resp, chain, fields, outnames, trans);\n });\n };\n }\n}\n\n/**\n * Base source for LocusZoom data sources that receive their data over the web. Adds default config parameters\n * (and potentially other behavior) that are relevant to URL-based requests.\n */\nclass BaseApiAdapter extends BaseAdapter {\n parseInit(config) {\n super.parseInit(config);\n\n /** @member {String} */\n this.url = config.url;\n if (!this.url) {\n throw new Error('Source not initialized with required URL');\n }\n }\n}\n\n/**\n * Data Source for Association Data from the LocusZoom/ Portaldev API (or compatible). Defines how to make a requesr\n * @public\n */\nclass AssociationLZ extends BaseApiAdapter {\n preGetData (state, fields, outnames, trans) {\n // TODO: Modify internals to see if we can go without this method\n const id_field = this.params.id_field || 'id';\n [id_field, 'position'].forEach(function(x) {\n if (!fields.includes(x)) {\n fields.unshift(x);\n outnames.unshift(x);\n trans.unshift(null);\n }\n });\n return {fields: fields, outnames:outnames, trans:trans};\n }\n\n getURL (state, chain, fields) {\n const analysis = chain.header.analysis || this.params.source || this.params.analysis; // Old usages called this param \"analysis\"\n if (typeof analysis == 'undefined') {\n throw new Error('Association source must specify an analysis ID to plot');\n }\n return `${this.url}results/?filter=analysis in ${analysis} and chromosome in '${state.chr}' and position ge ${state.start} and position le ${state.end}`;\n }\n\n normalizeResponse (data) {\n // Some association sources do not sort their data in a predictable order, which makes it hard to reliably\n // align with other sources (such as LD). For performance reasons, sorting is an opt-in argument.\n // TODO: Consider more fine grained sorting control in the future. This was added as a very specific\n // workaround for the original T2D portal.\n data = super.normalizeResponse(data);\n if (this.params && this.params.sort && data.length && data[0]['position']) {\n data.sort(function (a, b) {\n return a['position'] - b['position'];\n });\n }\n return data;\n }\n}\n\n/**\n * Fetch linkage disequilibrium information from a UMich LDServer-compatible API\n *\n * This source is designed to connect its results to association data, and therefore depends on association data having\n * been loaded by a previous request in the data chain.\n *\n * In older versions of LocusZoom, this was known as \"LDServer\". A prior source (targeted at older APIs) has been removed.\n */\nclass LDServer extends BaseApiAdapter {\n constructor(config) {\n super(config);\n this.__dependentSource = true;\n }\n\n preGetData(state, fields) {\n if (fields.length > 1) {\n if (fields.length !== 2 || !fields.includes('isrefvar')) {\n throw new Error(`LD does not know how to get all fields: ${fields.join(', ')}`);\n }\n }\n }\n\n findMergeFields(chain) {\n // Find the fields (as provided by a previous step in the chain, like an association source) that will be needed to\n // combine LD data with existing information\n\n // Since LD information may be shared across multiple assoc sources with different namespaces,\n // we use regex to find columns to join on, rather than requiring exact matches\n const exactMatch = function (arr) {\n return function () {\n const regexes = arguments;\n for (let i = 0; i < regexes.length; i++) {\n const regex = regexes[i];\n const m = arr.filter(function (x) {\n return x.match(regex);\n });\n if (m.length) {\n return m[0];\n }\n }\n return null;\n };\n };\n let dataFields = {\n id: this.params.id_field,\n position: this.params.position_field,\n pvalue: this.params.pvalue_field,\n _names_:null,\n };\n if (chain && chain.body && chain.body.length > 0) {\n const names = Object.keys(chain.body[0]);\n const nameMatch = exactMatch(names);\n // Internally, fields are generally prefixed with the name of the source they come from.\n // If the user provides an id_field (like `variant`), it should work across data sources( `assoc1:variant`,\n // assoc2:variant), but not match fragments of other field names (assoc1:variant_thing)\n // Note: these lookups hard-code a couple of common fields that will work based on known APIs in the wild\n const id_match = dataFields.id && nameMatch(new RegExp(`${dataFields.id}\\\\b`));\n dataFields.id = id_match || nameMatch(/\\bvariant\\b/) || nameMatch(/\\bid\\b/);\n dataFields.position = dataFields.position || nameMatch(/\\bposition\\b/i, /\\bpos\\b/i);\n dataFields.pvalue = dataFields.pvalue || nameMatch(/\\bpvalue\\b/i, /\\blog_pvalue\\b/i);\n dataFields._names_ = names;\n }\n return dataFields;\n }\n\n findRequestedFields (fields, outnames) {\n // Assumption: all usages of this source will only ever ask for \"isrefvar\" or \"state\". This maps to output names.\n let obj = {};\n for (let i = 0; i < fields.length; i++) {\n if (fields[i] === 'isrefvar') {\n obj.isrefvarin = fields[i];\n obj.isrefvarout = outnames && outnames[i];\n } else {\n obj.ldin = fields[i];\n obj.ldout = outnames && outnames[i];\n }\n }\n return obj;\n }\n\n normalizeResponse (data) {\n // The LD API payload does not obey standard format conventions; do not try to transform it.\n return data;\n }\n\n /**\n * Get the LD reference variant, which by default will be the most significant hit in the assoc results\n * This will be used in making the original query to the LD server for pairwise LD information\n * @returns {*|string} The marker id (expected to be in `chr:pos_ref/alt` format) of the reference variant\n */\n getRefvar(state, chain, fields) {\n let findExtremeValue = function(records, pval_field) {\n // Finds the most significant hit (smallest pvalue, or largest -log10p). Will try to auto-detect the appropriate comparison.\n pval_field = pval_field || 'log_pvalue'; // The official LZ API returns log_pvalue\n const is_log = /log/.test(pval_field);\n let cmp;\n if (is_log) {\n cmp = function(a, b) {\n return a > b;\n };\n } else {\n cmp = function(a, b) {\n return a < b;\n };\n }\n let extremeVal = records[0][pval_field], extremeIdx = 0;\n for (let i = 1; i < records.length; i++) {\n if (cmp(records[i][pval_field], extremeVal)) {\n extremeVal = records[i][pval_field];\n extremeIdx = i;\n }\n }\n return extremeIdx;\n };\n\n let reqFields = this.findRequestedFields(fields);\n let refVar = reqFields.ldin;\n if (refVar === 'state') {\n refVar = state.ldrefvar || chain.header.ldrefvar || 'best';\n }\n if (refVar === 'best') {\n if (!chain.body) {\n throw new Error('No association data found to find best pvalue');\n }\n let keys = this.findMergeFields(chain);\n if (!keys.pvalue || !keys.id) {\n let columns = '';\n if (!keys.id) {\n columns += `${columns.length ? ', ' : ''}id`;\n }\n if (!keys.pvalue) {\n columns += `${columns.length ? ', ' : ''}pvalue`;\n }\n throw new Error(`Unable to find necessary column(s) for merge: ${columns} (available: ${keys._names_})`);\n }\n refVar = chain.body[findExtremeValue(chain.body, keys.pvalue)][keys.id];\n }\n return refVar;\n }\n\n getURL(state, chain, fields) {\n // Accept the following params in this.params:\n // - method (r, rsquare, cov)\n // - source (aka panel)\n // - population (ALL, AFR, EUR, etc)\n // - build\n // The LD source/pop can be overridden from plot.state for dynamic layouts\n const build = state.genome_build || this.params.build || 'GRCh37';\n let source = state.ld_source || this.params.source || '1000G';\n const population = state.ld_pop || this.params.population || 'ALL'; // LDServer panels will always have an ALL\n const method = this.params.method || 'rsquare';\n\n if (source === '1000G' && build === 'GRCh38') {\n // For build 38 (only), there is a newer/improved 1000G LD panel available that uses WGS data. Auto upgrade by default.\n source = '1000G-FRZ09';\n }\n\n validateBuildSource(this.constructor.name, build, null); // LD doesn't need to validate `source` option\n\n let refVar = this.getRefvar(state, chain, fields);\n // Some datasets, notably the Portal, use a different marker format.\n // Coerce it into one that will work with the LDServer API. (CHROM:POS_REF/ALT)\n const REGEX_MARKER = /^(?:chr)?([a-zA-Z0-9]+?)[_:-](\\d+)[_:|-]?(\\w+)?[/_:|-]?([^_]+)?_?(.*)?/;\n const match = refVar && refVar.match(REGEX_MARKER);\n\n if (!match) {\n throw new Error('Could not request LD for a missing or incomplete marker format');\n }\n const [original, chrom, pos, ref, alt] = match;\n // Currently, the LD server only accepts full variant specs; it won't return LD w/o ref+alt. Allowing\n // a partial match at most leaves room for potential future features.\n refVar = `${chrom}:${pos}`;\n if (ref && alt) {\n refVar += `_${ref}/${alt}`;\n }\n // Preserve the user-provided variant spec for use when matching to assoc data\n chain.header.ldrefvar = original;\n\n return [\n this.url, 'genome_builds/', build, '/references/', source, '/populations/', population, '/variants',\n '?correlation=', method,\n '&variant=', encodeURIComponent(refVar),\n '&chrom=', encodeURIComponent(state.chr),\n '&start=', encodeURIComponent(state.start),\n '&stop=', encodeURIComponent(state.end),\n ].join('');\n }\n\n combineChainBody(data, chain, fields, outnames, trans) {\n let keys = this.findMergeFields(chain);\n let reqFields = this.findRequestedFields(fields, outnames);\n if (!keys.position) {\n throw new Error(`Unable to find position field for merge: ${keys._names_}`);\n }\n const leftJoin = function (left, right, lfield, rfield) {\n let i = 0, j = 0;\n while (i < left.length && j < right.position2.length) {\n if (left[i][keys.position] === right.position2[j]) {\n left[i][lfield] = right[rfield][j];\n i++;\n j++;\n } else if (left[i][keys.position] < right.position2[j]) {\n i++;\n } else {\n j++;\n }\n }\n };\n const tagRefVariant = function (data, refvar, idfield, outrefname, outldname) {\n for (let i = 0; i < data.length; i++) {\n if (data[i][idfield] && data[i][idfield] === refvar) {\n data[i][outrefname] = 1;\n data[i][outldname] = 1; // For label/filter purposes, implicitly mark the ref var as LD=1 to itself\n } else {\n data[i][outrefname] = 0;\n }\n }\n };\n\n // LD servers vary slightly. Some report corr as \"rsquare\", others as \"correlation\"\n let corrField = data.rsquare ? 'rsquare' : 'correlation';\n leftJoin(chain.body, data, reqFields.ldout, corrField);\n if (reqFields.isrefvarin && chain.header.ldrefvar) {\n tagRefVariant(chain.body, chain.header.ldrefvar, keys.id, reqFields.isrefvarout, reqFields.ldout);\n }\n return chain.body;\n }\n\n fetchRequest(state, chain, fields) {\n // The API is paginated, but we need all of the data to render a plot. Depaginate and combine where appropriate.\n let url = this.getURL(state, chain, fields);\n let combined = { data: {} };\n let chainRequests = function (url) {\n return fetch(url).then().then((response) => {\n if (!response.ok) {\n throw new Error(response.statusText);\n }\n return response.text();\n }).then(function(payload) {\n payload = JSON.parse(payload);\n Object.keys(payload.data).forEach(function (key) {\n combined.data[key] = (combined.data[key] || []).concat(payload.data[key]);\n });\n if (payload.next) {\n return chainRequests(payload.next);\n }\n return combined;\n });\n };\n return chainRequests(url);\n }\n}\n\n/**\n * Data source for GWAS catalogs of known variants\n * @public\n * @class\n * @param {Object|String} init Configuration (URL or object)\n * @param {Object} [init.params] Optional configuration parameters\n * @param {Number} [init.params.source=2] The ID of the chosen catalog. Defaults to EBI GWAS catalog, GRCh37\n * @param {('strict'|'loose')} [init.params.match_type='strict'] Whether to match on exact variant, or just position.\n */\nclass GwasCatalogLZ extends BaseApiAdapter {\n constructor(config) {\n super(config);\n this.__dependentSource = true;\n }\n\n getURL(state, chain, fields) {\n // This is intended to be aligned with another source- we will assume they are always ordered by position, asc\n // (regardless of the actual match field)\n const build_option = state.genome_build || this.params.build;\n validateBuildSource(this.constructor.name, build_option, null); // Source can override build- not mutually exclusive\n\n // Most of our annotations will respect genome build before any other option.\n // But there can be more than one GWAS catalog version available in the same API, for the same build- an\n // explicit config option will always take\n // precedence.\n // See: http://portaldev.sph.umich.edu/api/v1/annotation/gwascatalog/?format=objects\n const default_source = (build_option === 'GRCh38') ? 5 : 6; // EBI GWAS catalog\n const source = this.params.source || default_source;\n return `${this.url }?format=objects&sort=pos&filter=id eq ${source} and chrom eq '${state.chr}' and pos ge ${state.start} and pos le ${state.end}`;\n }\n\n findMergeFields(records) {\n // Data from previous sources is already namespaced. Find the alignment field by matching.\n const knownFields = Object.keys(records);\n // Note: All API endoints involved only give results for 1 chromosome at a time; match is implied\n const posMatch = knownFields.find(function (item) {\n return item.match(/\\b(position|pos)\\b/i);\n });\n\n if (!posMatch) {\n throw new Error('Could not find data to align with GWAS catalog results');\n }\n return { 'pos': posMatch };\n }\n\n extractFields (data, fields, outnames, trans) {\n // Skip the \"individual field extraction\" step; extraction will be handled when building chain body instead\n return data;\n }\n\n combineChainBody(data, chain, fields, outnames, trans) {\n if (!data.length) {\n return chain.body;\n }\n\n // TODO: Better reuse options in the future. This source is very specifically tied to the PortalDev API, where\n // the field name is always \"log_pvalue\". Relatively few sites will write their own gwas-catalog endpoint.\n const decider = 'log_pvalue';\n const decider_out = outnames[fields.indexOf(decider)];\n\n function leftJoin(left, right, fields, outnames, trans) { // Add `fields` from `right` to `left`\n // Add a synthetic, un-namespaced field to all matching records\n const n_matches = left['n_catalog_matches'] || 0;\n left['n_catalog_matches'] = n_matches + 1;\n if (decider && left[decider_out] && left[decider_out] > right[decider]) {\n // There may be more than one GWAS catalog entry for the same SNP. This source is intended for a 1:1\n // annotation scenario, so for now it only joins the catalog entry that has the best -log10 pvalue\n return;\n }\n\n for (let j = 0; j < fields.length; j++) {\n const fn = fields[j];\n const outn = outnames[j];\n\n let val = right[fn];\n if (trans && trans[j]) {\n val = trans[j](val);\n }\n left[outn] = val;\n }\n }\n\n const chainNames = this.findMergeFields(chain.body[0]);\n const catNames = this.findMergeFields(data[0]);\n\n var i = 0, j = 0;\n while (i < chain.body.length && j < data.length) {\n var left = chain.body[i];\n var right = data[j];\n\n if (left[chainNames.pos] === right[catNames.pos]) {\n // There may be multiple catalog entries for each matching SNP; evaluate match one at a time\n leftJoin(left, right, fields, outnames, trans);\n j += 1;\n } else if (left[chainNames.pos] < right[catNames.pos]) {\n i += 1;\n } else {\n j += 1;\n }\n }\n return chain.body;\n }\n}\n\n/**\n * Data Source for Gene Data, as fetched from the LocusZoom/Portaldev API server (or compatible format)\n * @public\n */\nclass GeneLZ extends BaseApiAdapter {\n getURL(state, chain, fields) {\n const build = state.genome_build || this.params.build;\n let source = this.params.source;\n validateBuildSource(this.constructor.name, build, source);\n\n if (build) {\n // If build specified, we auto-select the best current portaldev API dataset for that build\n // If build is not specified, we use the exact source ID provided by the user.\n // See: https://portaldev.sph.umich.edu/api/v1/annotation/genes/sources/?format=objects\n source = (build === 'GRCh38') ? 4 : 5;\n }\n return `${this.url}?filter=source in ${source} and chrom eq '${state.chr}' and start le ${state.end} and end ge ${state.start}`;\n }\n\n normalizeResponse(data) {\n // Genes have a very complex internal data format. Bypass any record parsing, and provide the data layer with\n // the exact information returned by the API. (ignoring the fields array in the layout)\n return data;\n }\n\n extractFields(data, fields, outnames, trans) {\n return data;\n }\n}\n\n/**\n * Data Source for Gene Constraint Data, as fetched from the gnomAD server (or compatible)\n *\n * This is intended to be the second request in a chain, with special logic that connects it to Genes data\n * already fetched.\n *\n * @public\n*/\nclass GeneConstraintLZ extends BaseApiAdapter {\n constructor(config) {\n super(config);\n this.__dependentSource = true;\n }\n getURL() {\n // GraphQL API: request details are encoded in the body, not the URL\n return this.url;\n }\n getCacheKey(state, chain, fields) {\n const build = state.genome_build || this.params.build;\n // GraphQL API: request not defined solely by the URL\n // Gather the state params that govern constraint query for a given region.\n return `${this.url} ${state.chr} ${state.start} ${state.end} ${build}`;\n }\n\n normalizeResponse(data) {\n return data;\n }\n\n fetchRequest(state, chain, fields) {\n const build = state.genome_build || this.params.build;\n if (!build) {\n throw new Error(`Data source ${this.constructor.name} must specify a 'genome_build' option`);\n }\n\n const unique_gene_names = chain.body.reduce(\n // In rare cases, the same gene symbol may appear at multiple positions. (issue #179) We de-duplicate the\n // gene names to avoid issuing a malformed GraphQL query.\n function (acc, gene) {\n acc[gene.gene_name] = null;\n return acc;\n },\n {}\n );\n let query = Object.keys(unique_gene_names).map(function (gene_name) {\n // GraphQL alias names must match a specific set of allowed characters: https://stackoverflow.com/a/45757065/1422268\n const alias = `_${gene_name.replace(/[^A-Za-z0-9_]/g, '_')}`;\n // Each gene symbol is a separate graphQL query, grouped into one request using aliases\n return `${alias}: gene(gene_symbol: \"${gene_name}\", reference_genome: ${build}) { gnomad_constraint { exp_syn obs_syn syn_z oe_syn oe_syn_lower oe_syn_upper exp_mis obs_mis mis_z oe_mis oe_mis_lower oe_mis_upper exp_lof obs_lof pLI oe_lof oe_lof_lower oe_lof_upper } } `;\n });\n\n if (!query.length) {\n // If there are no genes, skip the network request\n return Promise.resolve({ data: null });\n }\n\n query = `{${query.join(' ')} }`; // GraphQL isn't quite JSON; items are separated by spaces but not commas\n const url = this.getURL(state, chain, fields);\n // See: https://graphql.org/learn/serving-over-http/\n const body = JSON.stringify({ query: query });\n const headers = { 'Content-Type': 'application/json' };\n\n // FIXME: The gnomAD API sometimes has temporary CORS changes that temporarily break the genes track\n // If request blocked, return a fake \"no data\" signal so the genes track can still render w/o constraint info\n return fetch(url, { method: 'POST', body, headers }).then((response) => {\n if (!response.ok) {\n return [];\n }\n return response.text();\n }).catch((err) => []);\n }\n\n combineChainBody(data, chain, fields, outnames, trans) {\n if (!data) {\n return chain;\n }\n\n chain.body.forEach(function(gene) {\n // Find payload keys that match gene names in this response\n const alias = `_${gene.gene_name.replace(/[^A-Za-z0-9_]/g, '_')}`; // aliases are modified gene names\n const constraint = data[alias] && data[alias]['gnomad_constraint']; // gnomad API has two ways of specifying missing data for a requested gene\n if (constraint) {\n // Add all fields from constraint data- do not override fields present in the gene source\n Object.keys(constraint).forEach(function (key) {\n let val = constraint[key];\n if (typeof gene[key] === 'undefined') {\n if (typeof val == 'number' && val.toString().includes('.')) {\n val = parseFloat(val.toFixed(2));\n }\n gene[key] = val; // These two sources are both designed to bypass namespacing\n }\n });\n }\n });\n return chain.body;\n }\n}\n\n/**\n * Data Source for Recombination Rate Data, as fetched from the LocusZoom API server (or compatible)\n * @public\n */\nclass RecombLZ extends BaseApiAdapter {\n getURL(state, chain, fields) {\n const build = state.genome_build || this.params.build;\n let source = this.params.source;\n validateBuildSource(this.constructor.SOURCE_NAME, build, source);\n\n if (build) { // If build specified, choose a known Portal API dataset IDs (build 37/38)\n source = (build === 'GRCh38') ? 16 : 15;\n }\n return `${this.url}?filter=id in ${source} and chromosome eq '${state.chr}' and position le ${state.end} and position ge ${state.start}`;\n }\n}\n\n/**\n * Data Source for static blobs of data as raw JS objects. This does not perform additional parsing, which is required\n * for some sources (eg when joining together LD and association data).\n *\n * Therefore it is the responsibility of the user to pass information in a format that can be read and\n * understood by the chosen plot- a StaticJSON source is rarely a drop-in replacement.\n *\n * This source is largely here for legacy reasons. More often, a convenient way to serve static data is as separate\n * JSON files to an existing source (with the JSON url in place of an API).\n * @public\n */\nclass StaticSource extends BaseAdapter {\n parseInit(data) {\n // Does not receive any config; the only argument is the raw data, embedded when source is created\n this._data = data;\n }\n getRequest(state, chain, fields) {\n return Promise.resolve(this._data);\n }\n}\n\n\n/**\n * Data source for PheWAS data retrieved from a LocusZoom/PortalDev compatible API\n * @public\n * @param {String[]} init.params.build This datasource expects to be provided the name of the genome build that will\n * be used to provide pheWAS results for this position. Note positions may not translate between builds.\n */\nclass PheWASLZ extends BaseApiAdapter {\n getURL(state, chain, fields) {\n const build = (state.genome_build ? [state.genome_build] : null) || this.params.build;\n if (!build || !Array.isArray(build) || !build.length) {\n throw new Error(['Data source', this.constructor.SOURCE_NAME, 'requires that you specify array of one or more desired genome build names'].join(' '));\n }\n const url = [\n this.url,\n \"?filter=variant eq '\", encodeURIComponent(state.variant), \"'&format=objects&\",\n build.map(function (item) {\n return `build=${encodeURIComponent(item)}`;\n }).join('&'),\n ];\n return url.join('');\n }\n}\n\n\n/**\n * Base class for \"connectors\"- this is meant to be subclassed, rather than used directly.\n *\n * A connector is a source that makes no server requests and caches no data of its own. Instead, it decides how to\n * combine data from other sources in the chain. Connectors are useful when we want to request (or calculate) some\n * useful piece of information once, but apply it to many different kinds of record types.\n *\n * Typically, a subclass will implement the field merging logic in `combineChainBody`.\n *\n * @public\n * @param {Object} init Configuration for this source\n * @param {Object} init.sources Specify how the hard-coded logic should find the data it relies on in the chain,\n * as {internal_name: chain_source_id} pairs. This allows writing a reusable connector that does not need to make\n * assumptions about what namespaces a source is using.\n * @type {*|Function}\n */\nclass ConnectorSource extends BaseAdapter {\n constructor(config) {\n super(config);\n\n if (!config || !config.sources) {\n throw new Error('Connectors must specify the data they require as init.sources = {internal_name: chain_source_id}} pairs');\n }\n\n /**\n * Tells the connector how to find the data it relies on\n *\n * For example, a connector that applies burden test information to the genes layer might specify:\n * {gene_ns: \"gene\", aggregation_ns: \"aggregation\"}\n *\n * @member {Object}\n */\n this._source_name_mapping = config.sources;\n\n // Validate that this source has been told how to find the required information\n const specified_ids = Object.keys(config.sources);\n /** @property {String[]} Specifies the sources that must be provided in the original config object */\n\n this._getRequiredSources().forEach((k) => {\n if (!specified_ids.includes(k)) {\n // TODO: Fix constructor.name usage in minified bundles\n throw new Error(`Configuration for ${this.constructor.name} must specify a source ID corresponding to ${k}`);\n }\n });\n }\n\n // Stub- connectors don't have their own url or data, so the defaults don't make sense\n parseInit() {}\n\n getRequest(state, chain, fields) {\n // Connectors do not request their own data by definition, but they *do* depend on other sources having been loaded\n // first. This method performs basic validation, and preserves the accumulated body from the chain so far.\n Object.keys(this._source_name_mapping).forEach((ns) => {\n const chain_source_id = this._source_name_mapping[ns];\n if (chain.discrete && !chain.discrete[chain_source_id]) {\n throw new Error(`${this.constructor.name} cannot be used before loading required data for: ${chain_source_id}`);\n }\n });\n return Promise.resolve(chain.body || []);\n }\n\n parseResponse(data, chain, fields, outnames, trans) {\n // A connector source does not update chain.discrete, but it may use it. It bypasses data formatting\n // and field selection (both are assumed to have been done already, by the previous sources this draws from)\n\n // Because of how the chain works, connectors are not very good at applying new transformations or namespacing.\n // Typically connectors are called with `connector_name:all` in the fields array.\n return Promise.resolve(this.combineChainBody(data, chain, fields, outnames, trans))\n .then(function(new_body) {\n return {header: chain.header || {}, discrete: chain.discrete || {}, body: new_body};\n });\n }\n\n combineChainBody(records, chain) {\n // Stub method: specifies how to combine the data\n throw new Error('This method must be implemented in a subclass');\n }\n\n /**\n * Helper method since ES6 doesn't support class fields\n * @private\n */\n _getRequiredSources() {\n throw new Error('Must specify an array that identifes the kind of data required by this source');\n }\n}\n\nexport { BaseAdapter, BaseApiAdapter };\n\nexport {\n AssociationLZ,\n ConnectorSource,\n GeneConstraintLZ,\n GeneLZ,\n GwasCatalogLZ,\n LDServer,\n PheWASLZ,\n RecombLZ,\n StaticSource,\n};\n","module.exports = raremetal;"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/ext/lz-credible-sets.min.js b/dist/ext/lz-credible-sets.min.js index f73f4c72..ef224835 100644 --- a/dist/ext/lz-credible-sets.min.js +++ b/dist/ext/lz-credible-sets.min.js @@ -1,3 +1,3 @@ -/*! Locuszoom 0.13.0-beta.2 */ -var LzCredibleSets=function(e){var t={};function a(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,a),r.l=!0,r.exports}return a.m=e,a.c=t,a.d=function(e,t,o){a.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,t){if(1&t&&(e=a(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(a.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)a.d(o,r,function(t){return e[t]}.bind(null,r));return o},a.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(t,"a",t),t},a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},a.p="",a(a.s=9)}({3:function(e,t){e.exports=gwasCredibleSets},9:function(e,t,a){"use strict";a.r(t);var o=a(3);function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function s(e,t){for(var a=0;a=a.params.significance_threshold})))return Promise.resolve([]);var s=[];try{for(var i=o.scoring.bayesFactors(n),c=o.scoring.normalizeProbabilities(i),l=o.marking.findCredibleSet(c,r),u=o.marking.rescaleCredibleSet(l),p=o.marking.markBoolean(l),d=0;dPosterior probability: {{{{namespace[credset]}}posterior_prob|scinotation|htmlescape}}{{/if}}",t)),e.Layouts.add("tooltip","annotation_credible_set",{namespace:{assoc:"assoc",credset:"credset"},closable:!0,show:{or:["highlighted","selected"]},hide:{and:["unhighlighted","unselected"]},html:"{{{{namespace[assoc]}}variant|htmlescape}}
P Value: {{{{namespace[assoc]}}log_pvalue|logtoscinotation|htmlescape}}

Posterior probability: {{{{namespace[credset]}}posterior_prob|scinotation|htmlescape}}"}),e.Layouts.add("data_layer","association_credible_set",((a=e.Layouts.get("data_layer","association_pvalues",{unnamespaced:!0,id:"associationcredibleset",namespace:{assoc:"assoc",credset:"credset",ld:"ld"},fill_opacity:.7,tooltip:e.Layouts.get("tooltip","association_credible_set",{unnamespaced:!0}),fields:["{{namespace[assoc]}}variant","{{namespace[assoc]}}position","{{namespace[assoc]}}log_pvalue","{{namespace[assoc]}}log_pvalue|logtoscinotation","{{namespace[assoc]}}ref_allele","{{namespace[credset]}}posterior_prob","{{namespace[credset]}}contrib_fraction","{{namespace[credset]}}is_member","{{namespace[ld]}}state","{{namespace[ld]}}isrefvar"],match:{send:"{{namespace[assoc]}}variant",receive:"{{namespace[assoc]}}variant"}})).color.unshift({field:"lz_highlight_match",scale_function:"if",parameters:{field_value:!0,then:"#FFf000"}}),a)),e.Layouts.add("data_layer","annotation_credible_set",{namespace:{assoc:"assoc",credset:"credset"},id:"annotationcredibleset",type:"annotation_track",id_field:"{{namespace[assoc]}}variant",x_axis:{field:"{{namespace[assoc]}}position"},color:[{field:"lz_highlight_match",scale_function:"if",parameters:{field_value:!0,then:"#001cee"}},"#00CC00"],fields:["{{namespace[assoc]}}variant","{{namespace[assoc]}}position","{{namespace[assoc]}}log_pvalue","{{namespace[credset]}}posterior_prob","{{namespace[credset]}}contrib_fraction","{{namespace[credset]}}is_member"],match:{send:"{{namespace[assoc]}}variant",receive:"{{namespace[assoc]}}variant"},filters:[{field:"{{namespace[credset]}}is_member",operator:"=",value:!0}],behaviors:{onmouseover:[{action:"set",status:"highlighted"}],onmouseout:[{action:"unset",status:"highlighted"}],onclick:[{action:"toggle",status:"selected",exclusive:!0}],onshiftclick:[{action:"toggle",status:"selected"}]},tooltip:e.Layouts.get("tooltip","annotation_credible_set",{unnamespaced:!0}),tooltip_positioning:"top"}),e.Layouts.add("panel","annotation_credible_set",{id:"annotationcredibleset",title:{text:"SNPs in 95% credible set",x:50,style:{"font-size":"14px"}},width:800,height:45,min_height:45,proportional_width:1,margin:{top:25,right:50,bottom:0,left:50},inner_border:"rgb(210, 210, 210)",toolbar:e.Layouts.get("toolbar","standard_panel",{unnamespaced:!0}),interaction:{drag_background_to_pan:!0,scroll_to_zoom:!0,x_linked:!0},data_layers:[e.Layouts.get("data_layer","annotation_credible_set",{unnamespaced:!0})]}),e.Layouts.add("panel","association_credible_set",function(){var t=e.Layouts.get("panel","association",{unnamespaced:!0,id:"associationcrediblesets",namespace:{assoc:"assoc",credset:"credset"},data_layers:[e.Layouts.get("data_layer","significance",{unnamespaced:!0}),e.Layouts.get("data_layer","recomb_rate",{unnamespaced:!0}),e.Layouts.get("data_layer","association_credible_set",{unnamespaced:!0})]});return t.toolbar.widgets.push({type:"display_options",position:"right",color:"blue",button_html:"Display options...",button_title:"Control how plot items are displayed",layer_name:"associationcredibleset",default_config_display_name:"Linkage Disequilibrium (default)",options:[{display_name:"95% credible set (boolean)",display:{point_shape:"circle",point_size:40,color:{field:"{{namespace[credset]}}is_member",scale_function:"if",parameters:{field_value:!0,then:"#00CC00",else:"#CCCCCC"}},legend:[{shape:"circle",color:"#00CC00",size:40,label:"In credible set",class:"lz-data_layer-scatter"},{shape:"circle",color:"#CCCCCC",size:40,label:"Not in credible set",class:"lz-data_layer-scatter"}]}},{display_name:"95% credible set (gradient by contribution)",display:{point_shape:"circle",point_size:40,color:[{field:"{{namespace[credset]}}contrib_fraction",scale_function:"if",parameters:{field_value:0,then:"#777777"}},{scale_function:"interpolate",field:"{{namespace[credset]}}contrib_fraction",parameters:{breaks:[0,1],values:["#fafe87","#9c0000"]}}],legend:[{shape:"circle",color:"#777777",size:40,label:"No contribution",class:"lz-data_layer-scatter"},{shape:"circle",color:"#fafe87",size:40,label:"Some contribution",class:"lz-data_layer-scatter"},{shape:"circle",color:"#9c0000",size:40,label:"Most contribution",class:"lz-data_layer-scatter"}]}}]}),t}()),e.Layouts.add("plot","association_credible_set",{state:{},width:800,height:450,responsive_resize:!0,min_region_scale:2e4,max_region_scale:1e6,toolbar:e.Layouts.get("toolbar","standard_association",{unnamespaced:!0}),panels:[e.Layouts.get("panel","association_credible_set",{unnamespaced:!0}),e.Layouts.get("panel","annotation_credible_set",{unnamespaced:!0}),e.Layouts.get("panel","genes",{unnamespaced:!0})]})}"undefined"!=typeof LocusZoom&&LocusZoom.use(d),t.default=d}}).default; +/*! Locuszoom 0.13.0-beta.3 */ +var LzCredibleSets=function(e){var t={};function a(s){if(t[s])return t[s].exports;var o=t[s]={i:s,l:!1,exports:{}};return e[s].call(o.exports,o,o.exports,a),o.l=!0,o.exports}return a.m=e,a.c=t,a.d=function(e,t,s){a.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:s})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,t){if(1&t&&(e=a(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var s=Object.create(null);if(a.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)a.d(s,o,function(t){return e[t]}.bind(null,o));return s},a.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(t,"a",t),t},a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},a.p="",a(a.s=10)}({10:function(e,t,a){"use strict";a.r(t);var s=a(3);function o(e){const t=e.Adapters.get("BaseAdapter");e.Adapters.add("CredibleSetLZ",class extends t{constructor(e){super(...arguments),this.dependentSource=!0}parseInit(e){if(super.parseInit(...arguments),!this.params.fields||!this.params.fields.log_pvalue)throw new Error(`Source config for ${this.constructor.SOURCE_NAME} must specify how to find 'fields.log_pvalue'`);this.params=Object.assign({threshold:.95,significance_threshold:7.301},this.params)}getCacheKey(e,t,a){return[e.credible_set_threshold||this.params.threshold,e.chr,e.start,e.end].join("_")}fetchRequest(e,t){if(!t.body.length)return Promise.resolve([]);const a=this,o=e.credible_set_threshold||this.params.threshold;if(void 0===t.body[0][a.params.fields.log_pvalue])throw new Error("Credible set source could not locate the required fields from a previous request.");const i=t.body.map(e=>e[a.params.fields.log_pvalue]);if(!i.some(e=>e>=a.params.significance_threshold))return Promise.resolve([]);const r=[];try{const e=s.scoring.bayesFactors(i),a=s.scoring.normalizeProbabilities(e),n=s.marking.findCredibleSet(a,o),c=s.marking.rescaleCredibleSet(n),l=s.marking.markBoolean(n);for(let e=0;e{{{{namespace[assoc]}}variant|htmlescape}}
P Value: {{{{namespace[assoc]}}log_pvalue|logtoscinotation|htmlescape}}
{{#if {{namespace[credset]}}posterior_prob}}
Posterior probability: {{{{namespace[credset]}}posterior_prob|scinotation|htmlescape}}{{/if}}"}),e.Layouts.add("data_layer","association_credible_set",function(){const t=e.Layouts.get("data_layer","association_pvalues",{unnamespaced:!0,id:"associationcredibleset",namespace:{assoc:"assoc",credset:"credset",ld:"ld"},fill_opacity:.7,tooltip:e.Layouts.get("tooltip","association_credible_set",{unnamespaced:!0}),fields:["{{namespace[assoc]}}variant","{{namespace[assoc]}}position","{{namespace[assoc]}}log_pvalue","{{namespace[assoc]}}log_pvalue|logtoscinotation","{{namespace[assoc]}}ref_allele","{{namespace[credset]}}posterior_prob","{{namespace[credset]}}contrib_fraction","{{namespace[credset]}}is_member","{{namespace[ld]}}state","{{namespace[ld]}}isrefvar"],match:{send:"{{namespace[assoc]}}variant",receive:"{{namespace[assoc]}}variant"}});return t.color.unshift({field:"lz_highlight_match",scale_function:"if",parameters:{field_value:!0,then:"#FFf000"}}),t}()),e.Layouts.add("data_layer","annotation_credible_set",{namespace:{assoc:"assoc",credset:"credset"},id:"annotationcredibleset",type:"annotation_track",id_field:"{{namespace[assoc]}}variant",x_axis:{field:"{{namespace[assoc]}}position"},color:[{field:"lz_highlight_match",scale_function:"if",parameters:{field_value:!0,then:"#001cee"}},"#00CC00"],fields:["{{namespace[assoc]}}variant","{{namespace[assoc]}}position","{{namespace[assoc]}}log_pvalue","{{namespace[credset]}}posterior_prob","{{namespace[credset]}}contrib_fraction","{{namespace[credset]}}is_member"],match:{send:"{{namespace[assoc]}}variant",receive:"{{namespace[assoc]}}variant"},filters:[{field:"{{namespace[credset]}}is_member",operator:"=",value:!0}],behaviors:{onmouseover:[{action:"set",status:"highlighted"}],onmouseout:[{action:"unset",status:"highlighted"}],onclick:[{action:"toggle",status:"selected",exclusive:!0}],onshiftclick:[{action:"toggle",status:"selected"}]},tooltip:e.Layouts.get("tooltip","annotation_credible_set",{unnamespaced:!0}),tooltip_positioning:"top"}),e.Layouts.add("panel","annotation_credible_set",{id:"annotationcredibleset",title:{text:"SNPs in 95% credible set",x:50,style:{"font-size":"14px"}},width:800,height:45,min_height:45,proportional_width:1,margin:{top:25,right:50,bottom:0,left:50},inner_border:"rgb(210, 210, 210)",toolbar:e.Layouts.get("toolbar","standard_panel",{unnamespaced:!0}),interaction:{drag_background_to_pan:!0,scroll_to_zoom:!0,x_linked:!0},data_layers:[e.Layouts.get("data_layer","annotation_credible_set",{unnamespaced:!0})]}),e.Layouts.add("panel","association_credible_set",function(){const t=e.Layouts.get("panel","association",{unnamespaced:!0,id:"associationcrediblesets",namespace:{assoc:"assoc",credset:"credset"},data_layers:[e.Layouts.get("data_layer","significance",{unnamespaced:!0}),e.Layouts.get("data_layer","recomb_rate",{unnamespaced:!0}),e.Layouts.get("data_layer","association_credible_set",{unnamespaced:!0})]});return t.toolbar.widgets.push({type:"display_options",position:"right",color:"blue",button_html:"Display options...",button_title:"Control how plot items are displayed",layer_name:"associationcredibleset",default_config_display_name:"Linkage Disequilibrium (default)",options:[{display_name:"95% credible set (boolean)",display:{point_shape:"circle",point_size:40,color:{field:"{{namespace[credset]}}is_member",scale_function:"if",parameters:{field_value:!0,then:"#00CC00",else:"#CCCCCC"}},legend:[{shape:"circle",color:"#00CC00",size:40,label:"In credible set",class:"lz-data_layer-scatter"},{shape:"circle",color:"#CCCCCC",size:40,label:"Not in credible set",class:"lz-data_layer-scatter"}]}},{display_name:"95% credible set (gradient by contribution)",display:{point_shape:"circle",point_size:40,color:[{field:"{{namespace[credset]}}contrib_fraction",scale_function:"if",parameters:{field_value:0,then:"#777777"}},{scale_function:"interpolate",field:"{{namespace[credset]}}contrib_fraction",parameters:{breaks:[0,1],values:["#fafe87","#9c0000"]}}],legend:[{shape:"circle",color:"#777777",size:40,label:"No contribution",class:"lz-data_layer-scatter"},{shape:"circle",color:"#fafe87",size:40,label:"Some contribution",class:"lz-data_layer-scatter"},{shape:"circle",color:"#9c0000",size:40,label:"Most contribution",class:"lz-data_layer-scatter"}]}}]}),t}()),e.Layouts.add("plot","association_credible_set",{state:{},width:800,height:450,responsive_resize:!0,min_region_scale:2e4,max_region_scale:1e6,toolbar:e.Layouts.get("toolbar","standard_association",{unnamespaced:!0}),panels:[e.Layouts.get("panel","association_credible_set",{unnamespaced:!0}),e.Layouts.get("panel","annotation_credible_set",{unnamespaced:!0}),e.Layouts.get("panel","genes",{unnamespaced:!0})]})}"undefined"!=typeof LocusZoom&&LocusZoom.use(o),t.default=o},3:function(e,t){e.exports=gwasCredibleSets}}).default; //# sourceMappingURL=lz-credible-sets.min.js.map \ No newline at end of file diff --git a/dist/ext/lz-credible-sets.min.js.map b/dist/ext/lz-credible-sets.min.js.map index 59fa2e21..8d0fa475 100644 --- a/dist/ext/lz-credible-sets.min.js.map +++ b/dist/ext/lz-credible-sets.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack://[name]/webpack/bootstrap","webpack://[name]/external \"gwasCredibleSets\"","webpack://[name]/./esm/ext/lz-credible-sets.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","gwasCredibleSets","install","LocusZoom","base","CredibleSetLZ","config","arguments","dependentSource","this","params","fields","log_pvalue","Error","constructor","SOURCE_NAME","assign","threshold","significance_threshold","state","chain","credible_set_threshold","chr","start","end","join","body","length","Promise","resolve","self","nlogpvals","map","item","some","val","credset_data","scores","scoring","bayesFactors","posteriorProbabilities","normalizeProbabilities","credibleSet","marking","findCredibleSet","credSetScaled","rescaleCredibleSet","credSetBool","markBoolean","push","posterior_prob","contrib_fraction","is_member","e","console","error","data","outnames","trans","src","dest","keys","forEach","attr","Adapters","add","Layouts","unnamespaced","html","namespace","closable","show","or","hide","and","id","fill_opacity","tooltip","match","send","receive","color","unshift","field","scale_function","parameters","field_value","then","type","id_field","x_axis","filters","operator","behaviors","onmouseover","action","status","onmouseout","onclick","exclusive","onshiftclick","tooltip_positioning","title","text","x","style","width","height","min_height","proportional_width","margin","top","right","bottom","left","inner_border","toolbar","interaction","drag_background_to_pan","scroll_to_zoom","x_linked","data_layers","widgets","position","button_html","button_title","layer_name","default_config_display_name","options","display_name","display","point_shape","point_size","else","legend","shape","size","label","class","breaks","values","responsive_resize","min_region_scale","max_region_scale","panels","use"],"mappings":"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","file":"ext/lz-credible-sets.min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 9);\n","module.exports = gwasCredibleSets;","/**\n Custom code used to power credible sets demonstration example. This is not part of the core LocusZoom library,\n but can be included as a standalone file.\n\n The page must incorporate and load all libraries before this file can be used, including:\n - Vendor assets\n - LocusZoom\n - gwas-credible-sets (available via NPM or a related CDN)\n @module\n*/\n\nimport {marking, scoring} from 'gwas-credible-sets';\n\nfunction install (LocusZoom) {\n const BaseAdapter = LocusZoom.Adapters.get('BaseAdapter');\n /**\n * Custom data source that calculates the 95% credible set based on provided data.\n * This source must be requested as the second step in a chain, after a previous step that returns fields required\n * for the calculation.\n *\n * @param {Object} init.params\n * @param {Object} init.params.fields\n * @param {String} init.params.fields.log_pvalue The name of the field containing -log10 pvalue information\n * @param {Number} [init.params.threshold=0.95] The credible set threshold (eg 95%). Will continue selecting SNPs\n * until the posterior probabilities add up to at least this fraction of the total.\n * @param {Number} [init.params.significance_threshold=7.301] Do not perform a credible set calculation for this\n * region unless AT LEAST ONE SNP (as -log10p) exceeds the line of GWAS signficance. Otherwise we are declaring a\n * credible set when there is no evidence of anything being significant at all. If one snp is significant, it will\n * create a credible set for the entire region; the resulting set may include things below the line of significance.\n */\n class CredibleSetLZ extends BaseAdapter {\n constructor(config) {\n super(...arguments);\n this.dependentSource = true; // Don't do calcs for a region with no assoc data\n }\n\n parseInit(config) {\n super.parseInit(...arguments);\n if (!(this.params.fields && this.params.fields.log_pvalue)) {\n throw new Error(`Source config for ${this.constructor.SOURCE_NAME} must specify how to find 'fields.log_pvalue'`);\n }\n\n // Set defaults. Default sig threshold is the line of GWAS significance. (as -log10p)\n this.params = Object.assign(\n { threshold: 0.95, significance_threshold: 7.301 },\n this.params\n );\n }\n\n getCacheKey (state, chain, fields) {\n const threshold = state.credible_set_threshold || this.params.threshold;\n return [threshold, state.chr, state.start, state.end].join('_');\n }\n\n fetchRequest(state, chain) {\n if (!chain.body.length) {\n // No credible set can be calculated because there is no association data for this region\n return Promise.resolve([]);\n }\n\n const self = this;\n // The threshold can be overridden dynamically via `plot.state`, or set when the source is created\n const threshold = state.credible_set_threshold || this.params.threshold;\n // Calculate raw bayes factors and posterior probabilities based on information returned from the API\n if (typeof chain.body[0][self.params.fields.log_pvalue] === 'undefined') {\n throw new Error('Credible set source could not locate the required fields from a previous request.');\n }\n const nlogpvals = chain.body.map((item) => item[self.params.fields.log_pvalue]);\n\n if (!nlogpvals.some((val) => val >= self.params.significance_threshold)) {\n // If NO points have evidence of significance, define the credible set to be empty\n // (rather than make a credible set that we don't think is meaningful)\n return Promise.resolve([]);\n }\n\n const credset_data = [];\n try {\n const scores = scoring.bayesFactors(nlogpvals);\n const posteriorProbabilities = scoring.normalizeProbabilities(scores);\n\n // Use scores to mark the credible set in various ways (depending on your visualization preferences,\n // some of these may not be needed)\n const credibleSet = marking.findCredibleSet(posteriorProbabilities, threshold);\n const credSetScaled = marking.rescaleCredibleSet(credibleSet);\n const credSetBool = marking.markBoolean(credibleSet);\n\n // Annotate each response record based on credible set membership\n for (let i = 0; i < chain.body.length; i++) {\n credset_data.push({\n posterior_prob: posteriorProbabilities[i],\n contrib_fraction: credSetScaled[i],\n is_member: credSetBool[i],\n });\n }\n } catch (e) {\n // If the calculation cannot be completed, return the data without annotation fields\n console.error(e);\n }\n return Promise.resolve(credset_data);\n }\n\n combineChainBody(data, chain, fields, outnames, trans) {\n // At this point namespacing has been applied; add the calculated fields for this source to the chain\n if (chain.body.length && data.length) {\n for (let i = 0; i < data.length; i++) {\n const src = data[i];\n const dest = chain.body[i];\n Object.keys(src).forEach(function (attr) {\n dest[attr] = src[attr];\n });\n }\n }\n return chain.body;\n }\n }\n\n\n LocusZoom.Adapters.add('CredibleSetLZ', CredibleSetLZ);\n\n // Add related layouts to the central global registry\n LocusZoom.Layouts.add('tooltip', 'association_credible_set', function () {\n // Extend a known tooltip with an extra row of info showing posterior probabilities\n const l = LocusZoom.Layouts.get('tooltip', 'standard_association', { unnamespaced: true });\n l.html += '{{#if {{namespace[credset]}}posterior_prob}}
Posterior probability: {{{{namespace[credset]}}posterior_prob|scinotation|htmlescape}}{{/if}}';\n return l;\n }());\n\n LocusZoom.Layouts.add('tooltip', 'annotation_credible_set', {\n namespace: { 'assoc': 'assoc', 'credset': 'credset' },\n closable: true,\n show: { or: ['highlighted', 'selected'] },\n hide: { and: ['unhighlighted', 'unselected'] },\n html: '{{{{namespace[assoc]}}variant|htmlescape}}
'\n + 'P Value: {{{{namespace[assoc]}}log_pvalue|logtoscinotation|htmlescape}}
' +\n '
Posterior probability: {{{{namespace[credset]}}posterior_prob|scinotation|htmlescape}}',\n });\n\n LocusZoom.Layouts.add('data_layer', 'association_credible_set', function () {\n const base = LocusZoom.Layouts.get('data_layer', 'association_pvalues', {\n unnamespaced: true,\n id: 'associationcredibleset',\n namespace: { 'assoc': 'assoc', 'credset': 'credset', 'ld': 'ld' },\n fill_opacity: 0.7,\n tooltip: LocusZoom.Layouts.get('tooltip', 'association_credible_set', { unnamespaced: true }),\n fields: [\n '{{namespace[assoc]}}variant', '{{namespace[assoc]}}position',\n '{{namespace[assoc]}}log_pvalue', '{{namespace[assoc]}}log_pvalue|logtoscinotation',\n '{{namespace[assoc]}}ref_allele',\n '{{namespace[credset]}}posterior_prob', '{{namespace[credset]}}contrib_fraction',\n '{{namespace[credset]}}is_member',\n '{{namespace[ld]}}state', '{{namespace[ld]}}isrefvar',\n ],\n match: { send: '{{namespace[assoc]}}variant', receive: '{{namespace[assoc]}}variant' },\n });\n base.color.unshift({\n field: 'lz_highlight_match', // Special field name whose presence triggers custom rendering\n scale_function: 'if',\n parameters: {\n field_value: true,\n then: '#FFf000',\n },\n });\n return base;\n }());\n\n LocusZoom.Layouts.add('data_layer', 'annotation_credible_set', {\n namespace: { 'assoc': 'assoc', 'credset': 'credset' },\n id: 'annotationcredibleset',\n type: 'annotation_track',\n id_field: '{{namespace[assoc]}}variant',\n x_axis: {\n field: '{{namespace[assoc]}}position',\n },\n color: [\n {\n field: 'lz_highlight_match', // Special field name whose presence triggers custom rendering\n scale_function: 'if',\n parameters: {\n field_value: true,\n then: '#001cee',\n },\n },\n '#00CC00',\n ],\n fields: ['{{namespace[assoc]}}variant', '{{namespace[assoc]}}position', '{{namespace[assoc]}}log_pvalue', '{{namespace[credset]}}posterior_prob', '{{namespace[credset]}}contrib_fraction', '{{namespace[credset]}}is_member'],\n match: { send: '{{namespace[assoc]}}variant', receive: '{{namespace[assoc]}}variant' },\n filters: [\n // Specify which points to show on the track. Any selection must satisfy ALL filters\n { field: '{{namespace[credset]}}is_member', operator: '=', value: true },\n ],\n behaviors: {\n onmouseover: [\n { action: 'set', status: 'highlighted' },\n ],\n onmouseout: [\n { action: 'unset', status: 'highlighted' },\n ],\n onclick: [\n { action: 'toggle', status: 'selected', exclusive: true },\n ],\n onshiftclick: [\n { action: 'toggle', status: 'selected' },\n ],\n },\n tooltip: LocusZoom.Layouts.get('tooltip', 'annotation_credible_set', { unnamespaced: true }),\n tooltip_positioning: 'top',\n });\n\n LocusZoom.Layouts.add('panel', 'annotation_credible_set', {\n id: 'annotationcredibleset',\n title: { text: 'SNPs in 95% credible set', x: 50, style: { 'font-size': '14px' } },\n width: 800,\n height: 45,\n min_height: 45,\n proportional_width: 1,\n margin: { top: 25, right: 50, bottom: 0, left: 50 },\n inner_border: 'rgb(210, 210, 210)',\n toolbar: LocusZoom.Layouts.get('toolbar', 'standard_panel', { unnamespaced: true }),\n interaction: {\n drag_background_to_pan: true,\n scroll_to_zoom: true,\n x_linked: true,\n },\n data_layers: [\n LocusZoom.Layouts.get('data_layer', 'annotation_credible_set', { unnamespaced: true }),\n ],\n });\n\n LocusZoom.Layouts.add('panel', 'association_credible_set', function () {\n const l = LocusZoom.Layouts.get('panel', 'association', {\n unnamespaced: true,\n id: 'associationcrediblesets',\n namespace: { 'assoc': 'assoc', 'credset': 'credset' },\n data_layers: [\n LocusZoom.Layouts.get('data_layer', 'significance', { unnamespaced: true }),\n LocusZoom.Layouts.get('data_layer', 'recomb_rate', { unnamespaced: true }),\n LocusZoom.Layouts.get('data_layer', 'association_credible_set', { unnamespaced: true }),\n ],\n });\n // Add \"display options\" button to control how credible set coloring is overlaid on the standard association plot\n l.toolbar.widgets.push(\n {\n type: 'display_options',\n position: 'right',\n color: 'blue',\n // Below: special config specific to this widget\n button_html: 'Display options...',\n button_title: 'Control how plot items are displayed',\n layer_name: 'associationcredibleset',\n default_config_display_name: 'Linkage Disequilibrium (default)', // display name for the default plot color option (allow user to revert to plot defaults)\n\n options: [\n {\n // First dropdown menu item\n display_name: '95% credible set (boolean)', // Human readable representation of field name\n display: { // Specify layout directives that control display of the plot for this option\n point_shape: 'circle',\n point_size: 40,\n color: {\n field: '{{namespace[credset]}}is_member',\n scale_function: 'if',\n parameters: {\n field_value: true,\n then: '#00CC00',\n else: '#CCCCCC',\n },\n },\n legend: [ // Tells the legend how to represent this display option\n {\n shape: 'circle',\n color: '#00CC00',\n size: 40,\n label: 'In credible set',\n class: 'lz-data_layer-scatter',\n },\n {\n shape: 'circle',\n color: '#CCCCCC',\n size: 40,\n label: 'Not in credible set',\n class: 'lz-data_layer-scatter',\n },\n ],\n },\n },\n {\n // Second option. The same plot- or even the same field- can be colored in more than one way.\n display_name: '95% credible set (gradient by contribution)',\n display: {\n point_shape: 'circle',\n point_size: 40,\n color: [\n {\n field: '{{namespace[credset]}}contrib_fraction',\n scale_function: 'if',\n parameters: {\n field_value: 0,\n then: '#777777',\n },\n },\n {\n scale_function: 'interpolate',\n field: '{{namespace[credset]}}contrib_fraction',\n parameters: {\n breaks: [0, 1],\n values: ['#fafe87', '#9c0000'],\n },\n },\n ],\n legend: [\n {\n shape: 'circle',\n color: '#777777',\n size: 40,\n label: 'No contribution',\n class: 'lz-data_layer-scatter',\n },\n {\n shape: 'circle',\n color: '#fafe87',\n size: 40,\n label: 'Some contribution',\n class: 'lz-data_layer-scatter',\n },\n {\n shape: 'circle',\n color: '#9c0000',\n size: 40,\n label: 'Most contribution',\n class: 'lz-data_layer-scatter',\n },\n ],\n },\n },\n ],\n }\n );\n return l;\n }());\n\n LocusZoom.Layouts.add('plot', 'association_credible_set', {\n state: {},\n width: 800,\n height: 450,\n responsive_resize: true,\n min_region_scale: 20000,\n max_region_scale: 1000000,\n toolbar: LocusZoom.Layouts.get('toolbar', 'standard_association', { unnamespaced: true }),\n panels: [\n LocusZoom.Layouts.get('panel', 'association_credible_set', { unnamespaced: true }),\n LocusZoom.Layouts.get('panel', 'annotation_credible_set', { unnamespaced: true }),\n LocusZoom.Layouts.get('panel', 'genes', { unnamespaced: true }),\n ],\n });\n\n}\n\n\nif (typeof LocusZoom !== 'undefined') {\n // Auto-register the plugin when included as a script tag. ES6 module users must register via LocusZoom.use()\n // eslint-disable-next-line no-undef\n LocusZoom.use(install);\n}\n\n\nexport default install;\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack://[name]/webpack/bootstrap","webpack://[name]/./esm/ext/lz-credible-sets.js","webpack://[name]/external \"gwasCredibleSets\""],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","install","LocusZoom","BaseAdapter","Adapters","add","config","super","arguments","this","dependentSource","parseInit","params","fields","log_pvalue","Error","constructor","SOURCE_NAME","assign","threshold","significance_threshold","state","chain","credible_set_threshold","chr","start","end","join","body","length","Promise","resolve","self","nlogpvals","map","item","some","val","credset_data","scores","bayesFactors","posteriorProbabilities","normalizeProbabilities","credibleSet","findCredibleSet","credSetScaled","rescaleCredibleSet","credSetBool","markBoolean","push","posterior_prob","contrib_fraction","is_member","e","console","error","data","outnames","trans","src","dest","keys","forEach","attr","Layouts","unnamespaced","html","namespace","closable","show","or","hide","and","base","id","fill_opacity","tooltip","match","send","receive","color","unshift","field","scale_function","parameters","field_value","then","type","id_field","x_axis","filters","operator","behaviors","onmouseover","action","status","onmouseout","onclick","exclusive","onshiftclick","tooltip_positioning","title","text","x","style","width","height","min_height","proportional_width","margin","top","right","bottom","left","inner_border","toolbar","interaction","drag_background_to_pan","scroll_to_zoom","x_linked","data_layers","widgets","position","button_html","button_title","layer_name","default_config_display_name","options","display_name","display","point_shape","point_size","else","legend","shape","size","label","class","breaks","values","responsive_resize","min_region_scale","max_region_scale","panels","use","gwasCredibleSets"],"mappings":"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","file":"ext/lz-credible-sets.min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 10);\n","/**\n Custom code used to power credible sets demonstration example. This is not part of the core LocusZoom library,\n but can be included as a standalone file.\n\n The page must incorporate and load all libraries before this file can be used, including:\n - Vendor assets\n - LocusZoom\n - gwas-credible-sets (available via NPM or a related CDN)\n @module\n*/\n\nimport {marking, scoring} from 'gwas-credible-sets';\n\nfunction install (LocusZoom) {\n const BaseAdapter = LocusZoom.Adapters.get('BaseAdapter');\n /**\n * Custom data source that calculates the 95% credible set based on provided data.\n * This source must be requested as the second step in a chain, after a previous step that returns fields required\n * for the calculation.\n *\n * @param {Object} init.params\n * @param {Object} init.params.fields\n * @param {String} init.params.fields.log_pvalue The name of the field containing -log10 pvalue information\n * @param {Number} [init.params.threshold=0.95] The credible set threshold (eg 95%). Will continue selecting SNPs\n * until the posterior probabilities add up to at least this fraction of the total.\n * @param {Number} [init.params.significance_threshold=7.301] Do not perform a credible set calculation for this\n * region unless AT LEAST ONE SNP (as -log10p) exceeds the line of GWAS signficance. Otherwise we are declaring a\n * credible set when there is no evidence of anything being significant at all. If one snp is significant, it will\n * create a credible set for the entire region; the resulting set may include things below the line of significance.\n */\n class CredibleSetLZ extends BaseAdapter {\n constructor(config) {\n super(...arguments);\n this.dependentSource = true; // Don't do calcs for a region with no assoc data\n }\n\n parseInit(config) {\n super.parseInit(...arguments);\n if (!(this.params.fields && this.params.fields.log_pvalue)) {\n throw new Error(`Source config for ${this.constructor.SOURCE_NAME} must specify how to find 'fields.log_pvalue'`);\n }\n\n // Set defaults. Default sig threshold is the line of GWAS significance. (as -log10p)\n this.params = Object.assign(\n { threshold: 0.95, significance_threshold: 7.301 },\n this.params\n );\n }\n\n getCacheKey (state, chain, fields) {\n const threshold = state.credible_set_threshold || this.params.threshold;\n return [threshold, state.chr, state.start, state.end].join('_');\n }\n\n fetchRequest(state, chain) {\n if (!chain.body.length) {\n // No credible set can be calculated because there is no association data for this region\n return Promise.resolve([]);\n }\n\n const self = this;\n // The threshold can be overridden dynamically via `plot.state`, or set when the source is created\n const threshold = state.credible_set_threshold || this.params.threshold;\n // Calculate raw bayes factors and posterior probabilities based on information returned from the API\n if (typeof chain.body[0][self.params.fields.log_pvalue] === 'undefined') {\n throw new Error('Credible set source could not locate the required fields from a previous request.');\n }\n const nlogpvals = chain.body.map((item) => item[self.params.fields.log_pvalue]);\n\n if (!nlogpvals.some((val) => val >= self.params.significance_threshold)) {\n // If NO points have evidence of significance, define the credible set to be empty\n // (rather than make a credible set that we don't think is meaningful)\n return Promise.resolve([]);\n }\n\n const credset_data = [];\n try {\n const scores = scoring.bayesFactors(nlogpvals);\n const posteriorProbabilities = scoring.normalizeProbabilities(scores);\n\n // Use scores to mark the credible set in various ways (depending on your visualization preferences,\n // some of these may not be needed)\n const credibleSet = marking.findCredibleSet(posteriorProbabilities, threshold);\n const credSetScaled = marking.rescaleCredibleSet(credibleSet);\n const credSetBool = marking.markBoolean(credibleSet);\n\n // Annotate each response record based on credible set membership\n for (let i = 0; i < chain.body.length; i++) {\n credset_data.push({\n posterior_prob: posteriorProbabilities[i],\n contrib_fraction: credSetScaled[i],\n is_member: credSetBool[i],\n });\n }\n } catch (e) {\n // If the calculation cannot be completed, return the data without annotation fields\n console.error(e);\n }\n return Promise.resolve(credset_data);\n }\n\n combineChainBody(data, chain, fields, outnames, trans) {\n // At this point namespacing has been applied; add the calculated fields for this source to the chain\n if (chain.body.length && data.length) {\n for (let i = 0; i < data.length; i++) {\n const src = data[i];\n const dest = chain.body[i];\n Object.keys(src).forEach(function (attr) {\n dest[attr] = src[attr];\n });\n }\n }\n return chain.body;\n }\n }\n\n\n LocusZoom.Adapters.add('CredibleSetLZ', CredibleSetLZ);\n\n // Add related layouts to the central global registry\n LocusZoom.Layouts.add('tooltip', 'association_credible_set', function () {\n // Extend a known tooltip with an extra row of info showing posterior probabilities\n const l = LocusZoom.Layouts.get('tooltip', 'standard_association', { unnamespaced: true });\n l.html += '{{#if {{namespace[credset]}}posterior_prob}}
Posterior probability: {{{{namespace[credset]}}posterior_prob|scinotation|htmlescape}}{{/if}}';\n return l;\n }());\n\n LocusZoom.Layouts.add('tooltip', 'annotation_credible_set', {\n namespace: { 'assoc': 'assoc', 'credset': 'credset' },\n closable: true,\n show: { or: ['highlighted', 'selected'] },\n hide: { and: ['unhighlighted', 'unselected'] },\n html: '{{{{namespace[assoc]}}variant|htmlescape}}
'\n + 'P Value: {{{{namespace[assoc]}}log_pvalue|logtoscinotation|htmlescape}}
' +\n '{{#if {{namespace[credset]}}posterior_prob}}
Posterior probability: {{{{namespace[credset]}}posterior_prob|scinotation|htmlescape}}{{/if}}',\n });\n\n LocusZoom.Layouts.add('data_layer', 'association_credible_set', function () {\n const base = LocusZoom.Layouts.get('data_layer', 'association_pvalues', {\n unnamespaced: true,\n id: 'associationcredibleset',\n namespace: { 'assoc': 'assoc', 'credset': 'credset', 'ld': 'ld' },\n fill_opacity: 0.7,\n tooltip: LocusZoom.Layouts.get('tooltip', 'association_credible_set', { unnamespaced: true }),\n fields: [\n '{{namespace[assoc]}}variant', '{{namespace[assoc]}}position',\n '{{namespace[assoc]}}log_pvalue', '{{namespace[assoc]}}log_pvalue|logtoscinotation',\n '{{namespace[assoc]}}ref_allele',\n '{{namespace[credset]}}posterior_prob', '{{namespace[credset]}}contrib_fraction',\n '{{namespace[credset]}}is_member',\n '{{namespace[ld]}}state', '{{namespace[ld]}}isrefvar',\n ],\n match: { send: '{{namespace[assoc]}}variant', receive: '{{namespace[assoc]}}variant' },\n });\n base.color.unshift({\n field: 'lz_highlight_match', // Special field name whose presence triggers custom rendering\n scale_function: 'if',\n parameters: {\n field_value: true,\n then: '#FFf000',\n },\n });\n return base;\n }());\n\n LocusZoom.Layouts.add('data_layer', 'annotation_credible_set', {\n namespace: { 'assoc': 'assoc', 'credset': 'credset' },\n id: 'annotationcredibleset',\n type: 'annotation_track',\n id_field: '{{namespace[assoc]}}variant',\n x_axis: {\n field: '{{namespace[assoc]}}position',\n },\n color: [\n {\n field: 'lz_highlight_match', // Special field name whose presence triggers custom rendering\n scale_function: 'if',\n parameters: {\n field_value: true,\n then: '#001cee',\n },\n },\n '#00CC00',\n ],\n fields: ['{{namespace[assoc]}}variant', '{{namespace[assoc]}}position', '{{namespace[assoc]}}log_pvalue', '{{namespace[credset]}}posterior_prob', '{{namespace[credset]}}contrib_fraction', '{{namespace[credset]}}is_member'],\n match: { send: '{{namespace[assoc]}}variant', receive: '{{namespace[assoc]}}variant' },\n filters: [\n // Specify which points to show on the track. Any selection must satisfy ALL filters\n { field: '{{namespace[credset]}}is_member', operator: '=', value: true },\n ],\n behaviors: {\n onmouseover: [\n { action: 'set', status: 'highlighted' },\n ],\n onmouseout: [\n { action: 'unset', status: 'highlighted' },\n ],\n onclick: [\n { action: 'toggle', status: 'selected', exclusive: true },\n ],\n onshiftclick: [\n { action: 'toggle', status: 'selected' },\n ],\n },\n tooltip: LocusZoom.Layouts.get('tooltip', 'annotation_credible_set', { unnamespaced: true }),\n tooltip_positioning: 'top',\n });\n\n LocusZoom.Layouts.add('panel', 'annotation_credible_set', {\n id: 'annotationcredibleset',\n title: { text: 'SNPs in 95% credible set', x: 50, style: { 'font-size': '14px' } },\n width: 800,\n height: 45,\n min_height: 45,\n proportional_width: 1,\n margin: { top: 25, right: 50, bottom: 0, left: 50 },\n inner_border: 'rgb(210, 210, 210)',\n toolbar: LocusZoom.Layouts.get('toolbar', 'standard_panel', { unnamespaced: true }),\n interaction: {\n drag_background_to_pan: true,\n scroll_to_zoom: true,\n x_linked: true,\n },\n data_layers: [\n LocusZoom.Layouts.get('data_layer', 'annotation_credible_set', { unnamespaced: true }),\n ],\n });\n\n LocusZoom.Layouts.add('panel', 'association_credible_set', function () {\n const l = LocusZoom.Layouts.get('panel', 'association', {\n unnamespaced: true,\n id: 'associationcrediblesets',\n namespace: { 'assoc': 'assoc', 'credset': 'credset' },\n data_layers: [\n LocusZoom.Layouts.get('data_layer', 'significance', { unnamespaced: true }),\n LocusZoom.Layouts.get('data_layer', 'recomb_rate', { unnamespaced: true }),\n LocusZoom.Layouts.get('data_layer', 'association_credible_set', { unnamespaced: true }),\n ],\n });\n // Add \"display options\" button to control how credible set coloring is overlaid on the standard association plot\n l.toolbar.widgets.push(\n {\n type: 'display_options',\n position: 'right',\n color: 'blue',\n // Below: special config specific to this widget\n button_html: 'Display options...',\n button_title: 'Control how plot items are displayed',\n layer_name: 'associationcredibleset',\n default_config_display_name: 'Linkage Disequilibrium (default)', // display name for the default plot color option (allow user to revert to plot defaults)\n\n options: [\n {\n // First dropdown menu item\n display_name: '95% credible set (boolean)', // Human readable representation of field name\n display: { // Specify layout directives that control display of the plot for this option\n point_shape: 'circle',\n point_size: 40,\n color: {\n field: '{{namespace[credset]}}is_member',\n scale_function: 'if',\n parameters: {\n field_value: true,\n then: '#00CC00',\n else: '#CCCCCC',\n },\n },\n legend: [ // Tells the legend how to represent this display option\n {\n shape: 'circle',\n color: '#00CC00',\n size: 40,\n label: 'In credible set',\n class: 'lz-data_layer-scatter',\n },\n {\n shape: 'circle',\n color: '#CCCCCC',\n size: 40,\n label: 'Not in credible set',\n class: 'lz-data_layer-scatter',\n },\n ],\n },\n },\n {\n // Second option. The same plot- or even the same field- can be colored in more than one way.\n display_name: '95% credible set (gradient by contribution)',\n display: {\n point_shape: 'circle',\n point_size: 40,\n color: [\n {\n field: '{{namespace[credset]}}contrib_fraction',\n scale_function: 'if',\n parameters: {\n field_value: 0,\n then: '#777777',\n },\n },\n {\n scale_function: 'interpolate',\n field: '{{namespace[credset]}}contrib_fraction',\n parameters: {\n breaks: [0, 1],\n values: ['#fafe87', '#9c0000'],\n },\n },\n ],\n legend: [\n {\n shape: 'circle',\n color: '#777777',\n size: 40,\n label: 'No contribution',\n class: 'lz-data_layer-scatter',\n },\n {\n shape: 'circle',\n color: '#fafe87',\n size: 40,\n label: 'Some contribution',\n class: 'lz-data_layer-scatter',\n },\n {\n shape: 'circle',\n color: '#9c0000',\n size: 40,\n label: 'Most contribution',\n class: 'lz-data_layer-scatter',\n },\n ],\n },\n },\n ],\n }\n );\n return l;\n }());\n\n LocusZoom.Layouts.add('plot', 'association_credible_set', {\n state: {},\n width: 800,\n height: 450,\n responsive_resize: true,\n min_region_scale: 20000,\n max_region_scale: 1000000,\n toolbar: LocusZoom.Layouts.get('toolbar', 'standard_association', { unnamespaced: true }),\n panels: [\n LocusZoom.Layouts.get('panel', 'association_credible_set', { unnamespaced: true }),\n LocusZoom.Layouts.get('panel', 'annotation_credible_set', { unnamespaced: true }),\n LocusZoom.Layouts.get('panel', 'genes', { unnamespaced: true }),\n ],\n });\n\n}\n\n\nif (typeof LocusZoom !== 'undefined') {\n // Auto-register the plugin when included as a script tag. ES6 module users must register via LocusZoom.use()\n // eslint-disable-next-line no-undef\n LocusZoom.use(install);\n}\n\n\nexport default install;\n","module.exports = gwasCredibleSets;"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/ext/lz-dynamic-urls.min.js b/dist/ext/lz-dynamic-urls.min.js index af6ae94c..f5867644 100644 --- a/dist/ext/lz-dynamic-urls.min.js +++ b/dist/ext/lz-dynamic-urls.min.js @@ -1,3 +1,3 @@ -/*! Locuszoom 0.13.0-beta.2 */ -var LzDynamicUrls=function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=6)}({6:function(t,e,n){"use strict";function r(t){var e={};if(t)for(var n=("?"===t[0]?t.substr(1):t).split("&"),r=0;r tag mode.\nconst all = {\n paramsFromUrl,\n extractValues: _extractValues,\n plotUpdatesUrl,\n plotWatchesUrl,\n};\n\nexport default all;\nexport { paramsFromUrl, _extractValues as extractValues, plotUpdatesUrl, plotWatchesUrl };\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack://[name]/webpack/bootstrap","webpack://[name]/./esm/ext/lz-dynamic-urls.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","_parseQueryParams","queryString","query","pairs","substr","split","length","pair","decodeURIComponent","_extractValues","data","mapping","reverse","ret","newMapping","keys","forEach","k","asName","_setStateFromUrlHandler","plot","stateData","applyState","_setUrlFromStateHandler","state","paramsFromUrl","window","location","search","plotWatchesUrl","callback","listener","event","urlData","addEventListener","trackExternalListener","plotUpdatesUrl","eventContext","oldParams","serializedPlotData","newParams","assign","some","paramsObj","map","encodeURIComponent","join","history","pushState","document","title","replaceState","on","all","extractValues"],"mappings":"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","file":"ext/lz-dynamic-urls.min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 6);\n","/**\n * Optional LocusZoom extension: must be included separately, and after LocusZoom has been loaded\n *\n * This plugin exports helper functions, but does not modify the global registry. It does not require `LocusZoom.use`.\n *\n * Demonstrates a mechanism by which the plot can be loaded to a specific initial state based on the URL query string\n * (and, optionally, to update the URL bar when the plot state changes, with back button support)\n *\n * This makes it possible to create \"direct links\" to a particular plot of interest (and go back to a previous state\n * as the user interacts with the page). Optionally, there is support for custom callbacks to connect the URL to\n * arbitrarily complex plot behaviors.\n * @module\n */\n\nfunction _serializeQueryParams(paramsObj) {\n // Serialize an object of parameter values into a query string\n // TODO: Improve support for array values v[]=1&v[]=2\n return `?${\n Object.keys(paramsObj).map(function(key) {\n return `${encodeURIComponent(key)}=${encodeURIComponent(paramsObj[key])}`;\n }).join('&')}`;\n}\n\nfunction _parseQueryParams(queryString) {\n // Parse a query string into an object of parameter values.\n // Does not attempt any type coercion; all values are, therefore, strings.\n // TODO future: Support arrays / params that specify more than one value\n const query = {};\n if (queryString) {\n const pairs = (queryString[0] === '?' ? queryString.substr(1) : queryString).split('&');\n for (let i = 0; i < pairs.length; i++) {\n const pair = pairs[i].split('=');\n query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || '');\n }\n }\n return query;\n}\n\n// A useful helper function for serializing values from a provided object\nfunction _extractValues(data, mapping, reverse) {\n // Use the mapping to convert between {stateField: urlParam} (or the reverse). Any fields not referenced in\n // the \"key\" side of the mapping will be omitted from the return value.\n // Likewise, will omit any requested keys that the source side of the mapping has no information for\n reverse = reverse || false;\n\n const ret = {};\n let newMapping = mapping;\n if (reverse) {\n newMapping = {};\n Object.keys(mapping).forEach(function(k) {\n newMapping[mapping[k]] = k;\n });\n }\n\n Object.keys(newMapping).forEach(function(k) {\n const asName = newMapping[k];\n if (Object.prototype.hasOwnProperty.call(data, k)) {\n ret[asName] = data[k];\n }\n\n });\n return ret;\n}\n\nfunction _setStateFromUrlHandler(plot, stateData) {\n // A default way to deal with URL changes: push all the params as state into plot and rerender\n // More complex handlers are possible- example, URL parameters could be used to add or remove data layers\n plot.applyState(stateData);\n}\n\nfunction _setUrlFromStateHandler(plot, mapping) {\n // Serialize and return basic query params based solely on information from plot.state\n // More complex handlers are possible- the serializer can extract any information desired because it is given\n // a direct reference to the plot object\n\n // This default method does not use the eventContext data, because so many things change plot.state without\n // officially triggering an event.\n return _extractValues(plot.state, mapping);\n}\n\n/**\n * Extract plot parameters from the URL query string. Very useful for setting up the plot on initial page load.\n * @param {object} mapping How to map elements of plot state to URL param fields. Hash of\n * {plotFieldName: urlParamName} entries (both values should be unique)\n * @param {string} [queryString='window.location.search'] The query string to parse\n * @returns {object} Plot parameter values\n */\nfunction paramsFromUrl(mapping, queryString) {\n // Internal helper function: second argument only used for unit testing\n queryString = queryString || window.location.search;\n const queryParams = _parseQueryParams(queryString);\n return _extractValues(queryParams, mapping, true);\n}\n\n/**\n * Allows the plot to monitor changes in the URL and take action when the URL changes.\n *\n * For example, this enables using the browser back button to jump to a previous plot after user interaction.\n *\n * @param {Plot} plot A reference to the LZ plot\n * @param {object} mapping How to map elements of plot state to URL param fields. Hash of\n * {plotFieldName: urlParamName} entries (both values should be unique)\n * @param {function} [callback] Specify how the plot acts on information read in from query params.\n * The default behavior is to push the data into `plot.state`\n * Signature is function(plot, plotDataFromQueryString)\n * @returns {function} The function handle for the new listener (allows cleanup if plot is removed later)\n */\nfunction plotWatchesUrl(plot, mapping, callback) {\n callback = callback || _setStateFromUrlHandler;\n\n const listener = function (event) {\n const urlData = paramsFromUrl(mapping);\n // Tell the plot what to do with the params extracted from the URL\n callback(plot, urlData);\n };\n window.addEventListener('popstate', listener);\n plot.trackExternalListener(window, 'popstate', listener);\n return listener;\n}\n\n/**\n * Update the URL whenever the plot state changes\n * @param {Plot} plot A reference to the LZ plot\n * @param {object} mapping How to map elements of plot state to URL param fields. Hash of\n * {plotFieldName: urlParamName} entries (both values should be unique)\n * @param {function} [callback] Specify how plot data will be serialized into query params\n * The default behavior is to extract all the URL params from plot.state as the only source.\n * Signature is function(plot, mapping, eventContext)\n * @returns {function} The function handle for the new listener (allows cleanup if plot is removed later)\n */\nfunction plotUpdatesUrl(plot, mapping, callback) {\n callback = callback || _setUrlFromStateHandler;\n // Note: this event only fires when applyState receives *new* information that would trigger a rerender.\n // Plot state is sometimes changed without the event being fired.\n const listener = function (eventContext) {\n const oldParams = _parseQueryParams(window.location.search);\n // Apply custom serialization to convert plot data to URL params\n const serializedPlotData = callback(plot, mapping, eventContext);\n const newParams = Object.assign({}, oldParams, serializedPlotData);\n\n const update = Object.keys(newParams).some(function (k) {\n // Not every state change would affect the URL. Allow type coercion since query is a string.\n // eslint-disable-next-line eqeqeq\n return (oldParams[k] != newParams[k]);\n });\n if (update) {\n const queryString = _serializeQueryParams(newParams);\n\n if (Object.keys(oldParams).length) {\n history.pushState({}, document.title, queryString);\n } else {\n // Prevent broken back behavior on first page load: the first time query params are set,\n // we don't generate a separate history entry\n history.replaceState({}, document.title, queryString);\n }\n\n }\n };\n plot.on('state_changed', listener);\n return listener;\n}\n\n// Slight build quirk: we use a single webpack file for all modules, but `libraryTarget` expects the entire\n// module to be exported as `default` in diff --git a/examples/interval_annotations.html b/examples/interval_annotations.html index 1686d410..2f2b9b3c 100644 --- a/examples/interval_annotations.html +++ b/examples/interval_annotations.html @@ -11,7 +11,7 @@ - + LocusZoom.js ~ Interval Annotations Example @@ -115,11 +115,6 @@

Top Hits

// Generate the LocusZoom plot var plot = LocusZoom.populate("#plot", data_sources, layout); - // Add a basic loader to each panel (one that shows when data is requested and hides when one rendering) - plot.layout.panels.forEach(function(panel){ - plot.panels[panel.id].addBasicLoader(); - }); - // Create a method to parse a region string into a 600Kb genome range and load it function jumpTo(region) { var target = region.split(":"); diff --git a/examples/js/aggregation-tests-example-page.js b/examples/js/aggregation-tests-example-page.js index 84e30dd5..a40771f2 100644 --- a/examples/js/aggregation-tests-example-page.js +++ b/examples/js/aggregation-tests-example-page.js @@ -221,10 +221,6 @@ function createDisplayWidgets(label_store, context) { layout = customizePlotLayout(layout); const plot = LocusZoom.populate('#lz-plot', data_sources, layout); - // Add a basic loader to each panel (one that shows when data is requested and hides when one rendering) - plot.layout.panels.forEach(function(panel) { - plot.panels[panel.id].addBasicLoader(); - }); // Changes in the plot can be reflected in the URL, and vice versa (eg browser back button can go back to // a previously viewed region) diff --git a/examples/misc/covariates_model.html b/examples/misc/covariates_model.html index 1f1d5707..0138d2d6 100644 --- a/examples/misc/covariates_model.html +++ b/examples/misc/covariates_model.html @@ -101,11 +101,6 @@

Top Hits

// Generate the LocusZoom plot var plot = LocusZoom.populate("#plot", data_sources, layout); - // Add a basic loader to each panel (one that shows when data is requested and hides when one rendering) - plot.layout.panels.forEach(function(panel){ - plot.panels[panel.id].addBasicLoader(); - }); - // Create a method to parse a region string into a 600Kb genome range and load it function jumpTo(region) { var target = region.split(":"); diff --git a/examples/multiple_phenotypes_layered.html b/examples/multiple_phenotypes_layered.html index e81f3bd5..1102634c 100644 --- a/examples/multiple_phenotypes_layered.html +++ b/examples/multiple_phenotypes_layered.html @@ -133,11 +133,6 @@

Top Hits

// Generate the LocusZoom plot var plot = LocusZoom.populate("#plot", data_sources, layout); - // Add a basic loader to each panel (one that shows when data is requested and hides when one rendering) - plot.layout.panels.forEach(function(panel){ - plot.panels[panel.id].addBasicLoader(); - }); - // Create a method to parse a region string into a 600Kb genome range and load it function jumpTo(region) { var target = region.split(":"); diff --git a/examples/phewas_forest.html b/examples/phewas_forest.html index 0791c523..20d0e6d1 100644 --- a/examples/phewas_forest.html +++ b/examples/phewas_forest.html @@ -1,5 +1,5 @@ - + @@ -7,9 +7,11 @@ + - + + LocusZoom.js ~ PheWAS (Forest) Example diff --git a/index.html b/index.html index dc612c61..cb319ccc 100644 --- a/index.html +++ b/index.html @@ -76,7 +76,7 @@

Get LocusZoom.js

CSS
@@ -96,7 +96,7 @@
Dependencies
Javascript
@@ -244,11 +244,6 @@
Multiple Phenotypes (Layered)
LzDynamicUrls.plotUpdatesUrl(plot, stateUrlMapping); LzDynamicUrls.plotWatchesUrl(plot, stateUrlMapping); - // Add a basic loader to each panel (one that shows when data is requested and hides when one rendering) - plot.layout.panels.forEach(function(panel){ - plot.panels[panel.id].addBasicLoader(); - }); - // Create a method to parse a region string into a 600Kb genome range and load it function jumpTo(region) { var target = region.split(":"); diff --git a/package-lock.json b/package-lock.json index 92689c08..3d6b280c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "locuszoom", - "version": "0.13.0-beta.2", + "version": "0.13.0-beta.3", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -14,69 +14,60 @@ } }, "@babel/compat-data": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.11.0.tgz", - "integrity": "sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ==", - "dev": true, - "requires": { - "browserslist": "^4.12.0", - "invariant": "^2.2.4", - "semver": "^5.5.0" - } + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.7.tgz", + "integrity": "sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw==", + "dev": true }, "@babel/core": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.1.tgz", - "integrity": "sha512-XqF7F6FWQdKGGWAzGELL+aCO1p+lRY5Tj5/tbT3St1G8NaH70jhhDIKknIZaDans0OQBG5wRAldROLHSt44BgQ==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz", + "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.0", - "@babel/helper-module-transforms": "^7.11.0", - "@babel/helpers": "^7.10.4", - "@babel/parser": "^7.11.1", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.11.0", - "@babel/types": "^7.11.0", + "@babel/generator": "^7.12.10", + "@babel/helper-module-transforms": "^7.12.1", + "@babel/helpers": "^7.12.5", + "@babel/parser": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.10", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", "json5": "^2.1.2", "lodash": "^4.17.19", - "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" }, "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } + "@babel/parser": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.10.tgz", + "integrity": "sha512-PJdRPwyoOqFAWfLytxrWwGrAxghCgh/yTNCYciOz8QgjflA7aZhECPZAa2VUedKg2+QMWkI0L9lynh2SNmNEgA==", + "dev": true } } }, "@babel/generator": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz", - "integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.10.tgz", + "integrity": "sha512-6mCdfhWgmqLdtTkhXjnIz0LcdVCd26wS2JXRtj2XY0u5klDsXBREA/pG5NVOuVnF2LUrBGNFtQkIqqTbblg0ww==", "dev": true, "requires": { - "@babel/types": "^7.11.0", + "@babel/types": "^7.12.10", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, "@babel/helper-annotate-as-pure": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", - "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz", + "integrity": "sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.10" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { @@ -90,41 +81,38 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz", - "integrity": "sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz", + "integrity": "sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw==", "dev": true, "requires": { - "@babel/compat-data": "^7.10.4", - "browserslist": "^4.12.0", - "invariant": "^2.2.4", - "levenary": "^1.1.1", + "@babel/compat-data": "^7.12.5", + "@babel/helper-validator-option": "^7.12.1", + "browserslist": "^4.14.5", "semver": "^5.5.0" } }, "@babel/helper-create-class-features-plugin": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz", - "integrity": "sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz", + "integrity": "sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w==", "dev": true, "requires": { "@babel/helper-function-name": "^7.10.4", - "@babel/helper-member-expression-to-functions": "^7.10.5", + "@babel/helper-member-expression-to-functions": "^7.12.1", "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-replace-supers": "^7.12.1", "@babel/helper-split-export-declaration": "^7.10.4" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz", - "integrity": "sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz", + "integrity": "sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-regex": "^7.10.4", - "regexpu-core": "^4.7.0" + "regexpu-core": "^4.7.1" } }, "@babel/helper-define-map": { @@ -139,13 +127,12 @@ } }, "@babel/helper-explode-assignable-expression": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.4.tgz", - "integrity": "sha512-4K71RyRQNPRrR85sr5QY4X3VwG4wtVoXZB9+L3r1Gp38DhELyHCtovqydRi7c1Ovb17eRGiQ/FD5s8JdU0Uy5A==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.1.tgz", + "integrity": "sha512-dmUwH8XmlrUpVqgtZ737tK88v07l840z9j3OEhCLwKTkjlvKpfqXVIZ0wpK3aeOxspwGrf/5AP5qLx4rO3w5rA==", "dev": true, "requires": { - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.1" } }, "@babel/helper-function-name": { @@ -160,12 +147,12 @@ } }, "@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", + "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.10" } }, "@babel/helper-hoist-variables": { @@ -178,45 +165,47 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz", - "integrity": "sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", "dev": true, "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.12.7" } }, "@babel/helper-module-imports": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", - "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", + "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.5" } }, "@babel/helper-module-transforms": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", - "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", + "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-module-imports": "^7.12.1", + "@babel/helper-replace-supers": "^7.12.1", + "@babel/helper-simple-access": "^7.12.1", "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/helper-validator-identifier": "^7.10.4", "@babel/template": "^7.10.4", - "@babel/types": "^7.11.0", + "@babel/traverse": "^7.12.1", + "@babel/types": "^7.12.1", "lodash": "^4.17.19" } }, "@babel/helper-optimise-call-expression": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", - "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", + "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.10" } }, "@babel/helper-plugin-utils": { @@ -225,57 +214,45 @@ "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", "dev": true }, - "@babel/helper-regex": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.5.tgz", - "integrity": "sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg==", - "dev": true, - "requires": { - "lodash": "^4.17.19" - } - }, "@babel/helper-remap-async-to-generator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.4.tgz", - "integrity": "sha512-86Lsr6NNw3qTNl+TBcF1oRZMaVzJtbWTyTko+CQL/tvNvcGYEFKbLXDPxtW0HKk3McNOk4KzY55itGWCAGK5tg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz", + "integrity": "sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.10.4", "@babel/helper-wrap-function": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.1" } }, "@babel/helper-replace-supers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", - "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz", + "integrity": "sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-member-expression-to-functions": "^7.12.1", "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/traverse": "^7.12.5", + "@babel/types": "^7.12.5" } }, "@babel/helper-simple-access": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", - "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", + "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", "dev": true, "requires": { - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.1" } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz", - "integrity": "sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz", + "integrity": "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==", "dev": true, "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.12.1" } }, "@babel/helper-split-export-declaration": { @@ -293,10 +270,16 @@ "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", "dev": true }, + "@babel/helper-validator-option": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.1.tgz", + "integrity": "sha512-YpJabsXlJVWP0USHjnC/AQDTLlZERbON577YUVO/wLpqyj6HAtVYnWaQaN0iUN+1/tWn3c+uKKXjRut5115Y2A==", + "dev": true + }, "@babel/helper-wrap-function": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz", - "integrity": "sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug==", + "version": "7.12.3", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.12.3.tgz", + "integrity": "sha512-Cvb8IuJDln3rs6tzjW3Y8UeelAOdnpB8xtQ4sme2MSZ9wOxrbThporC0y/EtE16VAtoyEfLM404Xr1e0OOp+ow==", "dev": true, "requires": { "@babel/helper-function-name": "^7.10.4", @@ -306,14 +289,14 @@ } }, "@babel/helpers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", - "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", + "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", "dev": true, "requires": { "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/traverse": "^7.12.5", + "@babel/types": "^7.12.5" } }, "@babel/highlight": { @@ -359,36 +342,36 @@ } }, "@babel/parser": { - "version": "7.11.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz", - "integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.10.tgz", + "integrity": "sha512-PJdRPwyoOqFAWfLytxrWwGrAxghCgh/yTNCYciOz8QgjflA7aZhECPZAa2VUedKg2+QMWkI0L9lynh2SNmNEgA==", "dev": true }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz", - "integrity": "sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.1.tgz", + "integrity": "sha512-d+/o30tJxFxrA1lhzJqiUcEJdI6jKlNregCv5bASeGf2Q4MXmnwH7viDo7nhx1/ohf09oaH8j1GVYG/e3Yqk6A==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.10.4", + "@babel/helper-remap-async-to-generator": "^7.12.1", "@babel/plugin-syntax-async-generators": "^7.8.0" } }, "@babel/plugin-proposal-class-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz", - "integrity": "sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz", + "integrity": "sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.4", + "@babel/helper-create-class-features-plugin": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-proposal-dynamic-import": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz", - "integrity": "sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz", + "integrity": "sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -396,9 +379,9 @@ } }, "@babel/plugin-proposal-export-namespace-from": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.4.tgz", - "integrity": "sha512-aNdf0LY6/3WXkhh0Fdb6Zk9j1NMD8ovj3F6r0+3j837Pn1S1PdNtcwJ5EG9WkVPNHPxyJDaxMaAOVq4eki0qbg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz", + "integrity": "sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -406,9 +389,9 @@ } }, "@babel/plugin-proposal-json-strings": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz", - "integrity": "sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz", + "integrity": "sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -416,9 +399,9 @@ } }, "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.11.0.tgz", - "integrity": "sha512-/f8p4z+Auz0Uaf+i8Ekf1iM7wUNLcViFUGiPxKeXvxTSl63B875YPiVdUDdem7hREcI0E0kSpEhS8tF5RphK7Q==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz", + "integrity": "sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -426,9 +409,9 @@ } }, "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz", - "integrity": "sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz", + "integrity": "sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -436,9 +419,9 @@ } }, "@babel/plugin-proposal-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz", - "integrity": "sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.7.tgz", + "integrity": "sha512-8c+uy0qmnRTeukiGsjLGy6uVs/TFjJchGXUeBqlG4VWYOdJWkhhVPdQ3uHwbmalfJwv2JsV0qffXP4asRfL2SQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -446,20 +429,20 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz", - "integrity": "sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz", + "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.10.4" + "@babel/plugin-transform-parameters": "^7.12.1" } }, "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz", - "integrity": "sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz", + "integrity": "sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -467,33 +450,33 @@ } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz", - "integrity": "sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.7.tgz", + "integrity": "sha512-4ovylXZ0PWmwoOvhU2vhnzVNnm88/Sm9nx7V8BPgMvAzn5zDou3/Awy0EjglyubVHasJj+XCEkr/r1X3P5elCA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", "@babel/plugin-syntax-optional-chaining": "^7.8.0" } }, "@babel/plugin-proposal-private-methods": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz", - "integrity": "sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz", + "integrity": "sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.4", + "@babel/helper-create-class-features-plugin": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz", - "integrity": "sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz", + "integrity": "sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-create-regexp-features-plugin": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, @@ -507,9 +490,9 @@ } }, "@babel/plugin-syntax-class-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz", - "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz", + "integrity": "sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" @@ -597,56 +580,56 @@ } }, "@babel/plugin-syntax-top-level-await": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz", - "integrity": "sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz", + "integrity": "sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz", - "integrity": "sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz", + "integrity": "sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz", - "integrity": "sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz", + "integrity": "sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-module-imports": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.10.4" + "@babel/helper-remap-async-to-generator": "^7.12.1" } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz", - "integrity": "sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz", + "integrity": "sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz", - "integrity": "sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.1.tgz", + "integrity": "sha512-zJyAC9sZdE60r1nVQHblcfCj29Dh2Y0DOvlMkcqSo0ckqjiCwNiUezUKw+RjOCwGfpLRwnAeQ2XlLpsnGkvv9w==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-classes": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz", - "integrity": "sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz", + "integrity": "sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.10.4", @@ -654,52 +637,52 @@ "@babel/helper-function-name": "^7.10.4", "@babel/helper-optimise-call-expression": "^7.10.4", "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-replace-supers": "^7.12.1", "@babel/helper-split-export-declaration": "^7.10.4", "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz", - "integrity": "sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz", + "integrity": "sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-destructuring": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz", - "integrity": "sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz", + "integrity": "sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz", - "integrity": "sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz", + "integrity": "sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-create-regexp-features-plugin": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz", - "integrity": "sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz", + "integrity": "sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz", - "integrity": "sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz", + "integrity": "sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug==", "dev": true, "requires": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4", @@ -707,18 +690,18 @@ } }, "@babel/plugin-transform-for-of": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz", - "integrity": "sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz", + "integrity": "sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz", - "integrity": "sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz", + "integrity": "sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw==", "dev": true, "requires": { "@babel/helper-function-name": "^7.10.4", @@ -726,225 +709,224 @@ } }, "@babel/plugin-transform-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz", - "integrity": "sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz", + "integrity": "sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz", - "integrity": "sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz", + "integrity": "sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz", - "integrity": "sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz", + "integrity": "sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.10.5", + "@babel/helper-module-transforms": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz", - "integrity": "sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz", + "integrity": "sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.10.4", + "@babel/helper-module-transforms": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-simple-access": "^7.12.1", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz", - "integrity": "sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz", + "integrity": "sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q==", "dev": true, "requires": { "@babel/helper-hoist-variables": "^7.10.4", - "@babel/helper-module-transforms": "^7.10.5", + "@babel/helper-module-transforms": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-validator-identifier": "^7.10.4", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz", - "integrity": "sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz", + "integrity": "sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.10.4", + "@babel/helper-module-transforms": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz", - "integrity": "sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz", + "integrity": "sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.12.1" } }, "@babel/plugin-transform-new-target": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz", - "integrity": "sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz", + "integrity": "sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-object-super": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz", - "integrity": "sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz", + "integrity": "sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4" + "@babel/helper-replace-supers": "^7.12.1" } }, "@babel/plugin-transform-parameters": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz", - "integrity": "sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz", + "integrity": "sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.10.4", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-property-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz", - "integrity": "sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz", + "integrity": "sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-regenerator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz", - "integrity": "sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz", + "integrity": "sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng==", "dev": true, "requires": { "regenerator-transform": "^0.14.2" } }, "@babel/plugin-transform-reserved-words": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz", - "integrity": "sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz", + "integrity": "sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz", - "integrity": "sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz", + "integrity": "sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-spread": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz", - "integrity": "sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz", + "integrity": "sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0" + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz", - "integrity": "sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.7.tgz", + "integrity": "sha512-VEiqZL5N/QvDbdjfYQBhruN0HYjSPjC4XkeqW4ny/jNtH9gcbgaqBIXYEZCNnESMAGs0/K/R7oFGMhOyu/eIxg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-regex": "^7.10.4" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-template-literals": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz", - "integrity": "sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz", + "integrity": "sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz", - "integrity": "sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.10.tgz", + "integrity": "sha512-JQ6H8Rnsogh//ijxspCjc21YPd3VLVoYtAwv3zQmqAt8YGYUtdo5usNhdl4b9/Vir2kPFZl6n1h0PfUz4hJhaA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-unicode-escapes": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz", - "integrity": "sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz", + "integrity": "sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz", - "integrity": "sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz", + "integrity": "sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-create-regexp-features-plugin": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/preset-env": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.11.0.tgz", - "integrity": "sha512-2u1/k7rG/gTh02dylX2kL3S0IJNF+J6bfDSp4DI2Ma8QN6Y9x9pmAax59fsCk6QUQG0yqH47yJWA+u1I1LccAg==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.10.tgz", + "integrity": "sha512-Gz9hnBT/tGeTE2DBNDkD7BiWRELZt+8lSysHuDwmYXUIvtwZl0zI+D6mZgXZX0u8YBlLS4tmai9ONNY9tjRgRA==", "dev": true, "requires": { - "@babel/compat-data": "^7.11.0", - "@babel/helper-compilation-targets": "^7.10.4", - "@babel/helper-module-imports": "^7.10.4", + "@babel/compat-data": "^7.12.7", + "@babel/helper-compilation-targets": "^7.12.5", + "@babel/helper-module-imports": "^7.12.5", "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-proposal-async-generator-functions": "^7.10.4", - "@babel/plugin-proposal-class-properties": "^7.10.4", - "@babel/plugin-proposal-dynamic-import": "^7.10.4", - "@babel/plugin-proposal-export-namespace-from": "^7.10.4", - "@babel/plugin-proposal-json-strings": "^7.10.4", - "@babel/plugin-proposal-logical-assignment-operators": "^7.11.0", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4", - "@babel/plugin-proposal-numeric-separator": "^7.10.4", - "@babel/plugin-proposal-object-rest-spread": "^7.11.0", - "@babel/plugin-proposal-optional-catch-binding": "^7.10.4", - "@babel/plugin-proposal-optional-chaining": "^7.11.0", - "@babel/plugin-proposal-private-methods": "^7.10.4", - "@babel/plugin-proposal-unicode-property-regex": "^7.10.4", + "@babel/helper-validator-option": "^7.12.1", + "@babel/plugin-proposal-async-generator-functions": "^7.12.1", + "@babel/plugin-proposal-class-properties": "^7.12.1", + "@babel/plugin-proposal-dynamic-import": "^7.12.1", + "@babel/plugin-proposal-export-namespace-from": "^7.12.1", + "@babel/plugin-proposal-json-strings": "^7.12.1", + "@babel/plugin-proposal-logical-assignment-operators": "^7.12.1", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", + "@babel/plugin-proposal-numeric-separator": "^7.12.7", + "@babel/plugin-proposal-object-rest-spread": "^7.12.1", + "@babel/plugin-proposal-optional-catch-binding": "^7.12.1", + "@babel/plugin-proposal-optional-chaining": "^7.12.7", + "@babel/plugin-proposal-private-methods": "^7.12.1", + "@babel/plugin-proposal-unicode-property-regex": "^7.12.1", "@babel/plugin-syntax-async-generators": "^7.8.0", - "@babel/plugin-syntax-class-properties": "^7.10.4", + "@babel/plugin-syntax-class-properties": "^7.12.1", "@babel/plugin-syntax-dynamic-import": "^7.8.0", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", "@babel/plugin-syntax-json-strings": "^7.8.0", @@ -954,52 +936,49 @@ "@babel/plugin-syntax-object-rest-spread": "^7.8.0", "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", "@babel/plugin-syntax-optional-chaining": "^7.8.0", - "@babel/plugin-syntax-top-level-await": "^7.10.4", - "@babel/plugin-transform-arrow-functions": "^7.10.4", - "@babel/plugin-transform-async-to-generator": "^7.10.4", - "@babel/plugin-transform-block-scoped-functions": "^7.10.4", - "@babel/plugin-transform-block-scoping": "^7.10.4", - "@babel/plugin-transform-classes": "^7.10.4", - "@babel/plugin-transform-computed-properties": "^7.10.4", - "@babel/plugin-transform-destructuring": "^7.10.4", - "@babel/plugin-transform-dotall-regex": "^7.10.4", - "@babel/plugin-transform-duplicate-keys": "^7.10.4", - "@babel/plugin-transform-exponentiation-operator": "^7.10.4", - "@babel/plugin-transform-for-of": "^7.10.4", - "@babel/plugin-transform-function-name": "^7.10.4", - "@babel/plugin-transform-literals": "^7.10.4", - "@babel/plugin-transform-member-expression-literals": "^7.10.4", - "@babel/plugin-transform-modules-amd": "^7.10.4", - "@babel/plugin-transform-modules-commonjs": "^7.10.4", - "@babel/plugin-transform-modules-systemjs": "^7.10.4", - "@babel/plugin-transform-modules-umd": "^7.10.4", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.10.4", - "@babel/plugin-transform-new-target": "^7.10.4", - "@babel/plugin-transform-object-super": "^7.10.4", - "@babel/plugin-transform-parameters": "^7.10.4", - "@babel/plugin-transform-property-literals": "^7.10.4", - "@babel/plugin-transform-regenerator": "^7.10.4", - "@babel/plugin-transform-reserved-words": "^7.10.4", - "@babel/plugin-transform-shorthand-properties": "^7.10.4", - "@babel/plugin-transform-spread": "^7.11.0", - "@babel/plugin-transform-sticky-regex": "^7.10.4", - "@babel/plugin-transform-template-literals": "^7.10.4", - "@babel/plugin-transform-typeof-symbol": "^7.10.4", - "@babel/plugin-transform-unicode-escapes": "^7.10.4", - "@babel/plugin-transform-unicode-regex": "^7.10.4", + "@babel/plugin-syntax-top-level-await": "^7.12.1", + "@babel/plugin-transform-arrow-functions": "^7.12.1", + "@babel/plugin-transform-async-to-generator": "^7.12.1", + "@babel/plugin-transform-block-scoped-functions": "^7.12.1", + "@babel/plugin-transform-block-scoping": "^7.12.1", + "@babel/plugin-transform-classes": "^7.12.1", + "@babel/plugin-transform-computed-properties": "^7.12.1", + "@babel/plugin-transform-destructuring": "^7.12.1", + "@babel/plugin-transform-dotall-regex": "^7.12.1", + "@babel/plugin-transform-duplicate-keys": "^7.12.1", + "@babel/plugin-transform-exponentiation-operator": "^7.12.1", + "@babel/plugin-transform-for-of": "^7.12.1", + "@babel/plugin-transform-function-name": "^7.12.1", + "@babel/plugin-transform-literals": "^7.12.1", + "@babel/plugin-transform-member-expression-literals": "^7.12.1", + "@babel/plugin-transform-modules-amd": "^7.12.1", + "@babel/plugin-transform-modules-commonjs": "^7.12.1", + "@babel/plugin-transform-modules-systemjs": "^7.12.1", + "@babel/plugin-transform-modules-umd": "^7.12.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.1", + "@babel/plugin-transform-new-target": "^7.12.1", + "@babel/plugin-transform-object-super": "^7.12.1", + "@babel/plugin-transform-parameters": "^7.12.1", + "@babel/plugin-transform-property-literals": "^7.12.1", + "@babel/plugin-transform-regenerator": "^7.12.1", + "@babel/plugin-transform-reserved-words": "^7.12.1", + "@babel/plugin-transform-shorthand-properties": "^7.12.1", + "@babel/plugin-transform-spread": "^7.12.1", + "@babel/plugin-transform-sticky-regex": "^7.12.7", + "@babel/plugin-transform-template-literals": "^7.12.1", + "@babel/plugin-transform-typeof-symbol": "^7.12.10", + "@babel/plugin-transform-unicode-escapes": "^7.12.1", + "@babel/plugin-transform-unicode-regex": "^7.12.1", "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.11.0", - "browserslist": "^4.12.0", - "core-js-compat": "^3.6.2", - "invariant": "^2.2.2", - "levenary": "^1.1.1", + "@babel/types": "^7.12.10", + "core-js-compat": "^3.8.0", "semver": "^5.5.0" } }, "@babel/preset-modules": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.3.tgz", - "integrity": "sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", + "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -1010,9 +989,9 @@ } }, "@babel/register": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.10.5.tgz", - "integrity": "sha512-eYHdLv43nyvmPn9bfNfrcC4+iYNwdQ8Pxk1MFJuU/U5LpSYl/PH4dFMazCYZDFVi8ueG3shvO+AQfLrxpYulQw==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.12.10.tgz", + "integrity": "sha512-EvX/BvMMJRAA3jZgILWgbsrHwBQvllC5T8B29McyME8DvkdOxk4ujESfrMvME8IHSDvWXrmMXxPvA/lx2gqPLQ==", "dev": true, "requires": { "find-cache-dir": "^2.0.0", @@ -1023,57 +1002,62 @@ } }, "@babel/runtime": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz", - "integrity": "sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" } }, "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" + }, + "dependencies": { + "@babel/parser": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.10.tgz", + "integrity": "sha512-PJdRPwyoOqFAWfLytxrWwGrAxghCgh/yTNCYciOz8QgjflA7aZhECPZAa2VUedKg2+QMWkI0L9lynh2SNmNEgA==", + "dev": true + } } }, "@babel/traverse": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", - "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.10.tgz", + "integrity": "sha512-6aEtf0IeRgbYWzta29lePeYSk+YAFIC3kyqESeft8o5CkFlYIMX+EQDDWEiAQ9LHOA3d0oHdgrSsID/CKqXJlg==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.0", + "@babel/generator": "^7.12.10", "@babel/helper-function-name": "^7.10.4", "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.11.0", - "@babel/types": "^7.11.0", + "@babel/parser": "^7.12.10", + "@babel/types": "^7.12.10", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" }, "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } + "@babel/parser": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.10.tgz", + "integrity": "sha512-PJdRPwyoOqFAWfLytxrWwGrAxghCgh/yTNCYciOz8QgjflA7aZhECPZAa2VUedKg2+QMWkI0L9lynh2SNmNEgA==", + "dev": true } } }, "@babel/types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", - "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.10.tgz", + "integrity": "sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", @@ -1081,6 +1065,47 @@ "to-fast-properties": "^2.0.0" } }, + "@eslint/eslintrc": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", + "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + } + } + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1207,6 +1232,22 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "@types/eslint": { + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.6.tgz", + "integrity": "sha512-I+1sYH+NPQ3/tVqCeUSBwTE/0heyvtXqpIopUUArlBm0Kpocb8FbMa3AZ/ASKIFpN3rnEx932TTXDbt9OXsNDw==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/estree": { + "version": "0.0.45", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.45.tgz", + "integrity": "sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g==", + "dev": true + }, "@types/glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.2.tgz", @@ -1305,6 +1346,12 @@ } } }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, "@webassemblyjs/ast": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", @@ -1515,9 +1562,9 @@ } }, "acorn-jsx": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", - "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", "dev": true }, "acorn-walk": { @@ -1663,17 +1710,11 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, - "array.prototype.map": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array.prototype.map/-/array.prototype.map-1.0.2.tgz", - "integrity": "sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.4" - } + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true }, "asn1": { "version": "0.2.4", @@ -1787,67 +1828,146 @@ "dev": true }, "babel-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", - "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.2.tgz", + "integrity": "sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g==", "dev": true, "requires": { - "find-cache-dir": "^2.1.0", + "find-cache-dir": "^3.3.1", "loader-utils": "^1.4.0", - "mkdirp": "^0.5.3", - "pify": "^4.0.1", + "make-dir": "^3.1.0", "schema-utils": "^2.6.5" - } - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "dev": true, - "requires": { - "object.assign": "^4.1.0" - } - }, - "babel-plugin-module-resolver": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.0.0.tgz", - "integrity": "sha512-3pdEq3PXALilSJ6dnC4wMWr0AZixHRM4utpdpBR9g5QG7B7JwWyukQv7a9hVxkbGFl+nQbrHDqqQOIBtTXTP/Q==", - "dev": true, - "requires": { - "find-babel-config": "^1.2.0", - "glob": "^7.1.6", - "pkg-up": "^3.1.0", - "reselect": "^4.0.0", - "resolve": "^1.13.1" }, "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" } }, - "pkg-up": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "make-dir": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "requires": { - "find-up": "^3.0.0" + "semver": "^6.0.0" } - } - } - }, - "balanced-match": { - "version": "1.0.0", + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-plugin-module-resolver": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.0.0.tgz", + "integrity": "sha512-3pdEq3PXALilSJ6dnC4wMWr0AZixHRM4utpdpBR9g5QG7B7JwWyukQv7a9hVxkbGFl+nQbrHDqqQOIBtTXTP/Q==", + "dev": true, + "requires": { + "find-babel-config": "^1.2.0", + "glob": "^7.1.6", + "pkg-up": "^3.1.0", + "reselect": "^4.0.0", + "resolve": "^1.13.1" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + } + } + }, + "balanced-match": { + "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true @@ -2108,15 +2228,16 @@ } }, "browserslist": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.0.tgz", - "integrity": "sha512-pUsXKAF2lVwhmtpeA3LJrZ76jXuusrNyhduuQs7CDFf9foT4Y38aQOserd2lMe5DSSrjf3fx34oHwryuvxAUgQ==", + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.15.0.tgz", + "integrity": "sha512-IJ1iysdMkGmjjYeRlDU8PQejVwxvVO5QOfXH7ylW31GO6LwNRSmm/SgRXtNsEXqMLl2e+2H5eEJ7sfynF8TCaQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001111", - "electron-to-chromium": "^1.3.523", - "escalade": "^3.0.2", - "node-releases": "^1.1.60" + "caniuse-lite": "^1.0.30001164", + "colorette": "^1.2.1", + "electron-to-chromium": "^1.3.612", + "escalade": "^3.1.1", + "node-releases": "^1.1.67" } }, "buffer": { @@ -2260,9 +2381,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001114", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001114.tgz", - "integrity": "sha512-ml/zTsfNBM+T1+mjglWRPgVsu2L76GAaADKX5f4t0pbhttEp0WMawJsHDYlFkVZkoA+89uvBRrVrEE4oqenzXQ==", + "version": "1.0.30001165", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001165.tgz", + "integrity": "sha512-8cEsSMwXfx7lWSUMA2s08z9dIgsnR5NAqjXP23stdsU3AUWkCr/rr4s4OFtHXn5XXr6+7kam3QFVoYyXNPdJPA==", "dev": true }, "caseless": { @@ -2314,43 +2435,19 @@ "dev": true }, "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", "dev": true, "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", - "fsevents": "~2.1.1", + "fsevents": "~2.1.2", "glob-parent": "~5.1.0", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - }, - "dependencies": { - "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", - "dev": true - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - } + "readdirp": "~3.5.0" } }, "chownr": { @@ -2462,17 +2559,6 @@ } } }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -2498,6 +2584,12 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, + "colorette": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", + "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", + "dev": true + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -2584,12 +2676,12 @@ "dev": true }, "core-js-compat": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", - "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.8.1.tgz", + "integrity": "sha512-a16TLmy9NVD1rkjUGbwuyWkiDoN0FDpAwrfLONvHFQx0D9k7J9y0srwMT8QP/Z6HE3MIFaVynEeYwZwPX1o5RQ==", "dev": true, "requires": { - "browserslist": "^4.8.5", + "browserslist": "^4.15.0", "semver": "7.0.0" }, "dependencies": { @@ -3224,9 +3316,9 @@ } }, "electron-to-chromium": { - "version": "1.3.533", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.533.tgz", - "integrity": "sha512-YqAL+NXOzjBnpY+dcOKDlZybJDCOzgsq4koW3fvyty/ldTmsb4QazZpOWmVvZ2m0t5jbBf7L0lIGU3BUipwG+A==", + "version": "1.3.621", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.621.tgz", + "integrity": "sha512-FeIuBzArONbAmKmZIsZIFGu/Gc9AVGlVeVbhCq+G2YIl6QkT0TDn2HKN/FMf1btXEB9kEmIuQf3/lBTVAbmFOg==", "dev": true }, "elliptic": { @@ -3303,14 +3395,6 @@ "dev": true, "requires": { "ansi-colors": "^4.1.1" - }, - "dependencies": { - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - } } }, "entities": { @@ -3337,65 +3421,6 @@ "stackframe": "^1.1.1" } }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true - }, - "es-get-iterator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.0.tgz", - "integrity": "sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==", - "dev": true, - "requires": { - "es-abstract": "^1.17.4", - "has-symbols": "^1.0.1", - "is-arguments": "^1.0.4", - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-string": "^1.0.5", - "isarray": "^2.0.5" - }, - "dependencies": { - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - } - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, "es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -3403,9 +3428,9 @@ "dev": true }, "escalade": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.0.2.tgz", - "integrity": "sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true }, "escape-string-regexp": { @@ -3476,25 +3501,26 @@ } }, "eslint": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.6.0.tgz", - "integrity": "sha512-QlAManNtqr7sozWm5TF4wIH9gmUm2hE3vNRUvyoYAa4y1l5/jxD/PQStEjBMQtCqZmSep8UxrcecI60hOpe61w==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.15.0.tgz", + "integrity": "sha512-Vr64xFDT8w30wFll643e7cGrIkPEU50yIiI36OdSIDoSGguIeaLzBo0vpGvzo9RECUqq7htURfwEtKqwytkqzA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^0.2.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", "enquirer": "^2.3.5", - "eslint-scope": "^5.1.0", + "eslint-scope": "^5.1.1", "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^1.3.0", - "espree": "^7.2.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", "esquery": "^1.2.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "file-entry-cache": "^6.0.0", "functional-red-black-tree": "^1.0.1", "glob-parent": "^5.0.0", "globals": "^12.1.0", @@ -3526,12 +3552,11 @@ "dev": true }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -3560,15 +3585,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, "globals": { "version": "12.4.0", "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", @@ -3584,11 +3600,23 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "strip-ansi": { "version": "6.0.0", @@ -3600,154 +3628,151 @@ } }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, - "eslint-loader": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-4.0.2.tgz", - "integrity": "sha512-EDpXor6lsjtTzZpLUn7KmXs02+nIjGcgees9BYjNkWra3jVq5vVa8IoCKgzT2M7dNNeoMBtaSG83Bd40N3poLw==", + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { - "find-cache-dir": "^3.3.1", - "fs-extra": "^8.1.0", - "loader-utils": "^2.0.0", - "object-hash": "^2.0.3", - "schema-utils": "^2.6.5" + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" }, "dependencies": { - "find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } } + } + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true + }, + "eslint-webpack-plugin": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-2.4.1.tgz", + "integrity": "sha512-cj8iPWZKuAiVD8MMgTSunyMCAvxQxp5mxoPHZl1UMGkApFXaXJHdCFcCR+oZEJbBNhReNa5SjESIn34uqUbBtg==", + "dev": true, + "requires": { + "@types/eslint": "^7.2.4", + "arrify": "^2.0.1", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", + "schema-utils": "^3.0.0" + }, + "dependencies": { + "@types/json-schema": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", + "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", + "dev": true }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { - "semver": "^6.0.0" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", "dev": true, "requires": { - "p-limit": "^2.2.0" + "braces": "^3.0.1", + "picomatch": "^2.0.5" } }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", "dev": true, "requires": { - "find-up": "^4.0.0" + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true } } }, - "eslint-scope": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", - "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - }, "espree": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.2.0.tgz", - "integrity": "sha512-H+cQ3+3JYRMEIOl87e7QdHX70ocly5iW4+dttuR8iYSPr/hXKFb+7dBsZ7+u1adC4VrnPlTkv0+OwuPnDop19g==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "requires": { - "acorn": "^7.3.1", - "acorn-jsx": "^5.2.0", + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } } }, "esprima": { @@ -3992,12 +4017,12 @@ "dev": true }, "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", + "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", "dev": true, "requires": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" } }, "file-uri-to-path": { @@ -4078,37 +4103,36 @@ } }, "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { - "is-buffer": "~2.0.3" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" }, "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } } } }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - } - }, "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", + "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==", "dev": true }, "flush-write-stream": { @@ -4190,25 +4214,6 @@ "integrity": "sha512-33X7H/wdfO99GdRLLgkjUrD4geAFdq/Uv0kl3HD4da6HDixd2GUg8Mw7dahLCV9r/EARkmtYBB6Tch4EEokFTQ==", "dev": true }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - } - } - }, "fs-write-stream-atomic": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", @@ -4247,9 +4252,9 @@ "dev": true }, "gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true }, "get-caller-file": { @@ -4418,15 +4423,6 @@ "har-schema": "^2.0.0" } }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -4649,9 +4645,9 @@ "dev": true }, "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz", + "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==", "dev": true, "requires": { "parent-module": "^1.0.0", @@ -4703,9 +4699,9 @@ "dev": true }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", "dev": true }, "interpret": { @@ -4714,15 +4710,6 @@ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, "ip-regex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", @@ -4749,12 +4736,6 @@ } } }, - "is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", - "dev": true - }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -4770,12 +4751,6 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, - "is-callable": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", - "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", - "dev": true - }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -4796,12 +4771,6 @@ } } }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", @@ -4848,12 +4817,6 @@ "is-extglob": "^2.1.1" } }, - "is-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.1.tgz", - "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==", - "dev": true - }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -4885,9 +4848,9 @@ } }, "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, "is-plain-object": { @@ -4900,40 +4863,10 @@ } }, "is-potential-custom-element-name": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", - "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", - "dev": true - }, - "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-set": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.1.tgz", - "integrity": "sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==", - "dev": true - }, - "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "dev": true - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", + "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", + "dev": true }, "is-typedarray": { "version": "1.0.0", @@ -5143,20 +5076,32 @@ "istanbul-lib-report": "^3.0.0" } }, - "iterate-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/iterate-iterator/-/iterate-iterator-1.0.1.tgz", - "integrity": "sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw==", - "dev": true - }, - "iterate-value": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/iterate-value/-/iterate-value-1.0.2.tgz", - "integrity": "sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==", + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dev": true, "requires": { - "es-get-iterator": "^1.0.2", - "iterate-iterator": "^1.0.1" + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "js-tokens": { @@ -5191,9 +5136,9 @@ "dev": true }, "jsdoc": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.5.tgz", - "integrity": "sha512-SbY+i9ONuxSK35cgVHaI8O9senTE4CDYAmGSDJ5l3+sfe62Ff4gy96osy6OW84t4K4A8iGnMrlRrsSItSNp3RQ==", + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.6.tgz", + "integrity": "sha512-znR99e1BHeyEkSvgDDpX0sTiTu+8aQyDl9DawrkOGZTTW8hv0deIFXx87114zJ7gRaDZKVQD/4tr1ifmJp9xhQ==", "dev": true, "requires": { "@babel/parser": "^7.9.4", @@ -5311,15 +5256,6 @@ "minimist": "^1.2.5" } }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -5353,21 +5289,12 @@ "graceful-fs": "^4.1.9" } }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "klona": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz", + "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==", "dev": true }, - "levenary": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", - "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", - "dev": true, - "requires": { - "leven": "^3.1.0" - } - }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -5467,12 +5394,11 @@ }, "dependencies": { "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -5524,15 +5450,6 @@ "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", "dev": true }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, "lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -5635,6 +5552,12 @@ "readable-stream": "^2.0.1" } }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -5839,15 +5762,16 @@ } }, "mocha": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.1.3.tgz", - "integrity": "sha512-ZbaYib4hT4PpF4bdSO2DohooKXIn4lDeiYqB+vTmCdr6l2woW0b6H3pf5x4sM5nwQMru9RvjjHYWVGltR50ZBw==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz", + "integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==", "dev": true, "requires": { + "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.4.2", - "debug": "4.1.1", + "chokidar": "3.4.3", + "debug": "4.2.0", "diff": "4.0.2", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", @@ -5858,33 +5782,25 @@ "log-symbols": "4.0.0", "minimatch": "3.0.4", "ms": "2.1.2", - "object.assign": "4.1.0", - "promise.allsettled": "1.0.2", - "serialize-javascript": "4.0.0", - "strip-json-comments": "3.0.1", - "supports-color": "7.1.0", + "nanoid": "3.1.12", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "7.2.0", "which": "2.0.2", "wide-align": "1.1.3", - "workerpool": "6.0.0", + "workerpool": "6.0.2", "yargs": "13.3.2", "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.1" + "yargs-unparser": "2.0.0" }, "dependencies": { - "chokidar": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", - "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", "dev": true, "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.4.0" + "ms": "2.1.2" } }, "diff": { @@ -5939,12 +5855,12 @@ } }, "p-limit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", - "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { - "p-try": "^2.0.0" + "yocto-queue": "^0.1.0" } }, "p-locate": { @@ -5962,25 +5878,19 @@ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "readdirp": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", - "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", "dev": true, "requires": { - "picomatch": "^2.2.1" + "randombytes": "^2.1.0" } }, - "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", - "dev": true - }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -6015,6 +5925,12 @@ "dev": true, "optional": true }, + "nanoid": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", + "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", + "dev": true + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -6131,9 +6047,9 @@ } }, "node-releases": { - "version": "1.1.60", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.60.tgz", - "integrity": "sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==", + "version": "1.1.67", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.67.tgz", + "integrity": "sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg==", "dev": true }, "normalize-path": { @@ -6452,18 +6368,6 @@ } } }, - "object-hash": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.0.3.tgz", - "integrity": "sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg==", - "dev": true - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -6803,19 +6707,6 @@ "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", "dev": true }, - "promise.allsettled": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.2.tgz", - "integrity": "sha512-UpcYW5S1RaNKT6pd+s9jp9K9rlQge1UXKskec0j6Mmuq7UJCvlS2J2/s/yuPN8ehftf9HXMxWlKiPbGGUzpoRg==", - "dev": true, - "requires": { - "array.prototype.map": "^1.0.1", - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "iterate-value": "^1.0.0" - } - }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -6956,18 +6847,18 @@ } }, "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", "dev": true, "requires": { - "picomatch": "^2.0.4" + "picomatch": "^2.2.1" } }, "regenerate": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz", - "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", "dev": true }, "regenerate-unicode-properties": { @@ -7011,9 +6902,9 @@ "dev": true }, "regexpu-core": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz", - "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", + "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", "dev": true, "requires": { "regenerate": "^1.4.0", @@ -7301,31 +7192,101 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sass": { - "version": "1.26.10", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.26.10.tgz", - "integrity": "sha512-bzN0uvmzfsTvjz0qwccN1sPm2HxxpNI/Xa+7PlUEMS+nQvbyuEK7Y0qFqxlPHhiNHb1Ze8WQJtU31olMObkAMw==", + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.30.0.tgz", + "integrity": "sha512-26EUhOXRLaUY7+mWuRFqGeGGNmhB1vblpTENO1Z7mAzzIZeVxZr9EZoaY1kyGLFWdSOZxRMAufiN2mkbO6dAlw==", "dev": true, "requires": { "chokidar": ">=2.0.0 <4.0.0" } }, "sass-loader": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz", - "integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-10.1.0.tgz", + "integrity": "sha512-ZCKAlczLBbFd3aGAhowpYEy69Te3Z68cg8bnHHl6WnSCvnKpbM6pQrz957HWMa8LKVuhnD9uMplmMAHwGQtHeg==", "dev": true, "requires": { - "clone-deep": "^4.0.1", - "loader-utils": "^1.2.3", - "neo-async": "^2.6.1", - "schema-utils": "^2.6.1", - "semver": "^6.3.0" + "klona": "^2.0.4", + "loader-utils": "^2.0.0", + "neo-async": "^2.6.2", + "schema-utils": "^3.0.0", + "semver": "^7.3.2" }, "dependencies": { + "@types/json-schema": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", + "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true } } @@ -7430,15 +7391,6 @@ "safe-buffer": "^5.0.1" } }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -7645,25 +7597,56 @@ "dev": true }, "source-map-loader": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-1.0.1.tgz", - "integrity": "sha512-DE4CJyfCVoxFLsHyuVE9Sjcib8cs5qdmOq3wcev1Un/r6F2AfQJDhag4rzpPPA48A2QZyV3CTbc+NGoFMfKIOQ==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-1.1.3.tgz", + "integrity": "sha512-6YHeF+XzDOrT/ycFJNI53cgEsp/tHTMl37hi7uVyqFAlTXW109JazaQCkbc+jjoL2637qkH1amLi+JzrIpt5lA==", "dev": true, "requires": { - "data-urls": "^2.0.0", - "iconv-lite": "^0.5.1", + "abab": "^2.0.5", + "iconv-lite": "^0.6.2", "loader-utils": "^2.0.0", - "schema-utils": "^2.6.6", - "source-map": "^0.6.0" + "schema-utils": "^3.0.0", + "source-map": "^0.6.1", + "whatwg-mimetype": "^2.3.0" }, "dependencies": { + "@types/json-schema": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", + "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", + "dev": true + }, + "abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, "iconv-lite": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.2.tgz", - "integrity": "sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", "dev": true, "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "loader-utils": { @@ -7677,6 +7660,17 @@ "json5": "^2.1.2" } }, + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -7902,26 +7896,6 @@ } } }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -8356,12 +8330,6 @@ "imurmurhash": "^0.1.4" } }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", @@ -9025,9 +8993,9 @@ } }, "workerpool": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.0.tgz", - "integrity": "sha512-fU2OcNA/GVAJLLyKUoHkAgIhKb0JoCpSjLC/G2vYKxUjVmQwGbRVeoPJ1a8U4pnVofz4AQV5Y/NEw8oKqxEBtA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", + "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", "dev": true }, "wrap-ansi": { @@ -9090,15 +9058,6 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, "write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", @@ -9216,80 +9175,36 @@ } }, "yargs-unparser": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.1.tgz", - "integrity": "sha512-qZV14lK9MWsGCmcr7u5oXGH0dbGqZAIxTDrWXZDo5zUr6b6iUmelNKO6x6R1dQT24AH3LgRxJpr8meWy2unolA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "requires": { - "camelcase": "^5.3.1", - "decamelize": "^1.2.0", - "flat": "^4.1.0", - "is-plain-obj": "^1.1.0", - "yargs": "^14.2.3" + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "yargs": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", - "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^15.0.1" - } - }, - "yargs-parser": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", - "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } } } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/package.json b/package.json index 892511e1..18411c54 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "locuszoom", - "version": "0.13.0-beta.2", + "version": "0.13.0-beta.3", "main": "dist/locuszoom.app.min.js", "module": "esm/index.js", "sideEffects": true, @@ -42,25 +42,25 @@ "d3": "^5.16.0" }, "devDependencies": { - "@babel/core": "^7.11.1", - "@babel/preset-env": "^7.11.0", - "@babel/register": "^7.10.5", - "babel-loader": "^8.1.0", + "@babel/core": "^7.12.10", + "@babel/preset-env": "^7.12.0", + "@babel/register": "^7.12.10", + "babel-loader": "^8.2.2", "babel-plugin-module-resolver": "^4.0.0", "chai": "^4.2.0", "clean-webpack-plugin": "^3.0.0", - "eslint": "^7.6.0", - "eslint-loader": "^4.0.2", + "eslint": "^7.15.0", + "eslint-webpack-plugin": "^2.4.1", "friendly-errors-webpack-plugin": "^1.7.0", - "jsdoc": "^3.6.5", + "jsdoc": "^3.6.6", "jsdom": "^16.4.0", "jsdom-global": "^3.0.2", - "mocha": "~8.1.3", + "mocha": "~8.2.1", "nyc": "^15.1.0", - "sass": "^1.26.10", - "sass-loader": "^8.0.2", + "sass": "^1.30.0", + "sass-loader": "^10.1.0", "sinon": "^6.3.5", - "source-map-loader": "^1.0.1", + "source-map-loader": "^1.1.3", "webpack": "^4.44.1", "webpack-cli": "^3.3.12", "webpack-merge": "^4.2.2" diff --git a/test/unit/components/test_datalayer.js b/test/unit/components/test_datalayer.js index d14d5d91..5b0e9755 100644 --- a/test/unit/components/test_datalayer.js +++ b/test/unit/components/test_datalayer.js @@ -1,5 +1,6 @@ import {assert} from 'chai'; import * as d3 from 'd3'; +import sinon from 'sinon'; import { SCALABLE } from '../../../esm/registry'; import BaseDataLayer from '../../../esm/components/data_layer/base'; @@ -584,9 +585,8 @@ describe('LocusZoom.DataLayer', function () { }); }); - describe('Tool tip functions', function () { + describe('Tool tip display', function () { beforeEach(function () { - this.plot = null; this.layout = { panels: [ { @@ -671,7 +671,6 @@ describe('LocusZoom.DataLayer', function () { d.unselectElement(b); assert.isUndefined(d.tooltips[b_id]); }); - it('should allow tooltip open/close state to be tracked separately from element selection', function () { // Regression test for zombie tooltips returning after re-render const layer = this.plot.panels.p.data_layers.d; @@ -709,6 +708,96 @@ describe('LocusZoom.DataLayer', function () { }); }); + describe('data element behaviors', function () { + beforeEach(function() { + const data_sources = new DataSources() + .add('d', ['StaticJSON', [{ id: 'a', x: 1, y: 2 }, { id: 'b', x: 2, y:0 }, { id: 'c', x: 3, y:1 }]]); + + const layout = { + panels: [ + { + id: 'p', + data_layers: [ + { + id: 'd', + type: 'scatter', + fields: ['d:id', 'd:x', 'd:y'], + id_field: 'd:id', + x_axis: { field: 'd:x' }, + y_axis: { field: 'd:y'}, + behaviors: { + onclick: [{ action: 'link', href: 'https://dev.example/{{d:id}}', target: '_blank' }], + onmouseover: [{ action: 'set', status: 'highlighted', exclusive: true }], + onmouseout: [{ action: 'unset', status: 'highlighted' }], + onshiftclick: [{ action: 'toggle', status: 'selected' }], + }, + }, + ], + }, + ], + }; + d3.select('body').append('div').attr('id', 'plot'); + this.plot = populate('#plot', data_sources, layout); + }); + it('can link to an external website', function () { + // NOTE: Not all variants of this behavior are tested. This only tests opening links in another window. + // This is because JSDom sometimes has issues mocking window.location. + return this.plot.applyState().then(() => { + const openStub = sinon.stub(window, 'open'); + + // Select the first data element + const datapoint = this.plot.panels.p.data_layers.d.svg.group.select('.lz-data_layer-scatter'); + + assert.notEqual(datapoint.size(), 0, 'nodes are rendered'); + datapoint.dispatch('click', { bubbles: true} ); + + assert.ok(openStub.calledOnce, 'window.open was called with the specified location and target'); + assert.ok(openStub.calledWith('https://dev.example/a', '_blank'), 'The URL can incorporate parameters from the specified data element'); + }); + }); + it('applies status-based styles when an item receives mouse events', function () { + // Since sequence is important, this test exercises multiple scenarios in a specific order + return this.plot.applyState().then(() => { + // Select the first and second data points + const first = this.plot.panels.p.data_layers.d.svg.group.select('.lz-data_layer-scatter'); + const second = this.plot.panels.p.data_layers.d.svg.group.selectAll('.lz-data_layer-scatter').filter((d, i) => i === 1); + + assert.notEqual(first.size(), 0, 'nodes are rendered'); + assert.notEqual(second.size(), 0, 'nodes are rendered'); + first.dispatch('mouseover', { bubbles: true} ); + + assert.ok(first.node().classList.contains('lz-data_layer-scatter-highlighted'), 'Style is applied appropriately'); + assert.notOk(second.node().classList.contains('lz-data_layer-scatter-highlighted'), 'Style is only applied to the requested node'); + + // When a different element receives mouseover, check that exclusivity and styling are applied correctly + second.dispatch('mouseover', { bubbles: true} ); + assert.notOk(first.node().classList.contains('lz-data_layer-scatter-highlighted'), 'Style is removed from other nodes'); + assert.ok(second.node().classList.contains('lz-data_layer-scatter-highlighted'), 'Style is applied to the new mouseover node'); + + // On mouse out, styles are removed + second.dispatch('mouseout', { bubbles: true} ); + assert.notOk(second.node().classList.contains('lz-data_layer-scatter-highlighted'), 'Style is removed on mouseout'); + }); + }); + it('recognizes keyboard modifiers as distinct events', function () { + return this.plot.applyState().then(() => { + const openStub = sinon.stub(window, 'open'); + + // Select the first data element + const datapoint = this.plot.panels.p.data_layers.d.svg.group.select('.lz-data_layer-scatter'); + + assert.notEqual(datapoint.size(), 0, 'nodes are rendered'); + datapoint.node().dispatchEvent(new MouseEvent('click', {bubbles: true, shiftKey: true})); + + assert.ok(openStub.notCalled, 'The basic click event did not fire because a modifier key was used'); + assert.ok(datapoint.node().classList.contains('lz-data_layer-scatter-selected'), 'Style is applied appropriately'); + }); + }); + afterEach(function () { + sinon.restore(); + }); + }); + describe('Filtering operations', function () { it('can filter numeric data', function () { const layer = new BaseDataLayer({id: 'test', id_field: 'a'}); diff --git a/test/unit/components/test_panel.js b/test/unit/components/test_panel.js index 6e5bc63b..38c4ac24 100644 --- a/test/unit/components/test_panel.js +++ b/test/unit/components/test_panel.js @@ -280,32 +280,36 @@ describe('Panel', function() { }); it('should have a loader object with show/update/animate/setPercentCompleted/hide methods, a showing boolean, and selectors', function() { - const loader = this.panel.loader; - assert.isObject(this.panel.loader); - assert.isFalse(loader.showing); - assert.isNull(loader.selector); - assert.isNull(loader.content_selector); - assert.isNull(loader.progress_selector); + return this.plot.applyState().then(() => { + const loader = this.panel.loader; + assert.isObject(this.panel.loader); + assert.isFalse(loader.showing); + assert.isNull(loader.selector); + assert.isNull(loader.content_selector); + assert.isNull(loader.progress_selector); + }); }); it('should show/hide/update on command and track shown status', function() { - const loader = this.panel.loader; - assert.isFalse(loader.showing); - assert.isNull(loader.selector); - assert.isNull(loader.content_selector); - assert.isNull(loader.progress_selector); - - loader.show('test content'); - assert.isTrue(loader.showing); - assert.isFalse(loader.selector.empty()); - assert.isFalse(loader.content_selector.empty()); - assert.equal(loader.content_selector.html(), 'test content'); - assert.isFalse(loader.progress_selector.empty()); - loader.hide(); - assert.isFalse(loader.showing); - assert.isNull(loader.selector); - assert.isNull(loader.content_selector); - assert.isNull(loader.progress_selector); + return this.plot.applyState().then(() => { + const loader = this.panel.loader; + assert.isFalse(loader.showing); + assert.isNull(loader.selector); + assert.isNull(loader.content_selector); + assert.isNull(loader.progress_selector); + + loader.show('test content'); + assert.isTrue(loader.showing); + assert.isFalse(loader.selector.empty()); + assert.isFalse(loader.content_selector.empty()); + assert.equal(loader.content_selector.html(), 'test content'); + assert.isFalse(loader.progress_selector.empty()); + loader.hide(); + assert.isFalse(loader.showing); + assert.isNull(loader.selector); + assert.isNull(loader.content_selector); + assert.isNull(loader.progress_selector); + }); }); it('should allow for animating or showing discrete percentages of completion', function() { diff --git a/test/unit/ext/test_ext_intervals-track.js b/test/unit/ext/test_ext_intervals-track.js index 6dc51502..ac591172 100644 --- a/test/unit/ext/test_ext_intervals-track.js +++ b/test/unit/ext/test_ext_intervals-track.js @@ -1,8 +1,12 @@ import {assert} from 'chai'; +import sinon from 'sinon'; import LocusZoom from 'locuszoom'; import {DATA_LAYERS, LAYOUTS} from '../../../esm/registry'; import intervals_plugin from '../../../esm/ext/lz-intervals-track'; +import DataSources from '../../../esm/data'; +import * as d3 from 'd3'; +import {populate} from '../../../esm/helpers/display'; /** * Interval annotation track @@ -122,4 +126,82 @@ describe('Interval annotation track', function () { ); }); }); + + describe('collision detection and category grouping', function () { + beforeEach(function() { + this.plot = null; + const data_sources = new DataSources() + .add('intervals', ['StaticJSON', [ + { start: 100, end: 200, state_id: 'thing1', state_name: 'redfish', itemRgb: '255,0,0' }, + ]]); + + const layout = { + panels: [ LAYOUTS.get('panel', 'intervals') ], + state: { chr: 'X', start: 1, end: 500 }, + width: 800, height: 550, + }; + layout.panels[0].data_layers[0].split_tracks = true; + + d3.select('body').append('div').attr('id', 'plot'); + this.plot = populate('#plot', data_sources, layout); + this._intervals_source = data_sources.get('intervals'); + this._intervals_layer = this.plot.panels.intervals.data_layers.intervals; + }); + + it('re-renders the y-axis when categories change', function () { + return this.plot.applyState().then(() => { + assert.deepEqual(this._intervals_layer._categories, ['redfish'], 'Correct initial categories'); + + const renderSpy = sinon.spy(this._intervals_layer, 'updateSplitTrackAxis'); + + // Replace the original data and trigger a synchronous re-render (no new data fetching) + this._intervals_layer.data = [{ 'intervals:start': 100, 'intervals:end': 200, 'intervals:state_id': 'thing1', 'intervals:state_name': 'bluefish', 'intervals:itemRgb': '0,0,255' }]; + this._intervals_layer.render(); + + assert.ok(renderSpy.called, 'Axis was updated'); + assert.ok(renderSpy.calledWith(['bluefish']), 'Correct new categories were received'); + assert.deepEqual(this._intervals_layer._categories, ['bluefish'], 'Correct final categories'); + }); + }); + + it('does not re-render the y-axis when categories stay the same', function () { + return this.plot.applyState().then(() => { + assert.deepEqual(this._intervals_layer._categories, ['redfish'], 'Correct initial categories'); + + const renderSpy = sinon.spy(this._intervals_layer, 'updateSplitTrackAxis'); + + // Replace the original data and trigger a synchronous re-render (no new data fetching) + this._intervals_layer.data = [ // Same number of categories as original, different # of items + { 'intervals:start': 100, 'intervals:end': 200, 'intervals:state_id': 'thing1', 'intervals:state_name': 'redfish', 'intervals:itemRgb': '255,0,0' }, + { 'intervals:start': 101, 'intervals:end': 201, 'intervals:state_id': 'thing2', 'intervals:state_name': 'redfish', 'intervals:itemRgb': '255,0,0' }, + ]; + this._intervals_layer.render(); + + assert.ok(renderSpy.notCalled, 'Axis was not updated'); + assert.deepEqual(this._intervals_layer._categories, ['redfish'], 'Correct final categories'); + }); + }); + + it('draw status nodes only when relevant', function () { + return this.plot.applyState().then(() => { + const status_nodes = this._intervals_layer._statusnodes_group.node(); + assert.equal(status_nodes.childElementCount, 1, 'In split mode, 1 category means 1 status node'); + + // Selecting an element should also trigger a nice display for the associated "status node" background rectangle + const element = this._intervals_layer.data[0]; + assert.notOk(status_nodes.children[0].classList.contains('lz-data_layer-intervals-statusnode-selected'), 'Unselected elements are not styled as highlighted'); + this._intervals_layer.setElementStatus('selected', element, true, true); + assert.ok(status_nodes.children[0].classList.contains('lz-data_layer-intervals-statusnode-selected'), 'Selected elements get a highlighted style'); + + // Switch to merged tracks mode and count again + this._intervals_layer.layout.split_tracks = false; + this._intervals_layer.render(); + assert.equal(status_nodes.childElementCount, 0, 'No status nodes are rendered in merged tracks mode'); + }); + }); + + afterEach(function () { + sinon.restore(); + }); + }); }); diff --git a/webpack.common.cjs b/webpack.common.cjs index 2e52e59f..d749d406 100644 --- a/webpack.common.cjs +++ b/webpack.common.cjs @@ -1,8 +1,11 @@ /* eslint-env node */ const path = require('path'); const webpack = require('webpack'); -const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin'); + const { CleanWebpackPlugin } = require('clean-webpack-plugin'); +const ESLintPlugin = require('eslint-webpack-plugin'); +const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin'); + const PACKAGE = require('./package.json'); @@ -14,6 +17,7 @@ const FILENAMES = { LocusZoom: 'locuszoom.app.min.js', LzDynamicUrls: 'ext/lz-dynamic-urls.min.js', LzWidgetAddons: 'ext/lz-widget-addons.min.js', + LzForestTrack: 'ext/lz-forest-track.min.js', LzIntervalsTrack: 'ext/lz-intervals-track.min.js', LzCredibleSets: 'ext/lz-credible-sets.min.js', LzTabix: 'ext/lz-tabix-source.min.js', @@ -27,6 +31,7 @@ module.exports = { LocusZoom: path.resolve(srcPath, 'index.js'), LzDynamicUrls: path.resolve(srcPath, 'ext', 'lz-dynamic-urls.js'), LzWidgetAddons: path.resolve(srcPath, 'ext', 'lz-widget-addons.js'), + LzForestTrack: path.resolve(srcPath, 'ext', 'lz-forest-track.js'), LzIntervalsTrack: path.resolve(srcPath, 'ext', 'lz-intervals-track.js'), LzCredibleSets: path.resolve(srcPath, 'ext', 'lz-credible-sets.js'), LzTabix: path.resolve(srcPath, 'ext', 'lz-tabix-source.js'), @@ -39,28 +44,21 @@ module.exports = { }), new webpack.BannerPlugin(`Locuszoom ${PACKAGE.version}`), // add after uglify step new FriendlyErrorsWebpackPlugin(), + new ESLintPlugin(), ], resolve: { modules: [ - 'node_modules' + 'node_modules', ], }, module: { rules: [ - { - test: /\.m?js$/, - exclude: (file) => (/node_modules/.test(file)), - use: [ - { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } }, - 'eslint-loader' - ] - }, { test: /\.js$/, use: ['source-map-loader'], enforce: 'pre', }, - ] + ], }, output: { path: outputPath, @@ -83,5 +81,5 @@ module.exports = { 'gwas-credible-sets': 'gwasCredibleSets', 'tabix-reader': 'tabix', 'raremetal.js': 'raremetal', - } + }, };